LLM应用的分块策略

每日推荐一篇专注于解决实际问题的外文,精准翻译并深入解读其要点,助力读者培养实际问题解决和代码动手的能力。

欢迎关注公众号

原文标题:Chunking Strategies for LLM Applications

原文地址:https://www.pinecone.io/learn/chunking-strategies/


LLM应用的分块策略

在构建与LLM相关的应用程序的背景下,分块是将大段文本分解为较小段的过程。这是一种关键的技术,有助于在使用LLM嵌入内容后,优化从矢量数据库获取的内容的相关性。在本博客文章中,我们将探讨分块是否以及如何提高LLM相关应用程序的效率和准确性。

正如我们所知,我们在Pinecone中索引的任何内容都需要首先进行嵌入。分块的主要原因是确保我们嵌入的内容尽可能少地包含噪音,同时仍然在语义上相关。

例如,在语义搜索中,我们索引一系列文档,每个文档都包含特定主题的有价值信息。通过应用有效的分块策略,我们可以确保我们的搜索结果准确捕捉用户查询的本质。如果我们的文本块太小或太大,可能会导致不精确的搜索结果或错过展示相关内容的机会。通常来说,如果文本块在不考虑周围上下文的情况下对人类来说是有意义的,那么对语言模型来说也是有意义的。因此,找到语料库中文档的最佳分块大小对确保搜索结果准确和相关至关重要。

另一个例子是对话代理(我们之前使用Python和Javascript进行了介绍)。我们使用嵌入的块来构建基于知识库的对话代理的上下文,该知识库将代理置于可信的信息中。在这种情况下,选择正确的分块策略非常重要,原因有两个:首先,它将决定上下文是否真正与我们的提示相关。其次,它将决定我们是否能够将检索到的文本适应到上下文中,然后发送给外部模型提供商(例如,OpenAI),考虑到我们每次请求可以发送的令牌数量的限制。在某些情况下,比如在使用具有32k上下文窗口的GPT-4时,适应文本块可能不是问题。然而,我们需要注意,当我们使用非常大的文本块时,这可能会对我们从Pinecone得到的结果的相关性产生负面影响。

在这篇文章中,我们将探讨几种分块方法,并讨论在选择分块大小和方法时应考虑的权衡。最后,我们将给出一些关于确定最佳分块大小和方法的建议,这将适用于您的应用程序。

1.嵌入短内容和长内容

当我们嵌入我们的内容时,我们可以预见到根据内容的长度(如句子或段落,甚至整篇文章)的不同,会有不同的行为。

当一个句子被嵌入时,生成的向量专注于句子的特定含义。与其他句子嵌入比较时,比较通常会在这个层面上进行。这也意味着嵌入可能会错过在段落或文档中发现的更广泛的上下文信息。

当整个段落或文章被嵌入时,嵌入过程会同时考虑整体上下文和文本内部句子和短语之间的关系。这可能导致一个更全面的向量表示,捕捉文本的广泛含义和主题。另一方面,更大的输入文本大小可能会引入噪音或淡化单个句子或短语的重要性,使得在查询索引时找到精确匹配更困难。

查询的长度也会影响嵌入之间的关系。更短的查询,如单个句子或短语,会集中在特定的细节上,可能更适合与句子级别的嵌入进行匹配。超过一句话或一段落的更长查询可能会更符合段落或文档级别的嵌入,因为它可能在寻找更广泛的上下文或主题。

索引也可能是非均匀的,包含各种大小的块嵌入。这可能在查询结果的相关性方面带来挑战,但也可能带来一些积极的影响。一方面,由于长、短内容的语义表示之间的差异,查询结果的相关性可能会波动。另一方面,非均匀索引可能捕获更广泛的上下文和信息,因为不同大小的块代表了文本中不同级别的粒度。这可能更灵活地适应不同类型的查询。

2.分块的考虑因素

确定最佳分块策略的几个变量会根据使用场景的不同而变化。以下是一些需要考虑的关键因素:

(1)被索引的内容是什么性质?你是在处理长的文档,如文章或书籍,还是较短的内容,如推特或即时信息?答案将决定哪个模型更适合你的目标,因此,也会决定应用什么样的分块策略。

(2)你正在使用哪种嵌入模型,以及它对哪种大小的块有最佳的性能?例如,句子-转换器模型在处理单个句子时表现良好,但像text-embedding-ada-002这样的模型在处理包含256或512个标记的块时表现更好。

(3)你对用户查询的长度和复杂性有什么期望?他们会是短而具体,还是长且复杂?这可能会影响你选择如何分块内容,以便嵌入查询和嵌入块之间有更紧密的关联。

