Late Chunking×Milvus:如何提高RAG准确率

a08e7d6538cf8e9dcd3e7b41a8a4f65a.png

bc6b0a51ecec2d2e6a695808628b856d.png

01.

背景

在RAG应用开发中,第一步就是对于文档进行chunking(分块),高效的文档分块,可以有效的提高后续的召回内容的准确性。而对于如何高效的分块是个讨论的热点,有诸如固定大小分块,随机大小分块,滑动窗口重新采样,递归分块,基于内容语义分块等方法。而Jina AI提出的Late Chunking从另外一个角度来处理分块问题,让我们来具体看看。

02.

Late Chunking是什么

传统的分块在处理长文档时可能会丢失文档中长距离的上下文依赖关系,这对于信息检索和理解是一大隐患。即当关键信息散落在多个文本块中,脱离上下文的文本分块片段很可能失去其原有的意义,导致后续的召回效果比较差。

以Milvus 2.4.13 release note为例,假如分为如下两个文档块,如果我们要查询Milvus 2.4.13有哪些新功能?,直接相关内容在分块2里,而Milvus版本信息在分块1里,此时,Embedding 模型很难将这些指代正确链接到实体,从而产生质量不高的Embedding。

0ba5b5387e94376a38b9856e89cfd366.png

由于功能描述与版本信息不在同一个分块里,且缺乏更大的上下文文档,LLM 难以解决这样的关联问题。尽管有一些启发式算法试图缓解这一问题,如滑动窗口重新采样、重叠的上下文窗口长度以及多次文档扫描等,然而,像所有启发式算法一样,这些方法时灵时不灵,它们可能在某些情况下有效,但是没有理论上的保证。

传统的分块采用一种预先分块的策略,即先分块,再过 Embedding 模型。首先依据句子、段落或预设的最大长度等参数对文本进行切割。然后Embedding 模型会对这些分块逐一进行处理,通过平均池化等方法,将 token 级的 Embedding 聚合成单一的块 Embedding 向量。而Late Chunking则是先过 Embedding 模型再分块(late的含义就是在于此,先向量化再分块),我们先将 Embedding 模型的 transformer 层应用到整个文本,为每个 token 生成一个包含丰富上下文信息的向量表示序列。然后,再对这些 token 向量序列进行平均池化,最终得到考虑了整个文本上下文的块 Embedding。

9b73787186a59c3873f5410a9afc50a7.png

