多向量检索:lanchain,dashvector,milvus,vestorsearch,MUVERA
一、多向量检索的核心价值:让文档拥有 “多面索引”
为什么单向量检索会遇到瓶颈?
想象图书馆里每本书只能有一个索引标签,当我们想找 “人工智能在医疗领域的应用” 时,可能错过标题为 “机器学习诊断案例” 的书籍。
传统单向量检索就像这种单一标签系统,而多向量检索允许为每个文档创建多个 “语义标签”,比如将一本书同时索引到 “人工智能”、“医疗”、“机器学习” 等多个维度。
1 LangChain 中MultiVectorRetriever
ParentDocumentRetriever 文档拆分策略:
- 当处理长文档时,直接嵌入整个文档会导致语义模糊,而拆分成小片段又会丢失完整上下文。
- 处理方式:将文档拆分为子片段嵌入索引,但检索时返回完整父文档。就像将百科全书拆成词条索引,但用户查询时获得完整章节。
for i, doc in enumerate(docs):_id = doc_ids[i]# 拆分子片段_sub_docs = child_text_splitter.split_documents([doc])for _doc in _sub_docs:_doc.metadata[id_key] = _id # 关键:子片段关联父文档IDsub_docs.extend(_sub_docs)# 索引子片段和父文档
retriever.vectorstore.add_documents(sub_docs)
retriever.docstore.mset(list(zip(doc_ids, docs)))
高级检索策略:MMR 算法优化结果排序
- 当文档拆分后,我们还可以通过 Max Marginal Relevance(MMR)算法优化检索结果,平衡相关性和多样性:
from langchain.retrievers.multi_vector import SearchType
retriever.search_type = SearchType.mmr # 切换为MMR检索
len(retriever.invoke("justice breyer")[0].page_content) # 仍返回完整父文档
生成摘要文档索引
批量生成假设性问题
hypothetical_questions = chain.batch(docs, {“max_concurrency”: 5})
在实际应用中,我们可以结合多种向量类型:将文档拆分向量、摘要向量、假设性问题向量同时索引,形成 “多维度语义网络”。
retriever.vectorstore.add_documents(sub_docs) # 子片段向量
retriever.vectorstore.add_documents(summary_docs) # 摘要向量
retriever.vectorstore.add_documents(question_docs) # 问题向量
性能优化关键点
chunk_size 参数调优:拆分片段过小将丢失上下文(建议 200-500 字)
向量存储选择:Chroma 适合原型开发,生产环境推荐 Pinecone 等分布式存储
LLM 选择:摘要和问题生成可选用轻量级模型(如 gpt-3.5-turbo)
批量处理:使用 chain.batch () 批量生成摘要 / 问题,提升效率 50%+
2 DashVector
链接:
collection = client.get(name='multi_vector_demo')
docs = []
for i in range(10):docs.append(Doc(id=str(i),vectors={"title": np.random.random(4),"content": np.random.random(6)},))
ret = collection.insert(docs)
print(ret)
3 milvus
链接:
Milvus 允许在多个向量场上进行搜索,同时进行多个近似近邻(ANN)搜索,从而支持这种搜索。
如果要同时搜索文本和图像、描述同一对象的多个文本字段或密集和稀疏向量以提高搜索质量,多向量混合搜索尤其有用。
4 VectorSearch
链接
它结合了多种索引技术的优势,例如用于分布式索引的 FAISS 和用于分层搜索优化的 HNSWlib。
这种方法能够跨多台机器无缝管理大规模数据集。
此外,它还引入了用于多向量搜索的新算法,将文档编码为捕捉不同数据片段之间语义关系的高维嵌入。
将这些嵌入集成到向量数据库中,使系统能够根据用户查询高效地检索相关文档。
对现实世界数据集的实验表明,VectorSearch 的性能优于现有系统,在 1024 的索引维度下,召回率为 76.62%,准确率为 98.68%。
5 MUVERA
论文:MUVERA: Multi-Vector Retrieval via Fixed Dimensional Encodings
多向量检索的常用方法是多阶段pipeline,
首先使用SV MIPS找到每个查询标记的最相似文档标记,然后用Chamfer相似性重新评分。
ColBERTv2和PLAID基于此方法,增加了中间阶段的剪枝。
然而,这种方法可能无法找到真正的MV最近邻,且过程昂贵、复杂且对参数设置高度敏感。
为了解决这些挑战并缩小SV和MV检索之间的差距,我们提出一种基于轻量级且可证明正确的单一向量MIPS简化的多向量检索机制。
- 将多向量集转换为单个固定维度向量,使得点积近似多向量相似性。
实验表明,基于_{fde}点积的检索显著优于单一向量启发式。在BEIR IR数据集上,
的平均召回率比PLAID高10%,平均延迟低90%,并整合了乘积量化技术,显著减小了内存占用
5.1 Chamfer相似度和多向量检索
距离度量-Chamfer距离、Fréchet距离
为了提高检索系统的可扩展性,这必须在显著快于逐一计算 n个相似度 "CH(Q, Pi)"的时间复杂度下实现。
5.2 早期的多向量检索系统
如ColBERT,优化了SV启发式,通过查询每个查询词的MIPS索引找到初始候选集 P。
在ColBERTv2中,文档词元嵌入首先通过k-means聚类,使用聚类质心进行第一轮评分。
PLAID进一步优化了SV启发式,采用四阶段pipeline逐步修剪候选集。
DESSERT提出了一种基于LSH的替代方法,证明其算法可以在时间 Õ(n|Q|T)内恢复 eps-近似最近邻,其中T是任何查询词最多相似的文档词元数量。
我们的算法在相同时间内恢复 eps-近似最近邻且运行时间更短。
实验中,DESSERT比PLAID快2到5倍但召回率较低,而我们以较低延迟匹配甚至超过PLAID的召回率。DESSERT仍然采用基于个体查询词元嵌入的k-means聚类进行初始过滤,未能真正避免上述SV启发式的局限性。
5.3 固定维度编码Fixed Dimensional Encodings
生成FDEs的过程,类似于概率树嵌入技术,可以将向量转换为单个向量。例如,已用于将Earth Mover’s Distance嵌入到L-1度量中,以及将欧几里得最小生成树的权重嵌入到汉明度量中。由于处理内积而非L-p距离,因此需要不同的转换方法。
为了清晰起见,我们用归一化的Chamfer相似性来表述我们的结果,
我们的主要结果是FDEs给出了eps-加性近似的Chamfer相似性。证明利用LSH(SimHash)的性质来展示,对于每个查询点q,点q映射到一个簇A,该簇仅包含到q最近的点(在eps范围内)的点p;至少一个点与q相撞,使用了fill_empty_partitions方法。
FDE质量与维度的关系
在图中,我们评估FDE检索质量相对于Chamfer相似性(而不是标记的地面真实数据)。我们计算1Recall@N,即查询中Chamfer 1-最近邻在FED点积中排名前N的比例。我们选择从上述网格搜索中为各维度选择的帕累托最优的FDE参数。我们发现具有较少维度的FDE在多个BEIR检索数据集上实现了显著的召回。例如,在MS MARCO(其中
d. mavg ≈10K))我们使用dfde = 5120仅检索75个候选者实现了95%的召回。
单向量启发式检索与FDE检索结果
如图所示。我们为各维度构建一次FDE,使用Rreps=40, ksim=6, dproj=d=128, 然后应用最终投影减少到目标维度。
在MS MARCO上,即使4096维的FDE与去重后的SV启发式的召回率相同,但检索的候选者数量仅为1.75-3.75倍(我们的Recall@N与去重后的SV启发式的Recall@1.755-3.75N相同),
并且与非去重的SV启发式相比分别少10.5-15倍。
对于我们的10240维FED,这些数字分别为2.6-5倍和20-22.5倍。
例如,当dfde=10240和60候选者时我们达到80%的召回率,而dfde=4096和80候选者时同样达到80%的召回率,但SV启发式分别需要300和1200个候选者(去重和非去重分别)。见表中的进一步比较。