混合精度训练中的数值稳定性调优经验
最近在做大规模分布式模型训练时,踩了不少坑,特别想分享一下混合精度训练中数值稳定性的调优经验。
问题背景
在使用FP16进行训练时,遇到了loss突然爆炸(NaN)的问题。起初以为是学习率设置问题,但调整后仍然复现。
关键调优点
1. 梯度缩放因子设置
# 原始配置 - 踩坑版本
scaler = torch.cuda.amp.GradScaler(init_scale=2**16)
# 正确配置 - 经验版本
scaler = torch.cuda.amp.GradScaler(init_scale=2**15) # 降低初始缩放因子
2. 梯度裁剪策略
# 增加梯度裁剪保护
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
# 或者
torch.nn.utils.clip_grad_value_(model.parameters(), clip_value=1.0)
3. 精度切换时机
# 在关键层使用FP32
with torch.cuda.amp.autocast(enabled=False):
output = model(input)
# 或者
if step % 100 == 0:
# 每100步切换回FP32
with torch.cuda.amp.autocast(enabled=False):
loss = criterion(output, target)
实际效果
通过上述调优,loss稳定收敛,训练时长减少约20%,且没有出现数值爆炸。
小贴士
- 建议使用tensorboard监控loss变化
- 训练前先做小规模测试验证稳定性
- 多机训练时注意同步问题

讨论