梯度累积(Gradient Accumulation)是一种在深度学习训练中常用的技术,主要用于在显存有限的情况下模拟更大 batch size 的训练效果,或者稳定训练过程。下面从多个角度解释为什么需要它。
一、核心动机:显存不够,但想要大 batch
1. 大 batch size 的好处
- 梯度估计更稳定(方差小)
- 收敛更快(尤其配合合适的 learning rate)
- 某些任务(如对比学习、GAN、大模型)对 batch size 很敏感
2. 显存是瓶颈
训练时显存占用主要来自:
- 模型参数
- 中间激活值(forward)
- 梯度
- 优化器状态(如 Adam 的 momentum、variance)
batch size 越大,显存占用线性增长,很容易 OOM(Out of Memory)。
二、梯度累积的基本思想
把“大 batch”拆成多个“小 batch”,多次前向+反向,再统一更新参数
流程示意
for 小 batch in 大 batch:
forward
backward (梯度累加,不更新参数)
# 累积完 N 次后
optimizer.step()
optimizer.zero_grad()
等价于:
一个 batch size = N × 小 batch size
三、为什么梯度可以累积?
数学原理
梯度是期望的近似:
[
nabla_theta L approx frac{1}{N} sum_{i=1}^N nabla_theta L_i
]
多次 backward 得到的是:
[
sum nabla_theta L_i
]
再除以 N(或配合 learning rate),等价于一次大 batch 的梯度。
✅ 只要 loss 是线性可加的(大多数情况是)
四、梯度累积的主要用途
1. 突破显存限制(最常见)
| 场景 | 问题 | 梯度累积的作用 |
|---|
| 大模型 | 单卡显存不足 | 用小 batch 模拟大 batch |
| 长序列 | 激活值巨大 | 减少单次显存峰值 |
| 高分辨率图像 | 占用显存高 | 继续训练 |
2. 提升训练稳定性
- 小 batch 噪声大,训练抖动
- 累积后梯度更“可信”
- 对 对比学习、生成模型、强化学习 尤其重要
3. 多卡 / 多步训练策略的一部分
- 梯度累积 + DDP
- 梯度累积 + 混合精度
- 梯度累积 + 大模型微调(如 LoRA)
五、梯度累积 ≠ 完全等价大 batch
虽然数学上近似,但仍有差异:
| 方面 | 差异 |
|---|
| 学习率 | 通常需要重新调 |
| BatchNorm | 统计量可能不同 |
| 数值精度 | 累积误差略有不同 |
| 优化器状态 | 更新频率不同 |
实践中通常 效果非常接近,但超参要重新验证
六、什么时候不适合用梯度累积?
- BatchNorm 非常敏感的小数据集
- 对更新频率极其敏感的算法(如某些 RL)
- 你本身显存充足,没必要增加代码复杂度
七、一句话总结
梯度累积的本质:用时间换空间,用多次小 batch 的梯度,模拟一次大 batch 的效果。
如果你愿意,我可以:
- 给你 PyTorch 示例代码
- 对比 有无梯度累积的显存占用
- 结合 大模型 / LoRA / DDP 讲实际工程经验