核心要点

  • 用 fp16/bf16 做前向、反向计算,激活梯度显存减半,吞吐借 Tensor Core 提升

  • 保留一份 fp32 主权重(master weights)用于参数更新,避免低精度累积误差

  • fp16 动态范围窄,需 loss scaling 放大梯度防下溢;bf16 范围大常可免缩放

  • PyTorch AMP / DeepSpeed 一键开启,是大模型训练标配

标准回答

核心机制

混合精度同时使用低精度(fp16 或 bf16)和单精度(fp32):

  • fp16/bf16 计算:前向、反向中的矩阵乘等用半精度,激活/梯度显存约减半,并能命中 GPU 的 Tensor Core 大幅提速。
  • fp32 主权重:单独保存一份 fp32 参数做更新。半精度下极小的更新量会被舍入丢失,fp32 master weights 保证更新精度。
  • Loss Scaling:fp16 的可表示范围窄,小梯度容易下溢为 0。把 loss 放大一个 scale 再反传,梯度同比放大躲过下溢,更新前再 unscale 还原;动态 loss scaling 会自动调整该系数。

fp16 vs bf16

bf16 指数位与 fp32 相同、动态范围大,通常无需 loss scaling、更稳定,但尾数精度低;fp16 精度高但范围窄,需缩放。新硬件多优先 bf16。

收益与代价

收益:训练更快、显存更省、可上更大 batch/模型。代价:需注意数值稳定(如 softmax、norm 仍用 fp32),裁剪要在 unscale 后做。PyTorch autocast + GradScaler、DeepSpeed 均原生支持。

常见误区

⚠️ 常见踩坑

不是把所有运算都转 fp16——归一化、softmax、loss 等数值敏感算子仍保留 fp32;bf16 范围大但尾数精度低于 fp16,不等于"全面更好"。

追问

追问 1为什么必须保留一份 fp32 的主权重?

参数更新量(learning_rate × 梯度)常远小于权重本身,在 fp16 下与权重相加会因有效位数不足被舍入丢弃,导致更新失效。fp32 master weights 累积这些微小更新,再拷回 fp16 用于下一步计算。

追问 2loss scaling 的系数过大或过小会怎样?

过小则小梯度仍下溢丢失;过大则梯度可能上溢成 inf/NaN。动态 loss scaling 会在出现 inf/NaN 时跳过该步并调小系数,连续若干步正常则尝试调大,自动维持在安全区间。

延伸学习

与本题相关的知识库文章、术语、工具与行业资讯。

🛠️ AI 工具

  • Pytorch

    Meta 开源的深度学习框架,100K+ stars。以动态计算图和 Pythonic 风格著称,在学术界和工业界都有广泛应用,支持分布式训练、移动端部署和 ONNX 导出

  • DeepSpeed

    深度学习训练优化库,42,156+ stars。微软开发的开源深度学习优化库,提供 ZeRO 内存优化、3D 并行等核心技术,大幅降低大模型训练成本