← train.galvyn.xyz

Lesson 1.6 · Precision · Oct 18, 2026

bf16 costs nothing

bf16 and fp32 losses agree to three decimals at every evaluation, while bf16 ran at least 1.3× faster in 17% less memory.

GPUs do 16-bit maths several times faster than 32-bit. Mixed precision (bf16 autocast) runs the big matrix multiplies in bfloat16 while keeping the weights, gradients and optimizer state in fp32. Run A uses bf16, run B pure fp32. Same 30M model, batch 64 × 256 tokens of FineWeb-Edu, 2,000 steps, on an NVIDIA L4.

Lossthe two curves sit on top of each other
6810500100015002000step
Real data from the lab experiment. A: fineweb edu · B: fineweb edu
AB
val loss at step 400 / 1,200 / 2,0005.942 / 5.176 / 4.8975.941 / 5.178 / 4.898
tokens per second43.3k (sharing the GPU)32.9k (alone)
peak GPU memory12.8 GB15.3 GB

The losses agree to three decimals at every evaluation: bf16 lost nothing. It was also faster and smaller, and the speed number understates it: A shared the L4 with other lesson runs while B had it to itself (B ran later, alone, after an out-of-memory crash: pure fp32 at batch 64 needs a 3 GB tensor for the logits alone). On a dedicated GPU the gap is larger; on the home RTX A5000, matrix multiplies measured 40 TFLOPS in bf16 against 12 in fp32.

Why bfloat16 and not fp16: bf16 keeps fp32's exponent range (it just drops mantissa bits), so gradients don't underflow and no loss scaling is needed. The numbers are less precise, but training is noisy anyway: the seed alone moves the result more than bf16 does.

Every number here comes from this experiment in the lab, trained on one RTX A5000.