报错是这么冒出来的。用 colbertv2 做二阶段重排,文档向量是 768 维,查询侧 late interaction 直接抛 RuntimeError,原文 expected 128 but got 768,环境是 torch 2.4 加 transformers 4.44,单独跑 encoder 输出正常,一进 rerank 就崩,换 GPU 也一样。
中间走过弯路,把「文档向量是 bge-m3 产出的,和查询侧本来就不是同一套空间」当成主因,改完现象没变。
把日志和配置对完,能解释这个现象的基本就这几处。ColBERTv2 的线性投影把 768 压到 128,加载时跳过了 projection 权重。也可能是用了 bert-base-uncased 的 checkpoint 而不是 colbertv2 专用权重。
不容易想到的是,代码把查询的 128 维和文档的 768 维直接做了 matmul。
动手时先打印两侧向量的 shape 和模型配置
python -c "import torch;q=torch.load('q.pt');d=torch.load('d.pt');print(q.shape,d.shape)"
随后确认加载的 checkpoint 里有没有投影层
python -c "from transformers import AutoModel;m=AutoModel.from_pretrained('colbert-ir/colbertv2.0');print([n for n,_ in m.named_parameters() if 'linear' in n])"
然后用专用模型重新编码文档并校验维度
python encode_docs.py --model colbert-ir/colbertv2.0 --dim 128 --out docs_colbert.npy
末了重排前加一次维度断言再跑
python rerank.py --query q.pt --docs docs_colbert.npy --assert-dim 128
别只看报错消失,验证要多做一步。查询与文档向量都是 128 维,rerank 返回分数在 0 到 1 之间,和人工标注的排序一致,日志里不再出现 expected 128。
容易忽略的是,ColBERT 的 128 维是投影后的结果,不能拿普通 BERT 的 768 维向量凑;换编码模型时查询侧和文档侧必须同时重建,混用两套向量是最常见的崩溃原因。这类问题最好一次改到位,反复小改反而容易把原因搅混。
