4种最常用的LLM应用文本分块策略

在构建 LLM 应用程序时,分块(Chunking)是将大块文本分解成更小的片段的过程。 这是一项重要的技术,一旦我们使用LLM嵌入内容,它有助于优化我们从矢量数据库返回的内容的相关性。 在这篇博文中,我们将探讨它是否以及如何帮助提高LLM相关请求的效率和准确性。

众所周知,我们在 Pinecone 中索引的任何内容都需要首先嵌入。 分块的主要原因是确保我们嵌入的内容尽可能少,但在语义上仍然相关。

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

另一个例子是会话代理(Conversational Agent)。 我们使用嵌入的文本块根据知识库为会话代理构建上下文,该知识库使代理基于可信信息。 在这种情况下,对我们的分块策略做出正确的选择很重要,原因有两个:首先,它将确定上下文是否确实与我们的提示相关。 其次,考虑到我们可以为每个请求发送的令牌数量的限制,它将确定我们是否能够在将检索到的文本发送到外部模型提供商(例如 OpenAI)之前将其放入上下文中。 在某些情况下,例如在 32k 上下文窗口中使用 GPT-4 时,拟合块可能不是问题。 尽管如此,我们需要注意何时使用非常大的块,因为这可能会对我们从 Pinecone 返回的结果的相关性产生不利影响。

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

在这里插入图片描述

在线工具推荐: Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器

1、嵌入短内容和长内容

当我们嵌入内容时,我们可以根据内容是短(如句子)还是长(如段落或整个文档)来预测不同的行为。

当嵌入一个句子时,所得向量集中于该句子的特定含义。 与其他句子嵌入相比,比较自然会在该级别上进行。 这也意味着嵌入可能会错过段落或文档中更广泛的上下文信息。

当嵌入完整的段落或文档时,嵌入过程会考虑整体上下文以及文本中句子和短语之间的关系。 这可以产生更全面的矢量表示,捕获文本的更广泛的含义和主题。 另一方面,较大的输入文本可能会引入噪音或削弱单个句子或短语的重要性,从而使在查询索引时找到精确匹配变得更加困难。

查询的长度也会影响嵌入之间的相互关系。 较短的查询(例如单个句子或短语)将专注于细节,并且可能更适合与句子级嵌入进行匹配。 跨越多个句子或段落的较长查询可能更适合段落或文档级别的嵌入,因为它可能正在寻找更广泛的上下文或主题。

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

2、分块注意事项

有几个变量在确定最佳分块策略方面发挥着作用,这些变量根据用例而变化。 以下是需要牢记的一些关键方面:

  • 被索引的内容的性质是什么? 你是否正在处理长文档(例如文章或书籍)或较短的内容(例如推文或即时消息)? 答案将决定哪种模型更适合你的目标,以及应用哪种分块策略。
  • 你使用哪种嵌入模型,它在什么块大小上表现最佳? 例如, sentence-transformer模型在单个句子上效果很好,但像 text-embedding-ada-002 这样的模型在包含 256 或 512 个token的块上表现更好。
  • 你对用户查询的长度和复杂性有何期望? 它们会简短而具体,还是长而复杂? 这也可能会告诉您选择对内容进行分块的方式,以便嵌入式查询和嵌入式块之间有更紧密的相关性。
  • 检索到的结果将如何在你的特定应用程序中使用? 例如,它们会用于语义搜索、问答、摘要或其他目的吗? 例如,如果你的结果需要输入到具有令牌限制的另一个 LLM 中,那么必须考虑到这一点,并根据想要适应LLM请求的块数量来限制块的大小。

回答这些问题将使你能够开发一种平衡性能和准确性的分块策略,这反过来又将确保查询结果更相关。

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

3、4种分块策略

针对不同情况,我们介绍4种在LLM应用开发中常见的文本分块策略:按固定大小分块、按语句分块、递归分块和结构化文档分块。

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 按语句分块

正如我们之前提到的,许多模型都针对嵌入句子级内容进行了优化。 当然,我们会使用句子分块,并且有多种方法和工具可用于执行此操作。

最朴素的方法是按句点(“.”)和换行符分割句子。 虽然这可能快速且简单,但这种方法不会考虑所有可能的边缘情况。 这是一个非常简单的例子:

text = "..." # your text
docs = text.split(".")

自然语言工具包 (NLTK) 是一个流行的 Python 库,用于处理人类语言数据。 它提供了一个句子标记器,可以将文本分割成句子,帮助创建更有意义的块。 例如,要将 NLTK 与 LangChain 结合使用,可以执行以下操作:

