检索 · 2022

混合检索

同时保留关键词和向量两路召回,再把名次或分数合并。

常用 · 使用现成模型

要解决的问题

稠密检索擅长改写后的语义,稀疏检索擅长名字、错误码和原句。只用一路,总会漏掉另一类相关文档。

相对前一代的变化

它不替换稠密检索,而是让关键词检索和向量检索各返回一张名单,再用倒数排名融合或加权分数合成一张名单。

做法

两路各自取前若干条,用倒数排名融合按名次合并,或把归一化后的分数做凸组合。Bruch 等人比较过这两种融合:混合结果通常优于单独一路;倒数排名融合对参数敏感,有少量标注时凸组合往往更稳。

局限

两路各自取多少条、权重如何分配,都要调。融合提高召回时,也会把更多弱相关的块送进上下文。

在链路中的位置

替换朴素 RAG 里的单路召回,仍处在重排序和生成之前。

详解

「详解」根据 Datawhale《All-in-RAG》 的 混合检索 改写,有删节和重组,未包含原教程的代码、图片和练习。原教程与本节详解均按 CC BY-NC-SA 4.0 许可提供:使用时需署名并标明修改,不得用于商业目的,再次改编须以相同许可共享。

稀疏向量精确,稠密向量概括

稀疏向量的维度接近词表,绝大多数位置是零。非零值表示这个词在文档中的权重。BM25 在此基础上使用逆文档频率、词频饱和和文档长度归一化:常见词贡献低,同一个词重复出现的增益会减弱,过长文档会被惩罚。它能解释每个命中的词,也擅长型号、函数名和原句,但不能把“番茄”和“西红柿”当成近义。

稠密向量每一维通常都有值,但单维没有直接含义。语义模型可以把“西红柿炒蛋”放在靠近“番茄鸡蛋面”的位置,因此即使用词不同也能召回。代价是可解释性弱,而且可能错过必须逐字匹配的编号。

两张名单合成一张

混合检索让两路各自取回候选,再融合排序。倒数排名融合不比较原始分数,只使用名次。文档在某一路的名次越靠前,贡献越大,分数大约是各路 1/(名次+常数) 的和。它不需要把 BM25 分数和内积调到同一量纲,所以很稳,但也丢掉了分数之间的差距。

加权组合先把两路分数归一化,再按权重相加。有少量点击或标注时,可以调出更适合语料的比例;权重一旦过拟合,换一批问题就会失效。两路各自取多少条也要单独看:取得太少会在融合前丢掉正确答案,取得太多会把弱相关文档送进后面的重排。

一次编码可以同时产生两路向量

BGE-M3 可以同时给出稠密向量和稀疏权重。Milvus 中相应建立两个向量字段,分别建索引。查询时也生成两种向量,先分别搜索,再用 RRF 或加权排序器合并。

实现顺序是:定义含两种向量的集合,批量编码并插入,创建各自索引,然后执行混合搜索。检查时应同时保留两路的单独结果。只有融合结果变好、而单独结果没有异常变差,才能说明融合本身有帮助。