大语言模型中的低精度数据格式

如果只用一句话概括过去三年大模型训练与推理的硬件趋势 — 训练在从 BF16 走向 FP8,推理在从 FP8 走向 FP4。每一次精度下移一档,同样的硅片面积就能多塞一倍的 MAC 单元,LLM 训练吞吐与推理 token/s 直接翻倍。这条主线背后是一整张数据格式的谱系:FP32 / TF32 / FP16 / BF16 / FP8(两个变体) / FP6(两个变体) / FP4(MX 与 NV 两个版本) / INT8 / INT4。

但「精度下移」从来不是「整个模型换一种格式」这么简单。同一个 Transformer block 里,矩阵乘法可能跑 FP8、Softmax 在 FP32 下做、KV cache 又压到 INT8 — 精度是按运算类型混用的,不是按层混用。要看清这件事,得把每种格式的位结构、动态范围、硬件支持、和在 Transformer 里的实际位置全部铺开。

这篇文章的目的就是把这张谱系图一次性铺开,只覆盖有硬件原生 Tensor Core / 矩阵引擎支持的格式 — 纯软件模拟、研究阶段、或者只在论文里出现的格式(INT2、二值化、posit 等)略过不谈。

引子 — 低精度不只是省显存

很多人对低精度的第一反应是「省显存」。这只对了一半 — 真正决定为什么 NVIDIA / AMD / Google 都在卷低精度的,是另一个事实:每一代 Tensor Core 在更低精度下的吞吐量大致翻倍

架构旗舰卡同 SM 算力(主精度)同 SM 算力(最低精度)
Ampere (2020)A100312 TF (FP16)624 TOPS (INT8)
Hopper (2022)H100990 TF (FP16)1979 TF (FP8)
Blackwell (2024)B2002250 TF (FP16)9000 TF (FP4)
Rubin (2026)R100~8000 TF (FP16)50,000 TF (FP4)

把这张表放在一起看 — 位宽每减半,同代硅片上 MAC 单元数量翻倍,算力直接翻倍。所以低精度不只是「同样模型显存占用更小」,更是「同样硅片可以跑更大的模型」。这是 NVIDIA / AMD / Intel 这三年集体扑向 FP8 / FP4 的根本动力。

省显存当然也重要 — BF16 的模型权重比 FP32 小一半,INT4 量化的权重比 FP16 小四倍。但如果只有显存红利,没有算力红利,这条路根本走不远。

浮点数的通用表示 — 一个公式套所有格式

任何一个 IEEE 754 风格的浮点数都由三部分组成:

value=(1)S×2Ebias×(1.M)\text{value} = (-1)^S \times 2^{E - \text{bias}} \times (1.M)
  • S(sign,符号位) — 1 位,决定正负
  • E(exponent,指数位) — 共 ee 位,存的是「偏移后」的指数;真实指数 = EbiasE - \text{bias},其中 bias=2e11\text{bias} = 2^{e-1} - 1
  • M(mantissa / fraction,尾数位) — 共 mm 位,前面隐含一个「1.」(normal 数情况下)

所以一个浮点格式的关键参数就是「总位数 + ee + mm。决定动态范围的是 ee,决定精度的是 mm。下文所有格式都按这个模板套。

整数格式则是另一种 — 完全没有指数位,只有有符号 / 无符号的整数表示。它的范围线性、精度均匀,但表达范围受位宽硬性限制,实际使用时永远要搭一个外部的 scale factor 把整数「拉伸」或「收缩」到目标数值区间。这一点放到后面整数那一节细说。

浮点格式逐一拆解 — FP32 → FP4 同尺度对比

先一张图把九种浮点格式按同尺度铺开 — 每一格就是一个比特位。指数位宽决定动态范围、尾数位宽决定精度,这两个数轴的取舍是所有格式设计的核心:

