✨ 复制成功!

以文会友,打造好学人设!

📋 已复制到剪贴板:

混合精度训练中,FP16 和 BF16 有什么区别?为什么大模型训练更倾向于使用 BF16?Loss Scaling 的作用是什么?

创建时间:2026-09-18 更新时间:2026-09-18 阅读次数:1284 次 分类:分布式训练与工程优化

一、核心结论

混合精度训练的核心思想是:在训练过程中同时使用低精度和高精度,让计算用低精度加速、让关键状态用高精度保持稳定。

FP16 和 BF16 都是 16 位浮点数,但它们的位分配不同,导致动态范围和精度不同。大模型训练更倾向于 BF16,主要是因为 BF16 的动态范围更大,不容易溢出,训练更稳定。Loss Scaling 则是 FP16 训练中为了防止梯度下溢而引入的一种技巧。


二、FP16 和 BF16 的区别

1、位宽分配

FP16 是半精度浮点数,总共 16 位:

  • 1 位符号位
  • 5 位指数位
  • 10 位尾数位

BF16 是 Brain Floating Point 16,也是 16 位:

  • 1 位符号位
  • 8 位指数位
  • 7 位尾数位

2、动态范围

指数位决定动态范围。FP16 只有 5 位指数,BF16 有 8 位指数,和 FP32 的指数位一样多。

所以:

  • FP16 的动态范围大约是 $10^{-5}$ 到 $10^{4}$,最大值约为 $65504$;
  • BF16 的动态范围大约是 $10^{-38}$ 到 $10^{38}$,和 FP32 基本一致。

这意味着 BF16 能表示非常大和非常小的数,不容易上溢或下溢。

3、精度

尾数位决定精度。FP16 有 10 位尾数,BF16 只有 7 位尾数。

所以:

  • FP16 的精度更高,能表示更细小的数值差异;
  • BF16 的精度较低,有效数字大约只有 2 到 3 位十进制。

4、一句话对比

FP16 是“精度高但范围窄”,BF16 是“范围宽但精度低”。


三、为什么大模型训练更倾向于 BF16

1、大模型训练更容易出现数值溢出

大模型参数量大、层数深、激活值范围广,训练过程中容易出现:

  • 激活值过大导致上溢;
  • 梯度太小导致下溢。

FP16 的动态范围窄,最大值只有 $65504$,稍不注意就会溢出,产生 NaN 或 Inf。BF16 的动态范围和 FP32 一样,基本不会因为范围问题溢出。

2、BF16 不需要 Loss Scaling

FP16 训练通常必须配合 Loss Scaling,否则梯度容易下溢。BF16 因为动态范围大,通常不需要 Loss Scaling,训练流程更简单。

3、BF16 和 FP32 转换更简单

BF16 的指数位和 FP32 一样,都是 8 位。所以 FP32 转 BF16 基本就是截断尾数,硬件实现简单,转换开销小。

4、现代硬件支持好

NVIDIA A100、H100、H800 等大模型训练常用 GPU 都对 BF16 有良好支持,Tensor Core 可以直接加速 BF16 计算。Google TPU 也原生支持 BF16。

5、训练稳定性更好

大模型训练成本极高,一次训练可能几周甚至几个月。BF16 因为不容易溢出,训练稳定性更好,减少了中途失败的风险。

6、精度损失可以接受

虽然 BF16 尾数少、精度低,但大模型训练对精度损失的容忍度相对较高。很多实验表明,BF16 混合精度训练和 FP32 训练的最终效果差距很小。


四、Loss Scaling 的作用

1、为什么需要 Loss Scaling

FP16 的动态范围窄,很多梯度值非常小,比如 $10^{-8}$。FP16 能表示的最小正数大约是 $6 \times 10^{-5}$,所以这些梯度在 FP16 下会变成 0,也就是下溢。

梯度下溢会导致参数无法更新,训练失效。

2、Loss Scaling 的基本思想

