RAG(Retrieval-Augmented Generation,检索增强生成)是一种结合检索和生成能力的自然语言处理架构,旨在为大语言模型(LLM)提供额外的、来自外部知识源的信息。通过检索的模式为大语言模型的生成提供帮助,使大模型生成的答案更符合要求。
LLM 需要 RAG 进行检索优化的原因在于 LLM 存在一些缺点:
RAG 具有以下优点:
在 PDF 结构识别方面,基于规则的方法 PyPDF 存在一些问题:
PyPDF 的解析和分块工作流程是:先将 PDF 文档中的字符序列化为没有文档结构信息的长序列,然后使用分割规则如换行符“\n”进行分割,仅当组合块的长度不超过预定限制 N 个字符时,才会合并相邻块。
RAG(Retrieval-Augmented Generation),即检索增强生成,是一种结合检索和生成能力的自然语言处理架构,它旨在为大语言模型(LLM)提供额外的、来自外部知识源的信息。简单来说,就是通过检索的模式,为大语言模型的生成提供帮助,从而使大模型生成的答案更符合要求。[heading2]为什么LLM需要RAG?[content]众所周知,大模型已经在很多领域和问题下都取得了很好的效果,那为什么还需要RAG进行检索优化呢?[heading3]LLM的缺点[content]1.LLM无法记住所有知识,尤其是长尾的。受限于训练数据、现有的学习方式,对长尾知识的接受能力并不是很高;长尾数据是指数据集中某些类别数量较少,而其他类别样本数较多的不平衡“长尾”状态。例如在自然语言处理中,一些少见的词汇出现频率很低,而常见的词汇出现频率很高。2.LLM的知识容易过时,而且不好更新。只是通过微调,模型的接受能力其实并不高而且很慢,甚至有丢失原有知识的风险;3.LLM的输出难以解释和验证。一方面最终的输出的内容黑盒且不可控,另一方面最终的结果输出可能会受到幻觉之类的问题的干扰;4.LLM容易泄露隐私训练数据。用用户个人信息训练模型,会让模型可以通过诱导泄露用户的隐私;5.LLM的规模大,训练和运行的成本都很大。[heading3]RAG的优点[content]1.数据库对数据的存储和更新是稳定的,不像模型会存在学不会的风险。2.数据库的数据更新可以做得很敏捷,增删改查可解释,而且对原有的知识不会有影响。3.数据库的内容是明确、结构化的,加上模型本身的理解能力,一般而言数据库中的内容以及检索算法不出错,大模型的输出出错的可能就大大降低。4.知识库中存储用户数据,为用户隐私数据的管控带来很大的便利,而且可控、稳定、准确。5.数据库维护起来,可以降低大模型的训练成本,毕竟新知识存储在数据库即可,不用频繁更新模型,尤其是不用因为知识的更新而训练模型。
PyPDF似乎擅于检测段落的边界,因为它不会将一个段落分割成多个分块。但实际上它并没有解析段落的边界。在“2分块结果”部分我们可以看到,页面中的每个可视文本行在结果中都被解析为以“\n”结尾的一行,并且段落末尾没有特殊格式。PyPDF能够正确地划分段落,是因为我们使用了一个特殊的分隔符“.\n”,它会将一个以句点结尾的行视为可能是段落的结束。然而,这种启发式方法(Heuristic)在许多情况下可能不成立。1.PyPDF无法识别表格内的结构。在“2分块结果”部分,在分块1中,表格的上半部分表示为一系列短语,其中一个单元格可能被拆分成多行(例如单元格“China commerce(1)”),一些相邻的单元格可能被排列在一行中(例如第二行中的第三到第五个单元格,”services(1)Cainiao Cloud”)。所以,表格的结构被完全破坏。如果此分块被检索用于RAG,大语言模型无法从中辨别到任何有意义的信息。分块2的情况也是类似的。此外,表格的表头只存在于分块1中,因此分块2中的表格下半部分变得没有意义。1.PyPDF无法识别内容的阅读顺序。分块5的最后一行“Management Discussion and Analysis”实际位于页面顶部,但在结果中被解析为最后一句。这是因为PyPDF按照字符的存储顺序解析文档,而非它们的阅读顺序。当面对复杂布局时,这可能导致解析结果混乱。另一个案例2为复杂的跨页表格,其解析结果如附录中的图15所示。
我们先介绍基于PyPDF的解析和分块工作流程。首先,PyPDF将PDF文档中的字符序列化为一个没有文档结构信息的长序列。然后,PyPDF使用一些分割规则对该序列进行分割,如LangChain中的“RecursiveCharacterTextSplitter”函数。具体来说,该函数根据预定义的分隔符列表分割文档,如换行符“\n”。在此初始分割之后,仅当组合块的长度不超过预定限制N个字符时,才会合并相邻块。以下内容中,在没有上下文歧义的情况下,我们使用“PyPDF”来指代使用PyPDF + RecursiveCharacterTextSplitter进行文档解析和分块的方法。下面将分块的最大长度设置为300个词元(Token)。我们通过一个案例来观察PyPDF的固有特征。如图4所示,案例1的文档页面中的表格与双列文本混合布局,两者的边界难以区分。表格中间的行没有水平线,因此表格中的行很难被识别。段落既有单列布局(表下的注释),也有双列布局(页面下部的段落)。图4案例一中PyPDF的解析和分块结果(原文档:[4])。放大查看细节。PyPDF的解析和分块结果如图4所示。在“3分块结果可视化”部分,我们可以看到PyPDF正确识别了页面的单列和双列布局部分。但是PyPDF存在以下三个缺点:1.PyPDF无法识别段落和表格的边界。它错误地将表格分割成两部分,并将第二部分与后续段落合并为一个分块。