在深度学习训练(尤其是大模型或大规模数据训练)中,梯度累积(Gradient Accumulation)是一种常用技术,主要目的是在显存有限的情况下,模拟更大的批量大小(Batch Size),从而稳定训练、提升效果。下面从几个角度解释“为什么要用梯度累积”。
1. 显存限制:用小 Batch 跑出大 Batch 的效果
- 直接增大
batch_size 会显著增加显存占用(激活值、中间变量等) - 很多任务(如 LLM、多模态、高分辨率图像)连中等 batch 都放不下
- 梯度累积的做法:
- 每次只前向+反向一小批(如
batch_size=4) - 多次累积梯度(如累积 8 次)
- 再统一更新参数
- 等效 batch size =
micro_batch × accum_steps
例如:4 × 8 = 32
✅ 显存占用小,但训练动态接近大 batch
2. 大 Batch 的训练优势
较大的等效 batch size 通常带来:
- 梯度估计更准,噪声更小
- 损失曲面更平滑,训练更稳定
- 收敛更快(尤其配合合适 LR)
但硬件不支持直接大 batch → 梯度累积是“软件层替代方案”
3. 分布式 / 资源受限场景的必要手段
- 单卡显存小
- 多卡通信成本高
- 数据长序列(NLP、视频)难以并行
梯度累积允许:
4. 与学习率、调度器的配合
- 大 batch 通常需要更大 LR(Linear Scaling Rule)
- 梯度累积后:
- 可使用接近大 batch 的 LR 策略
- 更好的泛化表现
5. 典型使用场景
- ✅ 大模型微调(LoRA / SFT)
- ✅ 显存 < 模型需求
- ✅ 训练稳定性差(loss 抖动)
- ✅ 复现论文中的大 batch 设置
简单示例(伪代码)
optimizer.zero_grad()
for i, (x, y) in enumerate(dataloader):
loss = model(x, y) / accum_steps
loss.backward()
if (i + 1) % accum_steps == 0:
optimizer.step()
optimizer.zero_grad()
一句话总结
梯度累积让你用“多次小步计算”冒充“一次大步更新”,在显存不够时,依然享受大 batch 训练的好处。
如果你愿意,我也可以讲:
- 梯度累积 vs 梯度检查点
- 累积步数怎么选
- 和 Mixed Precision 的搭配注意点