Loss Scaling 的做法是:

  • 在计算 Loss 时,把 Loss 乘以一个较大的缩放因子 $S$,比如 $2^{16}$;
  • 这样反向传播时,所有梯度也会被放大 $S$ 倍;
  • 放大后的梯度在 FP16 下就能正常表示,不会下溢;
  • 在更新参数之前,再把梯度除以 $S$,恢复真实梯度。

用公式表示,假设原始 Loss 为 $L$,缩放后的 Loss 为:

$$ L' = S \cdot L $$

反向传播得到缩放后的梯度:

$$ g' = S \cdot g $$

更新参数前再还原:

$$ g = \frac{g'}{S} $$

3、动态 Loss Scaling

固定缩放因子可能不合适,所以实际中常用动态 Loss Scaling:

  • 如果一段时间内没有出现 Inf 或 NaN,就增大 $S$;
  • 如果出现 Inf 或 NaN,就减小 $S$,并跳过这一步更新。

这样可以在防止下溢和避免上溢之间自动平衡。

4、BF16 为什么通常不需要 Loss Scaling

BF16 的动态范围和 FP32 一样,最小正数大约是 $10^{-38}$,梯度下溢的风险极小。所以 BF16 训练通常不需要 Loss Scaling,流程更简单、更稳定。


五、实际训练中的常见做法

1、FP16 混合精度

  • 前向和反向用 FP16 计算;
  • 主权重用 FP32 保存;
  • Loss 用 FP32 计算;
  • 配合动态 Loss Scaling;
  • 常见于较早的混合精度训练实践。

2、BF16 混合精度

  • 前向和反向用 BF16 计算;
  • 主权重用 FP32 保存;
  • Loss 用 FP32 计算;
  • 通常不需要 Loss Scaling;
  • 目前大模型训练的主流选择。

3、混合精度中的关键点

  • 主权重保持 FP32,避免更新时精度损失;
  • 归一化层、Softmax 等对数值敏感的操作通常用 FP32;
  • 梯度裁剪、优化器更新等也常用 FP32。

六、简单评价这道面试题

1、这道题的价值

  • 这是一道非常基础但很重要的面试题,考察候选人对混合精度训练的理解;
  • 覆盖面好,一道题能考察 FP16、BF16、Loss Scaling 三个核心概念;
  • 区分度不错,初级可能只知道 FP16 和 BF16 都是半精度,中级能说清位分配和动态范围,高级能讲清 Loss Scaling 原理和大模型训练中的实际选择;
  • 贴近实战,混合精度是大模型训练的标配,几乎每个训练框架都会用到。

2、这道题的不足

  • 题目偏基础,对高级候选人来说可能不够深入;
  • 没有涉及更复杂的数值问题,比如梯度裁剪、参数更新精度、FP8 等;
  • 如果只考概念,容易让候选人背答案,需要追问实际调参经验才能区分水平。

3、建议的追问方向

  • FP16 训练中如果出现 NaN,你会怎么排查?
  • 动态 Loss Scaling 的增大和减小策略具体是怎么设计的?
  • BF16 精度低,为什么大模型训练还能接受?
  • FP8 训练和 FP16、BF16 有什么区别?目前有哪些实践?
  • 混合精度训练中,哪些操作必须保持 FP32?

4、总体评价

这是一道很好的大模型训练基础面试题,适合用来考察候选人对混合精度训练的系统理解。它更适合作为基础题或热身题,真正区分水平还需要配合追问实际调参和排错经验。如果候选人能把 FP16 和 BF16 的位分配、动态范围、精度差异、Loss Scaling 原理以及大模型训练中的实际选择都讲清楚,基本可以判断其具备混合精度训练的扎实基础。


📌 面试天下网:一款服务于上班族的口袋书,让大家在地铁里/公交上可以学习大模型技术!
📌 网站公告:【悬赏 200 元/篇】寻找“大模型面试战场”的一手回忆录
📌 网站公告:【大模型/Agent面试陪练1V1指导】正式启动......

评论专区

评论加载中...