(4)在你的特定应用中如何使用检索到的结果?例如,他们会被用于语义搜索,问答,总结,还是其他目的?例如,如果你的结果需要被输入到另一个具有标记限制的LLM中,你就必须考虑这个因素,并根据你希望适应到LLM请求的块数量来限制块的大小。

回答这些问题将使你能够制定出一个平衡性能和精度的分块策略,这反过来也将确保查询结果的相关性更高。

3.分块方法

有多种不同的分块方法,每种方法可能适合不同的情况。通过分析每种方法的优点和缺点,我们的目标是确定适合应用它们的正确场景。

3.1固定大小分块

这是最常见和最直接的分块方法:我们只需决定我们的块中的token数,并选择性地决定它们之间是否应存在任何重叠。一般来说,我们会希望块之间保持一些重叠,以确保语义上下文不会在块之间丢失。固定大小的分块在大多数常见情况下将是最好的路径。与其他形式的分块相比,固定大小的分块在计算上便宜且使用简单,因为它不需要使用任何NLP库。

以下是使用LangChain执行固定大小分块的示例:

text = "..." # your text
from langchain.text_splitter import CharacterTextSplitter
text_splitter = CharacterTextSplitter(
    separator = "\n\n",
    chunk_size = 256,
    chunk_overlap  = 20
)
docs = text_splitter.create_documents([text])
3.2内容感知分块

这是一组方法,用于利用我们正在分块的内容的性质,并应用更复杂的分块方法。以下是一些例子:

(1)句子分割

如我们之前提到的,许多模型都是针对嵌入句子级内容进行优化的。自然地,我们会使用句子分块,有几种方法和工具可以执行此操作,包括:

  • 简单分割:最简单的方法是按句号(“。”)和换行符进行分割。虽然这可能很快且简单,但此方法不能考虑所有可能的边缘情况。以下是一个非常简单的例子:
text = "..." # your text
docs = text.split(".")
  • NLTK:自然语言工具包(NLTK)是用于处理人类语言数据的流行Python库。它提供了一个可以将文本分割成句子的句子标记器,有助于创建更有意义的文本块。例如,要将NLTK与LangChain一起使用,您可以执行以下操作:
text = "..." # your text
from langchain.text_splitter import NLTKTextSplitter
text_splitter = NLTKTextSplitter()
docs = text_splitter.split_text(text)
  • spaCy:spaCy是另一个用于NLP任务的强大Python库。它提供了复杂的句子分割功能,可以有效地将文本划分为独立的句子,使得后续块中更好地保留上下文。例如,要将spaCy与LangChain一起使用,您可以执行以下操作:
text = "..." # your text
from langchain.text_splitter import SpacyTextSplitter
text_splitter = SpaCyTextSplitter()
docs = text_splitter.split_text(text)

(2)递归分块

递归分块使用一组分隔符以分层和迭代的方式将输入文本划分为更小的块。如果首次尝试分割文本未能产生所需大小或结构的块,该方法会递归地在结果块上调用自身,并使用不同的分隔符或标准,直到达到所需的块大小或结构。这意味着,虽然块不会完全相同大小,但它们仍会“渴望”达到类似的大小。

以下是如何使用LangChain进行递归分块的示例:

text = "..." # your text
from langchain.text_splitter import RecursiveCharacterTextSplitter
text_splitter = RecursiveCharacterTextSplitter(
    # Set a really small chunk size, just to show.
    chunk_size = 256,
    chunk_overlap  = 20
)

docs = text_splitter.create_documents([text])

(3)专用分块

Markdown和LaTeX是您可能会遇到的两个结构化和格式化内容的示例。在这些情况下,您可以使用专用的分块方法,在分块过程中保留内容的原始结构。

  • Markdown:Markdown是一种常用于格式化文本的轻量级标记语言。通过识别Markdown语法(例如,标题、列表和代码块),您可以基于其结构和层次智能地分割内容,从而产生更有语义连贯性的块。例如:
from langchain.text_splitter import MarkdownTextSplitter
markdown_text = "..."

markdown_splitter = MarkdownTextSplitter(chunk_size=100, chunk_overlap=0)
docs = markdown_splitter.create_documents([markdown_text])
  • LaTeX:LaTeX是一种常用于学术论文和技术文档的文档准备系统和标记语言。通过解析LaTeX命令和环境,您可以创建尊重内容逻辑组织的块(例如,章节、小节和方程式),从而获得更精确且与上下文相关的结果。例如:
from langchain.text_splitter import LatexTextSplitter
latex_text = "..."
latex_splitter = LatexTextSplitter(chunk_size=100, chunk_overlap=0)
docs = latex_splitter.create_documents([latex_text])

4.为您的应用确定最佳的块大小

