Jak naprawić błąd „RuntimeError: Błąd CUDA: Wywołano asercję po stronie urządzenia”

Opublikowany: 2025-10-14

Jeśli pracujesz z modelami głębokiego uczenia się w PyTorch, prawdopodobnie natknąłeś się na zagadkowy komunikat o błędzie, taki jak:

 RuntimeError: CUDA error: device-side assert triggered

Ten błąd może być niezwykle frustrujący, szczególnie gdy nie masz pewności, co go powoduje. W przeciwieństwie do wielu błędów programistycznych, które dają pomocny ślad stosu wskazujący problem, ten może bardziej sprawiać wrażenie, jakby procesor graficzny podnosił brwi i cicho odchodził. Ale nie martw się — pod koniec tego przewodnika nie tylko zrozumiesz, dlaczego tak się dzieje, ale także jak metodycznie to naprawić.

Co właściwie oznacza ten błąd?

Ten błąd występuje, gdy jądro CUDA działające na GPU napotka błąd asercji. Jest to zwykle spowodowane nieprawidłowymi danymi wejściowymi lub nieoczekiwanym zachowaniem, którego możesz nie wyłapać w trybie procesora. Ponieważ jest to problem na poziomie procesora graficznego, ma tendencję do zawieszania się bez szczegółowych komunikatów debugowania, do których jesteśmy przyzwyczajeni w przypadku wyjątków Pythona.

Typowe przyczyny obejmują:

  • Błędy indeksowania (np. próba użycia indeksu klasy, który nie istnieje)
  • Nieprawidłowe kształty tensora
  • Nieprawidłowe użycie funkcji straty
  • Dane, które przekraczają oczekiwania (jak puste tensory)

Na szczęście przy właściwym podejściu można wyśledzić i rozwiązać ten problem — omówmy, jak to zrobić.

Proces diagnozowania i naprawy krok po kroku

1.Uruchom swój model na procesorze

Pierwszym krokiem diagnostycznym jest wyłączenie CUDA i uruchomienie wszystkiego na procesorze. Często, gdy działa na procesorze, PyTorch wyświetla wyraźniejsze komunikaty o błędach, ponieważ potwierdzenia po stronie urządzenia są teraz zgłaszane jako wyjątki Pythona z pełnym kontekstem.

Aby przełączyć się do trybu procesora, zmodyfikuj swój kod w następujący sposób:

 device = torch.device("cpu") model.to(device)

Jeśli potwierdzenie się nie powiedzie, powinieneś teraz uzyskać znacznie bardziej informacyjny ślad stosu.

2. Sprawdź etykiety docelowe

Jedną z najczęstszych przyczyn tego błędu są niewłaściwe etykiety klas — szczególnie w przypadku użycia nn.CrossEntropyLoss . Ta funkcja straty oczekuje, że docelowy tensor będzie zawierał indeksy klas z zakresu od 0 do num_classes - 1 . Jeśli więc Twój model generuje 10 klas, elementami docelowymi muszą być liczby całkowite od 0 do 9.

Częsty błąd:

 # Target contains 10 instead of 0–9 range target = torch.tensor([10])

Jeśli te indeksy są poza zakresem, natkniesz się na potwierdzenie na GPU. Aby to sprawdzić, użyj:

 assert target.max().item() < num_classes

Jeśli dokonujesz klasyfikacji obrazu, upewnij się również, że kształt celu jest odpowiedni. W przypadku CrossEntropyLoss powinien mieć kształt [batch_size] , a nie kodowany na gorąco!

 # Incorrect (for CrossEntropyLoss) target = torch.tensor([[0, 0, 1], [1, 0, 0]]) # Correct target = torch.tensor([2, 0])

3. Sprawdź moduł DataLoader pod kątem błędów

Czasami błąd pochodzi ze zbioru danych lub modułu DataLoader, zwłaszcza gdy jest używany w szkoleniu wsadowym. Jeśli niektóre etykiety są uszkodzone lub niespójne, mogą uszkodzić model na GPU.

Sprawdź dokładnie swój zbiór danych w ten sposób:

 for i, (x, y) in enumerate(loader): assert y.dtype == torch.long assert y.max().item() < num_classes assert x.shape[0] == y.shape[0]

Jest to szczególnie przydatne, jeśli zbiór danych jest zbudowany z pliku CSV lub niestandardowej logiki przetwarzania, która może po cichu wprowadzić nieprawidłowe etykiety.

