记录一下那天晚上的排查过程。显存只够跑 batch size 1,于是把梯度累积设成 16,训练稳定性却明显不如别人 batch size 16 的结果。

刚开始盯着「随机性来源不同,样本顺序影响梯度方向」,折腾了半个多小时,排掉了。

把日志和配置对完,能解释这个现象的基本就这几处。批归一化类层对真实批大小敏感。也可能是累积时损失没有按步数归一化,等效学习率偏移。

还有一种情况,梯度裁剪在累积过程中被提前执行。

先确认模型是否含批相关层

python -c "print([n for n,_ in model.named_modules() if 'Norm' in type(_).__name__])"

损失除以累积步数保持尺度一致

loss = loss / accum_steps

梯度累积期间不要提前裁剪

if (step + 1) % accum_steps == 0: clip_grad_norm_(model.parameters(), 1.0)

适当调大学习率补偿小批次的噪声

python train.py --learning_rate 3e-4 --grad_accum 16

改完先别撤,确认这几项。训练曲线与大批次实验接近,loss 波动收窄,验证指标差距缩小到可接受范围。

数学上梯度是等价的,但优化器状态更新频率和随机性并不相同,小批次加累积不能完全替代真实大批次。监控比日志更早给出信号,事后回看经常能提前半小时发现异常。

作者 9823189