浮点数位结构同尺度对比 · 每格 = 1 bitS = 符号 · E = 指数(决定动态范围) · M = 尾数(决定精度)FP321 + 8 + 23TF321 + 8 + 10FP161 + 5 + 10BF161 + 8 + 7FP8 E4M31 + 4 + 3FP8 E5M21 + 5 + 2FP6 E3M21 + 3 + 2FP6 E2M31 + 2 + 3FP4 E2M11 + 2 + 1符号 S指数 E · 决定动态范围尾数 M · 决定精度
九种浮点格式按同尺度对齐(每格 = 1 bit)。FP32 / FP16 来自 IEEE 754,TF32 来自 NVIDIA,BF16 来自 Google Brain,FP8 由 NVIDIA / Arm / Intel 联合定义,FP6 / FP4 是 OCP 微缩格式标准的一部分。BF16 跟 FP32 共享 8 位指数,所以动态范围相同但精度只剩一半;FP8 的两个变体是同位宽下的两种取舍(E4M3 重精度走前向、E5M2 重范围走反向);FP4(E2M1) 一共只有 4 位 — 单看完全不可用,必须以 MX 微缩格式形式使用。

FP32 / TF32 — 基准与一个工程巧思 — 同 8 位指数 · 不同尾数

FP32(1 + 8 + 23 = 32 位)是所有现代 CPU / GPU 的基准格式。指数 8 位、bias = 127、动态范围约 1.2×10381.2 \times 10^{-38}3.4×10383.4 \times 10^{38},精度约 7 位十进制有效数字。

TF32(1 + 8 + 10 = 19 位,存在 32 位寄存器里)是 NVIDIA 在 A100 上引入的一个工程巧思 — 指数位和 FP32 完全一样(8 位),尾数砍到和 FP16 一样(10 位)。它名字里带「32」,但有效宽度只有 19 位。这么做的好处是:动态范围跟 FP32 完全相同 → 训练时不需要 loss scaling;精度只剩 ~3 位十进制 → 算得快很多。A100 / H100 / Blackwell 上 TF32 是 FP32 GEMM 的默认替代,不改一行代码就能加速

FP16 / BF16 — 训练时代的两个 16 位 — 一个重精度 · 一个重范围

FP16(1 + 5 + 10 = 16 位)是 IEEE 754 半精度,指数 5 位、bias = 15、动态范围约 6×1056 \times 10^{-5}6.5×1046.5 \times 10^{4},精度约 3-4 位十进制。这个动态范围对训练来说非常窄 — 梯度一旦小到 10710^{-7} 量级就会下溢成零。所以 FP16 训练必须配合 loss scaling(把 loss 放大到不会下溢的量级再反向传播)。

BF16(1 + 8 + 7 = 16 位)是 Google Brain 在 TPU v2 时代提出的格式,设计思想很直接 — 把 FP32 的尾数砍掉 16 位,保留全部 8 位指数。这样:

  • 动态范围跟 FP32 几乎相同 → 训练时不再需要 loss scaling,几乎可以「无痛」替换 FP32
  • 精度只剩 2-3 位十进制 → 比 FP16 还低
  • FP32 ↔ BF16 的转换只是截断 / 补零 → 硬件代价几乎为零

这就是为什么 2020 年之后,大模型训练几乎清一色地选 BF16 而不是 FP16 — 大模型训练对动态范围远比对精度敏感。这条经验是后面 FP8 设计的直接原型。

FP8 — 两个变体的分工 — E4M3 走前向 · E5M2 走反向

FP8 由 NVIDIA / Arm / Intel 在 2022 年联合提出(arxiv 2209.05433),H100 / MI300 / Gaudi 2/3 都原生支持。它同时定义了两个变体:

变体位结构动态范围精度用途
E4M31+4+3±448\pm 448(最大值)· 最小 normal 数 262^{-6}较高前向:权重 / 激活
E5M21+5+2±57344\pm 57344 · 最小 normal 数 2142^{-14}较低反向:梯度

为什么要两个变体?因为激活和梯度的动态范围差很多。激活值经过 LayerNorm 之后通常集中在小范围内,适合 E4M3 的「重精度、轻范围」;梯度的数值可能跨好几个数量级,必须用 E5M2 的「重范围、轻精度」兜住。

注意 E4M3 不严格遵循 IEEE 754 — 它没有 inf,把本来表示 inf 的编码挪用来扩展数值范围(最大值是 448 而不是 240)。E5M2 则严格遵循 IEEE 754,有 inf 和 NaN。

FP8 的 scaling:单看 8 位完全不够覆盖训练时的数值范围。所以 FP8 几乎总是搭配一个 FP32 的 per-tensor scaling factor(H100 的 Transformer Engine 自动维护),实际存储的数值是 FP8_value×scale\text{FP8\_value} \times \text{scale}。后面提到的 DeepSeek-V3 在这一层做了更细粒度的改进。

FP6 与 FP4 — 进入微缩格式时代 — 单看无意义 · 必须按块共享 scale

FP6 和 FP4 是 2023 年 OCP(Open Compute Project)发布的 微缩格式(Microscaling, MX) 规范的一部分,Blackwell 是第一代把它写进 Tensor Core 的硬件。

FP6 有两个变体:E3M2(范围大、精度低)和 E2M3(范围小、精度高),按场景选用。

FP4 在 Tensor Core 上有两个版本,都用 E2M1 的位结构,差别在于 scale 的粒度:

版本位结构块大小块 scale外层 scale
MXFP4(OCP)E2M1 (4 bit)32 元素E8M0(8 bit,纯指数)
NVFP4(NVIDIA)E2M1 (4 bit)16 元素FP8 E4M3(8 bit)FP32 per-tensor

为什么需要微缩格式?因为 FP4 一共只有 4 位,能表示的不同数值只有 16 个(包括正负零)。如果不分组共享一个 scale,这 16 个值根本覆盖不了实际权重的分布。MX 把「per-tensor scaling」做成「per-block scaling」 — 每 32 个数共享一个 8 位的指数 scale,等于在硬件层面就内置了 fine-grained 量化。

NVFP4 把块大小从 32 缩到 16,把块 scale 从纯指数 E8M0 换成更精细的 FP8(E4M3),再外面套一层 FP32 per-tensor scale — 三层 scale 结构让它在 Blackwell 推理上的精度比 MXFP4 明显更好,代价是 metadata 占用稍微多一点。

整数格式 INT8 / INT4 — 没有指数 · 完全靠 scale 兜底

整数格式可以看成是「全部尾数、零位指数」的特殊浮点 — 精度均匀、但动态范围完全靠外部 scale 决定。INT8 与 INT4 在 LLM 推理上几乎占据了消费级 / 部署侧的全部场景。

INT8 vs INT4 · 单独存在时能表示的数值线性轴(不再是浮点的对数轴) · 整数格式离不开外部 scaleINT8 · 有符号 · 256 个值−1280+127256 个均匀分布的值 · 必须配 scale 与 zero point 才能映射到实际数值INT4 · 有符号 · 16 个值-8-7-6-5-4-3-2-101234567只有 16 个不同的值 · 必须以 group-wise 共享 scale(每 32/64/128 个数一个 FP16 scale)
INT8 与 INT4 的取值范围 — 整数格式没有指数位,数值均匀分布在固定的整数区间内。INT4 一共只有 16 个不同的值(从 −8 到 +7),离开外部 scale 完全不能用。GPTQ、AWQ 这些权重量化算法的核心做的就是「找到一组合适的 group-wise scale,让权重量化后的精度损失最小」。

实际使用整数格式时,定点 → 浮点的映射公式是:

xfps(xintz)x_{\text{fp}} \approx s \cdot (x_{\text{int}} - z)

其中 ss 是 FP16 / FP32 的 scale,zz 是 zero point(对称量化 z=0z=0,非对称量化 z0z \neq 0)。INT8 通常 per-tensor 或 per-channel 一个 scale 就够;INT4 几乎必须 group-wise — 每 32 / 64 / 128 个数共享一个 scale,否则精度损失太大。GPTQ(arxiv 2210.17323)、AWQ(arxiv 2306.00978) 这些权重量化算法,核心都是在「找一组合适的 group-wise scale」。

