先把当时的情况摆出来。开启半精度训练后报 RuntimeError: expected scalar type Half but found Float,位置在自定义 loss 计算里。

原因不止一个,得分开看。自定义损失函数里新建的张量默认是 float32。也可能是模型部分子模块没有跟随 half 转换。

少数情况下是标签张量是整型,与预测结果类型不一致。不容易想到的是,混合精度下 autocast 范围没有覆盖到该段代码。

先确认模型参数的实际类型

python -c "import torch;print(next(model.parameters()).dtype)"

再往下用 autocast 包住前向与损失计算

with torch.autocast('cuda', dtype=torch.float16): loss = criterion(out, y)

手工创建张量时显式指定类型

weight = torch.tensor([1.0], device='cuda', dtype=torch.float16)

等前面都确认过,再统一标签类型后再计算损失

y = y.long(); out = out.float()

同一份数据我导出了两份,一份留底,一份拿来试。

别只看报错消失,验证要多做一步。训练能正常反向传播,loss 数值稳定,不再出现类型不匹配的报错。

容易忽略的是,autocast 只自动处理已知算子,自定义函数里的常量张量不会被转换,这类报错几乎都出在自己写的计算里。改动前把原配置备份一份,出问题能马上回滚,这比任何技巧都实用。

作者 9823189