text = "..." # your text
from langchain.text_splitter import NLTKTextSplitter
text_splitter = NLTKTextSplitter()
docs = text_splitter.split_text(text)

spaCy 是另一个用于 NLP 任务的强大 Python 库。 它提供了复杂的句子分割功能,可以有效地将文本分割成单独的句子,从而在生成的块中更好地保留上下文。 例如,要将 spaCy 与 LangChain 结合使用,可以执行以下操作:

text = "..." # your text
from langchain.text_splitter import SpacyTextSplitter
text_splitter = SpaCyTextSplitter()
docs = text_splitter.split_text(text)

3.3 递归分块

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

以下是如何在 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.4 结构化文档分块

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

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 命令和环境,你可以创建尊重内容逻辑组织的块(例如,部分、小节和方程),从而获得更准确且与上下文相关的结果。 例如:

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 标签或只会增加噪音的特定元素。
  • 选择块大小范围 - 数据经过预处理后,下一步是选择要测试的潜在块大小范围。 如前所述,选择应考虑内容的性质(例如,短消息或冗长的文档)、你将使用的嵌入模型及其功能(例如,令牌限制)。 目标是在保留上下文和保持准确性之间找到平衡。 首先探索各种块大小,包括用于捕获更细粒度语义信息的较小块(例如,128 或 256 个标记)和用于保留更多上下文的较大块(例如,512 或 1024 个标记)。
  • 评估每个块大小的性能 - 为了测试各种块大小,你可以使用多个索引或具有多个命名空间的单个索引。 使用代表性数据集,为要测试的块大小创建嵌入并将它们保存在索引中。 然后,可以运行一系列查询,可以评估其质量,并比较不同块大小的性能。 这很可能是一个迭代过程,你可以针对不同的查询测试不同的块大小,直到可以确定内容和预期查询的最佳性能块大小。

5、结束语

在大多数情况下,对内容进行分块非常简单 - 但当你开始偏离常规时,它可能会带来一些挑战。 没有一种万能的分块解决方案,因此适用于一种用例的方法可能不适用于另一种用例, 希望这篇文章能够帮助你更好地了解如何为LLM应用程序进行分块。


原文链接:LLM应用的分块策略 — BimAnt

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

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

相关文章

2023美团外卖商超药店月销量

数据包含:外卖商超、药店商品月销量、含商品skuid、规格spuid等内容 资源下载 ​​​​​​​https://download.csdn.net/download/WANJIAWEN1002/88444367?spm1001.2014.3001.5503

什么是网络中的服务质量 (QoS)?

什么是服务质量(QoS) 服务质量(QoS)是网络中用于管理质量并确定数据流量传输优先级的机制。它确保不同类型的数据流量,如语音、视频和数据,获得适当的服务水平。其主要目标是使网络和组织能够对流量进行优…

新发布的Java使用率均超Java8

Java 软件供应商 Azul 发布了首份年度 Java 现状调查报告,基于对全球 2062 名 Java 专业人士和基于 Java 的应用程序用户进行的调查。 Java 软件供应商 Azul 发布了首份年度 Java 现状调查报告,基于对全球 2062 名 Java 专业人士和基于 Java 的应用程序…

java命令行中文乱码原理和解决方式

今天发现用命令行javac编译文件时,若文件里有中文的话,可能会因为“源文件和javac编译使用的编码方式不同”导致乱码的产生,一般我的源文件用的是utf-8编码,但今天查资料发现javac默认使用系统的GBK编码方式,会出现乱码…

Error: “+“ and “-“ must be surrounded by whitespace in calculations.

加减之前一定要空格 改之前: 改之后: 然后就完美解决啦

Versal 自适应 SoC SelectMAP 启动检查表

Versal 自适应 SoC SelectMAP 启动检查表 本文档提供了有关 SelectMAP 启动设置的技巧和指南。在提交个案服务请求之前,应认真查看以下检查表。SelectMAP 启动模式的常规检查表: 是否已查看 SelectMAP 文档,了解连接和电源轨的用法&#…

vivado时序分析-3时序分析关键概念

1、时钟相移 时钟相移对应于延迟时钟波形 , 此波形与因时钟路径内的特殊硬件所导致的参考时钟相关。在 AMD FPGA 中 , 时钟相移通常是由 MMCM 或 PLL 原语引入的 , 前提是这些原语的输出时钟属性 CLKOUT*_PHASE 为非零值。 时序分析期间…

绝绝子神器!食品法规瞬间读懂,建议收藏上天在提醒你!

食品安全法律小助手 1、前言 从事食品相关工作,必须办理健康证,。现在粤省事app上可查看健康证,并且附带相关法律文件pdf,于是下载下来喂给GPT。让GPT学习,我不学习。 2、pdf转成txt文件 要使用Java将PDF文件转换为…