它们能表示的范围 — 对数轴上的一字排开

把所有浮点格式的动态范围放在同一条对数轴上,差异一眼就能看出来:

浮点格式动态范围 · 对数轴对齐每条 bar 的横向长度 = log₁₀(max) − log₁₀(min) · 颜色按位宽分组10⁻⁴⁰10⁻³⁰10⁻²⁰10⁻¹⁰110¹⁰10²⁰10³⁰10⁴⁰log scaleFP321.2e−38 → 3.4e38TF32同 FP32BF16同 FP32FP166.1e−5 → 6.5e4FP8 E5M26.1e−5 → 5.7e4FP8 E4M32e−3 → 448FP6 E3M20.06 → 28FP6 E2M30.13 → 7.5FP4 E2M10.5 → 6BF16 / TF32 与 FP32 共享 8 位指数 · 三条 bar 完全重合 · 这就是 BF16 训练可以无痛替换 FP32 的原因
九种浮点格式的动态范围(对数轴)。三条蓝色 bar(FP32 / TF32 / BF16) 长度一致,因为它们共享 8 位指数;FP16 与 FP8-E5M2 范围接近,都是「重指数」的设计;FP4 的 bar 几乎只是一个点 — 这正是它必须依赖 block-scale 才能用起来的直观证据。

几个值得点出来的观察:

  • 「重范围」vs「重精度」一眼区分。同位宽下,指数位多的(BF16、FP8-E5M2)适合训练 — 梯度跨数量级时不会溢出;尾数位多的(FP16、FP8-E4M3、FP6-E2M3)适合推理 — 权重数值分布已知,精度更值钱。
  • 位宽越往下走,范围越小到几乎是个点。FP4 一共只能覆盖 0.5 ~ 6 这个区间。它能用在 LLM 推理上,全靠外挂的 block-scale 把这条小 bar 「拉伸」或「收缩」到目标数值区间。
  • TF32 / BF16 是「FP32 的截断」。把它们和 FP32 叠在一起,bar 的左右端完全重合,只是精度刻度不同。这就是为什么 FP32 ↔ BF16 / TF32 转换硬件代价几乎为零。

Transformer block 内部的精度分配 — 训练 vs 推理

整个模型从来不是「全部用一种精度」 — Transformer 的每个组件按运算特性各自选精度。下面这张图把训练和推理两种模式的精度分配并排画出来:

Transformer block 内部精度分配 · 训练 vs 推理每个组件按运算类型混用不同精度 — 这是低精度真正难的地方训练 (Training)前向 + 反向 + 优化器推理 (Inference)前向 only · 权重已固定Master Weights + Optimizer StateFP32 · master + Adam m / v · ≈ 4× 参数EmbeddingBF16RMSNormFP32Q / K / V ProjectionFP8 in · FP32 accQ × KᵀFP8 / BF16SoftmaxFP32Attention × VFP8 / BF16Output ProjectionFP8-E4M3+ ResidualFP32 accFFN Linear 1FP8-E4M3SwiGLUBF16 / FP32FFN Linear 2FP8-E4M3+ ResidualFP32 acc… × N 层 …Backward · 梯度 GEMMFP8-E5M2 · 梯度兜底Loss + Loss ScalingFP32Static Weights · 离线量化 · 不再更新INT4 / FP4 + group-wise FP16 scaleEmbeddingBF16RMSNormBF16Q / K / V ProjectionINT4 W · BF16 actQ × KᵀBF16SoftmaxBF16KV cacheFP8 / INT8Attention × VBF16Output ProjectionINT4 / FP4+ ResidualBF16FFN Linear 1INT4 / FP4SwiGLUBF16FFN Linear 2INT4 / FP4+ ResidualBF16… × N 层 …LM Head · 输出 logitsBF16FP32BF16FP8INT8INT4 / FP4
Transformer block 内部的精度分配 — 左列训练、右列推理。训练侧几乎是「两层结构」 — 所有 GEMM 用 BF16 / FP8 输入但在 FP32 下累加,其余对数值敏感的 norm / softmax / residual 全部 FP32;再加上必须保留的 FP32 master weights 和 Adam 优化器状态(BF16 + FP32 master + Adam m + Adam v ≈ 14 字节/参数)。推理侧走向另一个极端 — 权重压到 INT4 / FP4,激活仍是 BF16,KV cache 单独压到 FP8 / INT8。

