遇到 addmm_impl_cpu_ not implemented for Half 报错,在 CPU 上做相似度计算时,直接把 half(float16)张量显式转换成 float32 就能解决,这个是 CPU 端 PyTorch 原生限制,CPU 的 addmm 矩阵乘加算子本身不支持 float16 半精度,GPU 上可以正常跑 half,但是 CPU 没有对应的内核实现,相似度计算里的矩阵乘法、余弦相似度、内积都会调用 addmm,只要传入 half 张量就直接抛出这个报错。很多场景是模型导出或者自动混合精度之后,向量 embedding 变成了 float16,放到 CPU 跑相似度匹配、召回、向量检索的时候触发报错,不需要换 GPU,只需要在矩阵运算前统一转成 float32,计算完之后你还可以按需转回 half 节省内存。你可以先定位报错的张量,找到 embedding 向量、权重矩阵,在相似度计算代码前面加上类型转换语句,优先用 tensor.float () 进行显式转换;也可以加载模型的时候直接指定 float32 加载,避免输出 half 张量。改完之后,余弦相似度、内积相似度、批量向量比对都可以正常在 CPU 执行,代价是张量占用内存变大一点,CPU 计算速度会小幅下降,纯 CPU 离线向量检索场景一般都能接受。
报错核心说明
- 报错原文:RuntimeError: "addmm_impl_cpu_" not implemented for 'Half'
- 含义:CPU 平台下 addmm 算子没有实现 float16(Half)版本
- 高频触发场景:向量 Embedding 余弦相似度、矩阵内积、线性层推理、批量向量召回
- 区分:GPU 是支持 half 的 addmm,只有 CPU 会出现这个报错
推荐代码写法(CPU 相似度计算)
方案1:计算前显式转float32(最推荐)
emb1 = emb1.float()
emb2 = emb2.float()
sim = torch.nn.functional.cosine_similarity(emb1, emb2)
方案2:矩阵形式相似度(召回常用)
emb = emb.float()
emb_norm = torch.nn.functional.normalize(emb)
sim_matrix = emb_norm @ emb_norm.T
可选修复清单
- 向量张量在相似度计算前调用 .float() 显式转为 float32
- 加载模型时,取消 fp16 参数,直接以 float32 加载模型
- 关闭 cpu 端 autocast 自动转 half 的逻辑
- 如果是批量推理,只在相似度计算模块转 float32,前面编码部分保留 half 节省内存
- 备选方案:切换到 GPU 运行,就不需要类型转换
不同方案对比表
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 相似度处显式转 float32 | 改动最小,不影响上游编码 | 少量内存增加 | 离线向量检索、CPU 相似度计算 |
| 全模型 float32 加载 | 全程稳定,不容易出类型错 | 模型内存占用翻倍 | 小模型、低并发 CPU 服务 |
| 迁移到 GPU 执行 | 速度快,原生支持 half | 需要 GPU 资源 | 线上高并发向量服务 |
| 使用 bfloat16 | 新版 CPU 支持 bf16 算子 | 老 CPU 不兼容,精度和 half 不一样 | 新 CPU、新版 PyTorch |
【相关 FAQ】
问题 1:addmm_impl_cpu_ not implemented for Half 报错,CPU 相似度计算显式转 float32 会影响相似度结果精度吗?
回答 1:addmm_impl_cpu_ not implemented for Half 报错,CPU 相似度计算显式转 float32,计算精度会更高,余弦相似度数值几乎没有明显偏差,适合向量检索、相似度匹配场景。
问题 2:addmm_impl_cpu_ not implemented for Half,能不能只在相似度计算部分转 float32,embedding 编码保持 half?
回答 2:addmm_impl_cpu_ not implemented for Half,是可以的,embedding 编码阶段保留 half 省内存,拿到向量之后,在进入相似度矩阵乘法前转 float32,是线上 CPU 服务最常用的写法。
问题 3:addmm_impl_cpu_ not implemented for Half,bfloat16 能不能在 CPU 上跑相似度计算避开这个报错?
回答 3:addmm_impl_cpu_ not implemented for Half 这个报错特指 float16(Half),新版 PyTorch 的 CPU 支持 bfloat16 的 addmm,但老 CPU 不支持 bfloat16 内核,兼容性不如显式转 float32 稳妥。
问题 4:addmm_impl_cpu_ not implemented for Half,为什么 GPU 跑相似度计算不会触发这个报错?
回答 4:addmm_impl_cpu_ not implemented for Half 是 CPU 算子限制,GPU 有专门针对 Half(float16)优化的 addmm 内核,GPU 上直接用 half 做相似度矩阵乘法是原生支持的。
问题 5:addmm_impl_cpu_ not implemented for Half,我在 CPU 做批量相似度召回,转 float32 之后内存涨很多怎么办?
回答 5:addmm_impl_cpu_ not implemented for Half,CPU 相似度计算转 float32 后内存翻倍,你可以分批切分向量,分块计算相似度,不用一次性把全部向量加载进内存。
【参考资料】
[2026-04-12](PyTorch 2.7 数值精度文档)PyTorch 官方文档
[2025-12-08](PyTorch CPU Autocast 算子说明)PyTorch 官方文档
[2023-08-10](CPU 环境部署模型解决 addmm_impl_cpu_报错)阿里云开发者社区
[2023-06-19](Half 类型矩阵乘法 CPU 报错讨论)PyTorch 论坛
【免责声明】
本内容仅为 addmm_impl_cpu_ not implemented for Half 报错的技术方案整理,不同 PyTorch 版本、CPU 架构会存在行为差异;代码示例仅作参考,上线前请自行测试向量相似度、召回指标是否符合业务预期;本内容不承担因为类型转换、精度变化、内存溢出带来的业务损失。
