FP8 vs FP4 vs BF16: number formats for AI, explained
Each halving of precision halves the memory per parameter and, on GPUs built for it, at least doubles peak tensor throughput. Here is how the formats work, which hardware runs them, and what you give up.

FP8 vs FP4 vs BF16 at a glance
| Format | Sign / exponent / mantissa bits | Largest finite value | Bytes per value | Typical use |
|---|---|---|---|---|
| FP32 | 1 / 8 / 23 | ≈ 3.4e38 | 4 | Master weights, optimizer state, accumulation |
| TF32 | 1 / 8 / 10 | ≈ 3.4e38 | 4 in memory | FP32 matrix math on NVIDIA tensor cores |
| BF16 | 1 / 8 / 7 | ≈ 3.4e38 | 2 | |
| FP16 | 1 / 5 / 10 | 65,504 | 2 | Inference; training needs loss scaling |
| FP8 E4M3 | 1 / 4 / 3 | 448 | 1 | Weights and activations |
| FP8 E5M2 | 1 / 5 / 2 | 57,344 | 1 | Gradients in FP8 training |
| FP6 E2M3 / E3M2 | 1 / 2 / 3 and 1 / 3 / 2 | 7.5 and 28 | 0.75 | |
| FP4 E2M1 | 1 / 2 / 1 | 6 | 0.5 |
Range versus precision: exponent and mantissa bits
Exponent bits set the range: how large and how small a value can get. Mantissa bits set the precision: how finely values are spaced within that range. Every format is a different split of the same budget.
- BF16 keeps FP32's 8 exponent bits, so it covers the same range, and cuts the mantissa to 7 bits, about two to three significant decimal digits. Because the range matches FP32, training needs no loss scaling, which is why BF16 has largely replaced FP16 for training.
- FP16 has more precision (10 mantissa bits) but tops out at 65,504, and small gradients underflow to zero, so FP16 training needs loss scaling.
- TF32
is not a storage format. It is a tensor-core mode, introduced with NVIDIA's Ampere generation, that takes FP32 inputs, multiplies them with a10-bit mantissa and accumulates in FP32. In PyTorch,torch.set_float32_matmul_precision("high")allows it.
FP8: E4M3 and E5M2
FP8 comes in two variants. E4M3 has more precision and a maximum of 448, so it is used for weights and activations. E5M2 trades a mantissa bit for range, up to 57,344, which suits gradients in FP8 training. NVIDIA's Transformer Engine, for example, uses E4M3 in the forward pass and E5M2 for gradients in its hybrid recipe.
FP6, FP4 and block scaling: NVFP4 vs MXFP4
| Format | Element | Values per block | Scale per block | Effective bits per value |
|---|---|---|---|---|
| NVFP4 (NVIDIA) | FP4 E2M1 | 16 | FP8 E4M3, plus one FP32 scale per tensor | ≈ 4.5 |
| MXFP4 (OCP Microscaling) | FP4 E2M1 | 32 | ≈ 4.25 | |
| MXFP6 (OCP Microscaling) | FP6 E2M3 or E3M2 | 32 | ≈ 6.25 | |
| MXFP8 (OCP Microscaling) | FP8 E4M3 or E5M2 | 32 | ≈ 8.25 |
Which GPUs support which formats
| GPU | Architecture | FP8 | FP6 | FP4 |
|---|---|---|---|---|
| H100, H200 | Hopper | Yes | No | No |
| L40S | Ada Lovelace | Yes | No | No |
| RTX 4090 (for reference; we do not rent it) | Ada Lovelace | Yes | No | No |
| B200, B300 | Blackwell, Blackwell Ultra | Yes | Yes | Yes |
| RTX PRO 6000, RTX 5090 | Blackwell | Yes | Yes | Yes |
| MI355X | AMD CDNA 4 | Yes | Yes (MXFP6) | Yes (MXFP4) |
Memory savings, worked out
| Format | Bits per weight, scales included | Weights | Where it fits |
|---|---|---|---|
| BF16 | 16 | ≈ 140 GB | One B200 (180 GB) or B300 (288 GB) |
| FP8 | 8 | ≈ 70 GB | One H100 tightly, one H200 comfortably |
| MXFP6 | ≈ 6.25 | ≈ 55 GB | One RTX PRO 6000 (96 GB), with room for the KV cache |
| NVFP4 | ≈ 4.5 | ≈ 39 GB | One RTX PRO 6000, with ample room for the KV cache |
| MXFP4 | ≈ 4.25 | ≈ 37 GB | One RTX PRO 6000; also native on the MI355X |
Accuracy: weights, activations and the KV cache
You can quantize three different things, and they behave differently.
- Weights
are fixed after training, so they can be quantized once, offline, with care. Weight-only 4-bit quantization with16-bit activations (W4A16) is along-established approach. - Activations change with every input and contain outliers: a few channels with magnitudes far larger than the rest. They need dynamic scaling or calibration. Quantizing both weights and activations to FP8 (W8A8) lets the matrix multiplications run on FP8 tensor cores; W4A4 with NVFP4 or MXFP4 is the most aggressive common setup.
- The KV cache
can be stored in FP8 to halve its memory, which buys concurrency or context length. Check long-context quality when you do.
Why vendors quote dense and sparse figures
| GPU | BF16, dense / sparse | FP8, dense / sparse | FP4, dense / sparse |
|---|---|---|---|
| H100, H200 | 989 / 1,979 TFLOPS | 1,979 / 3,958 TFLOPS | Not supported |
| B200 | 2.25 / 4.5 PFLOPS | 4.5 / 9 PFLOPS | 9 / 18 PFLOPS |
| B300 | 2.25 / 4.5 PFLOPS | 4.5 / 9 PFLOPS | 13.5 / 18 PFLOPS |
| MI355X | 2.5 / 5.0 PFLOPS | 5.0 / 10.1 PFLOPS | 10.1 PFLOPS (MXFP4) |
The sparse figures assume structured sparsity. On NVIDIA GPUs that is the 2:4 pattern: in every group of four consecutive weights, two are zero, so the tensor cores can skip half the multiplications. Most LLMs are served dense, so plan with the dense column. Compare like with like, since one headline may be sparse and another dense, and check the ratio rather than assuming it: the B300's FP4 figures (13.5 dense, 18 sparse) are not a clean 2×. Peak numbers are ceilings that real workloads reach only in part. Note also the pattern across each row: per these vendor figures, each halving of precision at least doubles dense peak throughput, which is the other half of the case for FP8 and FP4.
Practical advice: which precision to use
BF16 mixed precision, with FP32 master weights and optimizer state. Move to FP8 for large runs on H100 or newer once the loss curve matches a BF16 run.Pre-training and fullfine-tuning :Fine-tuning on a budget:QLoRA, which keeps the base model in 4-bit NF4 and trains16-bit adapters.- Serving on Hopper or Ada (H100, H200, L40S): FP8 weights and activations, plus an FP8 KV cache when you need more concurrency.
- Serving on Blackwell (B200, B300, RTX PRO 6000, RTX 5090): start with FP8, then try NVFP4 where memory or bandwidth is the bottleneck and your evaluations hold.
- Serving on the MI355X: FP8 first, then MXFP4 or MXFP6 with the same validation.
In code, the first steps are small:
# PyTorch: allow TF32 tensor cores for FP32 matrix multiplications
torch.set_float32_matmul_precision("high")
# vLLM: quantize weights to FP8 at load time and keep the KV cache in FP8
vllm serve <model> --quantization fp8 --kv-cache-dtype fp8
Whatever you pick, keep a BF16 baseline and an evaluation set, and compare before you ship. The VRAM calculator shows how each format changes the GPU you need, and our guide to the best GPU for LLM inference maps model sizes to hardware.
Frequently asked questions
Is FP8 better than BF16?
FP8 uses half the memory and, on GPUs with FP8 tensor cores, offers twice the peak throughput of BF16 per vendor figures. BF16 is more precise, so it remains the default for training, and FP8 inference should be validated against a BF16 baseline.
Does the H100 support FP4?
What is the difference between NVFP4 and MXFP4?
How much memory does FP4 save compared with BF16?
Close to four times for the weights: a 70B model drops from about 140 GB in BF16 to roughly 37 to 39 GB in MXFP4 or NVFP4, block scales included. The KV cache and activations are separate and shrink only if you quantize them too.
Should I train in FP8?
For large training runs on H100, H200 or Blackwell GPUs, FP8 can cut memory traffic and raise throughput, and libraries such as NVIDIA Transformer Engine handle the scaling. Validate the loss curve against a BF16 run first, since BF16 remains the safe default.
Dedicated GPUs, billed monthly
Whole GPUs from $449/mo, root access, bandwidth included. Pay with crypto.
See GPUs & pricing Size your GPU with the VRAM calculator

