混合精度训练(Mixed Precision Training)是一种在深度学习模型训练过程中,同时使用多种数值精度(主要是 FP16 半精度和 FP32 单精度)来加速训练、降低显存占用,同时尽量保持模型收敛稳定性和精度的技术。
下面从核心思想、实现方式、关键技术、优缺点几个方面来解释。
一、核心思想
传统训练通常使用 FP32(32 位浮点数) 进行计算和存储,精度高但:
混合精度训练的核心思想是:
在不影响模型精度收敛的前提下,用低精度(FP16)做大部分计算,用高精度(FP32)做关键步骤。
二、为什么要用 FP16?
FP16 的优势
- ✅ 计算速度快(GPU Tensor Core 可加速)
- ✅ 显存占用减半
- ✅ 提高 batch size 或模型规模
FP16 的问题
- ❌ 数值范围小,容易:
- 下溢(梯度变成 0)
- 上溢(梯度爆炸)
- ❌ 累加误差可能影响收敛
三、混合精度训练的基本做法
典型的混合精度训练流程如下:
1️⃣ 前向传播(Forward)
- 权重、激活、中间结果:使用 FP16
- 节省显存和计算资源
2️⃣ 损失计算(Loss)
3️⃣ 反向传播(Backward)
4️⃣ 参数更新(Update)
- 主权重(Master Weights)保持 FP32
- 梯度从 FP16 转回 FP32
- 用 FP32 更新参数
- 更新后再转回 FP16 用于下一轮前向
四、关键技术:损失缩放(Loss Scaling)
这是混合精度训练能成功的关键。
问题
在 FP16 中:
解决方法:Loss Scaling
- 在反向传播前,将 loss 乘以一个缩放因子(如 1024、2048)
- 梯度也被同步放大
- 更新参数前再 反缩放回去
✅ 避免梯度下溢
✅ 不影响数学等价性
五、常见实现方式
1️⃣ PyTorch 中的混合精度
使用 torch.cuda.amp:
from torch.cuda.amp import autocast, GradScaler
scaler = GradScaler()
for data, target in dataloader:
optimizer.zero_grad()
with autocast():
output = model(data)
loss = criterion(output, target)
scaler.scale(loss).backward()
scaler.step(optimizer)
scaler.update()
2️⃣ TensorFlow / Keras
tf.keras.mixed_precision.set_global_policy('mixed_float16')
六、适用场景
✅ 非常适合:
- Transformer / LLM 训练
- 大规模 CNN(ResNet、ViT)
- 显存受限但想增大 batch size
- NVIDIA GPU(支持 Tensor Core)
⚠️ 不太适合:
- 数值极其敏感的模型
- 某些旧 GPU(无 FP16 加速)
七、优缺点总结
✅ 优点
- 训练速度提升 1.5x~3x
- 显存占用减少约 30%~50%
- 对最终精度影响极小
❌ 缺点
八、一句话总结
混合精度训练就是用 FP16 做“体力活”,用 FP32 做“精细活”,从而在几乎不损失精度的前提下,让模型训练更快、更省显存。
如果你愿意,我也可以:
- 用 图示解释 FP32 / FP16 / BF16 的区别
- 对比 混合精度 vs 全精度 vs BF16 训练
- 结合 大模型训练(如 LLM)讲实际工程经验