几个非显然的细节:

  • GEMM 几乎是低精度的唯一战场。一个 Transformer block 里,真正参与「位宽下移」的就是那几个矩阵乘 — Q/K/V projection、attention 的两个 batched matmul、output projection、FFN 的两个线性层。其他地方(norm / softmax / residual / activation)虽然也能压精度,但收益相比 GEMM 小得多 — LLM 大部分计算和参数都在那几个 GEMM 上。
  • Softmax / Norm / Residual 几乎不动。这三个组件的共同点是「对数值范围 / 累加误差敏感」 — softmax 要算 exe^x,exp 对小数点后的位数极度敏感;norm 要算平方和,容易溢出;residual 是逐层累加的关键路径,误差会被 N 层放大。所以它们在训练侧基本都保持 FP32。
  • KV cache 是推理特有的精度优化点。长上下文时,KV cache 占的显存甚至超过权重本身。把它单独压到 FP8 / INT8 是 vLLM、TensorRT-LLM、SGLang 都默认提供的常规操作。
  • 训练显存的「14 字节/参数」。BF16 权重 2 字节 + FP32 master 4 字节 + Adam 一阶矩 4 字节 + Adam 二阶矩 4 字节 = 14 字节/参数。这就是为什么训练一个 70B 模型至少需要 ~1 TB 的显存(还没算激活)。

微缩格式 MX — 让 FP4 / FP6 真正能用的关键

前面铺过的对数轴上,FP4 / FP6 的范围短到几乎是个点。它们能在硬件上跑起来,根本不在格式本身,而在它们外挂的 block scaling

OCP 的 MX 规范定义了一个非常简单的结构 — 每 32 个数共享一个 8 位的指数 scale:

块大小: 32 元素
每元素:  FP4 (4 bit) 或 FP6 (6 bit) 或 FP8 (8 bit)
块 scale: E8M0 (8 bit, 纯指数, 无符号无尾数)

E8M0 是个特殊的「纯指数」格式 — 8 位全部用来存指数,没有符号也没有尾数,表示的就是 2E2^E 这个缩放因子。块内 32 个 FP4 数的实际数值 = FP4_value×2E\text{FP4\_value} \times 2^E

为什么是 32 元素一组、为什么 scale 用 E8M0?这是工程权衡 — 块越小精度越高但 metadata 占用越大;scale 用纯指数可以让乘法在硬件上变成「移位」,完全免费。Blackwell 的 FP4 Tensor Core 之所以能直接跑这个格式,就是因为硬件层面内置了这套块级 scale 解码电路。

NVIDIA 又在 MXFP4 基础上做了一个更激进的版本 NVFP4 — 块大小缩到 16、块 scale 换成 FP8(E4M3)、外面再套一层 FP32 per-tensor scale。三层 scale 结构让它的有效精度比 MXFP4 明显更好,代价是 metadata 多占一点空间。Blackwell 上 NVFP4 已经被实测能让推理精度接近 FP8,这是 FP4 真正变成「可用格式」的关键证据。

硬件支持矩阵 — V100 → Rubin · TPU · MI300

低精度真正能「飞起来」的根本原因是硬件加速 — 没有 Tensor Core / 矩阵引擎的原生支持,低精度只是节省内存,但算不快。下面这张矩阵把主流加速器按代际列出来,看每种格式从哪一代开始原生支持:

