先看现象。用 bge-m3 同时拿到稠密与稀疏向量,检索时把两路分数直接相加,结果反而不如只用稠密向量。

排查方向其实有限,先把可能性排一排。两路分数的量纲不同,直接相加会被一方主导。另一种情况是稀疏权重没有归一化,长文档占优。

不容易想到的是,融合前没有做去重,同文档重复计分。

还有一种情况,查询侧与文档侧用了不同的稀疏模式。

先分别做归一化后再加权融合

score = 0.7 * normalize(dense) + 0.3 * normalize(sparse)

接着用倒数排名融合避开量纲问题

final = 1 / (60 + rank_dense) + 1 / (60 + rank_sparse)

随后按文档 id 去重后合并分数

python -c "print(len(scores), len({s['id'] for s in scores}))"

剩下的就是在小测试集上网格搜索权重

python tune_weight.py --w 0.5,0.6,0.7,0.8

恢复的判定其实很直接。混合检索在测试集上的命中率高于单路,前十条结果里相关文档明显增多。

权重与数据分布强相关,别人调出来的零点七未必适合你的语料,最好用几十条标注样本做一次小规模搜索。同一份配置在测试环境跑通,不代表线上没事,两边的默认值经常不一样。

作者 9823189