What is mixed precision training?
Mixed precision training runs most of a neural network's math in a 16-bit float format, fp16 or bf16, while keeping a few sensitive values in 32-bit fp32. The forward and backward passes use 16-bit weights and activations, and the optimizer updates an fp32 master copy of the weights. With fp16, a loss scale keeps small gradients from rounding to zero.
Nearly every large model today is trained this way. Matrix multiplications in 16 bits run on GPU tensor cores at many times the fp32 rate, and 16-bit activations halve the memory that the backward pass has to keep. Frameworks expose it as a switch: PyTorch's autocast and GradScaler, or a bf16 setting in DeepSpeed and Megatron-LM. The same ideas carry over to fp8 training on the newest GPUs.
Key ideas
- Mixed precision runs matrix math in fp16 or bf16 and keeps master weights and optimizer state in fp32.
- Training with Adam needs about 16 bytes per parameter in mixed precision, the same as plain fp32; the memory saving comes from activations.
- fp16's normal range ends at 2^−14 below and 65,504 above, so small gradients round to zero without help.
- Loss scaling multiplies the loss by a power of 2 before backward and divides the gradients by it afterwards.
- Updates smaller than half the fp16 spacing vanish, which is why the optimizer updates an fp32 copy of the weights.
- bf16 keeps fp32's exponent range with fewer mantissa bits, so it trains without loss scaling.
Common questions
Should I train with fp16 or bf16?
Use bf16 if the hardware supports it, which includes NVIDIA GPUs from the A100 onward and Google TPUs. It needs no loss scaling and rarely overflows, so runs are simpler and more stable. fp16 remains the choice on older GPUs such as the V100 and T4, where bf16 tensor cores are missing.
Does mixed precision hurt model accuracy?
With loss scaling and fp32 master weights, Micikevicius et al. matched fp32 accuracy across image, speech, translation and language models. Most later large models were trained in mixed precision with no reported loss. Problems usually show up as loss spikes or NaNs, which point to overflow or to an operation that should stay in fp32.
What causes NaN losses in fp16 training?
An activation or gradient above 65,504 becomes inf, and inf turns into NaN through operations such as inf − inf or 0 × inf. Dynamic loss scaling catches overflow in the gradients, but not in the forward pass. Common fixes are keeping softmax and normalization in fp32, lowering the learning rate, or switching to bf16.
What is TF32?
TF32 is a tensor core mode on A100 and later GPUs that reads fp32 inputs, rounds them to 10 mantissa bits with fp32's 8 exponent bits, and accumulates in fp32. Code sees ordinary fp32 tensors, so it speeds up fp32 training without other changes. It is slower than bf16, because each value still takes 4 bytes in memory and the peak rate is half.
Related explainers
- Quantization — Shrinking model weights to 8 and 4 bits
- Backpropagation — How networks learn from their mistakes
- Optimizers — SGD, momentum, and Adam — smarter gradient descent
- Vanishing & Exploding Gradients — Why deep networks struggle and how to fix it
- KV Cache — Why LLM generation caches keys and values, and what it costs
- Mixture of Experts — Routing each token to a few experts in a much larger model
References
- Micikevicius et al. (2017), "Mixed Precision Training"
- Rajbhandari et al. (2019), "ZeRO: Memory Optimizations Toward Training Trillion Parameter Models"
- Kalamkar et al. (2019), "A Study of BFLOAT16 for Deep Learning Training"
- Korthikanti et al. (2022), "Reducing Activation Recomputation in Large Transformer Models"
- Micikevicius et al. (2022), "FP8 Formats for Deep Learning"
Last updated