Cum se remediază „RuntimeError: CUDA Error: Device-Side Assert Triggered”
Publicat: 2025-10-14Dacă lucrați cu modele de învățare profundă în PyTorch, sunt șanse să fi dat peste un mesaj de eroare derutant precum:
RuntimeError: CUDA error: device-side assert triggered
Această eroare poate fi incredibil de frustrantă, mai ales atunci când nu ești exact sigur ce o cauzează. Spre deosebire de multe erori de programare care vă oferă o urmărire utilă a stivei care indică problema, aceasta poate simți mai degrabă că GPU-ul tău își ridică sprâncenele și pleacă în liniște. Dar nu vă faceți griji - până la sfârșitul acestui ghid, veți înțelege nu numai de ce se întâmplă acest lucru, ci și cum să îl remediați metodic.
Ce înseamnă de fapt această eroare?
Această eroare apare atunci când un nucleu CUDA care rulează pe GPU-ul dvs. întâmpină o eroare de afirmare. Acest lucru se datorează, de obicei, unei intrări nevalide sau unui comportament neașteptat pe care s-ar putea să nu îl înțelegeți în modul CPU. Deoarece este o problemă la nivel de GPU, tinde să se blocheze fără mesajele detaliate de depanare pe care obișnuim să le vedem de la excepțiile Python.
Cauzele comune includ:
- Erori de indexare (de exemplu, încercarea de a utiliza un index de clasă care nu există)
- Forme tensoare nevalide
- Utilizarea incorectă a funcției de pierdere
- Date care încalcă așteptările (cum ar fi tensorii gol)
Din fericire, cu abordarea corectă, puteți găsi și remedia această problemă - să vedem cum.
Proces pas cu pas pentru diagnosticare și remediere
1.Rulați modelul dvs. pe procesor
Primul pas de diagnosticare este să dezactivați CUDA și să rulați totul pe CPU. Adesea, atunci când rulează pe CPU, PyTorch oferă mesaje de eroare mai clare, deoarece afirmările de pe partea dispozitivului sunt acum aruncate ca excepții Python cu context complet.
Pentru a comuta la modul CPU, modificați codul după cum urmează:
device = torch.device("cpu") model.to(device)
Dacă o afirmație eșuează, acum ar trebui să obțineți o urmă de stivă mult mai informativă.
2. Verificați etichetele țintă
Una dintre cele mai frecvente cauze ale acestei erori sunt etichetele de clasă necorespunzătoare - mai ales când se utilizează nn.CrossEntropyLoss
. Această funcție de pierdere se așteaptă ca tensorul țintă să includă indici de clasă între 0
și num_classes - 1
. Deci, dacă modelul dvs. scoate 10 clase, țintele trebuie să fie numere întregi de la 0 la 9.
Greseala comuna:
# Target contains 10 instead of 0–9 range target = torch.tensor([10])
Dacă acești indici sunt în afara limitelor, veți întâlni o afirmație pe GPU. Pentru a valida acest lucru, utilizați:
assert target.max().item() < num_classes
Dacă faceți clasificarea imaginilor, asigurați-vă, de asemenea, că forma țintei dvs. este adecvată. Pentru CrossEntropyLoss
ar trebui să fie de forma [batch_size]
, nu de codat one-hot!
# Incorrect (for CrossEntropyLoss) target = torch.tensor([[0, 0, 1], [1, 0, 0]]) # Correct target = torch.tensor([2, 0])
3. Inspectați DataLoader pentru erori
Uneori, eroarea vine de la setul de date sau de la DataLoader, mai ales atunci când este folosită în instruirea pe lot. Dacă unele etichete sunt corupte sau inconsecvente, ele pot rupe modelul dvs. de pe GPU.
Verificați setul de date astfel:
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]
Acest lucru este util în special dacă setul de date este construit dintr-un fișier CSV sau dintr-o logică de procesare personalizată care ar putea introduce în tăcere etichete nevalide.
dezvoltator introspectiv, inspectare cod, laptop, depanare