硬件支持矩阵 · 形式 × 代际实心绿 = 原生 Tensor Core / 矩阵引擎支持 · 半透明 = 仍支持但非主推 · 空圈 = 不支持NVIDIAAMDGOOGLE TPUV1002017T42018A1002020H1002022B2002024R1002026MI3002023MI3502025TPUv42021TPUv52024FP32IEEE 754TF32NVIDIAFP16IEEE 754BF16Google BrainFP8E4M3 / E5M2FP6MX 微缩FP4MXFP4 / NVFP4INT8定点INT4定点原生 Tensor Core支持但非主推不支持
主流加速器对各种低精度格式的硬件支持矩阵。绿色对角线从 FP16(2017 全员支持)一路下降到 FP4(2024 才出现于 Blackwell),大约每两年下移一格 — 对应「位宽每两年减半」的硬件节奏。FP32 / FP16 / INT8 是三个全员支持的「栈底」,越往下走越锁定到特定厂商和代际。Google TPU 一行有趣 — 跳过了 FP8 / FP4 这条线,坚持 BF16 + INT8 这套保守组合。

几个值得点出的模式:

  • 绿色对角线。把所有实心绿圆点连起来,你会看到一条对角下降的「阶梯」 — FP16(2017)→ BF16(2020)→ FP8(2022)→ FP4(2024),大约每两年下移一格。这条线就是「位宽每两年减半」的硬件节奏。
  • FP32 / FP16 / INT8 三个「栈底」。所有厂商都支持。这意味着只要代码用这三种格式,部署到任何加速器都没问题;越往下走越锁定到特定厂商和代际。
  • AMD 落后 NVIDIA 大约一代。MI300(2023)的格式覆盖度大致等于 NVIDIA 2022 年的 H100;MI350(2025)才补上 FP6 / FP4。
  • TPU 的「克制」。Google 在自家 workload 上验证 BF16 + INT8 已经够用,所以 TPU 没有跟进 FP8 / FP4。这是一个有趣的设计取向 — 当你既是硬件设计方又是模型设计方时,可以选择「软件迁就硬件」而不是「硬件追赶软件」。Gemini 训练栈一直围绕 BF16 就是这个选择的直接结果。

Rubin — 没有新格式 · 把 FP4 拉到 50 PFLOPS

英伟达 2024 年 GTC 上公布的下一代架构 Rubin(2026 年量产)有几个值得记一下的判断:

  • 没有引入新格式。Rubin 仍然是 FP64 / FP32 / TF32 / FP16 / BF16 / FP8 / FP6 / FP4 + INT8 / INT4 这套,和 Blackwell 完全一样。NVIDIA 这一代没有再发明新精度,而是把工程重点放在让 FP4 算力翻倍、让 FP4 真正好用上。
  • 性能倾斜得很明显。Rubin 的 FP4 / FP8 算力比 GB200 提升约 3.5×,而 FP16 只提升约 1.6×。这清晰反映了 NVIDIA 的预判 — 大部分训练和推理工作负载会从 BF16 / TF32 迁移到 FP8 / FP4。如果你还在用 BF16,Rubin 给你的提速远不如从 Hopper 到 Blackwell 时那么大。
  • Adaptive sparsity 取代 2:4 sparsity。之前几代的「结构化稀疏」几乎没人用(因为强制一半元素为零会掉精度)。Rubin 的自适应稀疏引擎在数据流中动态检测零元素并消除它们,同时不会把非零值置零,所以既能保持模型精度、又能提升性能。Rubin 公布的 50 PFLOPS FP4 算力就是靠这个机制 — 稀疏度越高越接近。
  • Rubin CPX 是个有趣的设计。专门给「长上下文 prefill」用的伙伴芯片,不用昂贵的 HBM4,改用 128 GB GDDR7。这反映出业界已经认识到 prefill 和 decode 的硬件需求完全不同 — prefill 计算密集要 FP4 算力,decode 内存带宽密集要大显存。

主流大模型的精度选择 — Llama 4 · DeepSeek-V3 · Gemini · Claude

把目前主流大模型的训练 / 推理精度放在一张表里:

主流大模型的训练与推理精度选择 · 2024-2026封闭模型的训练精度按硬件代际推测 · 开源模型有明确技术报告训练 (Training)服务端推理本地 / 量化推理Llama 2Meta · 2023BF16BF16 / FP16INT4 GPTQLlama 3 / 3.1Meta · 2024BF16 · 16K H100BF16 / FP8INT4 GPTQ / AWQLlama 4Meta · 2025FP8 · 32K H100FP8FP4 / INT4DeepSeek-V2DeepSeek · 2024BF16BF16 / FP8INT4DeepSeek-V3DeepSeek · 2024FP8 fine-grainedFP8INT4 / FP4Qwen 2.5Alibaba · 2024BF16BF16 / FP8INT4 AWQMixtral 8x7BMistral · 2024BF16BF16 / FP8INT4Gemini 2Google · 2024BF16 (TPU)BF16GPT-4OpenAI · 2023BF16 (推测)FP8 (推测)Claude 3 / 4Anthropic · 2024BF16 (推测)未公开BF16FP8INT4 / FP4未公开 / N/A
2024-2026 主流大模型的训练与推理精度选择。绿色 = BF16,橙色 = FP8,红色 = INT4 / FP4。可以看到一条清晰的迁移路径 — Llama 系列从 Llama 3 的 BF16 训练切到 Llama 4 的 FP8 训练;DeepSeek-V2 还在 BF16,V3 已经做到了 FP8 fine-grained 训练。Gemini 因为绑死 TPU 一直在 BF16。OpenAI / Anthropic 不公开训练精度,推测仍以 BF16 为主。

几个值得展开的观察:

  • FP8 训练的破冰点是 DeepSeek-V3(arxiv 2412.19437)。在它之前,业界一直对「FP8 比 FP16 还少 8 个数据位,怎么可能稳定训出大模型」持怀疑态度。DeepSeek-V3 的关键工程贡献是细粒度量化 — 对激活采用 1×128 的 tile-wise 分组,对权重采用 128×128 的 block-wise 分组,通过更细的 scale 粒度来对抗 outlier。这是 FP8 训练从「实验室可行」变成「6710 亿参数 MoE 稳定训完」的转折点。
  • Llama 4 把 FP8 训练做成了主流方案。Meta 在 FP8 上预训练 Llama 4 Behemoth(2 万亿参数级别),达到 ~390 TFLOPS/GPU,集群规模 32K H100。这是 FP8 训练从「DeepSeek 的孤例」变成「大厂方案」的关键节点。
  • 为什么 Gemini 一直停在 BF16 — 因为 Google TPU 没有原生 FP8 Tensor Core,所以 Gemini 的训练栈一直围绕 BF16。这跟前面硬件矩阵图里 TPU 那一列的「克制」是一致的。
  • 封闭模型的精度是黑箱。OpenAI 和 Anthropic 都不公开训练精度细节。表里 GPT-4 和 Claude 那两行的「BF16(推测)」是基于硬件代际的推断,不是公开信息。GPT-5 是否用了 FP8 同样不确定。
  • 推理侧已经「双轨」。服务端部署(vLLM、TensorRT-LLM、SGLang)倾向 FP8,因为既能省显存又能跑得快;本地部署(llama.cpp、Ollama)倾向 INT4 GPTQ / AWQ,因为消费级显卡上 FP4 硬件还很少。

总结 — 训练 BF16→FP8 · 推理 FP8→FP4

如果用一句话概括目前 LLM 数据格式的趋势:训练在 BF16 → FP8 的路上,推理在 FP8 → FP4 的路上,而每一步落地都依赖一代新硬件的 Tensor Core 支持

