在混合精度训练中:
常见溢出原因:
inf / nan原理:
在反向传播前把 loss 放大,使梯度在 FP16 范围内;更新参数前再缩小。
# PyTorch 示例
from torch.cuda.amp import GradScaler, autocast
scaler = GradScaler()
for x, y in data:
with autocast():
y_pred = model(x)
loss = criterion(y_pred, y)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
optimizer.zero_grad()✅ 注意事项:
自动完成方式:
optimizer = torch.optim.Adam(model.parameters())
# + GradScaler(会自动维护 master weights)防止梯度爆炸导致溢出:
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)搭配 AMP:
scaler.unscale_(optimizer)
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)✅ 推荐范围:
1.05~10❌ 不推荐:
log_softmax(x) # x 可能很大✅ 推荐:
F.log_softmax(x, dim=-1)
# 或
F.cross_entropy(logits, target)❌:
a / b # b 很小✅:
a / (b + eps)或改用:
torch.clamp(b, min=eps)混合精度 ≠ 可以随意增大学习率。
经验法则:
推荐流程:
AMP 已内置:
scaler.update()如果检测到 inf/nan:
for name, param in model.named_parameters():
if torch.isnan(param).any() or torch.isinf(param).any():
print(name)或:
torch.autograd.detect_anomaly()✅ 使用 torch.cuda.amp
✅ 动态 Loss Scaling
✅ 保持 FP32 master weights
✅ 梯度裁剪
✅ 避免极端数值操作
✅ 优先 LayerNorm
✅ 学习率不过大
如果你愿意,我可以:
只要告诉我你的模型类型即可。