一句话定义:混合精度训练(Mixed Precision Training)是指在训练神经网络时,让大部分乘加运算用 16 位浮点数(BF16 或 FP16)来跑,同时把权重、梯度等关键状态用 32 位浮点数(FP32)维护,从而在几乎不损失效果的前提下省显存、提速。
打个比方:草稿用铅笔,账本用钢笔
想象你在对账。为了快,你会在草稿纸上用铅笔飞快地加减,写错了随手擦;但最终的账本要用钢笔工整地记,因为一个数字写错,后面全乱。
混合精度就是这套双轨制:BF16 是那支铅笔——只有 16 位,显存占用是 FP32 的一半,硬件算它也更快;FP32 是那本账本——占地方、算得慢,但足够精确。典型做法是保留一份 FP32 的「主权重」,每一步先把权重转成 BF16 做前向和反向计算,得到梯度后再放回 FP32 累加并更新主权重。低精度负责跑量,高精度负责守住关键数字。
BF16 和 FP16 差在哪
两者都是 16 位,但内部结构不同。
| FP32 | FP16 | BF16 | |
|---|---|---|---|
| 位数 | 32 | 16 | 16 |
| 指数位(决定数值范围) | 8 | 5 | 8 |
| 尾数位(决定精细程度) | 23 | 10 | 7 |
| 典型特点 | 精确、慢、占显存 | 范围窄、易溢出,常需损失缩放 | 范围接近 FP32,不易溢出,精度略粗 |
FP16 的范围窄,小到一定程度的梯度会直接变成 0,所以常配一个损失缩放(loss scaling)技巧:先放大再缩回来。BF16 的指数位和 FP32 一样多,范围够宽,通常不需要这套操作,代价是尾数更少、精度略低。因此近年训练配置里 BF16 更常见——具体支持情况以硬件和框架的官方文档为准。
和相邻概念的区别
- 和量化(quantization)不同:量化多用于推理,训练完再压缩成 INT8/INT4,目标是部署时更省;混合精度发生在训练过程中,目标是训得更省更快。
- 和纯 FP32 训练不同:纯 FP32 最稳但最贵;混合精度用一半的显存装同样多的参数,还能吃上硬件对低精度的加速。
- 它不是「全都用 16 位」:归一化、损失函数、归约求和这类对数值敏感的操作,通常仍留在 FP32。
对实际工作的意义
对算法工程师:在支持低精度的加速卡上,往往只是给训练脚本加一个 dtype 或 autocast 开关,就可能换来更小的显存占用、更大的 batch size 或更短的训练时间。但它不是免费的午餐——遇到 NaN、loss 不下降时,第一件要查的事就是哪些算子被卷进了低精度。
对普通职场人:你听到的「训练成本下降」「显存不够用」这类讨论,很大一部分答案就在这一层工程优化里。它不改变模型结构,也不提升模型上限,只是把同一份计算跑得更便宜——这种看不见的节省,常常决定一个项目能不能真的做得起来。
