Mixed Precision
L’entraînement en précision mixte utilise des calculs en 16 bits et des poids maîtres FP32 pour les réseaux neuronaux, ce qui réduit la mémoire utilisée et le temps d’entraînement. Présentation du redimensionnement de la perte, de BF16 et d’AMP.
La précision mixte est une technique d’entraînement qui effectue la plupart des calculs d’un réseau de neurones en virgule flottante sur 16 bits, au format FP16 (précision demi-mot) ou BF16, tout en conservant une copie maîtresse des poids du modèle sur 32 bits (FP32) et en exécutant les opérations numériquement sensibles en FP32. Les valeurs sur 16 bits utilisent deux fois moins de mémoire et de bande passante que celles sur FP32, et les Tensor Cores des GPU modernes les multiplient beaucoup plus rapidement ; la précision mixte raccourcit donc l’entraînement et permet d’utiliser des tailles de lot plus grandes en mémoire, tout en conservant la même précision qu’en FP32. La méthode décrite par Micikevicius et al. en 2018, avec des poids maîtres FP32, des calculs FP16 et une mise à l’échelle de la perte, est désormais automatisée par les frameworks d’apprentissage profond sous le nom de précision mixte automatique (AMP).
Fonctionnement de la précision mixte#
Trois éléments permettent à la rétropropagation et aux mises à jour des poids pendant l’entraînement sur 16 bits d’égaler la précision de l’entraînement FP32 :
- Poids maîtres FP32 : L’optimiseur applique chaque mise à jour à une copie FP32 des poids. Une minuscule mise à jour ajoutée directement à un poids FP16 serait souvent arrondie à zéro, car FP16 ne conserve qu’environ trois chiffres décimaux significatifs.
- Précision par opération : Un contexte autocast exécute les multiplications matricielles et les convolutions sur 16 bits, où les Tensor Cores offrent le gain de vitesse le plus important, et conserve les réductions, softmax et la fonction de perte en FP32.
- Mise à l’échelle de la perte : FP16 ne peut pas représenter les valeurs inférieures à environ 6 × 10⁻⁸ ; de nombreux petits gradients seraient donc ramenés à zéro par sous-flux. La multiplication de la perte par un facteur d’échelle avant la rétropropagation déplace chaque gradient dans la plage FP16, puis les gradients sont divisés par le même facteur avant la mise à jour des poids.
Avec PyTorch AMP, torch.autocast gère la conversion de précision par opération et GradScaler gère la mise à l’échelle de la perte :
import torch
from torch import nn
# Use FP16 on an NVIDIA GPU and BF16 on CPU
device = "cuda" if torch.cuda.is_available() else "cpu"
dtype = torch.float16 if device == "cuda" else torch.bfloat16
model = nn.Linear(512, 10).to(device) # master weights stay in FP32
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
scaler = torch.amp.GradScaler(device, enabled=dtype == torch.float16) # loss scaling for FP16 only
x = torch.randn(64, 512, device=device)
with torch.autocast(device_type=device, dtype=dtype):
out = model(x) # the matrix multiply runs in 16-bit
loss = out.float().pow(2).mean()
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
print(f"Output: {out.dtype}, weights: {model.weight.dtype}, gradients: {model.weight.grad.dtype}")Sur CPU, l’extrait affiche torch.bfloat16 pour la sortie de la couche et torch.float32 pour les poids et leurs gradients ; sur un GPU NVIDIA, la sortie est torch.float16. Les calculs sur 16 bits et les poids maîtres FP32 coexistent au cours d’une même étape d’entraînement.
GradScaler de PyTorch ajuste dynamiquement le facteur d’échelle. Il démarre à 65,536, divise le facteur par deux et ignore l’étape chaque fois que les gradients mis à l’échelle contiennent des valeurs inf ou NaN, puis double le facteur après 2,000 étapes consécutives sans débordement, de sorte que le facteur se stabilise juste en dessous du seuil de débordement des gradients.
FP16, BF16 et précisions inférieures#
FP16 réserve 5 bits à l’exposant et 10 à la mantisse ; il est donc précis, mais déborde au-delà de 65,504. BF16 conserve les 8 bits d’exposant de FP32, couvrant la même plage jusqu’à environ 3.4 × 10³⁸, mais ne dispose que de 7 bits de mantisse : il n’a donc pas besoin de mise à l’échelle de la perte, au prix d’un arrondi moins précis. BF16 fonctionne sur les GPU NVIDIA à partir de la génération Ampere, sur les TPU de Google et sur de nombreux processeurs récents ; c’est le format d’entraînement habituel des grands modèles de langage. Le même principe s’étend à FP8 sur les GPU Hopper et Blackwell grâce au Transformer Engine de NVIDIA, ainsi qu’aux formats FP4 comme NVFP4 sur Blackwell.
La précision mixte en pratique#
Le principal risque pratique de l’AMP est qu’un modèle ou un GPU produise des pertes NaN sur 16 bits. L’entraînement Ultralytics YOLO26 active l’AMP par défaut avec amp=True : il compare d’abord les prédictions FP32 et AMP d’un modèle YOLO26n sur les GPU CUDA et repasse en FP32 en cas de désaccord, ou si le GPU appartient à une série connue pour produire des pertes NaN avec l’AMP, comme la série GTX 16. Définir amp="bf16" active l’autocast BF16 et désactive la mise à l’échelle de la perte.
La précision mixte est largement utilisée lorsque l’entraînement est limité par la mémoire ou le temps. Les équipes qui développent des véhicules autonomes entraînent des modèles de détection d’objets sur des millions d’images haute résolution ; réduire de moitié la mémoire des activations permet d’utiliser des images et des lots plus grands. En analyse d’images médicales, les volumes de tomodensitométrie et d’IRM en 3D dépassent souvent la mémoire du GPU en FP32, et les activations sur 16 bits rendent possible l’entraînement de modèles de segmentation sur des volumes entiers.
Précision mixte et concepts associés#
- Quantification de modèles : La quantification convertit un modèle entraîné en entiers de faible précision, comme INT8, pour accélérer l’inférence ; la précision mixte accélère l’entraînement et conserve les poids en virgule flottante.
- Entraînement conscient de la quantification : Le QAT simule l’arrondi en nombres entiers pendant l’entraînement afin que le modèle conserve sa précision après son déploiement en INT8.
- Précision demi-mot : La précision demi-mot désigne le format numérique FP16 lui-même, tandis que la précision mixte est la technique d’entraînement qui le combine avec FP32. Un entraînement entièrement en FP16, sans poids maîtres FP32 ni mise à l’échelle de la perte, perd les petites mises à jour à cause de l’arrondi et les petits gradients à cause du sous-flux, et ne converge souvent pas.










