FP8、FP4 与 BF16:AI 数值格式详解
精度每减半一次,每个参数占用的显存就减半;在专为此设计的 GPU 上,张量运算的峰值吞吐量至少翻一番。本文介绍这些格式的工作原理、哪些硬件能运行它们,以及您要为此付出的代价。

FP8、FP4 与 BF16 之间的选择,是显存、速度与准确度之间的权衡。BF16 每个值占两个字节,至今仍是训练的默认格式,在质量优先的推理场景中也是如此。FP8 每个值占一个字节,在新一代 GPU 上被广泛用于推理。FP4 每个值只占半个字节,必须配合块缩放才能使用,而且只有最新的硬件才能原生运行。本指南将介绍各格式的位布局、块缩放格式(NVFP4、MXFP4 和 MXFP6)、哪些 GPU 支持哪些格式,以及如何做出选择。
FP8、FP4 与 BF16 一览
浮点数由符号位、指数位和尾数位组成。下表按位宽从宽到窄的顺序,列出了 AI 工作中会遇到的各种格式。
| 格式 | 符号位 / 指数位 / 尾数位 | 最大有限值 | 每个值的字节数 | 典型用途 |
|---|---|---|---|---|
| FP32 | 1 / 8 / 23 | ≈ 3.4e38 | 4 | 主权重、优化器状态、累加 |
| TF32 | 1 / 8 / 10 | ≈ 3.4e38 | 4(在显存中) | 在 NVIDIA Tensor Core 上执行 FP32 矩阵运算 |
| BF16 | 1 / 8 / 7 | ≈ 3.4e38 | 2 | 训练、高质量推理 |
| FP16 | 1 / 5 / 10 | 65,504 | 2 | 推理;用于训练时需要损失缩放 |
| FP8 E4M3 | 1 / 4 / 3 | 448 | 1 | 权重和激活值 |
| FP8 E5M2 | 1 / 5 / 2 | 57,344 | 1 | FP8 训练中的梯度 |
| FP6 E2M3 / E3M2 | 1 / 2 / 3 和 1 / 3 / 2 | 7.5 和 28 | 0.75 | 块缩放权重(MXFP6) |
| FP4 E2M1 | 1 / 2 / 1 | 6 | 0.5 | 块缩放权重和激活值(NVFP4、MXFP4) |
范围与精度:指数位和尾数位
指数位决定范围:一个值最大能有多大、最小能有多小。尾数位决定精度:在这个范围内,数值之间的间隔有多细密。每种格式都是对同一份位数预算的不同分配。
- BF16 保留了 FP32 的 8 个指数位,因此覆盖的范围相同;尾数则削减到 7 位,约合两到三位有效十进制数字。由于范围与 FP32 一致,训练时无需损失缩放,这正是 BF16 在训练中基本取代了 FP16 的原因。
- FP16 的精度更高(10 个尾数位),但最大值只有 65,504,而且较小的梯度会下溢为零,因此 FP16 训练需要损失缩放。
- TF32 不是一种存储格式,而是 NVIDIA 随 Ampere 架构引入的一种 Tensor Core 运算模式:它接收 FP32 输入,以 10 位尾数做乘法,并以 FP32 累加。在 PyTorch 中,调用
torch.set_float32_matmul_precision("high")即可启用它。
Tensor Core 上的矩阵乘法以低精度数据作为输入,但以更高的精度累加,通常是 FP32。低精度的部分是您存储和搬运的数据;高精度累加则保护了求和的结果。
FP8:E4M3 与 E5M2
FP8 有两种变体。E4M3 精度更高,最大值为 448,因此用于权重和激活值。E5M2 用一个尾数位换来了更大的范围,最大可达 57,344,适合 FP8 训练中的梯度。例如,NVIDIA 的 Transformer 引擎在其混合(hybrid)方案中,前向传播使用 E4M3,梯度则使用 E5M2。
FP6、FP4 与块缩放:NVFP4 对比 MXFP4
采用 E2M1 布局的 FP4 只能表示 0、0.5、1、1.5、2、3、4 和 6,以及对应的负值。可表示的值这么少,每个张量只用一个缩放因子根本行不通。块缩放格式为每个小数据块单独配备一个缩放因子,与数据存放在一起。
| 格式 | 元素类型 | 每块数值个数 | 每块缩放因子 | 每个值的有效位数 |
|---|---|---|---|---|
| NVFP4(NVIDIA) | FP4 E2M1 | 16 | FP8 E4M3,另加每个张量一个 FP32 缩放因子 | ≈ 4.5 |
| MXFP4(OCP Microscaling) | FP4 E2M1 | 32 | 以 8 位表示的 2 的幂(E8M0) | ≈ 4.25 |
| MXFP6(OCP Microscaling) | FP6 E2M3 或 E3M2 | 32 | 以 8 位表示的 2 的幂(E8M0) | ≈ 6.25 |
| MXFP8(OCP Microscaling) | FP8 E4M3 或 E5M2 | 32 | 以 8 位表示的 2 的幂(E8M0) | ≈ 8.25 |
两种 FP4 格式的区别,在单个数据块上看得最清楚。假设某个块中绝对值最大的数是 0.42。NVFP4 可以选择接近 0.42 / 6 = 0.07 的缩放因子,于是 0.42 几乎正好落在最大码值 6 上。MXFP4 则必须使用 2 的幂:OCP 规范中的参考转换算法会选择 2⁻⁴ = 0.0625,把 0.42 映射为 6.72,超出了最大码值,因此被截断为 6,解码后为 0.375。更小的块和更精细的缩放因子,让 NVFP4 能更贴合每个块的数据,代价是每个值多占四分之一位。而 2 的幂缩放因子在硬件中应用起来成本更低,覆盖的范围也宽得多。
哪些 GPU 支持哪些格式
这里的“支持”,指的是 Tensor Core 能以该格式进行原生计算。任何 GPU 都可以存储 4 位权重,并在做乘法之前把它们展开为 16 位,GPTQ 和 AWQ 等仅权重量化方法正是采用这种做法;但这样节省的是显存和带宽,而不是算力。
| GPU | 架构 | FP8 | FP6 | FP4 |
|---|---|---|---|---|
| H100、H200 | Hopper | 支持 | 不支持 | 不支持 |
| L40S | Ada Lovelace | 支持 | 不支持 | 不支持 |
| RTX 4090(仅供参考,我们不出租) | Ada Lovelace | 支持 | 不支持 | 不支持 |
| B200、B300 | Blackwell、Blackwell Ultra | 支持 | 支持 | 支持 |
| RTX PRO 6000、RTX 5090 | Blackwell | 支持 | 支持 | 支持 |
| MI355X | AMD CDNA 4 | 支持 | 支持(MXFP6) | 支持(MXFP4) |
NVIDIA 的 Blackwell 数据中心 GPU,即 B200 和 B300,同时支持 NVFP4 和 OCP MX 格式。实际上,FP8 是 Hopper 和 Ada 架构的 Tensor Core 能原生运行的最低浮点精度,而 Blackwell 和 MI355X 又增加了 FP6 和 FP4。具体案例请参阅我们的 H200 与 B200 对比。我们单卡和 8 卡产品线中的每一款 GPU 都在硬件层面支持 FP8。
显存节省的具体计算
以 70B 参数的模型为例,仅权重一项:
| 格式 | 每个权重的位数(含缩放因子) | 权重 | 能装进哪里 |
|---|---|---|---|
| BF16 | 16 | ≈ 140 GB | 单张 B200(180 GB)或 B300(288 GB) |
| FP8 | 8 | ≈ 70 GB | 单张 H100 只能勉强装下,单张 H200 绰绰有余 |
| MXFP6 | ≈ 6.25 | ≈ 55 GB | 单张 RTX PRO 6000(96 GB),还能为 KV 缓存留出空间 |
| NVFP4 | ≈ 4.5 | ≈ 39 GB | 单张 RTX PRO 6000,能为 KV 缓存留出充足空间 |
| MXFP4 | ≈ 4.25 | ≈ 37 GB | 单张 RTX PRO 6000;MI355X 也能原生运行 |
实际的检查点会略大一些,因为嵌入层、输出层和归一化层的权重往往保持 16 位。另有两样东西不会随权重一起缩小:激活值,以及 KV 缓存(除非您也对它进行量化)。在受显存带宽限制的解码阶段,每个权重的字节数越少,意味着每生成一个 token 需要读取的字节数也越少,因此降低精度不仅能节省显存,还能加快生成速度。完整的估算方法,请参阅大语言模型(LLM)需要多少显存。
准确度:权重、激活值与 KV 缓存
可以量化的对象有三种,它们的表现各不相同。
- 权重在训练完成后就固定不变,因此可以离线、仔细地一次性完成量化。权重 4 位、激活值 16 位的仅权重量化(W4A16)是一种由来已久的方法。
- 激活值随每次输入而变化,并且含有离群值:少数通道的数值远大于其他通道。它们需要动态缩放或校准。把权重和激活值都量化为 FP8(W8A8),矩阵乘法就能在 FP8 Tensor Core 上运行;采用 NVFP4 或 MXFP4 的 W4A4 则是常见方案中最激进的一种。
- KV 缓存可以用 FP8 存储,使其显存占用减半,从而换取更高的并发或更长的上下文。这样做时,请检查长上下文下的质量。
训练比推理更保守。BF16 混合精度是标准做法;借助 Transformer 引擎等库,FP8 训练已在 Hopper 和 Blackwell 上成熟应用;4 位训练则仍是一个活跃的研究领域。
为什么厂商要同时公布稠密和稀疏算力
规格表通常会为每种格式给出两个算力数字。以下是厂商公布的单卡峰值算力:
| GPU | BF16(稠密 / 稀疏) | FP8(稠密 / 稀疏) | FP4(稠密 / 稀疏) |
|---|---|---|---|
| H100、H200 | 989 / 1,979 TFLOPS | 1,979 / 3,958 TFLOPS | 不支持 |
| 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) |
稀疏算力以结构化稀疏为前提。在 NVIDIA GPU 上,这指的是 2:4 模式:每 4 个连续的权重中有 2 个为零,因此 Tensor Core 可以跳过一半的乘法运算。大多数 LLM 都以稠密方式部署,所以请按稠密那一栏来规划。比较时要同类相比,因为一个宣传数字可能是稀疏算力,另一个却是稠密算力;也要核实两者之间的比例,而不要想当然:B300 的 FP4 算力(稠密 13.5,稀疏 18)并不是整整 2 倍。峰值数字只是上限,实际工作负载只能达到其中一部分。还请注意每一行中的规律:根据这些厂商数据,精度每减半一次,稠密峰值吞吐量至少翻一番,这正是支持 FP8 和 FP4 的另一半理由。
实用建议:该用哪种精度
- 预训练和全参数微调:BF16 混合精度,配合 FP32 主权重和优化器状态。在 H100 或更新的 GPU 上进行大规模训练时,一旦损失曲线与 BF16 训练相吻合,即可改用 FP8。
- 预算有限的微调:QLoRA,它以 4 位 NF4 格式保存基座模型,并训练 16 位适配器。
- 在 Hopper 或 Ada(H100、H200、L40S)上部署推理:权重和激活值采用 FP8;需要更高并发时,KV 缓存也采用 FP8。
- 在 Blackwell(B200、B300、RTX PRO 6000、RTX 5090)上部署推理:先用 FP8;当显存或带宽成为瓶颈、且评测结果站得住时,再尝试 NVFP4。
- 在 MI355X 上部署推理:先用 FP8,再经过同样的验证后尝试 MXFP4 或 MXFP6。
落到代码上,第一步只需要很少的改动:
# 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
无论选择哪种精度,都请保留一个 BF16 基线和一套评测集,在上线之前先做对比。显存计算器可以显示每种格式会如何改变您所需的 GPU;我们的大语言模型推理最佳 GPU 选型指南则把各种模型规模对应到了具体硬件。
常见问题
FP8 比 BF16 更好吗?
FP8 的显存占用只有 BF16 的一半;根据厂商数据,在配备 FP8 Tensor Core 的 GPU 上,其峰值吞吐量是 BF16 的两倍。BF16 的精度更高,因此仍是训练的默认格式;FP8 推理则应以 BF16 为基线进行验证。
H100 支持 FP4 吗?
不支持。H100 和 H200 等 Hopper GPU 支持 FP8,但没有 FP4 或 FP6 Tensor Core;这两种格式是随 Blackwell 才出现的。不过,您仍然可以通过仅权重量化在 H100 上存储 4 位权重,这样能节省显存,但计算仍以 16 位进行。
NVFP4 和 MXFP4 有什么区别?
两者都把数值存储为 4 位 E2M1 数字,每个块共享一个缩放因子。NVFP4 每块 16 个值,使用 FP8 E4M3 缩放因子;MXFP4 每块 32 个值,使用 2 的幂缩放因子。因此,NVFP4 能更贴合每个块的数据,存储开销则略高。
与 BF16 相比,FP4 能节省多少显存?
权重部分可缩减到接近原来的四分之一:70B 模型在 BF16 下约 140 GB,采用 MXFP4 或 NVFP4 后降至约 37 到 39 GB(含块缩放因子)。KV 缓存和激活值另外计算,只有对它们也做量化时才会缩小。
应该用 FP8 训练吗?
在 H100、H200 或 Blackwell GPU 上进行大规模训练时,FP8 可以减少显存读写流量、提高吞吐量,NVIDIA Transformer 引擎等库会负责处理缩放。请先将损失曲线与 BF16 训练进行对比验证,因为 BF16 仍是稳妥的默认选择。