uniapp发行web页面在老版本浏览器打开一片空白

uniapp发行的web页面(菜单->发行->网站-PC Web或手机H5),对于一些老的浏览器(或内核),打开一片空白; 而在新版本的浏览器中打开却正常。这是因为那些版本较低的浏览器不支持ES6的语法和新…

个人前端编程技巧总结

目录 1. 让界面位于当前屏幕的中心(屏幕中心)css代码示例 2. 界面透明但是内部元素不透明(毛玻璃)css代码示例 3. 将当前界面的参数传递到跳转的目标页面(携参跳转)js代码 1. 让界面位于当前屏幕的中心&…

Azure 机器学习 - 使用 Jupyter Notebook 探索 Azure 机器学习

目录 一、前言二、创建跳转盒 (VM)为 VM 启用 Azure Bastion 三、创建工作区四、连接到 VM 桌面五、连接到机器学习工作室允许工作室访问存储 六、停止计算实例七、清理资源 本文介绍如何创建并连接到安全的 Azure 机器学习工作区。 本文中的步骤使用 Azure 机器学习托管虚拟网…

Linux进程状态

目录 书面上的进程状态 Linux系统中的进程状态 R状态 S状态 D状态 T状态 下面是kill命令的一些选项 t状态 X状态 Z状态 进程状态查看 书面上的进程状态 在课本上操作系统的进程状态分为三种 运行态,就绪态,阻塞态 运行态:占有CP…

Clickhouse学习笔记(3)—— Clickhouse表引擎

前言: 有关Clickhouse的前置知识详见: 1.ClickHouse的安装启动_clickhouse后台启动_THE WHY的博客-CSDN博客 2.ClickHouse目录结构_clickhouse 目录结构-CSDN博客 Cickhouse创建表时必须指定表引擎 表引擎(即表的类型)决定了&…

翻页产品宣传册怎么制作,这有模板一键套用制作!

对于一个新手来说,想要在短时间内制作出一本精美的翻页产品宣传册,在一定程度上难度是比较大的。一本出色的翻页产品宣传册,既可以打造直观、奋发向上的宣传,又能更进一步的提高名气。 那么,如何制作出精美的翻页产品宣…

【链表】数据查找和合并

获取链表中间位置的数据 #include <stdio.h> #include <stdlib.h>/* 定义链表的结构体 */ struct Node {int data;struct Node *next; };/* 获取链表中处于中间位置的元素并打印出来*/ void printMiddle(struct Node *head) {struct Node *slow_ptr head;struct …

合并两个链表 --- 递归回溯算法练习二

目录 1. 分析题意 2. 分析算法原理 2.1. 递归思路&#xff1a; 1. 挖掘子问题&#xff1a; 3. 编写代码 3.1. step one 3.2. step two 3.3. step three 3.1. 递归写法 4. 补充 --- 迭代写法 5. 总结 1. 分析题意 力扣上原题链接如下&#xff1a; 21. 合并两个有序链表…

密码学 - RSA签名算法

实验九 RSA签名算法- 一、实验目的 通过实验掌握GMP开源软件的用法&#xff0c;理解RSA数字签名算法&#xff0c;学会RSA数字签名算法程序设计&#xff0c;提高一般数字签名算法的设计能力。 二、实验要求 (1)基于GMP开源软件&#xff0c;实现RSA签名算法。 (2)要求有对应…

【LeetCode笔试题】88.合并两个有序数组

问题描述 给你两个按 非递减顺序 排列的整数数组 nums1 和 nums2&#xff0c;另有两个整数 m 和 n &#xff0c;分别表示 nums1 和 nums2 中的元素数目。 请你 合并 nums2 到 nums1 中&#xff0c;使合并后的数组同样按 非递减顺序 排列。 注意&#xff1a;最终&#xff0c;合…

关灯游戏及扩展

7.8 图形界面应用案例——关灯游戏 题目&#xff1a; [案例]游戏初步——关灯游戏。 关灯游戏是很有意思的益智游戏&#xff0c;玩家通过单击关掉(或打开)一盏灯。如果关(掉&#xff08;或打开)一个电灯&#xff0c;其周围(上下左右)的电灯也会触及开关&#xff0c;成…

spring boot configuration annotation processor notconfigured解决方法

spring boot configuration annotation processor notconfigured解决方法 一、问题描述二、解决方法 一、问题描述 我在使用ConfigurationProperties注解的时候idea出现提示信息spring boot configuration annotation processor notconfigured&#xff0c;但是却不影响程序的运…