RAG开发中,如何用Milvus 2.5 BM25算法实现混合搜索

978adb9df7fb17d0fbb6e903f1cd2edf.png

93e94e828957d084a6757e1ea7266c0a.png

01.

背景

混合搜索(Hybrid Search)作为RAG应用中Retrieve重要的一环,通常指的是将向量搜索与基于关键词的搜索(全文检索)相结合,并使用RRF算法合并、并重排两种不同检索的结果,最终来提高数据的召回率。全文检索与语义检索不是非此即彼的关系。我们需要同时兼顾语义理解和精确的关键字匹配。比如学术论文的写作中,用户不仅希望在搜索结果看到与搜索查询相关的概念,同时也希望保留查询中使用的原始信息返回搜索结果,比如基于一些特殊术语和名称。因此,许多搜索应用正在采用混合搜索方法,结合两种方法的优势,以平衡灵活的语义相关性和可预测的精确关键字匹配。

从 Milvus 2.4 版本开始,我们引入了多向量搜索和执行混合搜索(多向量搜索)的能力。混合搜索允许用户同时搜索跨多个向量列的内容。这个功能使得可以结合多模态搜索、混合稀疏和全文关键词搜索、密集向量搜索以及混合密集和全文搜索,提供多样且灵活的搜索功能,增强了我们的向量相似性搜索和数据分析。

02.

Milvus BM25

在最新的Milvus 2.5里,我们带来了“全新”的全文检索能力

  • 对于全文检索基于的 BM25 算法,我们采用的是 Sparse-BM25,基于 Sparse Vector 实现的 BM25 在存储效率、检索性能上都打开了更多的空间,同时也融合在了 Milvus 以向量为核心检索范式的产品理念里;

  • 同时引入了原始文本插入和查询的能力,不需要用户手动将文本转成 Sparse Vector,这使得 Milvus 朝着非结构化数据处理的方向迈进了一步。

详情请参见 Milvus 2.5:全文检索上线,标量过滤提速,易用性再突破

Sparse-BM25 其原理类似 Elasticsearch 和其他全文搜索系统中常用的BM25算法,但针对稀疏向量设计,可以实现相同效果的全文搜索功能。

  • 具有数据剪枝功能的高效检索算法:通过剪枝来丢弃搜索查询中的低值稀疏向量,向量数据库可以显著减小索引大小并以最小的质量损失达成最优的性能。

  • 带来进一步的性能优化:将词频表示为稀疏向量而不是倒排索引,可以实现其他基于向量的优化。比如:用图索引替代暴力扫描,实现更有效的搜索;乘积量化(PQ)/标量量化(SQ),进一步减少内存占用。

详情请参见 Elasticsearch vs 向量数据库:寻找最佳混合检索方案

03.

Milvus BM25 Hybrid Search

1. 首先,准备数据和问题,数据来自Milvus 2.5 release notes,且通过llama-index的SentenceWindowNodeParser对于数据进行分块处理。

!wget https://raw.githubusercontent.com/milvus-io/milvus-docs/v2.5.x/site/en/release_notes.md -O milvus_2_5.mddocuments = SimpleDirectoryReader(input_files=["./milvus_2_5.md"]
).load_data()# Create the sentence window node parser 
node_parser = SentenceWindowNodeParser.from_defaults(window_size=3,window_metadata_key="window",original_text_metadata_key="original_text",
)# Extract nodes from documents
nodes = node_parser.get_nodes_from_documents(documents)# query question
query = "What are the key features in milvus 2.5?"

2. 其次,创建collection的schema以及索引,其中原始文本数据存于text列,而Sparse-BM25数据存于sparse_bm25列,这里需要通过转换Function来实现

bm25_function = Function(name="bm25",function_type=FunctionType.BM25,input_field_names=["text"],output_field_names="sparse_bm25",)
schema = MilvusClient.create_schema(auto_id=False,enable_dynamic_field=True,
)# Add fields to schema
schema.add_field(field_name="id", datatype=DataType.INT64, is_primary=True)
schema.add_field(field_name="text", datatype=DataType.VARCHAR, max_length=512, enable_analyzer=True)
schema.add_field(field_name="sparse_bm25", datatype=DataType.SPARSE_FLOAT_VECTOR)
schema.add_field(field_name="dense", datatype=DataType.FLOAT_VECTOR, dim=dense_dim)bm25_function = Function(name="bm25",function_type=FunctionType.BM25,input_field_names=["text"],output_field_names="sparse_bm25",)
schema.add_function(bm25_function)index_params = client.prepare_index_params()# Add indexes
index_params.add_index(field_name="dense",index_name="dense_index",index_type="IVF_FLAT",metric_type="IP",params={"nlist": 128},
)index_params.add_index(field_name="sparse_bm25",index_name="sparse_bm25_index",index_type="SPARSE_WAND", metric_type="BM25"
)# Create collection
client.create_collection(collection_name=collection_name,schema=schema,index_params=index_params
)

3. 然后,把数据进行Embedding之后,插入到Collection里,这里Embedding采用的是 OpenAI的 text-embedding-3-large

def gen_embedding(docs):model_name = "text-embedding-3-large"openai_ef = model.dense.OpenAIEmbeddingFunction(model_name=model_name, api_key=os.environ["OPENAI_API_KEY"])return openai_ef.encode_documents(docs)docs_embeddings = gen_embedding(docs)
query_embeddings = gen_embedding([query])# Assemble data
data = [{"id": idx, "dense": docs_embeddings[idx].data, "text": doc}for idx, doc in enumerate(docs)
]# Insert data
res = client.insert(collection_name=collection_name,data=data
)

4. 最后,进行查询测试

4.1. 我们先测试下普通查询

search_params = {"metric_type": "IP","params": {"nprobe": 10}}res = client.search(collection_name=collection_name,data=[query_embeddings[0]],anns_field="dense",limit=5,search_params=search_params,output_fields=["text"]
)

查询结果

TopK results:0
0  Enhancements in cluster management, indexing, and data handling introduce new levels of flexibil...
1  With this release, Milvus integrates powerful new features like term-based search, clustering co...
2  Milvus 2.5 introduces a built-in Cluster Management WebUI, reducing system maintenance difficult...
3  \n\nv2.5.0-beta\n\nRelease date: November 26, 2024\n\n| Milvus version | Python SDK version | No...
4                                                 \n\nRelease Notes\n\nFind out what’s new in Milvus!

从查询结果来看,最后一条召回内容与查询问题相关度不大。

4.2. 然后进行Hybrid Search。定义向量搜索和Sparse-BM25搜索

k=5 # get the top 5 docs related to the querysearch_params_dense: { "metric_type": "IP", "params": {"nprobe": 10}}
request_dense = AnnSearchRequest([query_embeddings[0].data], "dense", search_params_dense, limit=k)search_params_bm25 = {"metric_type": "BM25"}
request_bm25 = AnnSearchRequest([query], "sparse_bm25", search_params_bm25, limit=k)reqs = [request_dense, request_bm25]

这里使用RRFRanker来进行Hybrid Search

ranker = RRFRanker(100)res = client.hybrid_search(collection_name=collection_name,reqs=reqs,ranker=ranker,limit=5,output_fields=["text"]
)
for hits in res:print("TopK results:")for hit in hits:print(hit)

查询结果:

TopK results:0
0  \n\nv2.5.0-beta\n\nRelease date: November 26, 2024\n\n| Milvus version | Python SDK version | No...
1  Enhancements in cluster management, indexing, and data handling introduce new levels of flexibil...
2  This feature is disabled by default in Milvus 2.5 and will be officially available in version 3....
3  With this release, Milvus integrates powerful new features like term-based search, clustering co...
4  Powered by Tantivy, Milvus 2.5 has built-in analyzers and sparse vector extraction, extending th...

从结果来看,基于Sparse-BM25的Hybrid Search可以准确找到与查询相关的内容。相对于普通查询,召回的内容准确度更大。

04.

总结

本文讲述了Milvus 2.5中引入的Sparse-BM25基础原理,以及如何利用BM25算法实现RAG开发中的Hybrid Search(混合搜索)实践。通过引入Sparse-BM25算法,Milvus能够在稀疏向量上执行高效的全文检索,并与密集向量搜索相结合,提升检索的召回率和精确度。

参考文档:

  • https://zilliz.com/blog/hybrid-search-with-milvus

  • https://milvus.io/docs/multi-vector-search.md

代码可通过链接获取:https://pan.baidu.com/s/1eArbrvqmkYTJ-DS8eDkbJA?pwd=1234 提取码: 1234

