PyTorch 默认就是梯度累加的:
optimizer.zero_grad()
for i in range(accumulation_steps):
outputs = model(inputs[i])
loss = criterion(outputs, targets[i])
loss = loss / accumulation_steps
loss.backward() # 梯度自动累加
optimizer.step()
optimizer.zero_grad()✅ 关键点:
loss.backward() 不会清除梯度backward() 的梯度会自动相加accumulation_steps 是为了等效大 batchnn.DataParallel 自动做梯度求和:
model = nn.DataParallel(model)
outputs = model(inputs)
loss = criterion(outputs, targets)
loss.backward() # 各 GPU 梯度自动 sum 到主卡
optimizer.step()✅ 内部机制:
all_reduce(sum) 梯度⚠️ 注意:
在 DistributedDataParallel 中:
model = DistributedDataParallel(model, device_ids=[local_rank])loss.backward() 时:✅ 等价于:
global_grad = grad_rank0 + grad_rank1 + ... + grad_rankN⚠️ 重要细节:
loss = loss / world_size或
for p in model.parameters():
p.grad /= world_size如果你不用 DDP,想自己控制:
# rank 0 ~ N
grad = p.grad.clone()
dist.all_reduce(grad, op=dist.ReduceOp.SUM)
p.grad = grad或:
dist.all_reduce(p.grad, op=dist.ReduceOp.SUM)✅ 常用于:
optimizer.zero_grad()
for i in range(accum_steps):
out = model(x[i])
loss = crit(out, y[i]) / (accum_steps * world_size)
loss.backward()
optimizer.step()| 场景 | 是否自动累加 | 是否跨设备 |
|---|---|---|
| 单卡多 batch | ✅ | ❌ |
| DataParallel | ✅ | ✅ |
| DDP | ✅ | ✅ |
| 手动 all_reduce | ✅ | ✅ |
如果你有具体场景(比如:DDP + 梯度累积 / 自定义并行 / 混合精度),可以直接说,我可以给针对性代码。