RagFlow是当前比较流行的一个开源RAG应用,它的特点是号称基于深度文档理解(DeepDoc)进行构建的文档处理引擎,能够大幅提升RAG的实际效果。我前段时间由于工作需要通读了一下Ragflow的源码(基于0.17.0)版本,发现它在文档解析,文档检索等方面确实有一些独到的地方,这里就给大家分享一下我的一些理解吧,希望能帮助大家发现一些新的RAG优化的思路。
RAG最重要的部分就是文档的解析,所谓的**“Garbage in Garbage out”**, 如果文档解析的效果不好,应该收集的信息没有收集到,那么后续的检索过程做再多的优化也于事无补。所以我们先来看一下RagFlow是怎么做文档解析的。
任务生成与管理
用户在页面上提交一个文档的解析请求,RagFlow会将其封装为一个异步任务到后台进行处理
-
任务切分
系统会根据文档类型和配置规则对任务进行切分。例如: -
- PDF文件按页码范围切分(如1-50页、51-100页等)。
- Excel文件按行切分(每3000行为一个子任务)。
- 切分后的子任务将被放入异步任务队列,由Redis负责管理和分发。
-
任务去重优化
通过提取任务信息的哈希值,对任务队列进行去重,避免重复处理。
文档解析器
文档解析任务处理时,RagFlow会根据文档的文件类型以及用户选择的解析器(parser),来确定如何对文件进行解析。 RagFlow提供了多种类型的解析器,针对不同文档类型和内容特性进行优化。解析器分为两类:
- 文件类型解析器:针对PDF、PPT、Word等文件格式的核心逻辑,源码位于
deepdoc/parser
。 - 内容类型解析器:根据文档内容特性(如论文、Q/A、表格等)进一步细化对不同类型文档的处理方式,用户可选择适合的解析器以达到最好的解析效果。
class ParserType(StrEnum): PRESENTATION = "presentation" LAWS = "laws" MANUAL = "manual" PAPER = "paper" RESUME = "resume" BOOK = "book" QA = "qa" TABLE = "table" NAIVE = "naive" PICTURE = "picture" ONE = "one" AUDIO = "audio" EMAIL = "email" KG = "knowledge_graph" TAG = "tag"
文档解析流程
我们这里以PDF文档的解析过程为例进行解释。PDF应该是我们日常最容易遇到的文档类型之一,而且由于其来源的复杂性(从word,ppt等文件导出,影印版的纯图片PDF,标准生成的pdf文档等),所以处理过程也是所有类型文档中流程最为复杂的,它的解析过程主要分为6个步骤(这里选择的是general解析器,源码位于 rag/app/naive.py
)
def __call__(self, filename, binary=None, from_page=0, to_page=100000, zoomin=3, callback=None): start = timer() first_start = start callback(msg="OCR started") self.__images__( filename if not binary else binary, zoomin, from_page, to_page, callback ) callback(msg="OCR finished ({:.2f}s)".format(timer() - start)) logging.info("OCR({}~{}): {:.2f}s".format(from_page, to_page, timer() - start)) start = timer() self._layouts_rec(zoomin) callback(0.63, "Layout analysis ({:.2f}s)".format(timer() - start)) start = timer() self._table_transformer_job(zoomin) callback(0.65, "Table analysis ({:.2f}s)".format(timer() - start)) start = timer() self._text_merge() callback(0.67, "Text merged ({:.2f}s)".format(timer() - start)) tbls = self._extract_table_figure(True, zoomin, True, True) # self._naive_vertical_merge() self._concat_downward() # self._filter_forpages() logging.info("layouts cost: {}s".format(timer() - first_start)) return [(b["text"], self._line_tag(b, zoomin)) for b in self.boxes], tbls
1. 图像转换与OCR提取
- 将PDF页面转换为高清图片。
- 使用OCR技术提取文字信息,同时结合PDF原生文本提取功能,提升文字提取性能。
- 优势:统一图片和文字处理逻辑,兼容扫描件PDF场景。
2. 布局分析
- 使用预训练模型分析每个页面的布局情况,将页面切分为文本、标题、图表、页眉/页脚等几个不同的类型区域。
- 记录区域的类型及其在图片中的坐标位置,并与OCR的文本块结果关联,为后续处理提供数据支撑。
3. 表格增强处理
- 针对布局分析中识别为表格的区域,使用预训练表格模型提取更加详细的结构化的表格数据(行列信息)。
4. 简单文本块合并
-
对前面识别出来的文本块进行合并,提升文本连贯性和可读性。相对于第五步的合并,这里没有使用任何预训练模型,只是基于布局规则的简单合并。
-
合并条件:
-
- 布局一致性:同一布局区域且为普通文本。
- 垂直对齐:文本框垂直距离小于页面平均行高的1/3或1/5。
- 水平连续性:水平间距满足阈值或存在标点衔接。
-
合并操作:扩展坐标、居中对齐、文本拼接、移除冗余。
5. 垂直方向文本块合并
- 进一步进行垂直方向上的文本块合并,将垂直方向上连续且语义相关的文本块(如跨行段落、跨页内容)合并为完整的文本段落,解决OCR结果中文本被错误分段的问题。这里主要使用XGBoost模型进行连续性判断。
- 模型特征输入:几何特征(文本块的间距、高度比)、上下文特征(结尾的标点、跨页数)、语义特征(分词连续性)、布局特征(表格关联性)。
最终解析完成后生成并插入到ES中的文本块(chunk),主要包含五部分的信息:
- 文本块所在的文档标题信息(标题内容和分词结果)。
- 文本块的文本信息(内容及分词结果,内容受用户指定的最大token影响,但没有严格限制,合并时可能会超出)
- 文本块的文本信息的向量化数据(用于后面基于向量的相似性比对)
- 文本块对应文档页的图片信息
- 文本块在页图片中坐标信息
从整个PDF文档的处理过程来看,使用了大量的预训练小模型来处理诸如OCR, 布局识别,表格内容识别等功能,确实可以称之为**“DeepDoc”**。但这也造成整个PDF的解析过程比起其它同类的应用来说要慢上不上,对硬件也有一定的要求。不过通过一系列复杂的处理,确实的提高了文档中有效内容的识别率,
其它类型的解析器
其它类型的解析器主要是在 general 解析器的基础上在流程上做一些调整和删减,整体不太大,这里只简单举两个例子:
- Presentation解析器:仅执行图片转换和文本提取,每页单独切分为一个独立的文本块(文本块的token数不受限制),不进行表格解析和复杂合并。
- QA解析器:执行前四步解析,并通过正则表达式匹配问题和答案,生成完整的问答形式文本块(文本块的token数不受限制)
QUESTION_PATTERN = [ r"第([零一二三四五六七八九十百0-9]+)问", r"第([零一二三四五六七八九十百0-9]+)条", r"[\((]([零一二三四五六七八九十百]+)[\))]", r"第([0-9]+)问", r"第([0-9]+)条", r"([0-9]{1,2})[\. 、]", r"([零一二三四五六七八九十百]+)[ 、]", r"[\((]([0-9]{1,2})[\))]", r"QUESTION (ONE|TWO|THREE|FOUR|FIVE|SIX|SEVEN|EIGHT|NINE|TEN)", r"QUESTION (I+V?|VI*|XI|IX|X)", r"QUESTION ([0-9]+)",]
LLM辅助增强
在完成原始的文本块解析过程之后,RagFlow还支持通过LLM对切片过程进行进一步的增强,提升后续的检索召回率。主要功能包括:
1. 自动关键词提取(auto_keywords)
利用LLM自动提取每个文本块的关键字(数量由topn
配置决定),提取的关键字将更新文本块的important_kwd
(原始关键词)和important_tks
(分词后关键词)字段。
2. 自动问题生成(auto_questions)
利用LLM从文本块中自动提炼该文本块可能关联的问题(数量由topn
配置决定),提取的问题会更新文本块的question_kwd
(原始问题)和question_tks
(分词后问题)字段。这几个新增的字段都会和文本块一起存入到ES中,在查询阶段执行混合检索时(关键字匹配+向量)时,其中关键字匹配会对文本块的不同字段赋予不同的匹配权重值(见下),从这里可以看出上述几个字段的意义,就是加强关键字检索阶段的精度。检索的具体过程以后再单独写一篇文章,这里就不展开了。
self.query_fields = [ "title_tks^10", "title_sm_tks^5", "important_kwd^30", "important_tks^20", "question_tks^20", "content_ltks^2", "content_sm_ltks", ]
3. RAPTOR召回增强策略
开启该策略后,则完成原始文档解析之后,还会尝试对生成的文本块进行聚合提炼,逐层总结概要(会大大增加一个文档的文本块个数)。大致过程如下:
- 对原始文本块集合基于向量相似性,进行聚类,聚合成不同的分组(使用GMM)。
- 拼接分组内所有文本块的文本,使用LLM总结为为一段新的文本。
- 重复聚类和总结,直到分组数量为1。
- 返回原始文本块和所有通过总结得到的新的文本块。
此外还有知识图谱增强(GraphRAG), 这个网络上有很多介绍了,这里就不展开了。应该说开启LLM文档解析增强后,解析效果确实会得到明显改善(特别是RAPTOR),但也会显著的增加文档解析的耗时(这个增加的可不是一点半点,如果文档比较大又比较多的话,解析过程会让你抓狂),而且如果对接的是外部的LLM,也会额外消耗大量的token成本。怎么选择就只有看具体的业务场景了。
总结
RagFlow在文档切片过程中提供了丰富的配置项供用户进行选择,几乎涵盖了目前RAG领域的各种最新的研究成果,特别是利用一系列的深度学习模型在文档解析时引入布局识别,表格结构解析等专有技术,有效提供了文档内容获取的质量,无愧于开源RAG领域的SOTA。
如何学习大模型 AI ?
由于新岗位的生产效率,要优于被取代岗位的生产效率,所以实际上整个社会的生产效率是提升的。
但是具体到个人,只能说是:
“最先掌握AI的人,将会比较晚掌握AI的人有竞争优势”。
这句话,放在计算机、互联网、移动互联网的开局时期,都是一样的道理。
我在一线互联网企业工作十余年里,指导过不少同行后辈。帮助很多人得到了学习和成长。
我意识到有很多经验和知识值得分享给大家,也可以通过我们的能力和经验解答大家在人工智能学习中的很多困惑,所以在工作繁忙的情况下还是坚持各种整理和分享。但苦于知识传播途径有限,很多互联网行业朋友无法获得正确的资料得到学习提升,故此将并将重要的AI大模型资料包括AI大模型入门学习思维导图、精品AI大模型学习书籍手册、视频教程、实战学习等录播视频免费分享出来。
第一阶段(10天):初阶应用
该阶段让大家对大模型 AI有一个最前沿的认识,对大模型 AI 的理解超过 95% 的人,可以在相关讨论时发表高级、不跟风、又接地气的见解,别人只会和 AI 聊天,而你能调教 AI,并能用代码将大模型和业务衔接。
- 大模型 AI 能干什么?
- 大模型是怎样获得「智能」的?
- 用好 AI 的核心心法
- 大模型应用业务架构
- 大模型应用技术架构
- 代码示例:向 GPT-3.5 灌入新知识
- 提示工程的意义和核心思想
- Prompt 典型构成
- 指令调优方法论
- 思维链和思维树
- Prompt 攻击和防范
- …
第二阶段(30天):高阶应用
该阶段我们正式进入大模型 AI 进阶实战学习,学会构造私有知识库,扩展 AI 的能力。快速开发一个完整的基于 agent 对话机器人。掌握功能最强的大模型开发框架,抓住最新的技术进展,适合 Python 和 JavaScript 程序员。
- 为什么要做 RAG
- 搭建一个简单的 ChatPDF
- 检索的基础概念
- 什么是向量表示(Embeddings)
- 向量数据库与向量检索
- 基于向量检索的 RAG
- 搭建 RAG 系统的扩展知识
- 混合检索与 RAG-Fusion 简介
- 向量模型本地部署
- …
第三阶段(30天):模型训练
恭喜你,如果学到这里,你基本可以找到一份大模型 AI相关的工作,自己也能训练 GPT 了!通过微调,训练自己的垂直大模型,能独立训练开源多模态大模型,掌握更多技术方案。
到此为止,大概2个月的时间。你已经成为了一名“AI小子”。那么你还想往下探索吗?
- 为什么要做 RAG
- 什么是模型
- 什么是模型训练
- 求解器 & 损失函数简介
- 小实验2:手写一个简单的神经网络并训练它
- 什么是训练/预训练/微调/轻量化微调
- Transformer结构简介
- 轻量化微调
- 实验数据集的构建
- …
第四阶段(20天):商业闭环
对全球大模型从性能、吞吐量、成本等方面有一定的认知,可以在云端和本地等多种环境下部署大模型,找到适合自己的项目/创业方向,做一名被 AI 武装的产品经理。
- 硬件选型
- 带你了解全球大模型
- 使用国产大模型服务
- 搭建 OpenAI 代理
- 热身:基于阿里云 PAI 部署 Stable Diffusion
- 在本地计算机运行大模型
- 大模型的私有化部署
- 基于 vLLM 部署大模型
- 案例:如何优雅地在阿里云私有部署开源大模型
- 部署一套开源 LLM 项目
- 内容安全
- 互联网信息服务算法备案
- …
学习是一个过程,只要学习就会有挑战。天道酬勤,你越努力,就会成为越优秀的自己。
如果你能在15天内完成所有的任务,那你堪称天才。然而,如果你能完成 60-70% 的内容,你就已经开始具备成为一名大模型 AI 的正确特征了。