如果常见的分块方法(如固定分块)不能轻松适用于您的用例,以下是一些提示,帮助您找出最优的块大小。

  • 预处理你的数据 - 在确定应用程序的最佳块大小之前,你首先需要预处理你的数据以确保质量。例如,如果你的数据是从网页获取的,你可能需要删除HTML标签或特定只增加噪音的元素。

  • 选择一定范围的块大小 - 数据预处理完成后,下一步是选择一定范围的潜在块大小进行测试。如前所述,这个选择应考虑到内容的性质(例如,短消息或长篇文档)、你将使用的嵌入模型及其功能(例如,token限制)。目标是在保留上下文和维持准确性之间找到平衡。可以通过探索不同的块大小开始,包括较小的块(例如,128或256 token)用于捕获更细粒度的语义信息,和较大的块(例如,512或1024 token)用于保留更多的上下文。

  • 评估每个块大小的性能 - 为了测试各种块大小,你可以使用多个索引或单个索引与多个命名空间。有了代表性的数据集,创建你想要测试的块大小的嵌入,然后保存在你的索引中。然后你可以运行一系列可以评估质量的查询,并比较各种块大小的性能。这很可能是一个迭代的过程,在这个过程中你要测试各种块大小与不同的查询,直到你能确定最适合你的内容和预期查询的最佳性能的块大小。

5.结论

在大多数情况下,对您的内容进行分块是相当简单的 - 但当您开始走出常规思维时,它可能会带来一些挑战。分块没有一种适合所有情况的解决方案,所以对一个用例有效的方法可能对另一个用例无效。希望这篇文章可以帮助您更好地理解如何为您的应用程序进行分块的方法。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

FPGA项目(13)——基于FPGA的电梯控制系统

1.摘要 随着科技的发展,电梯早在上个世纪就已进入人们的生活。对于电梯的控制,传统的方法是使用继电器——接触器控制系统进行控制。随着EDA技术的发展,FPGA已广泛应用于各项电子设计中,本设计即利用FPGA来实现对电梯控制系统的设…

事务失效的十种常见场景

学习事务失效场景 1 概述 事务的传播类型isolationTransactionnal注解属性 事务方法未被Spring管理方法使用final类型修饰非public修饰的方法同一个类中的方法相互调用方法的事务传播类型不支持事务异常被内部catch,程序生吞异常数据库不支持事务未配置开启事务错…

媒体捕捉-拍照

引言 在项目开发中,从媒体库中选择图片或使用相机拍摄图片是一个极为普遍的需求。通常,我们使用UIImagePickerController来实现单张图片选择或启动相机拍照。整个拍照过程由UIImagePickerController内部实现,无需我们关心细节,只…

Spring Boot整合 EasyExcel 实现复杂 Excel 表格的导入与导出功能

文章目录 1. 简介2. 引入依赖3. 导入功能实现3.1 创建实体类3.2 编写导入 Controller3.3 编写导入页面 4. 导出功能实现4.1 编写导出 Controller4.2 编写导出页面 5. 启动应用 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 &…

HttpClient入门

HttpClient入门 简介 HttpClient 是 Apache HttpComponents 项目中的一个开源的 Java HTTP 客户端库,用于发送 HTTP 请求和处理 HTTP 响应。它提供了一组强大而灵活的 API,使得在 Java 程序中执行 HTTP 请求变得相对简单 maven依赖 org.apache.httpco…

C语言操作符下

在这篇文章中&#xff0c;主要讲解关系操作符、条件操作符、逻辑操作符&#xff0c;及其短路。 一. 关系操作符 C语言用于比较的表达式&#xff0c;称为关系表达式&#xff0c;里面运用的运算符就称“关系运算符”&#xff0c;主要有下面6个&#xff1a; < 小于运算符>…

基于Vite创建简单Vue3工程

首先安装node.js环境&#xff0c;没有node.js环境&#xff0c;便没有npm命令。 1、Vue3创建执行命令 D:\TABLE\test>npm create vuelatestVue.js - The Progressive JavaScript Framework√ 请输入项目名称&#xff1a; ... vue_test √ 是否使用 TypeScript 语法&#xff…

【C++】Windows编译FileZilla Client

按照Compiling FileZilla 3 under Windows - FileZilla Wiki (filezilla-project.org)操作即可。 1.下载安装MSYS2 msys2-x86_64-20220118.exe 2.更新MSYS2 进入MSYS2 MinGW 64-bit shell&#xff0c;运行 pacman -Syu重复退出shell&#xff0c;更新MSYS2。直到没有可更新…

【Maven】工程依赖下载失败错误解决

在使用 Maven 构建项目时&#xff0c;可能会发生依赖项下载错误的情况&#xff0c;主要原因有以下几种&#xff1a; 下载依赖时出现网络故障或仓库服务器宕机等原因&#xff0c;导致无法连接至 Maven 仓库&#xff0c;从而无法下载依赖。 依赖项的版本号或配置文件中的版本号错…

