大模型 RAG:文档分块方案与 RAG 全流程
一 RAG 与文本分块
1.1 为什么要文档分块
在上一篇文章《大模型 RAG:基于 PgSql 的向量检索》中,简单介绍了 RAG 概念和简要实现。在实际的应用中,技术方案远不会这样简单。
我们知道,大模型在预训练阶段获取的知识是有限的,一般需要数据增强模块引入外部知识库,通过知识检索的方式搜索于用户提问相关的知识,这也是 RAG 相关应用架构出现的原因。但这又引申出另一个问题,外部知识文档往往比较长,可能是包含几十页甚至数百页的内容,如果直接使用会存在以下问题
1.大模型处理的上下文长度有限:大模型在预训练过程都有上下文长度限制,如果超过长度限制大模型会将超出部分丢弃,从而影响回答的性能表现。(注:目前很多大模型已经支持 192K 甚至更大的超长上下文窗口+搜索增强知识库,但基于成本和性能考虑,大文档分 chunk 依然是 RAG 方案必须包含的环节)。
2.语义杂揉不利于任务检索:长文档中各个片段的语义之前可能存在较大的差异,如果当成一个整体来做知识检索会存在语义的杂揉,应当将长文档切分成更多的小块,促使每个小块内部表意一致,块之间表意存在多样性,从而更充分的发挥知识检索的作用
所以我们需要根据一定策略将文本切分为小块,以便适应大模型的上下文窗口,同时提高知识检索的精度。
1.2 分块的目标
文本分块不是盲目的切分,而是必须在不影响或尽量降低对整体效果影响的前提下进行。所以文本分块(chunk)最核心的目的就是把相同语义的 token 聚集在一起,不同语义的 token 互相分开,利于后续的 retrieve 和 rerank。举个例子:我们有一个 word 文档,分为多个段落,每个段落都是一个问题的问答对。那么显然把一个问答对作为一个 chunk 划分是最理想的结果。
二 常用的文本分块技术方案
常见 chunk 方案有按照字符 chunk、按 token、按段落、递归划分、语义划分、代理划分等。Langchain 作为一个 LLM 协调框架,内置了一些用于分块以及加载文档的工具,提供了很多可以开箱即用的 chunk 方法:
CharacterTextSplitter
RecursiveCharacterTextSplitter
Split by tokens
Semantic Chunking
HTMLHeaderTextSplitter
MarkdownHeaderTextSplitter
RecursiveJsonSplitter
Split Cod
由于相关的代码解说文章已经很多,这里不再赘述,只以 RecursiveCharacterTextSplitter、SentenceSplitter 和 HTMLHeaderTextSplitter 为例:
2.1 RecursiveCharacterTextSplitter
基于字符数来递归地分割文本。每个块都保持在指定的长度以下,这对于具有自然段落或句子间断的文档特别有用,确保了块的可管理性和易于处理性,而不会丢失文档的固有结构。
Langchain 中的递归字符文本分割器方法根据字符数将文本分割成块,以确保每个块低于指定的长度。这种方法有助于保持文档中段落或句子的自然断开。
2.2 SentenceSplitter
SentenceSplitter 是在句子边界上分割文本,这种方法能够保持文本的上下文完整性。句子通常代表完整的思想,这使得这种方法非常适合那些对内容有连贯理解的场景。
2.3 HTMLHeaderTextSplitter
HTMLHeaderTextSplitter 是一个网页代码分块器,它根据 HTML 元素拆分文本,并将相关元数据分配给分块内的每个标头。它可以返回单个分块或将具有相同元数据的元素组合在一起,以保持语义分组并保留文档的结构上下文。此拆分器可与分块管道中的其他文本拆分器结合使用。
三 自实现的文本 chunk 方法
尽管 LangChain 和 llamaIndex 都已经提供了文本 Chunk 方法,但不幸的是这两者提取语义 embedding 用的都是 openAI 的接口,要收费不说,大陆地区还面临被封 API 的风险,更关键的是在很多企业内根本不允许使用。所以我们只能参考 LangChain 中各方法的实现原理,自行开发和调试文本 chunk 方法。
四 从文档角度出发的 RAG 技术方案
从文档角度出发,RAG 流程中的各个主要环节如下:
关键概念说明:
RAPTOR:RAPTOR 模型提出了一种创新的策略。它通过递归地进行文本片段的向量化、聚类和摘要生成,构建了一个树状索引结构。这种结构不仅捕捉了文档的高层次主题,还保留了低层次的细节,允许基于语义相似性而非仅仅是文本顺序对节点进行分组。这样的树状结构使得 RAPTOR 能够在不同的抽象层次上加载文档的上下文片段,从而有效地回答不同层次的问题。
GraphRAG:2024 年 4 月微软推出 GraphRAG,并于 7 月 2 日开源。GraphRAG 仍然沿袭了 RAG 的思路,即通过检索来增强模型的准确性。不过,与 RAG 不同的是,GraphRAG 还引入了“知识图谱”(Knowledge Graph)技术,以增强模型的“检索”能力,以实现对复杂信息的高效和可靠检索,从而提高 LLM 问答系统对于复杂信息的答案生成的准确性。GraphRAG 示意图如下:
版权声明: 本文为 InfoQ 作者【程序员架构进阶】的原创文章。
原文链接:【http://xie.infoq.cn/article/d15dc2f986801a54112abb338】。文章转载请联系作者。
评论