7.6 混合精度训练:精度与速度的权衡
混合精度训练(Mixed Precision Training)使用半精度浮点数(FP16 或 BF16)代替全精度 FP32 进行大部分计算,是现代大语言模型训练的标配技术。7.5 把激活值的安置摆成了三选一——留在显存、重计算、卸载到主机内存——三条路争的都是「哪些数该留下」,每个数自身的位宽一位没动。本节换的正是位宽这条轴:数还是那些数。
7.6.1 为什么使用半精度
FP32 使用 32 位存储一个浮点数,FP16 只需 16 位。半精度带来两个直接好处:
显存减半:同样大小的模型参数和激活值只需一半的显存,允许训练更大的模型或使用更大的批次。
计算加倍:现代 GPU(如 NVIDIA A100、H100)的 FP16/BF16 吞吐量是 FP32 的 2 倍以上。Tensor Core 针对半精度矩阵运算进行了专门优化。
7.6.2 精度问题与解决方案
直接使用 FP16 训练会遇到精度不足的问题:
梯度下溢:FP16 能表示的最小正数约为 ,小于此值的梯度会变为零(下溢),导致无法学习。损失缩放(Loss Scaling)是标准的解决方案:在计算反向传播之前将损失值乘以一个大常数(如 1024 或自动调整),放大梯度以避免下溢,然后在参数更新前将梯度除以同样的常数恢复原始尺度。
参数更新精度:微小的权重更新可能在 FP16 下被舍入为零。因此,混合精度训练维护一份FP32 的主权重副本,参数更新在 FP32 下进行,然后将更新后的参数截断为 FP16 用于下一轮前向传播。
7.6.3 BF16 的优势
BF16(Brain Floating Point 16)与 FP16 使用相同的 16 位,但分配了更多的位给指数部分(8 位指数 vs FP16 的 5 位),从而拥有与 FP32 相同的数值范围。代价是精度略低(7 位尾数 vs FP16 的 10 位)。
BF16 的关键优势是:不容易出现梯度下溢问题,因此通常不需要损失缩放。这简化了训练流程,减少了调试难度。如今,支持 BF16 的硬件(A100 及以后)上的大模型训练几乎都使用 BF16。
7.6.4 FP8 的前沿探索
NVIDIA H100 和 H200 GPU 引入了 FP8 精度支持(8 位浮点数),可进一步提升吞吐量。FP8 常见 E4M3 和 E5M2 两种编码:前者保留 3 位尾数、精度更高,后者保留 2 位尾数、动态范围更大,因此需要更精细的量化策略:
Per-tensor 动态缩放:与 FP16 的单一损失缩放不同,FP8 通常需要为每个张量(激活值、梯度、权重)单独维护缩放因子,根据其数值范围动态调整。
数值范围处理:由于精度极限,过小的梯度可能下溢为零,过大的值可能溢出为 inf/NaN 或饱和,需要更激进的缩放策略、amax 跟踪和异常检测。
动态缩放与 amax 跟踪:FP8 训练通常维护每个张量或块的缩放元数据,根据当前或历史 amax 动态调整;分布式张量还需要在 rank 间同步 amax。某些推理或离线量化流程会做校准,但这不是 Transformer Engine 式 FP8 训练的唯一机制。
DeepSeek-V3 等前沿模型已开始探索 FP8 训练,通过分组 FP8(将权重矩阵按行或块分组,每组使用独立的缩放因子)在保持数值稳定性的同时实现了显著的效率提升。
还有一个比缩放策略更隐蔽的坑:低精度 GEMM 的准确性主要取决于累加精度,而 Tensor Core 的累加精度未必够。DeepSeek-V3 技术报告实测发现,H800 上 FP8 GEMM 的累加精度只保留约 14 位,远低于 FP32 累加;内积维度 越大,误差累积越明显——用两个随机矩阵在 下测试,Tensor Core 有限的累加精度带来了接近 2% 的最大相对误差。这个量级足以毁掉训练,而它与你怎么设缩放因子无关。
他们的对策是周期性提升累加精度:每累加 个元素的 MMA 就把中间结果提升到 CUDA Core 上做一次高精度累加,再继续。这是一个典型的「在硬件行为与数值需求之间打补丁」的做法——也提示了排查低精度训练问题时的一个检查项:在怀疑缩放策略之前,先确认累加是在哪里、以什么精度做的。
7.6.5 4 比特预训练:NVFP4
精度压缩的下一站是 4 比特。这里首先要分清两件常被混为一谈的事:推理侧的 4 比特量化(把训练好的权重压到 4 位再部署,见 10.4 节)和训练侧的 4 比特预训练(前向、反向、梯度本身就在 4 位算)。后者难得多,直到 2025 年下半年才出现可信的大规模证据。
需要区分的还有格式本身:NVFP4 是 NVIDIA 定义、Blackwell 原生支持的 4 位浮点格式,与 MXFP4 或泛称的“FP4”并不等同;当前有据可查的大规模 4 比特预训练几乎都是 NVFP4。
NVIDIA 在 Pretraining Large Language Models with NVFP4 中给出了第一个关键证据:用 NVFP4 训练一个 120 亿参数模型、消耗 10 万亿词元,论文称这是当时公开记录中最长的 4 比特精度训练运行,其训练损失与下游任务准确率与 FP8 基线相当(例如 MMLU-Pro 为 62.58% 对 62.62%)。它靠四件事把 4 位训稳:
随机 Hadamard 变换(RHT):抑制块内离群值,让数值分布更适合极低位宽
二维量化方案:保证前向与反向传播使用一致的表示
随机舍入:获得无偏的梯度估计,避免确定性舍入累积系统性偏差
选择性高精度层:一部分敏感层不做 4 位量化
之后 NVIDIA 的 Nemotron 3 系列把它推到了前沿规模:Super(120B 总参 / 12B 激活)用 NVFP4 完成了 25T 词元量级的预训练,Ultra(550B / 55B 激活)沿用同一 NVFP4 配方,预训练规模为 20T 词元。Ultra 的做法清楚地展示了“选择性高精度”在实践中意味着什么——网络最后 15%(16 层)、Mamba 输出投影、latent 投影、QKV 与注意力投影、MTP 层和嵌入层都保留在更高精度,其余大部分线性层才走 NVFP4。
这里有两个必须诚实交代的口径。第一,基线是 FP8 而非 BF16,官方措辞是“与 FP8 基线相当”(comparable),不是“无损”——实测确实存在可测量的差距。第二,不要把 DeepSeek-V4 当作 FP4 预训练的例子:它的 FP4 用在后训练的量化感知训练(MoE 专家权重与 indexer 的 QK 路径)和推理阶段,其大规模预训练框架仍是 FP8。这正是本节开头那条区分的现实意义。
最后更新于