详解Vue3中的事件监听方式

本文主要介绍Vue3中的事件监听方式。 目录 一、v-on指令二、使用符号简写三、事件修饰符四、动态事件名五、常见的监听事件六、自定义事件 在Vue3中&#xff0c;事件监听的方式与Vue2有一些不同。 下面是Vue3中事件监听方式的详细介绍&#xff1a; 一、v-on指令 Vue3中仍然使…

[嵌入式AI从0开始到入土]9_yolov5在昇腾上推理

[嵌入式AI从0开始到入土]嵌入式AI系列教程 注&#xff1a;等我摸完鱼再把链接补上 可以关注我的B站号工具人呵呵的个人空间&#xff0c;后期会考虑出视频教程&#xff0c;务必催更&#xff0c;以防我变身鸽王。 第一章 昇腾Altas 200 DK上手 第二章 下载昇腾案例并运行 第三章…

OCP NVME SSD规范解读-3.NVMe管理命令-part2

NVMe-AD-8&#xff1a;在某些情况下&#xff08;如Sanitize命令、Format NVM命令或TCG Revert方法后数据被清除&#xff09;&#xff0c;设备应允许读取已清除的LBAs而不产生错误&#xff0c;并在最后一次清除完成后&#xff0c;对未写入LBAs的读取返回所有零值给主机 NVMe-AD…

【北亚数据恢复】mysql表被truncate,表数据被delete的数据恢复案例

云服务器数据恢复环境&#xff1a; 华为ECS云服务器&#xff0c;linux操作系统&#xff0c;mysql数据库&#xff08;innodb引擎&#xff09;。作为网站服务器使用。 云服务器故障&#xff1a; 在执行mysql数据库版本更新测试时&#xff0c;误将本应该在测试库上执行的sql脚本执…

【JavaScript】浮点数精度问题

✨ 专栏介绍 在现代Web开发中&#xff0c;JavaScript已经成为了不可或缺的一部分。它不仅可以为网页增加交互性和动态性&#xff0c;还可以在后端开发中使用Node.js构建高效的服务器端应用程序。作为一种灵活且易学的脚本语言&#xff0c;JavaScript具有广泛的应用场景&#x…

移动端开发框架mui代码在安卓模拟器上运行2(HbuilderX连接到模拟器)模拟器窗口及多开设置

开发工具 HBuilder X 3.8.12.20230817 注意&#xff1a;开发工具尽量用最新的或较新的。太旧的版本在开发调试过程中可能会出现莫名其妙的问题。 接上篇&#xff0c;移动端开发框架mui代码在安卓模拟器上运行&#xff08;HbuilderX连接到模拟器&#xff09;&#xff0c;这篇主要…

Mediapipe绘制实时3d铰接骨架图——Mediapipe实时姿态估计

一、前言 大约两年前&#xff0c;基于自己的理解我曾写了几篇关于Mediapipe的文章&#xff0c;似乎帮助到了一些人。这两年&#xff0c;忙于比赛、实习、毕业、工作和考研。上篇文章已经是一年多前发的了。这段时间收到很多私信和评论&#xff0c;请原谅无法一一回复了。我将尝…

HarmonyOS 实践之应用状态变量共享

平时在开发的过程中&#xff0c;我们会在应用中共享数据&#xff0c;在不同的页面间共享信息。虽然常用的共享信息&#xff0c;也可以通过不同页面中组件间信息共享的方式&#xff0c;但有时使用应用级别的状态管理会让开发工作变得简单。 根据不同的使用场景&#xff0c;ArkTS…

HarmonyOS 组件通用属性之通用事件 文档参数讲解(触摸事件)

好 本文 我们来说说触摸事件 字面意思也非常好理解 就是我们手机手指触摸物体触发 我们先在编辑器组件介绍中 找到这个东西的基本用法 Button("跳转").onTouch((event: TouchEvent) > {})最明显的就是 event 的类型变了 点击事件的是 ClickEvent 而这里是 Touc…

14 2023.12.31 --------release--------misc--------

呵呵 一部分 misc 存在草稿箱好久了 而且 也并没有那么重要, 直接放出去吧 今年的 专业技能方面的收获主要是一些方面 linux 方面, 这部分内容主要是集中在上半年 90 telnet 连接上对方服务之后 立即 “Connection closed by foreign host.“ 89 重写 /proc/sys/vm/nr_pd…

【LMM 002】大型语言和视觉助手 LLaVA-1.5

论文标题&#xff1a;Improved Baselines with Visual Instruction Tuning 论文作者&#xff1a;Haotian Liu, Chunyuan Li, Yuheng Li, Yong Jae Lee 作者单位&#xff1a;University of Wisconsin-Madison, Microsoft Research, Columbia University 论文原文&#xff1a;htt…
最新文章