波波算法笔记

Bob Peng

RAGRetrievalAugmentedGeneration检索增强生成进阶优化思路

2025-04-01
RAGRetrievalAugmentedGeneration检索增强生成进阶优化思路

RAGRetrievalAugmentedGeneration检索增强生成进阶优化思路

承接上次RAG学习项目的分享,如果你没有看过上一篇,这里是跳转链接

用RAG技术让大模型开卷考试,建立私人数据库

上次的分享仅仅限于学习RAG的基本思路,只能说是一个最小的框架,其中有许多的问题需要解决优化,下面我会简单谈一下需要优化的点以及技术难点。

这里笔者根据RAG的组成部分,分开介绍每个部分可以有那些优化思路与技术点。

1.文档解析器

2.文本分割器

3.Embedding模型

4.RAG增强

5.若干检索优化技巧

6.多模态RAG

文档解析器

明确目标:

文档解析器的主要目标是将非结构化的文档(如PDF、Word、PPT等)转换为结构化的数据,以便后续处理和分析

python有很多文档解析工具。实际上文档解析也是一个非常复杂的问题,例如不同格式的文件,包括但不限于不限于PDF。存在PDF文档是扫描件,文档中的表格解析有可能会丢失数据。开源的PDF解析工具有很多,也各有优缺点。

何况大部分的专业文档都是以 PDF 格式存储,低精度的 PDF 解析会显著影响专业知识问答的效果

So , 终极目标就是, 高精度解析文档,且不丢失信息!

非结构化文档分类

高度结构化的文档:这些文档基于标记语言,如Markdown、HTML、LaTeX等,通常具有明确的结构和格式,解析相对简单。

半结构化的文档:这类文档如Word文档,具有一定的结构(如段落、标题等)

低结构化的文档:如PPT和PDF等文档,通常结构不明确,需要通过OCR(光学字符识别)技术进行文本提取和解析。

痛难点和技术

文件解析,有两种方式。关键在于 选择合适的方式进行文件解析

1.使用开源的方式去解析。LangChain 等框架也已经集成了 RAG 的流程、方法、API。

例如:

from langchain.text_splitter import CharacterTextSplitter,MarkdownTextSplitter  
from langchain.document_loaders import UnstructuredFileLoader,UnstructuredMarkdownLoader  
from langchain.document_loaders import UnstructuredPDFLoader  
from langchain.document_loaders import UnstructuredImageLoader  
from rapidocr_onnxruntime import RapidOCR  

这种就需要根据不同的文件类型选择合适的文档解析器。

2.使用OCR的技术去解析。这一种较为复杂,到目前为止,还没有一个特别好的模型能够做到很高的识别率

(1)公式识别

使用Nougat等工具进行公式的识别和解析,这是处理技术文档时常见的需求。OCR(光学字符识别)

(2)表格识别:

处理低结构化文档时,表格内容的识别是一个难点。常用的表格识别工具包括PaddleOCR、阿里追光、>Camelot和lineless_table_rec等。

(3)文字识别:

主要工具有Umi-OCR、Rapid-OCR和PaddleOCR等,用于处理不同格式的文档,提取其中的文字信息。

文本分割器

明确目标:

文本分割器用于 将解析后的文本进一步处理和分析,通常需要将其分割为更小的片段。

切分方法

文本分割的方法主要有以下几种:

(1)基于规则的分割

使用CharacterTextSplitter、RecursiveCharacterTextSplitter等工具,根据特定的规则(如字符数、段落标记等)进行文本分割。

(2)基于模型/算法的分割

使用如damo/nlp_bert_document-segmentation_chinese-
base、NLTKTextSplitter、SpacyTextSplitter等模型和算法,通过自然语言处理技术对文本进行智能分割。这些方法依赖于机器学习模型,可以更加智能地理解文本的结构和内容。

(3)针对高度结构化的非结构化文本的分割器

使用MarkdownTextSplitter、PythonCodeTextSplitter、HTMLHeaderTextSplitter、LatexTextSplitter等工具,针对特定格式的文本进行分割。这些分割器针对特定格式进行了优化,可以更准确地分割结构化内容。

(4)面向token的分割

使用SentenceTransformersTokenTextSplitter等工具,根据文本的token(最小单位,如词、字符等)进行分割。这种方法通常用于需要更加细粒度地处理和分析文本内容的场景。

文本切割策略

chunk_size:这是每个参数块的大小。chunk_size的选择取决于数据的类型,ebedding模型等,处理长文本需要大的chunk_size

Overlap: 在某些情况下,参数块之间可能需要有一定的重叠,以确保模型在处理数据时的连续性和一致性。
这通常发生在模型需要考虑输入序列的上下文信息时。

例如:在处理长文本时,如果每个chunk处理的数据没有重叠,可能会导致生成的文本在chunk边界处出现不连贯的情况。严重就会导致 关键信息被切分到两个不同的chunk ,进行检索时得不到答案。所以保证overlap的长度比关键信息长。

总结

文本分割器本质上没有优劣之分,它们各自的优势在于适配不同的文件格式和文本处理需求。
每种文本分割器都是为特定类型的文档设计的,能够根据文档的格式和结构特点进行高效的分割和处理。

