Garder le premier échec et son contexte
Ce guide commence après un lancement réussi : PyTorch voit le périphérique, puis votre application échoue sur un batch ou un opérateur. Si aucun petit calcul ne fonctionne, repartez du diagnostic initial. Sinon, conservez la première erreur, le numéro d’itération et la dernière étape terminée. Une succession de messages après le premier échec peut décrire ses conséquences plutôt que plusieurs causes indépendantes.
Notez la révision du code, les versions de Python et de PyTorch, le backend, le type numérique et les formes des entrées. Pour les données, préférez un identifiant interne et les dimensions à une copie intégrale du contenu. Cherchez ce qui distingue le batch fautif : longueur, cible absente, dernier lot incomplet, augmentation ou branche rarement utilisée. Ce dossier permet de refaire le cas sans relancer toute une campagne.
Localiser le lancement fautif malgré l’asynchronisme
Sur CUDA, des opérations sont mises en file et peuvent se terminer après le retour de la fonction Python. Une erreur remontée pendant une copie vers CPU ou une lecture de scalaire peut donc venir d’un calcul précédent. La documentation PyTorch explique cette exécution asynchrone. La ligne indiquée par la trace est un point d’observation à examiner, pas toujours la cause.
Pour une reproduction courte sur NVIDIA/CUDA, proposez un lancement séparé avec CUDA_LAUNCH_BLOCKING=1. Cette option rend les appels synchrones et peut rapprocher l’erreur de son origine. Elle sert au diagnostic, pas au chronométrage. Vous pouvez aussi placer provisoirement des synchronisations entre grandes étapes pour réduire l’intervalle suspect. Retirez ensuite cette instrumentation : elle modifie l’ordonnancement habituel.
La commande suivante est pédagogique et n’a pas été exécutée. Elle suppose un terminal POSIX et un script train.py existant. L’affectation s’applique à ce lancement seulement ; adaptez la syntaxe à votre shell. Ne généralisez pas cette variable NVIDIA à une pile ROCm.
CUDA_LAUNCH_BLOCKING=1 python train.pyLire une famille d’erreur sans conclure trop vite
Le message réduit le champ de recherche ; il ne remplace pas un cas reproductible. Un indice hors domaine, un tenseur sur le mauvais périphérique et une allocation impossible appellent des vérifications différentes. Gardez la distinction entre données invalides, contrat d’opérateur et environnement binaire. Changer simultanément le batch, la précision et les bibliothèques supprime cette distinction.
Après une assertion exécutée sur le périphérique, n’essayez pas de poursuivre le même entraînement dans le même processus. NVIDIA indique que cudaErrorAssert invalide les allocations existantes et impose de terminer puis relancer le processus. Dans un notebook, cela implique de redémarrer son noyau avant la reproduction corrigée. Redémarrer ne corrige toutefois ni une cible erronée ni un index invalide.
Faites défiler le tableau pour lire toutes les colonnes.| Indice observé | Première vérification | Conclusion à éviter |
|---|---|---|
| device-side assert | Indices, cibles et conditions de l’opérateur | Le GPU est forcément défectueux |
| Out of memory | Formes, durée de vie des tenseurs, mémoire du processus | Toute erreur CUDA est un manque de VRAM |
| Opérateur ou noyau non disponible | Versions, extension, backend et dtype | Réinstaller tout au hasard |
| Périphériques différents | Placement du modèle et de chaque entrée | Ajouter une copie sans comprendre son origine |
Exemple travaillé : une classe 4 dans un problème à quatre classes
Prenons un classificateur pédagogique dont la sortie possède quatre colonnes. Ses classes sont indexées de 0 à 3. Un fichier d’annotations contenant la valeur 4 peut révéler un encodage de 1 à 4 ou une cinquième classe inattendue. Augmenter simplement la taille de sortie ferait disparaître une contrainte sans résoudre la signification des annotations.
Le contrôle proposé ci-dessous s’applique avant le transfert des cibles CPU. Il n’a pas été exécuté. Il illustre le contrat CrossEntropyLoss pour des indices de classes de type long, avec ignore_index=-100 explicitement choisi. Il ne couvre pas les cibles constituées de distributions de probabilités. Dans ce scénario, [0, 2, 4] doit être refusé ; ce résultat attendu est déduit de la règle, pas présenté comme une mesure.
Corrigez ensuite le mapping dans la préparation des données et contrôlez sa bijection avec les noms de classes. Ne soustrayez pas 1 partout tant que vous ne savez pas si toutes les sources utilisent la même convention. Ajoutez le cas fautif à un petit ensemble de vérification conservé avec le projet.
import torch
classes = 4
ignore_index = -100
target = torch.tensor([0, 2, 4], dtype=torch.long)
if target.ndim != 1 or target.dtype != torch.long:
raise ValueError("Cibles : vecteur d’indices attendu")
valid = target[target != ignore_index]
if valid.numel() == 0:
raise ValueError("Aucune cible exploitable dans ce batch")
if bool(((valid < 0) | (valid >= classes)).any()):
raise ValueError("Indice de classe hors domaine")Réduire le programme sans effacer le déclencheur
Rejouez d’abord une seule entrée ou un seul batch avec les mêmes transformations. Retirez le suivi distant, l’écriture de résultats et les branches sans rapport avec l’échec. Gardez le dtype, les formes et l’opérateur suspects. Si l’erreur dépend d’une longueur ou d’une disposition mémoire particulière, un tenseur arbitraire de petite taille risque de ne plus la reproduire.
Comparez une modification à la fois : extension facultative désactivée, opérateur de référence, précision habituelle ou même opération sur CPU lorsqu’elle y existe. Un succès CPU est un indice, pas une validation CUDA. Pour une fonction personnalisée, consignez aussi les hypothèses sur strides, contiguïté et tailles. Cherchez un exemple qui échoue avant correction et réussit après, avec une vérification de sortie plutôt que la seule absence d’exception.
Vérifier la correction sur le périmètre initial
Une correction acceptable doit passer le cas minimal, les cas voisins et une portion représentative du parcours original. Reprenez notamment le dernier batch, une entrée courte, une entrée longue et les valeurs limites du mapping. Vérifiez que les éléments refusés sont identifiables et que le nombre d’entrées traitées reste celui attendu. Ignorer silencieusement les exceptions peut transformer un crash visible en résultat incomplet.
Retirez le mode de diagnostic, repartez d’un processus neuf et confirmez le comportement avec la configuration normale. Conservez la cause, le changement appliqué et le contrôle de non-régression. Si vous aviez interrompu un entraînement, repartez d’un checkpoint cohérent validé avant l’erreur ; la présence d’un fichier écrit pendant une panne ne suffit pas à garantir sa reprise.
Savoir quand demander une analyse plus ciblée
Si le même cas minimal échoue avec des entrées valides, préparez une demande précise : opération, formes, types, backend, versions et premier message pertinent. Retirez les identifiants personnels et les chemins inutiles. Une extension binaire peut nécessiter sa propre matrice de compatibilité ; le support général de PyTorch ne valide pas automatiquement cette extension.
Sur ROCm, PyTorch conserve l’interface torch.cuda et les noms de périphérique cuda. Vérifiez torch.version.hip pour identifier cette pile avant d’appliquer une procédure NVIDIA. Les messages, outils et options de diagnostic peuvent différer. Aucun contrôle décrit ici ne prouve la compatibilité des environnements préparés avec une offre Kernodeck ; utilisez ces critères pour préciser votre besoin avant de choisir le GPU.