把全文拎成几条:

  • 位宽下降不只是省显存,更是换算力。同样硅片,每降一档精度,MAC 单元数量翻倍 — 这是 Tensor Core 算力呈对数式上涨的根本来源。
  • 指数 vs 尾数的取舍贯穿所有格式。训练偏好指数多(BF16 / FP8-E5M2),要兜住梯度的动态范围;推理偏好尾数多(FP8-E4M3 / FP6-E2M3),权重数值已知、精度更值钱。
  • 位宽越往下走,越离不开 block-scale。FP8 还能 per-tensor scale,FP6 / FP4 必须 block-wise(MX / NVFP4),否则单个数表达能力太弱。整数格式则永远依赖外部 scale。
  • 精度是按运算混用的,不是按层。Transformer block 里的每个组件按运算特性各自选精度 — GEMM 是低精度的主战场,softmax / norm / residual 几乎永远保持高精度。
  • 三条主线决定了下一代硬件方向。NVIDIA 在卷 FP4 / FP6 算力(Rubin)、AMD 在追赶 FP8 / FP4(MI350)、Google 在「克制」中坚持 BF16 + INT8(TPU)。这三条路决定了未来 3-5 年大模型的训练和部署成本曲线。

下一篇可以继续深挖的几个方向 — DeepSeek-V3 的 FP8 fine-grained scaling 工程细节、Blackwell 上 NVFP4 vs MXFP4 在不同 workload 上的精度对比、TPU 坚持 BF16 路线背后的「软硬协同」哲学。

参考资料 — 标准 · 论文 · 工程博客

标准与白皮书

  • OCP Microscaling Formats (MX) Specification v1.0 (2023) — MXFP4 / MXFP6 / MXFP8 / E8M0 block scale 的官方规范。opencompute.org · MX v1.0 spec
  • NVIDIA / Arm / Intel FP8 White Paper — 「FP8 Formats for Deep Learning」(2022) — E4M3 / E5M2 两个变体的设计动机与训练实验。arxiv.org/abs/2209.05433
  • NVIDIA Blackwell Architecture Whitepaper (2024) — 第二代 Transformer Engine、NVFP4 块结构、FP4 Tensor Core 设计细节。
  • NVIDIA Hopper Architecture Whitepaper (2022) — 第一代 Transformer Engine、FP8 Tensor Core、per-tensor scaling 机制。

论文 — 训练侧

  • DeepSeek-V3 Technical Report (2024) — 首个超大规模 FP8 训练的工程报告,详细描述 fine-grained tile-wise / block-wise scaling 与 outlier 处理。arxiv.org/abs/2412.19437
  • The Llama 3 Herd of Models (Meta, 2024) — BF16 训练 405B 模型的工程实践,16K H100 集群细节。arxiv.org/abs/2407.21783
  • Transformer Engine: Mixed-Precision FP8 Training (NVIDIA, 2022+) — H100 上 FP8 训练的 delayed scaling 机制,Megatron-LM / NeMo 默认依赖。github.com/NVIDIA/TransformerEngine

论文 — 推理量化

  • LLM.int8(): 8-bit Matrix Multiplication for Transformers at Scale (Dettmers, 2022) — 把 INT8 量化首次稳定用到大模型,发现 outlier 的存在与处理。arxiv.org/abs/2208.07339
  • GPTQ: Accurate Post-Training Quantization for Generative Pre-trained Transformers (Frantar et al., 2022) — INT4 权重量化,基于二阶信息的逐层最优 scale 求解。arxiv.org/abs/2210.17323
  • AWQ: Activation-aware Weight Quantization (Lin et al., 2023) — 基于激活幅度的 group-wise scale 选择,效果优于 GPTQ。arxiv.org/abs/2306.00978
  • SmoothQuant: Accurate and Efficient Post-Training Quantization for LLMs (Xiao et al., 2022) — 通过「smooth」把激活的 outlier 转移到权重上,让 W8A8 量化变得可行。arxiv.org/abs/2211.10438

工程博客与文档

  • NVIDIA Developer Blog · Transformer Engine — H100 / B200 上 FP8 / FP4 训练的实战教程。developer.nvidia.com
  • vLLM 文档 · Quantization — INT8 / FP8 / INT4 推理量化的开源实现细节。docs.vllm.ai · Quantization
  • Tim Dettmers 博客 — LLM 量化最权威的工程视角,bitsandbytes 库的作者。timdettmers.com
  • Hugging Face · Quantization Guide — GPTQ / AWQ / BitsAndBytes 在 transformers 库里的统一入口。huggingface.co · quantization