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

Passer en précision mixte sans perdre le contrôle numérique

Établissez une référence en précision habituelle, activez autocast sur le calcul avant et la perte, puis comparez sorties, gradients et qualité sur les mêmes entrées. En entraînement FP16, GradScaler aide à gérer les gradients de petite amplitude ; il ne rend pas tout modèle compatible. BF16 possède un comportement numérique différent. Gardez un critère explicite de retour arrière avant de rechercher un gain de mémoire ou de vitesse.

7 min de lecture · Guide pour développeurs

Commencer par une référence qui répond au besoin

Choisissez un jeu court avec entrées ordinaires, cas limites et frontières de décision. Figez modèle, poids, prétraitement et mode train ou eval. Une comparaison entre deux modèles ou deux batches ne permet pas d’attribuer leur différence à la précision.

Enregistrez la sortie utile à votre application, pas seulement la perte. Pour un classificateur, cela peut inclure scores et décisions ; pour une régression, erreur et valeurs extrêmes. Vérifiez déjà la présence de NaN ou d’inf dans la référence. Une exécution FP32 incorrecte ne devient pas une base fiable parce qu’elle possède davantage de bits.

Fixez tolérance, qualité minimale et absence de non-finis avant l’essai. PyTorch rappelle que le calcul flottant ne garantit pas des résultats identiques entre appareils ou chemins d’exécution.

Distinguer autocast, format numérique et GradScaler

autocast choisit le type de certaines opérations selon leur politique de calcul. Il ne transforme pas tout le programme en un format unique. Avec cet usage, évitez de convertir manuellement tout le modèle par half(). La documentation actuelle recommande torch.autocast ou torch.amp.autocast ; les anciennes interfaces torch.cuda.amp sont dépréciées.

GradScaler agit sur l’échelle de la perte et des gradients pendant l’entraînement. Il ne s’emploie pas comme un accélérateur de l’inférence, qui n’effectue pas de backward. FP16 dispose d’une plage numérique plus restreinte que BF16 ; un modèle conçu pour BF16 peut déborder en FP16. Une baisse répétée de l’échelle n’établit donc pas que le problème est résolu.

Choisissez le format à partir des contraintes du modèle et des opérations réellement utilisées, puis vérifiez la prise en charge de la cible. Le nom commercial d’une carte ou une préférence de préparation PyTorch ne prouve pas que votre opérateur personnalisé possède le noyau souhaité.

Faites défiler le tableau pour lire toutes les colonnes.
Décisions de précision à valider sur le projet
ChoixRôleContrôle nécessaire
Référence FP32Point de comparaison du projetSorties finies et qualité attendue
Autocast FP16Certaines opérations en précision réduitePlage numérique et gradients
Autocast BF16Autre compromis plage/précisionOpérateurs disponibles et qualité
GradScalerGestion de l’échelle des gradientsMises à jour réellement effectuées

Placer les étapes de l’entraînement dans le bon ordre

Le fragment proposé suppose un modèle et un optimiseur déjà construits, une entrée et une cible sur le même GPU, et une perte scalaire. Il n’a pas été exécuté et ne constitue pas une validation d’une offre. Le contexte autocast entoure le forward et la perte ; le backward se déroule après sa fermeture. Le scaler est créé une fois pour la session d’entraînement, pas à chaque batch.

Pour inspecter ou écrêter les gradients, retirez d’abord leur facteur d’échelle avec unscale_. Les exemples AMP officiels précisent de le faire une seule fois par optimiseur et après l’accumulation des gradients destinés à sa mise à jour. Le seuil d’écrêtage 1.0 ci-dessous est une valeur illustrative à choisir pour votre projet, pas une recommandation universelle.

Les gardes interrompent ici le diagnostic si perte, gradients ou norme totale ne sont pas finis. Ces lectures CPU sont intrusives : ne chronométrez pas ce fragment. Accumulation, optimiseurs multiples et ordonnanceur demandent leur propre définition de la mise à jour.

Séquence AMP pédagogique sur GPU, non exécutée
import torch

# Préconditions : model, optimizer, loss_fn, inputs et targets existent.
# Le modèle et les entrées sont sur le même périphérique CUDA/HIP.
dtype = torch.float16  # Choix à valider ; BF16 est un autre essai.
scaler = torch.amp.GradScaler("cuda", enabled=(dtype == torch.float16))

# À placer dans votre boucle, avec scaler conservé entre les batches.
optimizer.zero_grad(set_to_none=True)
with torch.autocast(device_type="cuda", dtype=dtype):
    prediction = model(inputs)
    loss = loss_fn(prediction, targets)
if not bool(torch.isfinite(loss).item()):
    raise FloatingPointError("Perte non finie : interrompre le diagnostic")
scaler.scale(loss).backward()
scaler.unscale_(optimizer)
if any(p.grad is not None and
       not bool(torch.isfinite(p.grad).all().item())
       for p in model.parameters()):
    raise FloatingPointError("Gradient non fini : interrompre le diagnostic")
torch.nn.utils.clip_grad_norm_(
    model.parameters(), max_norm=1.0, error_if_nonfinite=True,
)
scaler.step(optimizer)
scaler.update()

Exemple travaillé : deux décisions proches ne sont pas interchangeables