分割时,根据数据的情况,设置 合适的 chunk_size 、 chunk_overlap

Embedding模型

明确目标:

Embedding模型的主要任务是 将输入文本转换为固定维度的向量表示,使得相似的文本在向量空间中相近
。根据图中的信息,我们可以将Embedding模型分为三大类:对称模型和非对称模型、混合模型。

模型类别

  1. 1. 对称模型(query, text)

对称模型在训练时,将查询和文本对称地看待。这意味着在训练过程中,模型同时学习查询和文本的向量表示,使得相似的查询和文本在向量空间中彼此接近。

sentence-T5

2 .非对称模型(query, text)

非对称模型在训练时,将查询和文本视为不同的输入。这种方法更适合处理查询和文本内容差异较大的情况。

GTR、stella-v2、piccolo

3.混合模型

m3e、gte、bge

如何选择

1.模型性能

MTEB - Embedding 模型排行榜 [1] 可以先看看huggingface的模型排行榜,有对各个语言、下游任务评分,优先选择评分高的

https://huggingface.co/spaces/mteb/leaderboard

2.模型是否适配场景

由于模型预训练的数据以及参数不同,导致模型在不同方面的性能存在差距。

例如:使用不同 语种 的数据预训练导致模型在理解不同语种数据时的性能有差异。

预训练数据的max_token在512左右,那么该模型在理解向量化 chunk_size 长度为512的性能会更好。

RAG增强

这里只提一下Ranker

什么是Ranker

在检索增强生成(RAG)的简单方法中,检索阶段可能会检索到大量上下文, 但并非所有这些内容都与问题紧密相关。因此我们希望对检索的内容进行再次筛选。

回忆一下,在上一篇文章中我们使用的是“余弦相似度”。但是,相似度不代表相关性,

例如:

Question:Bob现在多大了?

Answer1:Bob现在很大

Answer2:他20岁

Result : Answer2

这个过程类似于排序过程中的粗排和精排。粗排检索效率较快,但是召回的内容并不一定强相关。而精排效率较低,因此适合在粗排的基础上进行进一步优化。

在 RAG 中, 精排 的术语就叫 重排序(Re-Rank) ,重排技术能够重新排序和筛选文档,将相关内容置于前列,从而提高 RAG
的效果。

使用重排模型

与 embedding
模型不同,重排模型将查询和上下文作为输入,并直接输出相似性得分。需要注意的是,重排模型使用交叉熵损失进行优化,使得相关性得分是无界的,甚至可以是负数。

目前,可用的重排模型并不多。一种选择是通过 API 访问的 Cohere 提供的在线模型。还有开源模型如 bge-reranker-base 和 bge-
reranker-large[1] 等。

若干检索优化技巧

Query Transforming

子问题分解,长prompt压缩,生成补充问题以实现用户问题的提纯。

Output Parser :

要求输出易于解析的answer并使用pydantic等预先校验。

Meta-Data/Self-Query :

在被检索数据中加入诸如标题,页码,日期等信息。

父子块关联 (Auto-Merging) :

在知识分割的时候,同时分割成小块(子块)与天块(交块),小块用来做嵌入与索引,确保语义检索更精确;大块通过小块关联获得,即若与query相关的子块足够多,则返回父块,确保包含更多的上下文信息。

文本块假设问题/摘要生成 :

通过对分割后的知识块做进一步处理,如生成假设问题,提取摘要等,使得在嵌入时生成更多的向量,从而能够包含更丰富的语义信息,使其能够在检索时更容易被捕获,提高知识块被召回的精度。

Classification Step :

使用文档相关的元整数据来对用户的意图领域进行分类。

Sentence Window Retriever :

将文档分割为句子级,检索时同时返回相邻的若干文本块。

上下文压缩 :

对检索到的文本块,根据query的上下文用一个LLM进行压缩,然后对压缩后的文本块进行重排。

Medprompt :

先搜索相关知识,再基于知识生成思维链,再多次调整答案的表述方式,取频率最高的答案作为最终答案。

Stepback-Prompt :

将StepBack-prompt方法集成到RAG过程中,即给出step-
back示例,让LLM生成stepback问题,对stepback问题和原始问题分别进行搜索和重排,然后令LLM进行编排。

记忆模块 :

利用LLM自身的记忆能力来指导检索。原则是找到与当前输入最相似的记忆。例如,Self-
mem送代地使用一个检索增强生成器来创建一个无限的记忆池,结合“原始问题”和“对偶问题”。

多模态RAG

方法

1.使用多模态大模型(如GPT4-V、LLaVA、FUYU-8b)生成图片摘要。

2.对文本/表格/图片摘要进行向量化处理,并存储到多向量检索器中。(如果存在多模态嵌入模型,就无需摘要,直接嵌入)

3.当没有生成应答的多模态大模型时,根据查询召回原始文本/表格和图片摘要。

4.当存在有生成应答的多模态大模型时在对话时,根据查询召回原始文本/表格/图片。

5.构造完整的提示(Prompt),访问大模型生成应答结果。

引用链接

[1] MTEB - Embedding 模型排行榜:
https://huggingface.co/spaces/mteb/leaderboard