作者介绍

d3446255d7bd198ab10a167015641d96.jpeg

Zilliz 黄金写手:臧伟

推荐阅读

fb3d90dd4d68a73eb74d7ef3ac3a8971.png

560e5f378e592e8c1a4d7e8cdf0d3349.png

64743bc81432c36f6df5bf76c086a30d.png

802e235a127400cabe4a6a33fdc11a74.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/493735.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

简洁IIC协议讲述

目录 一:首先,IIC传输是在2条线上传输的。 二:时钟信号的频率和占空比解释(可以看作PWM波形) 三:传输信号的流程图(起始和终止信号都是由主机(我)控制) 四:开始信号和…

spring学习(spring-DI(setter注入、构造器注入、自动装配方式))

目录 一、spring容器(DI)依赖注入的几种实现方式。 (1)手动注入。 (2)自动注入。 (3)图解如下。 二、spring容器实现(DI)依赖注入-setter注入方式。 (1)setter注入方式的基本介绍。 …

AI的进阶之路:从机器学习到深度学习的演变(三)

(承接上集:AI的进阶之路:从机器学习到深度学习的演变(二)) 四、深度学习(DL):机器学习的革命性突破 深度学习(DL)作为机器学习的一个重要分支&am…

什么?Flutter 可能会被 SwiftUI/ArkUI 化?全新的 Flutter Roadmap

在刚刚过去的 FlutterInProduction 活动里,Flutter 官方除了介绍「历史进程」和「用户案例」之外,也着重提及了未来相关的 roadmap ,其中就有 3.27 里的 Swift Package Manager 、 Widget 实时预览 和 Dart 与 native 平台原生语言直接互操作…

mysql的事务控制和数据库的备份和恢复

事务控制语句 行锁和死锁 行锁 两个客户端同时对同一索引行进行操作 客户端1正常运行 客户端2想修改,被锁行 除非将事务提交才能继续运行 死锁 客户端1删除第5行 客户端2设置第1行为排他锁 客户端1删除行1被锁 客户端2更新行5被锁 如何避免死锁 mysql的备份和还…

基于 uniapp 开发 android 播放 webrtc 流

一、播放rtsp协议流 如果 webrtc 流以 rtsp 协议返回&#xff0c;流地址如&#xff1a;rtsp://127.0.0.1:5115/session.mpg&#xff0c;uniapp的 <video> 编译到android上直接就能播放&#xff0c;但通常会有2-3秒的延迟。 二、播放webrtc协议流 如果 webrtc 流以 webrt…

(OCPP服务器)SteVe编译搭建全过程

注意&#xff1a;建议使用3.6.0&#xff0c;我升级到3.7.1&#xff0c;并没有多什么新功能&#xff0c;反而电表的实时数据只能看到累计电能了&#xff0c;我回退了就正常&#xff0c;数据库是兼容的&#xff0c;java版本换位java11&#xff0c;其他不变就好 背景&#xff1a;…

C++ OpenGL学习笔记(2、绘制橙色三角形绘制、绿色随时间变化的三角形绘制)

相关文章链接 C OpenGL学习笔记&#xff08;1、Hello World空窗口程序&#xff09; 目录 绘制橙色三角形绘制1、主要修改内容有&#xff1a;1.1、在主程序的基础上增加如下3个函数1.2、另外在主程序外面新增3个全局变量1.3、编写两个shader程序文件 2、initModel()函数3、initS…

数据结构大作业——家谱管理系统(超详细!完整代码!)

目录 设计思路&#xff1a; 一、项目背景 二、功能分析 查询功能流程图&#xff1a; 管理功能流程图&#xff1a; 三、设计 四、实现 代码实现&#xff1a; 头文件 结构体 函数声明及定义 创建家谱树头结点 绘制家谱树&#xff08;打印&#xff09; 建立右兄弟…

Leaflet的zoom层级-天地图层级之间的关系

Leaflet的tileLayer请求地址分析 天地图的瓦片服务地址&#xff1a; http://t1.tianditu.com/img_c/wmts?layerimg&styledefault&tilematrixsetc&ServiceWMTS&RequestGetTile&Version1.0.0&Formattiles&TileMatrix{z}&TileCol{x}&TileRo…

常用的JVM启动参数有哪些?