(图片来源:https://jina.ai/news/late-chunking-in-long-context-embedding-models/)

Late Chunking生成的块Embedding,每个块都编码了更多的上下文信息,从而提高了编码的质量和准确性。我们可以通过支持长上下文的 Embedding 模型,如 jina-embeddings-v2-base-en,它能够处理长达8192个token 的文本(相当于 10 页 A4 纸),基本满足了大多数长文本的上下文需求。

综上所述,我们可以看到Late Chunking在RAG应用中的优势:

  • 提高准确性:通过保留上下文信息,与简单分块相比,Late Chunking为查询返回了相关度更高的内容。

  • 高效的LLM调用:Late Chunking可以减少传递给LLM的文本量,因为它返回的分块更少且相关度更高。

03.

测试Late Chunking

3.1. Late Chunking基础实现

函数sentence_chunker对于原始文档以段落进行分块,返回分块内容以及分块标记信息span_annotations(即分块的开始和结束标记)

def sentence_chunker(document, batch_size=10000):nlp = spacy.blank("en")nlp.add_pipe("sentencizer", config={"punct_chars": None})doc = nlp(document)docs = []for i in range(0, len(document), batch_size):batch = document[i : i + batch_size]docs.append(nlp(batch))doc = Doc.from_docs(docs)span_annotations = []chunks = []for i, sent in enumerate(doc.sents):span_annotations.append((sent.start, sent.end))chunks.append(sent.text)return chunks, span_annotations

函数 document_to_token_embeddings 通过模型 jinaai/jina-embeddings-v2-base-en 的模型以及tokenizer,返回整个文档的Embedding。

def document_to_token_embeddings(model, tokenizer, document, batch_size=4096):tokenized_document = tokenizer(document, return_tensors="pt")tokens = tokenized_document.tokens()outputs = []for i in range(0, len(tokens), batch_size):start = iend   = min(i + batch_size, len(tokens))batch_inputs = {k: v[:, start:end] for k, v in tokenized_document.items()}with torch.no_grad():model_output = model(**batch_inputs)outputs.append(model_output.last_hidden_state)model_output = torch.cat(outputs, dim=1)return model_output

函数 late_chunking 对整个文档的Embedding以及原始分块的标记信息span_annotations进行分块。

def late_chunking(token_embeddings, span_annotation, max_length=None):outputs = []for embeddings, annotations in zip(token_embeddings, span_annotation):if (max_length is not None):annotations = [(start, min(end, max_length - 1))for (start, end) in annotationsif start < (max_length - 1)]pooled_embeddings = []for start, end in annotations:if (end - start) >= 1:pooled_embeddings.append(embeddings[start:end].sum(dim=0) / (end - start))pooled_embeddings = [embedding.detach().cpu().numpy() for embedding in pooled_embeddings]outputs.append(pooled_embeddings)return outputs

如使用模型jinaai/jina-embeddings-v2-base-en进行Late Chunking

tokenizer = AutoTokenizer.from_pretrained('jinaai/jina-embeddings-v2-base-en', trust_remote_code=True)
model     = AutoModel.from_pretrained('jinaai/jina-embeddings-v2-base-en', trust_remote_code=True)# First chunk the text as normal, to obtain the beginning and end points of the chunks.
chunks, span_annotations = sentence_chunker(document)
# Then embed the full document.
token_embeddings = document_to_token_embeddings(model, tokenizer, document)
# Then perform the late chunking
chunk_embeddings = late_chunking(token_embeddings, [span_annotations])[0]

3.2. 与传统Embedding方法对比

我们以milvus 2.4.13 release note 这一段内容为例,

Milvus 2.4.13 introduces dynamic replica load, allowing users to adjust the number of collection replicas without needing to release and reload the collection.

This version also addresses several critical bugs related to bulk importing, expression parsing, load balancing, and failure recovery.

Additionally, significant improvements have been made to MMAP resource usage and import performance, enhancing overall system efficiency.

We highly recommend upgrading to this release for better performance and stability.

分别进行传统Embedding,即先分块,然后进行Embedding。以及Late Chunking方式Embedding,即先Embedding,然后再分块。然后,把 milvus 2.4.13 分别与这两种Embedding方式的结果进行对比

cos_sim = lambda x, y: np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))milvus_embedding = model.encode('milvus 2.4.13')for chunk, late_chunking_embedding, traditional_embedding in zip(chunks, chunk_embeddings, embeddings_traditional_chunking):print(f'similarity_late_chunking("milvus 2.4.13", "{chunk}")')print('late_chunking: ', cos_sim(milvus_embedding, late_chunking_embedding))print(f'similarity_traditional("milvus 2.4.13", "{chunk}")')print('traditional_chunking: ', cos_sim(milvus_embedding, traditional_embeddings))

从结果来看,词语 milvus 2.4.13 与分块文档Late Chunking结果相似度高于传统Embedding。原因是Late Chunking先对于全部文本段落进行Embedding,使得整个文本段落得到了 milvus 2.4.13 信息,进而在后续的文本比较中显著的提高了相似度。

similarity_late_chunking("milvus 2.4.13", "Milvus 2.4.13 introduces dynamic replica load, allowing users to adjust the number of collection replicas without needing to release and reload the collection.")
late_chunking: 0.8785206
similarity_traditional("milvus 2.4.13", "Milvus 2.4.13 introduces dynamic replica load, allowing users to adjust the number of collection replicas without needing to release and reload the collection.")
traditional_chunking: 0.8354263similarity_late_chunking("milvus 2.4.13", "This version also addresses several critical bugs related to bulk importing, expression parsing, load balancing, and failure recovery.")
late_chunking: 0.84828955
similarity_traditional("milvus 2.4.13", "This version also addresses several critical bugs related to bulk importing, expression parsing, load balancing, and failure recovery.")
traditional_chunking: 0.7222632similarity_late_chunking("milvus 2.4.13", "Additionally, significant improvements have been made to MMAP resource usage and import performance, enhancing overall system efficiency.")
late_chunking: 0.84942204
similarity_traditional("milvus 2.4.13", "Additionally, significant improvements have been made to MMAP resource usage and import performance, enhancing overall system efficiency.")
traditional_chunking: 0.6907381similarity_late_chunking("milvus 2.4.13", "We highly recommend upgrading to this release for better performance and stability.")
late_chunking: 0.85431844
similarity_traditional("milvus 2.4.13", "We highly recommend upgrading to this release for better performance and stability.")
traditional_chunking: 0.71859795

