混合精度训练(Mixed Precision Training)主要通过利用硬件加速、减少内存占用和带宽压力来提升训练效率,同时配合数值稳定性策略保证模型收敛。下面从原理、收益、实现方式和注意事项四个方面说明。
一、核心原理
混合精度训练是指在训练中同时使用 FP16(半精度)和 FP32(单精度):
- FP16:用于大部分计算(前向、反向、参数更新中的一部分)
- FP32:用于保存主权重、关键累加操作,避免数值下溢或精度损失
本质:用尽可能低的精度做计算,用必要的精度保稳定。
二、为什么能提升效率
1. 计算加速(最关键)
- 现代 GPU(如 NVIDIA Ampere、Hopper 架构)
- Tensor Core 对 FP16 / BF16 有数倍于 FP32 的吞吐
- 矩阵乘法(GEMM)在 FP16 下:
- 吞吐量更高
- 延迟更低
✅ 实际收益:
2. 显存占用降低
FP16 相比 FP32:
影响包括:
- 更大 batch size
- 更深 / 更宽的模型
- 更长序列长度
✅ 常见效果:
3. 显存带宽压力减小
在很多模型中,带宽瓶颈 > 计算瓶颈
三、混合精度如何保证数值稳定
1. 主权重(Master Weights)
- 优化器维护一份 FP32 主权重
- 前向 / 反向使用 FP16
- 更新时再写回 FP32
✅ 防止长期训练中的精度漂移
2. Loss Scaling(损失缩放)
FP16 的问题:
解决方法:
loss_scaled = loss * scale
grad = grad / scale
✅ 避免梯度下溢
3. 关键操作保持 FP32
通常包括:
- BatchNorm
- Softmax(部分框架)
- 优化器状态(Adam 的 m / v)
四、常见实现方式
1. PyTorch(AMP)
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
for x, y in dataloader:
optimizer.zero_grad()
with autocast():
y_hat = model(x)
loss = criterion(y_hat, y)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
✅ 自动管理精度与 scaling
2. TensorFlow / Keras
tf.keras.mixed_precision.set_global_policy('mixed_float16')
3. 大模型常用组合
- BF16(而非 FP16)
- 动态范围更大
- 通常不需要 loss scaling
- 配合:
- ZeRO
- Gradient Checkpointing
- Flash Attention
五、适用场景与限制
✅ 非常适合
- Transformer / LLM
- CNN(ResNet、ViT)
- 显存受限或追求吞吐
⚠️ 需要注意
- 极端数值敏感任务(如物理仿真)
- 自定义算子未支持 AMP
- 旧 GPU(无 Tensor Core)
六、一句话总结
混合精度训练通过用 FP16 / BF16 加速计算、减少显存和带宽压力,同时用 FP32 主权重和 loss scaling 保证数值稳定,从而显著提升训练效率和可扩展性。
如果你愿意,我可以:
- 对比 FP16 vs BF16 vs FP32
- 分析 你当前模型是否适合混合精度
- 给出 具体框架(PyTorch / DeepSpeed / Megatron)的最佳配置