GPU pour vos projets · paiement crypto sans KYC Comment louer
Français
Ouvrir la console
Guide pratique / KERNODECK

Une erreur CUDA apparaît : quelle opération faut-il examiner ?

Conservez le premier échec, identifiez le batch concerné et réduisez l’application jusqu’à l’opération qui le déclenche. Sur CUDA, l’exécution asynchrone peut faire remonter l’erreur plus tard que sa cause. Vérifiez ensuite les indices, formes, types et périphériques avant de modifier l’environnement. Cette méthode concerne une application déjà lancée ; elle ne remplace pas le contrôle initial de disponibilité du GPU.

7 min de lecture · Guide pour développeurs

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.

Lancement de diagnostic proposé, non exécuté
CUDA_LAUNCH_BLOCKING=1 python train.py

Lire 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.
Pistes de diagnostic, sans association automatique entre message et cause
Indice observéPremière vérificationConclusion à éviter
device-side assertIndices, cibles et conditions de l’opérateurLe GPU est forcément défectueux
Out of memoryFormes, durée de vie des tenseurs, mémoire du processusToute erreur CUDA est un manque de VRAM
Opérateur ou noyau non disponibleVersions, extension, backend et dtypeRéinstaller tout au hasard
Périphériques différentsPlacement du modèle et de chaque entréeAjouter 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.

Garde CPU pédagogique pour des indices de classes
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.

Vos questions

CUDA_LAUNCH_BLOCKING=1 corrige-t-il une erreur CUDA ?

Non. Il rend les appels CUDA synchrones pour aider à localiser l’opération fautive. Utilisez-le sur une reproduction courte, puis corrigez la cause et retirez-le avant de mesurer les performances normales.

Puis-je continuer un notebook après une device-side assert ?

Redémarrez le noyau avant de rejouer le cas corrigé. Une assertion côté périphérique peut laisser le contexte inutilisable et les allocations invalides. La relance restaure un contexte, mais ne corrige pas des indices ou des données erronés.

Si le même calcul passe sur CPU, le GPU est-il défectueux ?

Non. Ce résultat distingue deux chemins d’exécution. Un dtype, une extension, un noyau ou une contrainte de données peut expliquer la différence. Reproduisez une opération minimale sur la pile GPU concernée avant de conclure.

La procédure NVIDIA est-elle identique sur ROCm ?

Pas entièrement. PyTorch pour ROCm utilise aussi torch.cuda, mais les outils et certaines variables de diagnostic diffèrent. Identifiez HIP avec torch.version.hip et consultez la documentation correspondant au backend réel.