梯度累积是一种在深度学习训练中解决内存不足问题的技术。当模型较大或批量大小(batch size)较大时,一次性计算梯度可能会导致内存不足。梯度累积通过在多个小批量上累积梯度,然后进行一次参数更新,从而有效地减少了内存需求。以下是梯度累积如何解决内存不足问题的详细解释:
import torch
from torch.utils.data import DataLoader
# 假设我们有一个模型和数据加载器
model = ...
train_loader = DataLoader(dataset=..., batch_size=32, shuffle=True)
# 设置累积步数
accumulation_steps = 4
# 初始化全局梯度
optimizer = torch.optim.SGD(model.parameters(), lr=0.01)
for param_group in optimizer.param_groups:
param_group['accum_grads'] = [torch.zeros_like(param) for param in param_group['params']]
# 训练循环
for epoch in range(num_epochs):
model.train()
for i, (inputs, targets) in enumerate(train_loader):
# 前向传播
outputs = model(inputs)
loss = criterion(outputs, targets)
# 反向传播,计算梯度
loss = loss / accumulation_steps # 缩放损失以匹配累积梯度
loss.backward()
# 累积梯度
if (i + 1) % accumulation_steps == 0:
# 更新参数
for param, accum_grad in zip(model.parameters(), optimizer.param_groups[0]['accum_grads']):
param.grad = accum_grad
param.grad.data.add_(param.grad)
param.grad.data /= accumulation_steps # 缩放梯度
# 清空累积梯度
for accum_grad in optimizer.param_groups[0]['accum_grads']:
accum_grad.zero_()
print(f'Epoch {epoch+1}/{num_epochs}, Loss: {loss.item()}')
通过合理使用梯度累积,可以在有限的硬件资源下训练更大规模的模型,提高训练效率。