快速结论:该报错发生在将 CanineModel 导出为 FP16 ONNX 模型时,原因是浅层编码器(shallow character encoder)中的 3D 注意力掩码始终使用 float32 类型,导致与 float16 的注意力分数混合后类型不匹配。优先排查 _create_3d_attention_mask_from_input_mask 函数是否创建了 float32 掩码。
问题场景
用户使用 Transformers 库中的 CanineModel(google/canine-s),在调用 model.half() 后通过 torch.onnx.export 导出 FP16 ONNX 模型时触发报错。该问题在 PyTorch 2.9.0+cu129 / CUDA 和 PyTorch 2.11.0+cu128 / CUDA 环境下均能复现,且不限于特定 GPU 型号。
报错原文
RuntimeError: expected scalar type Float but found Half
File ".../transformers/models/canine/modeling_canine.py", line 353, in forward
context_layer = torch.matmul(attention_probs, value_layer)
RuntimeError: expected scalar type Float but found Half
原因分析
根本原因是 _create_3d_attention_mask_from_input_mask() 函数中始终使用 .float() 方法生成 float32 类型掩码,而调用 model.half() 后,query_layer、key_layer、value_layer 均为 float16 类型。当 float32 掩码加到 float16 的 attention_scores 上时,attention_scores 被提升为 float32,导致后续 torch.matmul(attention_probs, value_layer) 中两个张量类型不一致(float32 vs float16)。
该问题仅影响浅层字符编码器(initial_char_encoder / final_char_encoder),深层编码器使用的 create_bidirectional_mask() 具有 dtype 感知能力,不会触发此问题。
环境排查
- 确认 Transformers 版本(Issue 中为 5.12.1)
- 确认 PyTorch 版本(Issue 中涉及 2.9.0+cu129 和 2.11.0+cu128)
- 确认 ONNX 及 ONNX Runtime 版本(onnx 1.22.0, onnxruntime 1.23.2)
- 确认是否调用了
model.half() - 确认模型是否为
CanineModel
解决步骤
- 临时调试方案(非官方修复):在
CanineSelfAttention.forward()中,将attention_mask转换为与attention_scores相同的 dtype:
attention_mask = attention_mask.to(attention_scores.dtype)
将其插入在attention_scores = attention_scores + attention_mask之前。 - 官方修复:该问题已在 PR #47083 中修复,建议升级到包含该修复的 Transformers 版本。
验证方法
成功执行 torch.onnx.export 且不抛出 dtype 相关异常,然后使用 ONNX Runtime 加载导出的模型并运行推理,确认输出正常。
注意: 修复此 dtype 问题后,_repeat_molecules() 中可能还会遇到第二个设备放置问题(RuntimeError: Expected all tensors to be on the same device),该问题在 Issue 中已记录但尚未完全诊断。
参考来源
huggingface/transformers #47050
AI 工具推荐
想把多个 AI 模型放在一个入口?
GamsGo AI 集成 ChatGPT、DeepSeek、Gemini、Claude、Midjourney、Veo 等常用模型,适合写作、绘图、视频和日常 AI 工作流。
推广链接:通过此链接购买,我可能获得佣金,不影响你的价格。
这个方案解决了吗?
可以继续搜索完整报错,或查看同一工具的其他排查指南。


