| 项目 | FP32 | FP16(混合精度) |
|---|---|---|
| 显存 | 高 | 低 |
| 计算速度 | 慢 | 快 |
| 数值稳定性 | 高 | 中等(需处理) |
FP32 weights
↓ 转成 FP16
FP16 weights → forward → loss → backward → FP16 gradients
↓
FP32 gradients → 更新 FP32 weightsFP16 的值范围小,梯度容易下溢(变成 0),因此:
loss = loss * scale
gradients /= scaletorch.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()autocast() 只作用于:model()lossautocast 外手动转 half()model = model.half()
input = input.half()mixed_float16from tensorflow.keras.mixed_precision import set_global_policy
set_global_policy('mixed_float16')或:
policy = tf.keras.mixed_precision.Policy('mixed_float16')
tf.keras.mixed_precision.set_global_policy(policy)✅ 自动处理 loss scaling
from transformers import Trainer, TrainingArguments
args = TrainingArguments(
...,
fp16=True # 开启混合精度
)
trainer = Trainer(model, args=args)| 操作 | 建议 |
|---|---|
| Softmax(数值敏感) | 自动回退 FP32 |
| BatchNorm | 保持 FP32 |
| 损失函数 | 使用 FP32 |
| 学习率 schedule | FP32 |
autocast 会自动处理这些。✅ 原因:
✅ 解决:
scaler = GradScaler(init_scale=1024)✅ 检查:
autocast❌ 不需要
✅ 适合:
❌ 不适合:
混合精度训练 = FP16 计算 + FP32 主权重 + Loss Scaling
如果你愿意,我可以: