跳到主内容
快讯直播
AI智模界
AI 词典

损失缩放:让 FP16 训练不掉链子

一句话定义:损失缩放(Loss Scaling)是AI 词典:混合精度训练">混合精度训练里的一个技巧——先把损失(loss)人为放大若干倍再反向传播,等算出梯度后再按同样倍数缩回去,避免很小的梯度在 FP16 下被"抹成 0"。

为什么需要它

FP16(16 位半精度浮点)能表示的数值范围很窄,比它最小正规数还小的一批数字会直接变成 0,这叫下溢(underflow)。而深度学习里很多梯度天然就很小,比如某个权重每步只需要改动百万分之一量级。这个数用 FP16 存,结果就是 0:参数根本没动,训练看起来在跑,其实原地踏步。

打个生活化的比方

你要往汤里放 0.001 克盐,可手里的勺子最小刻度是 1 克,怎么量都是 0。办法是:先假设整包盐放大 1000 倍,用勺子舀出 1 克,最后再把这 1 克按 1000:1 折算回去。放大只是为了让"小"变成"能被量出来",最后必须除回来,否则结果就错了。

具体怎么走一遍

1. 前向传播照常算,得到一个正常的 loss。

2. 反向传播之前,把 loss 乘上缩放系数 S(常见做法是取 2 的若干次方倍)。

3. 反向传播算出的每个梯度,都是真实值的 S 倍,正好落在 FP16 能表示的区间里。

4. 参数更新前,先把梯度整体除以 S 还原。这一步通常叫 unscale,必须发生在梯度裁剪、梯度累积之前。

5. 真正保存的权重仍然是 FP32(主权重),只把计算过程交给 FP16。

缩放系数 S 有两种玩法:静态设定,简单但怕遇到极端情况;动态调整更常用——连续若干步没有出现 inf/NaN 就把 S 调大一点,一旦溢出就调小并跳过这一步。loss 突然变成 NaN,很多时候就是系数涨得太猛。

别和邻居搞混

概念解决什么问题典型手段
损失缩放小梯度在 FP16 下下溢为 0loss 乘 S,梯度除 S
梯度裁剪梯度爆炸、数值过大按范数截断梯度
混合精度用低精度换速度和显存低精度计算 + FP32 主权重

损失缩放是混合精度这套大框架里的一小块补丁,不是它的同义词;它治的是"太小",梯度裁剪治的是"太大",方向正好相反。

对从业者意味着什么

开混合精度时,损失缩放基本是标配,通常由框架的自动混合精度(AMP)自动完成,一般不用手写。但你要知道它的存在:训练 loss 无端变 NaN、参数不更新、梯度全为 0,都要往缩放系数上想一层。相比之下,BF16(bfloat16)的指数位和 FP32 一样宽,动态范围大得多,通常不需要损失缩放,代价是尾数精度更低——选哪种精度、要不要手动配置,以官方文档为准。

对非技术的职场人,这背后是一条通用经验:当工具刻度不够细时,先把量放大到可测量的尺度再换算回去,比换一把更贵的尺子便宜得多。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。