梯度累积是一种在深度学习训练过程中,在不增加显存占用的前提下,模拟更大 batch size 训练效果的技术。
其核心思想是:
将多个小 batch 的前向和反向传播分开进行,把计算得到的梯度累加(accumulate),直到达到目标 batch size 后,再统一更新一次模型参数。
✅ 用时间换空间
假设目标 batch size 为 B,实际可用 batch size 为 b,累积步数为:
[
K = frac{B}{b}
]
每次:
[
theta = theta - eta cdot g
]
对于第 k 个 micro-batch:
[
g_{acc} = g_{acc} + g_k
]
当 k == K 时:
[
theta = theta - eta cdot frac{g_{acc}}{K}
]
注意:是否除以 K 取决于框架实现(有些自动平均,有些需手动处理)
┌────────────┐
│ micro-batch 1 │ → forward → backward → 累加梯度
├────────────┤
│ micro-batch 2 │ → forward → backward → 累加梯度
├────────────┤
│ ... │
├────────────┤
│ micro-batch K │ → forward → backward → 累加梯度
│ │ → optimizer.step()
│ │ → optimizer.zero_grad()
└────────────┘accumulation_steps = 4
optimizer.zero_grad()
for i, (x, y) in enumerate(dataloader):
pred = model(x)
loss = criterion(pred, y)
loss = loss / accumulation_steps
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()loss / accumulation_steps:保证梯度尺度正确optimizer.step() 只在累积完成后调用zero_grad() 防止梯度泄漏| 对比项 | 大 Batch | 梯度累积 |
|---|---|---|
| 显存占用 | 高 | 低 |
| 计算效率 | 高 | 稍低 |
| 数值结果 | 完全一致 | 近似一致 |
| 实现复杂度 | 低 | 中 |
在理想情况下,二者训练结果几乎等价
✅ 解决方案:
梯度累积的本质:
用多次小batch的反向传播,等价替代一次大batch的反向传播
它是:
如果你愿意,我也可以: