Comment réparer « RuntimeError : Erreur CUDA : assertion côté périphérique déclenchée »
Publié: 2025-10-14Si vous travaillez avec des modèles d'apprentissage profond dans PyTorch, il est probable que vous soyez tombé sur un message d'erreur déroutant tel que :
RuntimeError: CUDA error: device-side assert triggeredCette erreur peut être incroyablement frustrante, surtout lorsque vous ne savez pas exactement quelle en est la cause. Contrairement à de nombreuses erreurs de programmation qui vous donnent une trace utile de la pile indiquant le problème, celle-ci peut donner davantage l'impression que votre GPU lève les sourcils et s'éloigne tranquillement. Mais ne vous inquiétez pas, à la fin de ce guide, vous comprendrez non seulement pourquoi cela se produit, mais également comment y remédier méthodiquement.
Que signifie réellement cette erreur ?
Cette erreur se produit lorsqu'un noyau CUDA exécuté sur votre GPU rencontre un échec d'assertion. Cela est généralement dû à une entrée non valide ou à un comportement inattendu que vous pourriez ne pas détecter en mode CPU. Comme il s'agit d'un problème au niveau du GPU, il a tendance à planter sans les messages de débogage détaillés que nous avons l'habitude de voir dans les exceptions Python.
Les causes courantes incluent :
- Erreurs d'indexation (par exemple, essayer d'utiliser un index de classe qui n'existe pas)
- Formes tensorielles invalides
- Utilisation incorrecte de la fonction de perte
- Des données qui dépassent les attentes (comme les tenseurs vides)
Heureusement, avec la bonne approche, vous pouvez localiser et résoudre ce problème. Voyons comment procéder.
Processus étape par étape pour diagnostiquer et réparer
1.Exécutez votre modèle sur le processeur
La première étape de diagnostic consiste à désactiver CUDA et à tout exécuter sur le processeur. Souvent, lorsqu'il est exécuté sur le processeur, PyTorch fournit des messages d'erreur plus clairs, car les assertions côté périphérique sont désormais générées sous forme d'exceptions Python avec un contexte complet.
Pour passer en mode CPU, modifiez votre code comme suit :
device = torch.device("cpu") model.to(device)Si une assertion échoue, vous devriez désormais obtenir une trace de pile beaucoup plus informative.
2. Vérifiez vos étiquettes cibles
L'une des causes les plus fréquentes de cette erreur est des étiquettes de classe incorrectes, en particulier lors de l'utilisation nn.CrossEntropyLoss . Cette fonction de perte s'attend à ce que votre tenseur cible inclue des indices de classe compris entre 0 et num_classes - 1 . Ainsi, si votre modèle génère 10 classes, les cibles doivent être des nombres entiers compris entre 0 et 9.
Erreur courante :
# Target contains 10 instead of 0–9 range target = torch.tensor([10])Si ces indices sont hors limites, vous rencontrerez une assertion sur le GPU. Pour valider cela, utilisez :
assert target.max().item() < num_classes Si vous effectuez une classification d'images, assurez-vous également que la forme de votre cible est appropriée. Pour CrossEntropyLoss , il doit être de forme [batch_size] , et non codé à chaud !
# Incorrect (for CrossEntropyLoss) target = torch.tensor([[0, 0, 1], [1, 0, 0]]) # Correct target = torch.tensor([2, 0])3. Inspectez le DataLoader pour les erreurs
Parfois, l'erreur vient de votre ensemble de données ou de DataLoader, notamment lorsqu'il est utilisé dans une formation par lots. Si certaines étiquettes sont corrompues ou incohérentes, elles risquent de casser votre modèle sur le GPU.
Vérifiez votre ensemble de données comme ceci :
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]Ceci est particulièrement utile si votre ensemble de données est construit à partir d'un fichier CSV ou d'une logique de traitement personnalisée qui pourrait introduire silencieusement des étiquettes non valides.
développeur introspectif, inspection du code, ordinateur portable, débogage