introspektywny programista, sprawdzanie kodu, laptop, debugowanie

Inne częste pułapki

4. Niedopasowane rozmiary partii

Czasami model lub funkcja straty oczekuje, że dane wejściowe będą miały określony kształt. Niedopasowania mogą prowadzić do subtelnych problemów. Upewnij się, że wielkość partii w danych wejściowych i docelowych jest zgodna:

 # torchvision models usually expect [N, 3, 224, 224] assert inputs.shape[1:] == (3, 224, 224)

Ma to szczególne znaczenie w przypadku korzystania z modułu DataLoader z drop_last=False — ostatnia partia może być mniejsza w zależności od rozmiaru zestawu danych. Twój model lub operacje, takie jak BatchNorm, muszą obsługiwać go poprawnie lub jawnie sprawdzać, czy są mniejsze partie.

5. Przypadkowe tensory na różnych urządzeniach

Upewnij się, że funkcje wejściowe i model znajdują się na tym samym urządzeniu. Jeśli wyślesz swój model do CUDA, ale pozostawisz dane wejściowe na procesorze, wszystko nieoczekiwanie zakończy się niepowodzeniem, często bez przydatnych błędów.

Zawsze dokładnie sprawdź za pomocą:

 assert inputs.device == model.device

Wskazówka dla zaawansowanych: Włącz pełne raportowanie błędów

Jeśli uruchomienie na procesorze nie pomaga lub pracujesz w mieszanej konfiguracji CPU/GPU i nadal nie pojawiają się przydatne błędy — spróbuj ustawić:

 CUDA_LAUNCH_BLOCKING=1 python my_script.py

To mówi PyTorchowi, aby uruchamiał kod GPU synchronicznie, więc ulegnie awarii dokładnie w miejscu awarii. Może to nieco spowolnić wykonanie, ale zapewnia znacznie wyraźniejsze śledzenie.

Tylko w Pythonie, bez modyfikowania powłoki:

 import os os.environ["CUDA_LAUNCH_BLOCKING"] = "1"

Teraz środowisko wykonawcze powinno oferować bardziej szczegółowe informacje o tym, gdzie wystąpiło potwierdzenie CUDA.

Napraw na przykładzie

Spójrzmy na praktyczny przykład. Załóżmy, że budujesz model klasyfikacji cyfr w MNIST i definiujesz ostateczną warstwę modelu w następujący sposób:

 self.fc = nn.Linear(128, 10)

W pętli treningowej masz:

 criterion = nn.CrossEntropyLoss() output = model(images) # Output shape: [batch_size, 10] loss = criterion(output, labels)

Ale twoje etykiety są takie:

 labels = torch.tensor([[0], [1], [2]])

Ten kształt jest nieprawidłowy. CrossEntropyLoss oczekuje etykiet jako wektora 1D indeksów klas:

 labels = torch.tensor([0, 1, 2])

Samo naprawienie tego kształtu może rozwiązać problem.

model pytorcha, funkcja utraty, błąd GPU, naprawa

Podsumowanie: lista kontrolna umożliwiająca naprawienie błędu

Zanim zaczniesz wyrywać włosy, postępuj zgodnie z poniższą listą kontrolną:

  1. Przejdź do trybu procesorai spróbuj ponownie — komunikat o błędzie może być bardziej opisowy.
  2. Sprawdź etykiety zajęć:upewnij się, że mieszczą się w prawidłowym zakresie i mają prawidłowy format.
  3. Sprawdzaj dane pochodzące z modułu DataLoader— iteruj po partiach i sprawdzaj, czy nie występują anomalie.
  4. Zapewnij odpowiednie kształty i wymiary tensora, szczególnie w przypadku wyników i celów.
  5. Użyj CUDA_LAUNCH_BLOCKING=1aby uzyskać szczegółowe, synchroniczne śledzenie z CUDA.

Wniosek

Chociaż błąd wywołany potwierdzeniem po stronie urządzeniamoże początkowo wydawać się niejasny i nieprzejrzysty, ostatecznie jest to sposób, w jaki Twój model lub dane macha do Ciebie czerwoną flagą. Systematycznie sprawdzając etykiety, kształty danych oraz korzystając z trybu procesora i blokowania uruchamiania, prawie zawsze można wyizolować problem.

Następnym razem, zamiast reagować zamieszaniem, będziesz uzbrojony w wiedzę i zestaw narzędzi diagnostycznych. Miłego debugowania!