跳转到内容

混合精度与 FP8

降精度是唯一同时改善"算力"与"带宽"两侧的手段:位宽减半,Tensor Core 峰值算力翻倍、显存与带宽需求减半(见Roofline)。从 FP32 到 FP16/BF16 再到 FP8,每一次精度下探都是一次性能跃迁——也都是一次数值风险的重新定价。本章讲清楚各格子的特性、训练怎么稳住、以及哪些风险是真实的。

格式位宽指数/尾数动态范围峰值算力(H100)主要用途
FP32328/23~10³⁸67 TFLOPS累加器、优化器状态
TF3219(存储 32)8/10~10³⁸495 TFLOPSFP32 的加速替身
FP16165/10~6×10⁴989 TFLOPS训练(配 loss scale)
BF16168/7~10³⁸989 TFLOPS训练的默认选择
FP8 E4M384/3~4481979 TFLOPS前向/大模型训练
FP8 E5M285/2~5.7×10⁴1979 TFLOPS梯度(范围大、精度低)
FP44—极小9000+(B200)推理/极限场景

关键理解:位宽买两样东西——范围(指数)与精度(尾数),两者互相挤占:

  • FP16 的尾数多(精度高)但指数少(范围窄,容易上/下溢)——所以需要 loss scaling
  • BF16 把 FP16 的尾数位拿去给了指数位:范围与 FP32 一样大(不会溢出),精度低一点(尾数 7 位)——范围换精度,训练从此不用管 loss scale,这是 BF16 成为默认的原因
  • FP8 的 E4M3(前向,精度优先)与 E5M2(梯度,范围优先)就是这个权衡在 8 位上的重演

"混合"的意思是:计算用低精度,敏感处保留 FP32:

前向/反向:BF16(或 FP8)—— 矩阵乘与激活
权重主副本:FP32 —— 优化器更新的基准
梯度累加:FP32 —— 多微批的求和不能丢精度
优化器状态:FP32 —— 动量/方差是敏感累加量

这就是"16 B/参数"显存公式的来源(2 B 权重 + 2 B 梯度 + 12 B FP32 优化器状态,见数据并行)。

Loss scaling(FP16 专属):FP16 范围窄,小梯度下溢成 0。解法:loss 乘一个大数(如 2¹⁶)放大梯度,反向后再除回来。BF16 范围与 FP32 相同,不需要 loss scaling——这是一次巨大的工程简化。

FP8 的算力翻倍是真实的(H100 FP8 1979 TFLOPS),但直接全 FP8 训练会崩。生产级 FP8 训练(DeepSeek-V3、GPT 混合方案)的标配护栏:

一、只对"安全"的矩阵乘用 FP8:前向的大 GEMM(QKV、FFN)用 E4M3;attention 的 softmax、LayerNorm、所有 reduction 保持 BF16/FP32。

二、动态缩放(per-tensor / per-block scaling):FP8 的表示范围太小,每个张量按自己的实际数值范围缩放到 FP8 的格子中心,算完再缩回:

Xfp8=XsX⋅clip,sX=448max⁡∣X∣X_{\text{fp8}} = \frac{X}{s_X} \cdot \text{clip}, \qquad s_X = \frac{448}{\max|X|}

DeepSeek-V3 的细粒度缩放(per-block/per-group)是 FP8 训练稳定的关键改进。

三、累加器与主副本保持高精度:FP8 矩阵乘的累加器仍是 FP32,权重主副本 FP32——低精度只在"搬运与计算"上,敏感处一律高精度。

收益是真实的:FP8 GEMM 快 ~1.5–2 倍、带宽省一半、显存省一半。成本是工程复杂度(缩放、精度监控、kernel 支持),所以"BF16 起步、稳了再 FP8"是标准路径。

风险场景症状防护
FP16 下溢小梯度loss 不动/梯度为 0loss scaling 或改 BF16
FP16 上溢大 lossNaN/infloss scaling 的动态调整
BF16 累加误差长序列求和训练慢漂移累加器用 FP32
FP8 量化误差全 FP8loss 曲线抬升细粒度缩放 + 混合精度
优化器状态低精度实验性做法长训练发散FP32 优化器状态(别省这 12 B)
推理 KV cache FP8长上下文长程注意力退化抽测长程任务再上

监控比防护更重要:训练中持续监控梯度范数、loss 突变、NaN 计数——精度问题在曲线上的特征(跳变、抬升、平台)比事后复现容易得多。

  1. 训练:BF16 起步(无 loss scale、范围安全),验证训练稳定后再评估 FP8
  2. 推理:BF16 基线 → INT8/FP8 量化(算力带宽双收益,见量化)→ 极限场景 FP4
  3. 别动的地方:优化器状态、梯度累加、softmax/LN——省这 12 B/参数的代价是训练发散,不值得
  4. 迁移对比:换精度(BF16→FP8)时用固定的检查点/数据集跑对比实验,loss 曲线 + 下游评测双确认
  • 位宽买"范围+精度":BF16 用精度换范围(免 loss scaling),FP8 的 E4M3/E5M2 重演这个权衡。
  • 混合精度 = 低精度计算 + FP32 敏感处(主副本/累加器/优化器状态),16 B/参数显存公式由此而来。
  • FP8 训练的护栏:只对大 GEMM、细粒度动态缩放、累加器高精度;收益 1.5–2 倍是真实的。
  • 精度问题在 loss 曲线上有特征(跳变/抬升/平台),持续监控优于事后防护。
  • 路径:BF16 起步 → FP8 → FP4;优化器状态别省,softmax/LN 别动。