梯度累积(Gradient Accumulation)是一种在深度学习训练中常用的技术,主要用于在显存有限的情况下模拟更大 batch size 的训练效果,或者在分布式训练中提高稳定性与效率。下面从原理、动机和适用场景几个方面解释“为何要用梯度累积技术”。
一、核心动机:显存不足,但想要大 batch
1. 显存限制
训练深度神经网络时:
- 大 batch size 可以:
- 让梯度估计更稳定
- 加速收敛
- 提高分布式训练效率
- 但 大 batch 会直接增加显存占用,尤其是:
- 激活值(activation)
- 中间变量
- 优化器状态(如 Adam 的 momentum、variance)
很多情况下:
模型 + 数据 已经接近显存上限,无法再增大 batch size
2. 梯度累积的思路
梯度累积的本质是:
把多个小 batch 的梯度“加起来”,再统一更新模型参数
等价于:
[
text{batch size} = N times k
]
其中:
- N:单步实际 batch size
- k:累积步数
- 显存上:
- 每步只跑小 batch
- 不增加额外显存开销
二、梯度累积在数值上等价于大 batch
1. 理论等价性
假设:
- loss 是平均值(mean loss)
- 优化器是 SGD / Adam
那么:
accumulate 4 个 batch 的梯度
再 optimizer.step()
与:
一次 forward 4 倍数据
在数学上是等价的
✅ 前提是:
- loss 是 mean(不是 sum)
- 学习率、优化器状态一致
2. 为什么还要提“等价”?
因为很多初学者会误以为:
“梯度累积只是省显存,但效果会变差”
实际上是:
只要用得好,效果几乎一模一样
三、梯度累积的典型使用场景
✅ 场景 1:GPU 显存不足
这是最常见的原因:
- 大模型(LLM、ViT、Large CNN)
- 高分辨率输入(图像、视频)
- 长序列(NLP)
例如:
单卡显存:24GB
能跑的最大 batch size:8
理想 batch size:32
→ 累积 4 步
✅ 场景 2:复现论文或训练配置
很多论文中的 batch size 是:
但现实是:
- 只有 1~8 张卡
- 单卡 batch size 很小
梯度累积可以:
在不改变训练逻辑的前提下,还原论文设定
✅ 场景 3:微调大模型(LoRA / PEFT)
在微调 LLM 时:
- 通常 batch size 很小(1~4)
- 但希望梯度更稳定
梯度累积可以:
✅ 场景 4:分布式训练中的“微 batch”
在:
- 数据并行(DDP)
- 流水线并行(Pipeline Parallel)
常见做法:
- 每个 GPU 上用 micro batch
- 多个 micro batch 累积后再同步梯度
这是:
分布式训练的事实标准做法
四、梯度累积的代价与注意事项
❌ 代价
- 训练速度变慢
- 每 k 步才更新一次参数
- 反向传播次数不变,但参数更新频率降低
- 学习率可能需要调整
- 大 batch 通常需要:
- 稍大的学习率
- warmup
- 否则可能收敛变慢
⚠️ 注意事项
- BN(BatchNorm)会受影响
- BN 依赖当前 batch 的统计量
- 梯度累积 ≠ 真正的大 batch BN
- 解决方案:
- 用 SyncBatchNorm
- 或改用 GroupNorm / LayerNorm
- loss 计算方式要一致
- 不要忘记清零梯度
optimizer.zero_grad()
for i in range(k):
loss = model(data)
loss = loss / k
loss.backward()
optimizer.step()
五、一句话总结
梯度累积是为了在显存受限的情况下,实现“大 batch 训练”的数学等价效果,同时兼顾训练稳定性与工程可行性。
如果你愿意,我也可以:
- 用 PyTorch 示例代码 详细说明
- 对比 梯度累积 vs 大 batch vs 分布式训练
- 分析 某个具体模型(如 LLM、ViT)是否适合用梯度累积
你可以直接告诉我你的使用场景。