在开源大模型微调过程中,梯度更新策略的选择直接影响训练效率和模型性能。本文将分享几种常见梯度更新策略的对比测试及踩坑经验。
梯度裁剪 vs 梯度累积
梯度裁剪(Gradient Clipping) 是防止梯度爆炸的有效手段。在使用 torch.nn.utils.clip_grad_norm_ 时,需注意裁剪阈值的选择:
# 示例代码
for batch in dataloader:
optimizer.zero_grad()
outputs = model(batch)
loss = criterion(outputs, targets)
loss.backward()
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0) # 裁剪阈值设为1.0
optimizer.step()
若裁剪阈值设置过小,会导致梯度被过度压缩;过大则失去效果。建议从 0.1 到 1.0 之间逐步调优。
梯度累积策略
在显存受限的环境中,我们常采用梯度累积策略来模拟大 batch size 的训练效果:
accumulation_steps = 4
for i, batch in enumerate(dataloader):
outputs = model(batch)
loss = criterion(outputs, targets) / accumulation_steps # 注意除以累积步数
loss.backward()
if (i + 1) % accumulation_steps == 0:
optimizer.step()
optimizer.zero_grad()
实践对比:Adam vs AdamW
在微调阶段,我们发现 AdamW 在大型预训练模型上表现更优。原因在于其对权重衰减的处理方式不同,建议使用 torch.optim.AdamW 而非传统 Adam。
optimizer = torch.optim.AdamW(model.parameters(), lr=5e-5, weight_decay=0.01)
坑点总结
- 未正确设置梯度累积步数:容易导致训练不稳定或效果下降;
- 梯度裁剪阈值选择不当:可能使模型无法收敛;
- AdamW 与 Adam 混用:不同优化器参数设置差异较大,需注意调整。
建议在正式训练前,先进行小规模测试验证策略有效性。

讨论