先记住这个答案
单向量余弦相似度将整个文本池化为一个向量,只做一次点积,比较的是全局语义;而 ColBERT 式 MaxSim 让查询和文档各保留一串逐 token 向量,对每个查询 token 在文档全部 token 中取最大余弦相似度再求和。这样能对齐细粒度词义,例如“苹果公司”与“Apple Inc.”中“苹果”与“Apple”精确匹配,但也因此需要每个 token 都存向量,索引体积和在线计算量显著增加。
- 保留 token 级对齐,能精准匹配局部语义。
- 索引体积放大为 token 数倍,需量化压缩。
- MaxSim 分数无固定上界,需校准后才能用阈值。
从全局点到局部匹配的机制转变
单向量模型如常见 embedding,将整段文字经池化压成一个稠密向量,检索时只计算一次余弦或点积。这种方式把词级细粒度关系平均掉,查询“苹果发布会”与文档“Apple event”只能靠整体语义相近,无法确认“苹果”与“Apple”是否对位。
ColBERT 式做法不同,编码器为每个 token 输出一个向量,查询和文档各有一串向量。对于每个查询 token,遍历文档全部 token 计算出所有余弦相似度并取最大值,得到 MaxSim = Σ q_i ∈ Q max_{d_j ∈ D} cos(q_i, d_j),这些最大相似度之和就是两段文本的相关性分数。
这个“晚交互”机制本质上是保留词级双向对齐:每个查询词只需在文档中找到一个最相关的词即可,而不是强迫整体表示匹配。它特别擅长处理单词不同形态、同义词、缩写等局部对应,但也因此把每个 token 都变成索引项,费用随之上升。
产品型号检索的单向量失误案例
假设技术支持知识库有 8000 篇文档,每篇含产品“R-2040”的说明。用户查询“R2040 故障”,单向量余弦检索可能因全局池化而难以区分不同型号标识的细微差异,返回的前 5 条多是其他型号手册,因为整体语义更接近“产品故障”。
改用 ColBERT 后,每个 token 都是独立向量。查询中“R”“2040”“故障”分别匹配文档里“R-2040”的对应 token,“2040”能精确命中型号中的数字,MaxSim 得分明显高于无关文档,top1 即正确手册。修改索引需把每篇文档的约 500 个 token 都存为向量,存储由单向量的一行变为 500 行。
这个场景说明细粒度对齐能解决实体变体匹配。但代价非常具体:8000 篇 × 500 token,若每向量 128 维 float32,原始单向量只要约 4MB,这里涨到约 2GB,必须考虑用乘积量化把每个向量压到 8bit 或更低位,否则内存无法接受。
MaxSim 失效与压缩校正的边界
当文档很长且包含大量无关 token 时,每个查询 token 都会在全局文档 token 中寻找最大值,可能把不相关的常见词当成最佳匹配。例如查询“给小猫洗澡”,文档是科普文章,提到很多“猫”但核心不是洗澡,某些 token 的最大相似度可能来自“猫”而拉高总分。
此时单纯增加文档长度并不能稳定提高召回,反而让噪声 token 成为强匹配源。可操作判断是:若发现高分段中出现语义跳跃的段落,可对文档 token 做重要性剪枝,只保留名词/动词等,或对 MaxSim 得分除以文档长度做归一化,但效果有限。
另一个边界是索引放大。一段 512 token 的文档,逐 token 向量使索引体积膨胀到原来的数百倍,热门库无法直接支撑。业内通用做法是先跑近似最近邻检索,如对每个查询 token 用 HNSW 取前 k 个候选文档,再做精排,但这也把问题从单次点积变成多次查询,延迟升高需用批量矩阵乘法并行优化。
容易答错的地方
- MaxSim 分数在 0 到 1 之间
- 实际上 MaxSim 是对每个查询 token 的最大值求和,查询长度 n 可使分数最高到 n,即便向量归一化,最大也只是 n 而非 1,需要额外归一化才能与单向量分数比较。
- 先平均文档所有 token 向量再匹配
- 平均会抵消局部特异性,丢失每个 token 最匹配的独立信息。MaxSim 保留每个 token 在全集中查找的能力,与平均后单点运算有本质不同。
面试官还会怎么问?
MaxSim 分数通常落在什么范围?
如果所有向量都 L2 归一化,每个查询 token 的最大余弦在 [-1,1],实际为正数居多,求和后范围是 [-n,n]。在线使用前需用训练数据校准,或做 softmax 缩放,不能直接套用单向量余弦阈值。
为什么 ColBERT 把交互放在查询时而不是训练时?
因为文档侧可预先编码和索引,查询到来时才与文档 token 交互,这叫晚交互。若早交互则在检索每个文档时都要重新编码文档,无法用向量索引加速,只能暴力比对。
如何降低 MaxSim 的检索延迟?
常用两阶段:先用单向量或量化索引粗筛出数百候选,再对候选文档逐个计算 MaxSim 精排。也可把查询 token 变成批量查询,但延迟敏感场景往往限制查询 token 数为 32 个。
参考资料
示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。