梯度累积(Gradient Accumulation)是一种在显存受限时,通过多次前向+反向传播、多次累积梯度后再统一更新参数的训练技巧。它本质上是在用时间换空间,让小显存设备也能跑大 batch 或大模型。
下面从适用场景、不适用场景、典型例子三个层面说明。
一、梯度累积适用的典型场景
1️⃣ 显存不足以支持大 batch size
这是最常见、最经典的使用场景。
问题:
- 模型大(如 LLM、ViT、Large CNN)
- 输入分辨率高(高分辨率图像、长文本)
- 想用大 batch 提升训练稳定性或收敛速度
- 单卡显存不够
解决方案:
大 batch = 小 batch × 累积步数
例如:
- 理想 batch size = 128
- 单卡最多支持 batch size = 32
- 累积 4 步梯度再更新参数
✅ 效果等价于大 batch
✅ 显存占用只和小 batch 有关
2️⃣ 大模型训练(LLM / 多模态模型)
如:
- GPT / LLaMA / ChatGLM
- CLIP / BLIP / Flamingo
- 多卡仍显存紧张
原因:
- 激活值(activation)占用显存巨大
- Optimizer states(Adam 的 m/v)也很大
梯度累积可以:
- 减少每次 forward/backward 的显存峰值
- 配合:
- 混合精度(FP16 / BF16)
- 梯度检查点(Gradient Checkpointing)
3️⃣ 多卡训练但单卡 batch size 很小
例如:
- 数据并行(DDP)
- 每张卡 batch size = 1 或 2
问题:
- 单卡 batch 太小 → 梯度噪声大
- 全局 batch 仍不够大
做法:
✅ 提高训练稳定性
✅ 减少通信频率(可选)
4️⃣ 长序列 / 高分辨率输入
例如:
- NLP:长文本(>2048 tokens)
- CV:高分辨率图像(4K、医学影像)
- 视频模型:多帧输入
特点:
- 单样本显存占用就很大
- 实际 batch size 被迫很小
✅ 梯度累积几乎是必选项
5️⃣ 强化学习 / 生成模型
如:
原因:
- 采样不稳定
- 需要较大“有效 batch”
- 每次 rollout 或生成代价高
✅ 累积多次采样的梯度,提高稳定性
6️⃣ 推理式训练 / 在线学习
✅ 累积到一定步数再更新模型
二、梯度累积不适用的场景
❌ 1️⃣ 对 batch size 极度敏感的任务
例如:
- BatchNorm 在小 batch 下表现差
- 某些对比学习 / 自监督任务
⚠️ 注意:
- 梯度累积 不会 改变 BN 的统计量
- 可能需要:
- Synchronized BatchNorm
- 或改用 LayerNorm
❌ 2️⃣ 实时性要求高的训练
⚠️ 可能影响:
- 收敛速度(wall-clock time)
- 在线学习响应速度
❌ 3️⃣ 优化器对梯度历史强依赖
部分特殊优化器(少见):
(大多数 Adam / SGD 没问题)
三、典型使用示意
accumulation_steps = 4
optimizer.zero_grad()
for i, (x, y) in enumerate(dataloader):
loss = model(x, y)
loss = loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
四、一句话总结
梯度累积适用于:显存受限,但希望获得大 batch 效果的场景。
✅ 大模型
✅ 长序列 / 高分辨率
✅ 多卡但 batch 小
✅ 强化学习 / 生成模型
如果你愿意,我也可以:
- 帮你判断 你的任务是否适合梯度累积
- 对比 梯度累积 vs 大 batch vs 分布式训练
- 结合 PyTorch / DeepSpeed / Megatron 给你具体配置建议