Alte capcane comune
4. Dimensiunile loturilor nepotrivite
Uneori, modelul sau funcția de pierdere se așteaptă ca intrările să aibă anumite forme. Nepotrivirile pot duce la probleme subtile. Asigurați-vă că dimensiunea lotului în intrări și obiective se aliniază:
# torchvision models usually expect [N, 3, 224, 224] assert inputs.shape[1:] == (3, 224, 224)
Acest lucru contează în special când utilizați DataLoader cu drop_last=False
— ultimul lot poate fi mai mic în funcție de dimensiunea setului de date. Modelul sau operațiunile dvs. precum BatchNorm trebuie să le gestioneze corect sau să verifice în mod explicit dacă există loturi mai mici.
5. Tensori accidentali pe diferite dispozitive
Asigurați-vă că atât caracteristicile de intrare, cât și modelul sunt pe același dispozitiv. Dacă trimiteți modelul dvs. la CUDA, dar lăsați intrările pe procesor, lucrurile vor eșua în mod neașteptat, adesea fără erori utile.
Verificați întotdeauna cu:
assert inputs.device == model.device
Sfat avansat: activați raportarea completă a erorilor
Dacă rularea pe CPU nu ajută sau lucrați într-o configurație mixtă CPU/GPU și tot nu primiți erori utile - încercați să setați:
CUDA_LAUNCH_BLOCKING=1 python my_script.py
Acest lucru îi spune lui PyTorch să ruleze codul GPU sincron, astfel încât se va prăbuși exact în punctul de defecțiune. Poate încetini puțin execuția, dar oferă o urmărire mult mai clară.
Numai în Python, fără a modifica shell-ul:
import os os.environ["CUDA_LAUNCH_BLOCKING"] = "1"
Acum, runtime-ul ar trebui să ofere informații mai specifice despre locul unde a avut loc afirmația CUDA.
Remediați prin exemplu
Să ne uităm la un exemplu practic. Să presupunem că construiți un model pentru clasificarea cifrelor pe MNIST și definiți stratul de model final după cum urmează:
self.fc = nn.Linear(128, 10)
În bucla de antrenament, aveți:
criterion = nn.CrossEntropyLoss() output = model(images) # Output shape: [batch_size, 10] loss = criterion(output, labels)
Dar etichetele tale sunt ca:
labels = torch.tensor([[0], [1], [2]])
Această formă este incorectă. CrossEntropyLoss
se așteaptă la etichete ca un vector 1D al indicilor de clasă:
labels = torch.tensor([0, 1, 2])
Remedierea acestei forme ar putea rezolva problema.
model pytorch, funcție de pierdere, eroare gpu, remediere
Rezumat: Lista de verificare pentru a remedia eroarea
Înainte de a începe să vă smulgeți părul, urmați această listă de verificare:
- Comutați în modul CPUși încercați din nou - mesajul de eroare ar putea fi mai descriptiv.
- Verificați etichetele de clasă:asigurați-vă că se află în intervalul valid și formatul corect.
- Inspectați datele care provin de la DataLoader- repetați prin loturi și verificați dacă există anomalii.
- Asigurați-vă formele și dimensiunile tensorilor adecvate, în special pentru ieșiri și ținte.
- Utilizați
CUDA_LAUNCH_BLOCKING=1
pentru a obține o urmărire detaliată, sincronă de la CUDA.
Concluzie
În timp ce eroarea declanșată de anunț la nivelul dispozitivuluise poate simți la început vagă și opac, în cele din urmă este modul în care modelul sau datele dvs. vă transmit un steag roșu. Prin verificarea sistematică a etichetelor, formelor datelor și utilizând modul CPU și blocarea lansării, puteți izola aproape întotdeauna problema.
Data viitoare, în loc să reacționezi cu confuzie, vei fi înarmat cu cunoștințe și un set de instrumente de diagnosticare. Depanare fericită!