Supposons un service qui choisit la classe au score maximal. Sur une entrée pédagogique, la référence produit deux scores très proches : 1,0000 et 1,0003. Un autre chemin numérique pourrait modifier leur ordre ou créer une égalité. Ces nombres illustrent une frontière de décision ; ils ne sont pas des sorties mesurées de FP16 ou BF16.

La bonne vérification comporte deux niveaux. Comparez les scores avec des tolérances explicites, puis comparez la décision et la règle appliquée aux égalités. Une différence faible en valeur absolue peut changer l’action choisie. À l’inverse, une différence numérique visible peut rester sans conséquence pour une tâche dont le seuil se trouve loin des scores observés.

Consignez identifiants, sorties de référence, essai AMP et impact sur la décision. Fixez la règle d’acceptation avant de lire les résultats. N’élargissez pas la tolérance pour faire disparaître un cas gênant ; des sorties d’échelles différentes peuvent nécessiter des critères distincts.

Faites défiler le tableau pour lire toutes les colonnes.
Fiche pédagogique de comparaison, à compléter par des mesures
CritèreRéférenceEssai AMPDécision
Sorties finiesÀ vérifierÀ vérifierRefuser les non-finis inexpliqués
Écart numériqueValeurs conservéesÉcart à calculerTolérance définie avant l’essai
Décision applicativeClasse ou actionClasse ou actionExaminer les changements
Qualité sur le jeu fixéÀ mesurerÀ mesurerRespecter le seuil du projet

Interpréter les NaN et les mises à jour sautées

Quand des non-finis apparaissent, cherchez la première étape qui les produit : entrée, sortie intermédiaire, perte ou gradient. Rejouez le même cas en référence, puis désactivez localement autocast autour de l’opération suspecte en contrôlant aussi le type de ses entrées. Repasser tout un entraînement en FP32 peut servir de comparaison, mais ne localise pas automatiquement le problème.

Le scaler peut éviter une mise à jour lorsque les gradients contiennent des inf ou des NaN. Une boucle qui continue n’a donc pas nécessairement effectué autant de mises à jour que d’itérations. Consignez ce comportement pendant le diagnostic. Ne faites pas progresser aveuglément une politique d’apprentissage supposée suivre les mises à jour effectives.

Une perte finie ne garantit pas des gradients finis. À l’inverse, un incident ponctuel ne suffit pas à déclarer un entraînement inutilisable : examinez sa fréquence, la progression et la qualité. La recette AMP fournit une méthode pour isoler séparément autocast et le scaling lorsque l’un des deux est suspect.

Préparer un retour arrière reproductible

Avant l’essai, conservez la configuration de référence, les poids, l’état de l’optimiseur et un checkpoint cohérent. Si votre entraînement utilise un scaler, son état fait aussi partie de la reprise. Documentez le dtype et les éventuelles régions laissées en FP32. Reprendre avec une politique différente est un changement expérimental à identifier, pas une continuation implicitement équivalente.

Revenez à la configuration précédente si les sorties deviennent non finies, si la qualité sort du critère fixé ou si les mises à jour cessent d’avancer de façon exploitable. Conservez le cas qui a motivé ce retour. Après une modification, recommencez la comparaison sur le même jeu avant d’étendre la durée.

L’exercice Kernodeck de checkpoints vérifie une reprise CPU sans AMP. Réutilisez sa méthode de comparaison en ajoutant les états réellement consommés par votre boucle.

Mesurer les gains seulement après la validation numérique

Après validation, mesurez mémoire et temps sans le diagnostic détaillé. Gardez formes, batch, modèle et qualité. Les lectures de scalaires, synchronisations et profileurs peuvent modifier les durées ; retirez les contrôles intrusifs de la mesure finale.

Sur ROCm, le nom de périphérique PyTorch reste cuda et les interfaces correspondantes sont réutilisées. Cela ne garantit ni les mêmes noyaux ni des résultats identiques à NVIDIA. Vérifiez le backend et les opérateurs du projet sur la cible. Aucune réduction fixe de mémoire, multiplication de vitesse ou compatibilité de préparation Kernodeck n’est annoncée par ce guide.

Vos questions

AMP signifie-t-il que tous les tenseurs passent en FP16 ?

Non. autocast applique une politique par opération. Certaines opérations restent dans une précision différente. Convertir manuellement tout le modèle en half() n’est pas équivalent à utiliser autocast et peut modifier les conditions de stabilité.

BF16 remplace-t-il toujours FP16 avantageusement ?

Non. Les deux formats ont des compromis différents, et leur prise en charge dépend des opérations et de l’environnement. Comparez la qualité et le coût sur votre charge ; la plage plus large de BF16 ne garantit pas à elle seule la précision requise.

GradScaler est-il nécessaire pour une inférence ?

Le scaler intervient dans l’entraînement avec gradients, pas dans une inférence sans backward. Pour cette dernière, contrôlez plutôt les sorties et la qualité sous autocast, en conservant le mode d’évaluation attendu.

Une perte finie suffit-elle à accepter AMP ?

Non. Vérifiez aussi les gradients, les mises à jour, la qualité et les décisions de l’application. Une petite différence numérique peut être décisive près d’un seuil ; un entraînement qui continue peut aussi sauter certaines mises à jour.