Autres pièges courants
4. Tailles de lots incompatibles
Parfois, le modèle ou la fonction de perte s'attend à ce que les entrées présentent certaines formes. Les disparités peuvent entraîner des problèmes subtils. Assurez-vous que la taille de votre lot en entrées et en cibles est alignée :
# torchvision models usually expect [N, 3, 224, 224] assert inputs.shape[1:] == (3, 224, 224) Cela est particulièrement important lors de l'utilisation de DataLoader avec drop_last=False : le dernier lot peut être plus petit en fonction de la taille de votre ensemble de données. Votre modèle ou vos opérations comme BatchNorm doivent le gérer correctement ou vérifier explicitement les lots plus petits.
5. Tenseurs accidentels sur différents appareils
Assurez-vous que vos fonctionnalités d’entrée et votre modèle se trouvent sur le même appareil. Si vous envoyez votre modèle à CUDA mais laissez vos entrées sur le processeur, les choses échoueront de manière inattendue, souvent sans erreurs utiles.
Vérifiez toujours avec :
assert inputs.device == model.deviceAstuce avancée : Activer le rapport d'erreurs complet
Si l'exécution sur CPU ne vous aide pas, ou si vous travaillez dans une configuration mixte CPU/GPU et que vous n'obtenez toujours pas d'erreurs utiles, essayez de définir :
CUDA_LAUNCH_BLOCKING=1 python my_script.pyCela indique à PyTorch d'exécuter le code GPU de manière synchrone, afin qu'il plante au point exact de la défaillance. Cela peut ralentir un peu l’exécution, mais cela fournit un traçage beaucoup plus clair.
En Python uniquement, sans modifier le shell :
import os os.environ["CUDA_LAUNCH_BLOCKING"] = "1"Le moteur d'exécution devrait désormais offrir des informations plus spécifiques sur l'endroit où l'assertion CUDA s'est produite.
Corriger par l'exemple
Regardons un exemple pratique. Supposons que vous construisiez un modèle pour la classification des chiffres sur MNIST et que vous définissiez votre couche de modèle finale comme suit :
self.fc = nn.Linear(128, 10)Dans la boucle de formation, vous avez :
criterion = nn.CrossEntropyLoss() output = model(images) # Output shape: [batch_size, 10] loss = criterion(output, labels)Mais vos étiquettes ressemblent à :
labels = torch.tensor([[0], [1], [2]]) Cette forme est incorrecte. CrossEntropyLoss attend les étiquettes comme vecteur 1D d'indices de classe :
labels = torch.tensor([0, 1, 2])Corriger cette forme à lui seul pourrait résoudre le problème.
modèle pytorch, fonction de perte, erreur GPU, correctif
Résumé : liste de contrôle pour corriger l'erreur
Avant de commencer à vous arracher les cheveux, suivez cette liste de contrôle :
- Passez en mode CPUet réessayez : le message d'erreur peut être plus descriptif.
- Vérifiez les étiquettes de classe :assurez-vous qu’elles se trouvent dans la plage valide et que leur format est correct.
- Inspectez les données provenant du DataLoader : parcourez les lots et recherchez les anomalies.
- Assurez-vous que les formes et les dimensions des tenseurs sont appropriées, en particulier pour les sorties et les cibles.
- Utilisez
CUDA_LAUNCH_BLOCKING=1pour obtenir un traçage détaillé et synchrone de CUDA.
Conclusion
Bien que l'erreur déclenchée par l'assertion côté appareilpuisse sembler vague et opaque au début, c'est en fin de compte le moyen utilisé par votre modèle ou vos données pour vous alerter. En vérifiant systématiquement vos étiquettes, vos formes de données et en utilisant le mode CPU et le blocage du lancement, vous pouvez presque toujours isoler le problème.
La prochaine fois, au lieu de réagir avec confusion, vous serez armé de connaissances et d’une boîte à outils de diagnostic. Bon débogage !
