分布式密集检索系统提供强大的语义搜索能力,但它们并非没有局限。密集检索器有时难以处理精确的关键词匹配,特别是对于在嵌入 (embedding)模型训练期间未充分表示的特定标识符、代码或词汇表 (vocabulary)外术语。反之,BM25或TF-IDF等传统稀疏检索方法擅长词汇匹配,但缺乏足够的语义理解,无法捕获同义词或相关思想。混合检索作为一种颇具吸引力的策略浮现,它采用两种方法的互补优势,提供了更全面的、通常也更准确的检索结果,尤其是在大规模应用时。具体内容包括专为大规模分布式RAG设计的混合检索系统的架构、实现和优化。
混合检索的根本原则是合并来自两种不同类型检索器的结果:
- 密集检索器:这些系统通常由向量 (vector)数据库驱动,使用密集向量 (dense vector)嵌入来表示文本的语义。它们擅长寻找与查询相似的文档,即使这些文档不共享精确的关键词。
- 稀疏检索器:这些系统通常基于BM25等算法,并使用倒排索引实现(例如,在Elasticsearch或OpenSearch等系统中)。它们根据共享关键词及其统计重要性(如词频和逆文档频率)来匹配文档。
快速比较突出显示了它们的互补特性:
| 特性 |
密集检索器(向量搜索) |
稀疏检索器(例如BM25) |
| 匹配方式 |
语义 |
词汇(关键词) |
| 优点 |
同义词、思想、上下文 (context) |
精确性、特定术语、代码 |
| 缺点 |
可能遗漏特定关键词、模糊性 |
字面匹配、语义差异 |
| 表示形式 |
密集向量 |
倒排索引、词项权重 (weight) |
| 查询适用性 |
自然语言、详细问题 |
基于关键词、已知项搜索 |
合并:整合密集与稀疏结果
混合检索中的重要步骤是合并从密集和稀疏检索器获得的排序列表。目标是生成一个受益于两种信号的单一重新排序列表。有几种常见的合并技术:
加权和组合
这是一种直接的方法,其中来自密集(Sdense)和稀疏(Ssparse)检索器的得分进行线性组合。每个文档d获得一个混合得分:
Shybrid(d)=α⋅Sdense(d)+(1−α)⋅Ssparse(d)
这里,α是介于0和1之间的权重 (weight)因子,它决定了密集得分与稀疏得分的相对重要性。
加权和的一个重大挑战是,来自密集(例如,余弦相似度,通常在[−1,1]或[0,1]范围内)和稀疏检索器(例如,BM25得分,通常为正且无上限)的得分通常在不同的尺度上,并具有不同的分布。有效使用需要先进行得分归一化 (normalization)(例如,应用于每个检索列表中的得分的最小-最大归一化、Z-分数归一化),然后才能应用加权和。调整α通常需要实验和A/B测试。
倒数排序融合 (RRF)
RRF提供了一种参数 (parameter)较少的替代方法,它通过完全依赖文档在每个列表中的排序来避免得分归一化问题。文档d的RRF得分计算如下:
SRRF(d)=∑i∈{密集, 稀疏}k+ranki(d)1
其中ranki(d)是文档d在系统i检索的列表中的排序,而k是一个常数(通常设为60,但可以调整)。未出现在列表中的文档在该列表中被视为具有无限排序(对总和贡献0)。最终列表按SRRF排序。RRF因其简单性和无需得分缩放的有效性而常被选用。
学习排序 (LTR)
对于更复杂的合并,可以训练机器学习 (machine learning)模型(学习排序模型)来组合来自密集和稀疏检索器的特征,以及其他文档和查询特征,以预测最佳排序。虽然LTR方法可能提供最佳质量,但在特征工程、训练数据收集和模型部署方面引入了相当大的复杂性。
大规模混合检索的架构设计
在分布式环境中,混合检索系统通常包含一个编排器,它将用户查询分派到独立的、可独立扩展的密集和稀疏检索集群。然后将结果返回给一个合并组件。
一种常见的分布式混合检索架构。编排器将查询并行化到专门的检索后端,然后合并引擎组合它们的输出。
此架构的主要考虑事项:
- 并行执行:对密集和稀疏系统的查询应并行执行,以最小化延迟。
- 独立扩展:密集检索集群(例如,分片向量 (vector)数据库)和稀疏检索集群(例如,Elasticsearch、OpenSearch)可以根据其特定的负载特性独立扩展。
- 预设K值:编排器通常从每个检索器请求一定数量的顶部结果(Kd来自密集, Ks来自稀疏)。这些K值是重要的调优参数 (parameter),平衡了召回率与合并的计算成本。
- 合并服务:合并引擎可以是应用所选合并逻辑的无状态服务。
规模扩展与运行挑战
在大规模应用中实现混合检索带来了若干挑战:
- 延迟:总延迟是响应最慢的检索器的响应时间与合并处理时间之和。对两种检索路径的积极优化和高效的合并算法是必要的。对单个检索调用的超时和熔断器可以防止级联故障。
- 吞吐量 (throughput):系统必须处理两个检索后端和合并服务上的组合负载。每个组件都需要充分的资源配置。
- 数据一致性:保持密集向量 (vector) (dense vector)索引和稀疏倒排索引与源数据同步是一项重要的运行任务。底层文档的更改必须反映在这两个系统中,理想情况下通过变更数据捕获(CDC)管道实现(如第4章所述)。
- 资源管理:操作和维护两个不同且复杂的分布式系统(向量数据库集群和搜索引擎集群)会增加运行开销。
- 得分归一化 (normalization)复杂性(对于加权和):如前所述,在异构系统中实现有意义的得分归一化可能很困难。向量数据库中的分片策略或BM25中不同的得分配置等因素可能导致得分分布在分片或索引之间存在差异,从而使全局归一化变得复杂。
进阶混合检索技术
有几种进阶技术可以增强混合检索系统:
- 自适应加权或选择:系统可以动态调整,而不是采用固定的α(在加权和中)或总是使用两个检索器。查询分析可以确定查询是更偏向关键词(有利于稀疏结果)还是更偏向语义(有利于密集结果)。例如,带有特定产品代码的短查询可能会高度侧重,甚至单独使用稀疏检索器。
- 稀疏嵌入 (embedding)(例如,SPLADE, uniCOIL, BGE-M3):这些模型学习文本的稀疏向量 (vector)表示,其中只有少数维度具有非零值。这些“学习到的稀疏”表示可以在传统倒排索引中高效地建立索引,并且通常优于BM25,同时保留其效率和精确匹配能力。它们有效地提供了一个更具语义意识的稀疏检索组件。
- 多阶段检索:混合检索可以在多阶段检索管道中作为高效的第一阶段。从合并后的混合列表中选出的前N个文档随后被传递给计算量更大的重排序器,例如交叉编码器模型,后者可以提供更细粒度的相关性评分。
- 为混合联动微调 (fine-tuning)密集模型:如果对密集模型进行微调,则可以设计训练数据和目标,使其与现有稀疏系统更具互补性,可能优化多样性或稀疏系统遗漏的特定类型的信息。
实践实施考量
构建混合检索系统时,请记住以下几点:
- 选择Kd和Ks:在合并之前从每个检索器获取的结果数量是一个权衡。Kd和Ks值较小意味着更快的合并,但可能会遗漏一个检索器排序较低但另一个检索器排序较高的相关文档。较大的值增加了找到所有相关文档的机会,但增加了合并开销。这通常需要凭经验进行调整。
- 文档分块的影响:文档分块策略(第4章讨论)对密集和稀疏检索都有影响。为密集检索的语义连贯性优化的分块,可能不适合稀疏检索的关键词分布。如果性能差异过大,这可能需要仔细考量,甚至采用不同的分块/索引策略。
- 故障处理:设计时应考虑弹性。如果一个检索器组件发生故障或超时,系统应优雅地降级,例如返回可用检索器的结果或显示结果质量降低。
混合检索无疑为您的检索架构增加了复杂性。然而,对于处理大规模多样化数据集上多种用户查询的应用,检索质量的改进,特别是捕获关键词驱动和语义意图的能力的增强,通常能为此项投资带来可观的回报。实施混合检索的决定应源于对系统当前检索局限性的清晰了解,以及对潜在收益的数据驱动评估。