混合精度训练

26.6.12更新(新增混合精度训练伪代码)


低精度的优点:

1)计算速度提升

2)显存占用变小

3)数据传输带宽占用小

低精度的缺点:

1)表示范围问题,表示不了太大太小的值

2)大数吃小数问题:将小数转换成和大数的进制一样的表达方式,但是由于过小,超出了大数的范围,所以溢出了

前向传播和损失计算

第一步,master weights(FP32) --weights(FP16)

主权重存储在FP32格式中

前向传播之前,会将FP32权重转换为FP16格式

第二步,weights(FP16)--loss(FP32)

使用FP16权重前向传播计算,得到预测值,计算得到LOSS,使用FP32进行存储,因为LOSS过小的话无法精确表示

存储高精度,前向传播低精度,loss高精度

损失缩放

第三步,Loss (FP32) → Scaled Loss (FP32)

通过人为放大loss,反向传播计算出的梯度会相应放大N倍,从而让梯度值落在FP16的安全范围内

loss缩放

反向传播和梯度处理

第四步,Scaled Loss (FP32) → Scaled Gradients (FP16)

梯度相应放大,但是还是在FP16可表示范围内

第五步,Scaled Gradients (FP16) → Scaled Gradients (FP32)

后续梯度更新要有高精度

梯度缩放,梯度精度还原

梯度还原和更新

第六步,Scaled Gradients (FP32) → Gradients (FP32)

将放大的梯度恢复正常

第七步,Gradients (FP32) → Master Weights (FP32)

用梯度更新主权重

梯度缩放还原,主权重更新

第八步,Master Weights (FP32) → weights(FP16)

进行下一次训练

这个过程巧妙地解决了:

速度和显存;精度和稳定性

在现代深度学习框架(如 PyTorch、PaddlePaddle)中,开启混合精度训练非常简单,通常只需要几行代码。以 PyTorch 为例,主要依靠 torch.cuda.amp 模块中的两个核心组件:

  • autocast:自动为你选择合适的精度。在这个上下文管理器里的运算,框架会自动判断哪些该用 FP16,哪些必须用 FP32。
  • GradScaler:自动帮你完成上述的“损失缩放”操作,防止梯度下溢。
# 伪代码示例

# 0. 导入工具
from torch.cuda.amp import GradScaler, autocast

# 1. 初始化(训练开始前 1 次)
scaler = GradScaler()

# 2. 训练循环(每个 batch)
for data, label in dataloader:
    optimizer.zero_grad()  # 梯度清零
    
    # 3. 前向传播 + 自动混合精度
    with autocast():
        output = model(data)
        loss = criterion(output, label)
    
    # 4. 反向传播:缩放 loss + 计算梯度
    scaler.scale(loss).backward()

    # ============= 可选(梯度裁剪)=============
    # 如果要裁剪梯度,必须先反缩放!
    scaler.unscale_(optimizer)
    torch.nn.utils.clip_grad_norm_(model.parameters(), max_norm=1.0)
    # ==========================================

    # 5. 更新参数
    scaler.step(optimizer)
    
    # 6. 更新缩放因子
    scaler.update()

参考视频:

RethinkFun投稿视频-RethinkFun视频分享-哔哩哔哩视频

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值