混合精度训练中的梯度缩放器 | AI生成和翻译

Home 2025.10

torch.cuda.amp.GradScaler 是 PyTorch 的一个工具类,旨在使用自动混合精度(AMP)进行混合精度训练时自动缩放梯度。它有助于防止使用 float16(半精度)张量时梯度下溢,否则梯度可能变得过小而无法精确表示。


为什么使用 GradScaler

在混合精度训练中:


基本用法

import torch
from torch.cuda.amp import autocast, GradScaler

model = MyModel().cuda()
optimizer = torch.optim.Adam(model.parameters())
scaler = GradScaler()  # 默认 init_scale=2**16

for data, target in dataloader:
    optimizer.zero_grad()

    # 1. 使用 autocast 进行前向传播
    with autocast():
        output = model(data)
        loss = loss_fn(output, target)

    # 2. 缩放损失并执行反向传播
    scaler.scale(loss).backward()

    # 3. 反缩放 + 优化器步骤
    scaler.step(optimizer)

    # 4. 更新缩放因子以备下一次迭代
    scaler.update()

关键方法

方法 用途
scaler.scale(loss) .backward() 之前缩放损失
scaler.step(optimizer) 反缩放梯度并调用 optimizer.step()
scaler.update() 为下一次迭代调整缩放因子
scaler.unscale_(optimizer) 手动反缩放梯度(很少需要)
scaler.get_scale() 返回当前缩放因子

缩放工作原理(内部)

  1. 初始缩放因子:通常为 2**16 = 65536
  2. backward() 之后,检查梯度中是否存在 inf/NaN
  3. 如果没有 inf/NaN → 下次缩放因子可能增加(例如 ×2)。
  4. 如果发现 inf/NaN → 跳过 optimizer.step()减小缩放因子(例如 ÷2),并在稍后重试。

这使得训练对偶尔的溢出具有鲁棒性


常用参数

scaler = GradScaler(
    init_scale=2.**16,     # 起始缩放因子
    growth_factor=2.0,     # 无 inf 时倍增
    backoff_factor=0.5,    # 有 inf 时折半
    growth_interval=2000,  # 增长前的步数
    enabled=True
)

梯度裁剪示例

scaler.scale(loss).backward()
scaler.unscale_(optimizer)  # 裁剪前需要反缩放
torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
scaler.step(optimizer)
scaler.update()

注意:在裁剪或检查梯度之前,务必先进行 unscale_


最佳实践


不适用的场景


官方文档

https://pytorch.org/docs/stable/amp.html#torch.cuda.amp.GradScaler


如果需要完整的训练循环示例或与手动缩放的比较,请告诉我!


Back

x-ai/grok-4-fast

Donate