Skip to content

为什么需要混合精度训练? ​

  • 标签:大模型、AI、微调

🏛 业务架构师 ​

混合精度训练指用 FP16/BF16 做前向和反向计算、用 FP32 维护主权重和优化器状态的训练方式(配合损失缩放防下溢)。为什么需要它,算两笔账:

速度与容量账:现代 GPU 的半精度算力是单精度的 2~8 倍(Tensor Core 加持),显存占用减半——同样的预算,训练快 2~3 倍、batch size 翻倍,或用同样硬件微调更大参数的模型。对微调团队,这意味着实验轮次直接翻倍。

数值稳定性账:为什么不全用半精度?学习率更新等精细计算半精度会累积舍入误差,权重更新量太小会被精度"吃掉"(下溢)。所以混合精度的设计哲学是"计算快的地方用半精度、关键累积的地方留全精度"——性能与精度的工程平衡。BF16 的出现进一步缓解了溢出问题(动态范围与 FP32 相同),已成为 2026 年的默认选择。

业务视角:混合精度不是可选项而是基础设施级默认——主流训练框架(PyTorch 的 autocast、DeepSpeed、Unsloth)一行配置开启。真正的业务含义是:训练成本曲线近三年下降了十倍以上,其中精度工程贡献显著——这让"业务团队养得起自己的微调流水线"成为现实,微调从研究中心的专利变成了业务部门的标准工具。

🏗 系统架构师 ​

混合精度训练 = 前向/反向用低精度(fp16/bf16)计算,权重更新用高精度(fp32)主副本,是 LLM 训练的默认配置。

为什么必须:

  • 显存:fp32 权重 7B 模型 28GB,bf16 只要 14GB——加上激活和优化器状态,混合精度对大模型是"训得动"的前提;加上 fp16/bf16 的 Tensor Core 加持,算力利用率翻数倍;
  • 速度与能耗:低精度矩阵乘吞吐 2~8 倍于 fp32,训练时间从周级降到天级,电费同步降。

精度安全机制:权重主副本保持 fp32(累积更新不丢精度)、loss scaling(fp16 梯度下溢时放大再回缩)、bf16(指数位宽与 fp32 相同)天然无下溢问题——2026 年主流硬件(Ampere 之后)一律选 bf16,fp16 只在老硬件出现。

架构师视角的谱系:训练精度(bf16 混合精度)与推理量化(int8/int4 权重量化)是两件事——前者保训练稳定,后者省推理成本;量化感知训练(QAT)是两者的桥梁。容量规划时精度直接进算式:7B bf16 推理显存 ≈ 14GB + KV Cache(随上下文长度线性增长),这是 GPU 选型的第一公式。

💻 全栈开发专家 ​

混合精度训练 = 前向/反向用 FP16 或 BF16,权重主副本和优化器状态用 FP32。为什么需要:显存减半(16bit 激活和梯度)、Tensor Core 对半精度有数倍加速,训练吞吐接近翻倍,而精度损失可控。

关键细节:

  • 主权重 FP32:小梯度更新在 16bit 下会被舍入吞掉(下溢),所以 master weights 用 FP32,每步更新后再转回 16bit 参与计算;
  • Loss Scaling(FP16):反向梯度常小于 16bit 最小表示,先放大 loss 再缩回,防梯度下溢;BF16 没这个问题——指数位和 FP32 一样宽、动态范围大,不需要 loss scaling,这就是 A100 之后主流选 BF16 的原因;
  • AMP 一行开启:
python
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
with autocast(dtype=torch.bfloat16):   # Ampere+ 用 bf16
    loss = model(batch).loss
scaler.scale(loss).backward()
scaler.step(optimizer); scaler.update()

工程实战提醒:某些算子(LayerNorm、softmax 的部分实现)保持 FP32 更稳,autocast 会自动处理;微调 LLM 常配「bf16 基座 + LoRA + paged_adamw_8bit」,这套组合是消费级显卡调 7B 的标准配置;遇到 loss 变 NaN 先查是否混了 FP16 没开 scaling。