3.3. Milvus中测试Late Chunking

导入Late Chunking数据到Milvus

batch_data=[]
for i in range(len(chunks)):data = {"content": chunks[i],"embedding": chunk_embeddings[i].tolist(),}batch_data.append(data)res = client.insert(collection_name=collection,data=batch_data,
)

查询测试

我们定义cosine相似度查询方法,以及使用Milvus原生查询方法分别对于Late Chunking进行查询。

def late_chunking_query_by_milvus(query, top_k = 3):query_vector = model(**tokenizer(query, return_tensors="pt")).last_hidden_state.mean(1).detach().cpu().numpy().flatten()res = client.search(collection_name=collection,data=[query_vector.tolist()],limit=top_k,output_fields=["id", "content"],)return [item.get("entity").get("content") for items in res for item in items]def late_chunking_query_by_cosine_sim(query, k = 3):cos_sim = lambda x, y: np.dot(x, y) / (np.linalg.norm(x) * np.linalg.norm(y))query_vector = model(**tokenizer(query, return_tensors="pt")).last_hidden_state.mean(1).detach().cpu().numpy().flatten()results = np.empty(len(chunk_embeddings))for i, (chunk, embedding) in enumerate(zip(chunks, chunk_embeddings)):results[i] = cos_sim(query_vector, embedding)results_order = results.argsort()[::-1]return np.array(chunks)[results_order].tolist()[:k]

从结果来看,两个方法返回内容是一致的,这表明Milvus中对于Late Chunking查询结果是准确。

> late_chunking_query_by_milvus("What are new features in milvus 2.4.13", 3)['\n\n### Features\n\n- Dynamic replica adjustment for loaded collections ([#36417](https://github.com/milvus-io/milvus/pull/36417))\n- Sparse vector MMAP in growing segment types ([#36565](https://github.com/milvus-io/milvus/pull/36565))...
> late_chunking_query_by_cosine_sim("What are new features in milvus 2.4.13", 3)['\n\n### Features\n\n- Dynamic replica adjustment for loaded collections ([#36417](https://github.com/milvus-io/milvus/pull/36417))\n- Sparse vector MMAP in growing segment types ([#36565](https://github.com/milvus-io/milvus/pull/36565))...

04.

总结

我们介绍了Late Chunking产生的背景,基本概念以及基础实现,然后通过在Mivlus测试发现,Late Chunking效果不错。总体来看,Late Chunking在准确性、效率和易于实施方面的结合,使其成为RAG应用的一个有效的方法。

参考文档:

  • https://stackoverflow.blog/2024/06/06/breaking-up-is-hard-to-do-chunking-in-rag-applications

  • https://jina.ai/news/late-chunking-in-long-context-embedding-models/

  • https://jina.ai/news/what-late-chunking-really-is-and-what-its-not-part-ii/

示例代码:

链接: https://pan.baidu.com/s/1cYNfZTTXd7RwjnjPFylReg?pwd=1234 提取码: 1234

代码在 aws g4dn.xlarge 机器上运行

作者介绍

3c2c4e21c504e468d0b29116615688df.jpeg

Milvus 黄金写手:臧伟


2024年非结构化数据峰会的报名通道现已开启!

作为备受瞩目的年度重磅盛会,本次大会以“数绘万象,智联八方”为主题,邀请广大AI产业伙伴,从生态构建、客户案例、技术前瞻、商业化落地等多个角度共同研讨智能化的新未来。

如果您对AI产业化落地充满热情,渴望加入这场智慧的盛宴,请移步至文章末尾,扫描二维码即刻报名参与!

5507e16736f2536a4093dbc6a45789bd.jpeg

62dcbab4e8f279cc23fc138ffe9a79a5.png

a8ca4a6e794a5df9d962a1d2585d3650.png

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

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

相关文章

蓝桥杯备赛(持续更新)

16届蓝桥杯算法类知识图谱.pdf 1. 格式打印 %03d&#xff1a;如果是两位数&#xff0c;将会在前面添上一位0 %.2f&#xff1a;会保留两位小数 如果是long&#xff0c;必须在数字后面加上L。 2. 进制转化 2.1. 十进制转任意进制&#xff1a; 十进制转任意进制时&#xff…

责任链模式 Chain of Responsibility

1 意图 使多个对象都有机会处理请求&#xff0c;从而避免请求的发送者和接收者之间的耦合关系。将这些对象连成一条链&#xff0c;并沿着这条链传递该请求&#xff0c;直到有一个对象处理它为止。 2 结构 Handler 定义一个处理请求的接口;(可选)实现后继链。 ConcreteHandler …

SQL Server 2008 R2 详细安装教程及错误解决教程

SQL Server 2008 R2 详细安装教程及错误解决教程 文章目录 SQL Server 2008 R2 详细安装教程及错误解决教程1.装载或解压ISO文件2. 运行setup程序3. 下载并安装.NET Framework3.54.选择全新安装或向现有安装添加功能5.输入秘钥同意条款6.选择安装类型7.设置角色8.功能选择9.实例…

国际版JAVA同城打车源码同城服务线下结账系统源码适配PAD支持Android+IOS+H5

架构分析 导航栏&#xff1a;位于界面上方&#xff0c;包含了“数据中心”、“消息”、“用户中心”等主要功能模块的入口&#xff0c;方便用户快速访问。左侧功能模块&#xff1a;在界面的左侧&#xff0c;以列表形式展示了多个功能模块&#xff0c;如“数据中心”、“消息中…

营销页面设计:精准触达目标群体的艺术

在当今数字化的商业世界中&#xff0c;营销页面设计扮演着至关重要的角色。成功的营销页面设计不仅仅是美观那么简单&#xff0c;它需要结合场景设计、精准定位目标群体、巧妙运用设计元素以及精心策划的色彩搭配&#xff0c;共同编织出一张引人入胜的视觉网络。 今天就以洋河…

gdb和make工具

gdb工具&#xff1a; GDB的主要功能 断点设置&#xff1a;允许开发者在特定的代码行设置断点&#xff0c;当程序执行到该行时会自动暂停&#xff0c;方便开发者进行调试和分析。 变量查看与修改&#xff1a;在程序运行过程中&#xff0c;可以查看和修改变量的值&#xff0c;以…

爬虫-------字体反爬

目录 一、了解什么是字体加密 二. 定位字体位置 三. python处理字体 1. 工具库 2. 字体读取 3. 处理字体 案例1:起点 案例2:字符偏移: 5请求数据 - 发现偏移量 5.4 多套字体替换 套用模板 版本1 版本2 四.项目实战 1. 采集目标 2. 逆向结果 一、了解什么是…

web实操3——servlet

课程链接b站&#xff1a;第12课 https://www.bilibili.com/video/BV1qv4y1o79t?spm_id_from333.788.videopod.episodes&vd_source05a3c1275b87b47507d869e9349ee3cd&p233 为什么只要写一个实现Servlet的类就可以被调用 tomcat根据url去web.xml里定位到我们写的类后&…

HTML 基础标签——分组标签 <div>、<span> 和基础语义容器

文章目录 1. `<div>` 标签特点用途示例2. `<span>` 标签特点用途示例3. `<fieldset>` 标签特点用途示例4. `<section>` 标签特点用途示例5. `<article>` 标签特点用途示例总结HTML中的分组(容器)标签用于结构化内容,将页面元素组织成逻辑区域…

NPU 可不可以代替 GPU

结论 先说结论&#xff0c;GPU分为可以做图形处理的传统意义上的真GPU&#xff0c;做HPC计算的GPGPU和做AI加速计算的GPGPU&#xff0c;所以下面分别说&#xff1a; 对于做图形处理的GPU&#xff0c;这个就和NPU 一样&#xff0c;属于DSA&#xff0c;没有替代性。当然&#xf…

2024年无线领夹麦克风十大品牌推荐,衣领麦克风哪个品牌好

声音&#xff0c;是沟通的桥梁&#xff0c;是信息的载体。在信息爆炸的时代&#xff0c;如何让自己的声音脱颖而出&#xff0c;成为了每个人都需要思考的问题。无线领夹麦克风&#xff0c;以其小巧便携、无线传输的特点&#xff0c;成为了众多声音爱好者的首选。市场上无线领夹…

杨传辉:云+AI 时代的一体化数据库|OceanBase发布会实录

在 2024 OceanBase 年度发布会 上&#xff0c; OceanBase CTO 杨传辉进行了主题为《云和 AI 时代的一体化数据库战略思考》的演讲&#xff0c;本文为演讲实录&#xff0c;欢迎阅读。 视频观看可点击&#xff1a;https://www.oceanbase.com/video/9001825 各位 OceanBase 的客…

[大模型]视频生成-Sora简析

参考资料&#xff1a; Sora技术报告https://openai.com/index/video-generation-models-as-world-simulators/4分钟详细揭密&#xff01;Sora视频生成模型原理https://www.bilibili.com/video/BV1AW421K7Ut 一、概述 相较于Gen-2、Stable Diffusion、Pika等生成模型的前辈&am…

【docker入门】docker的安装

目录 Centos 7 添加docker 官方仓库到yum源 将 Docker 的官方镜像源替换为国内可以的 Docker 镜像源 安装docker 配置docker加速源 Ubuntu 创建 gpg key 目录 下载 gpg key 添加国内可用镜像源到 系统的 APT 仓库中 安装docker 配置加速源 Centos 7 添加docker 官方仓…

2024年【汽车修理工(高级)】考试总结及汽车修理工(高级)试题及解析

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 汽车修理工&#xff08;高级&#xff09;考试总结是安全生产模拟考试一点通总题库中生成的一套汽车修理工&#xff08;高级&#xff09;试题及解析&#xff0c;安全生产模拟考试一点通上汽车修理工&#xff08;高级&a…

vscode的一些使用心得

问题1&#xff1a;/home目录空间有限 连接wsl或者remote的时候&#xff0c;会在另一端下载一个.vscode-server&#xff0c;vscode的插件都会安装进去&#xff0c;导致空间增加很多&#xff0c;可以选择更换这个文件的位置 参考&#xff1a;https://blog.csdn.net/weixin_4389…

Qt(openCV的应用)

1. OpenCV简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉库&#xff0c;它提供了丰富的图像处理和计算机视觉功能。该库由英特尔公司发起&#xff0c;并在 BSD 许可证下发布&#xff0c;因此它是免费的&#xff0c;且开放源代…

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用

【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用 目录 文章目录 【大语言模型】ACL2024论文-06 探索思维链COT在多模态隐喻检测中的应用目录摘要研究背景问题与挑战如何解决创新点算法模型1. 知识总结模块&#xff08;Knowledge Summarization Module&…

【Android】时区规则库tzdata更新

1 背景&#xff1a; 最近我遇到墨西哥城时区&#xff0c;会出现夏令时&#xff0c;而墨西哥城在2022年底都已经取消夏令时了。 看起来是要更新RK3588上的时区库&#xff0c;我的还是2021a&#xff0c;而现在都已经2024年了 这样能看版本号&#xff1a; cat /system/usr/sha…

【论文速看】DL最新进展20241106-图像分类、图像分割、时间序列预测

目录 【图像分类】【图像分割】【时间序列预测】 【图像分类】 [2024 解耦数据增强] Decoupled Data Augmentation for Improving Image Classification 机构&#xff1a;腾讯优图 论文链接&#xff1a;https://arxiv.org/pdf/2411.02592v1 代码链接&#xff1a;无 最近在图…