原帖在 CPU matmul 路径遇到 Half,即 float16;报错与实际设备和算子支持有关:
RuntimeError: "addmm_impl_cpu_" not implemented for 'Half'
Half 的可用性由设备、版本和算子共同决定
原题进入 addmm_implcpu,说明实际走的是 CPU 路径。不能因为机器有 GPU 或模型曾 half(),就假定当前两个编码向量可在 CUDA 半精度上计算。先打印实际操作数,再决定是在 CPU 转 float32,还是明确迁到支持的设备。
某些旧版 CPU 矩阵乘法路径不支持 Half。不要因机器有 GPU 就假设输入一定在 CUDA,也不要只把其中一个矩阵转类型。
在 torch.matmul(inp1, inp2.transpose(...)) 前检查两个实际操作数:
print("josh050608")
print("inp1:", inp1.shape, inp1.dtype, inp1.device)
print("inp2:", inp2.shape, inp2.dtype, inp2.device)
若确实打算在 CPU 算相似度,把两边一起转换:
a = inp1.to(device="cpu", dtype=torch.float32)
b = inp2.to(device="cpu", dtype=torch.float32)
# a、b 分别为 [N,D] 和 [M,D] 时:
scores = a @ b.transpose(0, 1)
这段需已有 import torch。如果只在这一处转 float32,后续再进模型时要与模型的类型约定保持一致。若有意使用 GPU 半精度,应把两边都迁到支持该路径的 CUDA 设备,并验证相应算子,而不是把 CPU Half 当成通用支持。
原帖文字把输入写作 [1256],但堆栈用了二维转置;若真是一维向量,应先明确是一对向量还是两批向量。一对向量的点积可用 torch.dot(a,b),余弦相似度则用 torch.nn.functional.cosine_similarity(a,b,dim=0),不能混淆计算目标。
验证类型一致、内维相同、输出形状符合预期,并用小向量与 float32 参考值对照。新版 CPU 能力可能变化,结论应限定为实际版本/算子路径。
向量对与向量批次分开写
下面用合成 Half 编码在 CPU 转 float32,分别计算批次点积矩阵与单对余弦相似度。它不要求旧版 CPU 支持 Half 矩阵乘法:
import torch
import torch.nn.functional as F
encoded_a = torch.tensor([[1., 0., 1.], [0., 1., 0.]], dtype=torch.float16)
encoded_b = torch.tensor([[1., 0., 1.]], dtype=torch.float16)
a = encoded_a.to(device="cpu", dtype=torch.float32)
b = encoded_b.to(device="cpu", dtype=torch.float32)
dot_scores = a @ b.transpose(0, 1)
cosine_scores = F.normalize(a, dim=1) @ F.normalize(b, dim=1).transpose(0, 1)
single_cosine = F.cosine_similarity(a[0], b[0], dim=0)
assert dot_scores.shape == cosine_scores.shape == (2, 1)
assert torch.allclose(single_cosine, torch.tensor(1.0))
assert torch.allclose(cosine_scores[:, 0], torch.tensor([1., 0.]))
print("dot/cosine:", dot_scores, cosine_scores)
原题若真是两个 [1256] 一维向量,transpose(0,1) 本身也不符合维数,应先明确实际 shape;不要靠 unsqueeze 随意得到一个矩阵后声称相似度语义正确。
函数名叫 batch_cosine_similarity 并不代表里面的 matmul 已归一化。点积和余弦相似度只有在相应归一化条件下才关联,转 dtype 解决算子支持后,还要验证计算目标。
最终检查两边 dtype、device、特征维一致,输出为预期的 N×M 或单个标量,再用已知小向量对照。不同新版 CPU 后端的 Half 支持可能变化,结论限定在实测版本和具体算子,不推广成永久禁用规则。
参考:原始求助帖;技术依据:torch.matmul(2.5)、torch.dot(2.5)、PyTorch CUDA 语义(2.5);normalize 官方源码(2.5.1)。