大家好&#xff0c;我是锋哥。今天分享关于【常用的JVM启动参数有哪些?】面试题。希望对大家有帮助&#xff1b; 常用的JVM启动参数有哪些? 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 JVM启动参数用于配置Java虚拟机&#xff08;JVM&#xff09;的运行时行为…

CTF学习24.12.21[隐写术进阶]

MISC08[隐写术进阶] PDF文件隐写 隐写的加密&#xff1a;wbStego4open工具的下载和使用 1.wbStego4open介绍&#xff1a; wbStego4open是一个隐写开源工具&#xff0c;它支持Windows和Linux平台&#xff0c;可以使用wbStego4open把文件隐藏到BMP、TXT、HTM和PDF文件中&#…

电脑丢失dll文件一键修复的多种方法分析,电脑故障修复攻略

电脑在使用过程中&#xff0c;有时会遇到DLL文件丢失的情况&#xff0c;这可能导致软件无法正常运行或系统出现故障。当面对这种状况时&#xff0c;不必过于慌张&#xff0c;因为有多种有效的修复方法可供选择。下面我们一起来看看电脑丢失dll文件的多种解决方法。 一.了解什么…

Redis篇--常见问题篇5--热Key(Hot Key,什么是热Key,服务降级,一致性哈希)

热key&#xff08;Hot Key&#xff09;是指在Redis中访问频率非常高、读写请求非常频繁的键。由于Redis是单线程模型&#xff0c;所有操作都是串行执行的&#xff0c;Hot Key处理不好&#xff0c;会产生一些问题。比如短时间的群蜂效应&#xff08;群蜂请求&#xff09;&#x…

VSCode:Markdown插件安装使用 -- 最简洁的VSCode中Markdown插件安装使用

VSCode&#xff1a;Markdown插件安装使用 1.安装Marktext2.使用Marktext 本文&#xff0c;将在Visual Studio Code中&#xff0c;安装和使用Markdown插件&#xff0c;以Marktext插件为例。 1.安装Marktext 打开VSCode&#xff0c;侧边栏中找到扩展模块(或CtrlShiftX快捷键)&am…

SpringBoot+Vue3实现阿里云视频点播 实现教育网站 在上面上传对应的视频,用户开会员以后才能查看视频

要使用阿里云视频点播&#xff08;VOD&#xff09;实现一个教育网站&#xff0c;其中用户需要成为会员后才能查看视频&#xff0c;这个过程包括上传视频、设置权限控制、构建前端播放页面以及确保只有付费会员可以访问视频内容。 1. 视频上传与管理 创建阿里云账号&#xff…

深度学习——现代卷积神经网络(七)

深度卷积神经网络 学习表征 观察图像特征的提取⽅法。在合理地复杂性前提下&#xff0c;特征应该由多个共同学习的神经⽹络层组成&#xff0c;每个层都有可学习的参数。 当年缺少数据和硬件支持 AlexNet AlexNet⽐相对较⼩的LeNet5要深得多。 AlexNet由⼋层组成&#xff1a…

免费送源码:Java+ssm++MVC+HTML+CSS+MySQL springboot 社区医院信息管理系统的设计与实现 计算机毕业设计原创定制

摘 要 随着互联网趋势的到来&#xff0c;各行各业都在考虑利用互联网将自己推广出去&#xff0c;最好方式就是建立自己的互联网系统&#xff0c;并对其进行维护和管理。在现实运用中&#xff0c;应用软件的工作规则和开发步骤&#xff0c;采用Java技术建设社区医院信息管理系统…

Marin说PCB之POC电路layout设计仿真案例---06

我们书接上回啊&#xff0c;对于上面的出现原因我这个美女同事安娜说会不会你把POC电感下面的相邻两层的CUT_OUT的尺寸再去加大一些会不会变得更好呢&#xff1f;这个难道说是真的有用吗&#xff1f;小编我先自己算一卦看下结果。 本期文章我们就接着验证通过改善我们的单板POC…

简洁清爽epub 阅读器

Jane Reader 是一款现代化的 epub 阅读器&#xff0c;有简洁清爽&#xff0c;支持自动多栏、多主题、直排模式等&#xff0c;开发者想要提供「媲美于印刷书籍的阅读体验」 Jane Reader 目前提供以下功能&#xff1a; 支持 epub 电子书格式&#xff1b; 内置书库&#xff1b; 支…