今天是2024年10月22日,星期二,北京,天气雨。
一场秋雨一场寒,天寒莫忘加衣裳。
今天我们来看两个工作,一个是关于RAG的切分策略,Meta-Chunking,里面基于数学常识提到的边际采样分块(Margin Sampling Chunking)通过LLMs对连续句子是否需要分割进行二元分类,基于边际采样得到的概率差异来做出决策,和困惑度分块(Perplexity Chunking):通过分析困惑度分布特征来精确识别文本块边界的思路值得看看,此外,我们再回顾下切分的一些现有方法跟优缺点。
另一个是直接的文档多模态思路,VisRAG,其中提到的文档图像向量化、召回思路,尤其是为了处理多个检索到的页面,提出的三种机制:页面拼接、加权选择和多图像VLM。页面拼接将所有页面水平拼接成一个图像;加权选择为每个页面生成一个答案,并根据置信度选择最终答案;多图像VLM可以直接接受多个图像作为输入,适用于跨图像推理,是个思路。
多看,多思考,多总结,供大家一起参考并思考。
一、Meta-Chunking文本切分方法
文本分块是RAG落地过程中的一个重要步骤,我们之前也讲过多重方案。
传统的文本分块方法主要基于规则或语义相似性,但这些方法在捕捉句子间细微的逻辑关系方面存在不足。
LumberChunker利用LLMs识别内容开始偏离的位置,但其对LLMs的指令跟随能力要求较高,资源消耗和时间成本较大。
先回顾下已有的方法。
一个是基于规则的分块方法,这种方法将长文本分割成固定长度的段落,例如两百个中文字或单词,不考虑句子边界,例如,Llama index在分割时同时考虑句子的完整性和令牌数量。它优先保持句子边界,同时确保每个块中的令牌数量接近预设阈值。可以使用Llama index中的SimpleNodeParser函数,通过调整块大小参数来控制段落长度。重叠部分通过使用块重叠参数动态重叠段落来处理,确保在分割和重叠过程中保持句子的完整性。
一个是动态分块方法,例如相似性分块使用预训练的句子嵌入模型计算句子之间的余弦相似度。通过设置相似度阈值,选择相似度较低的句子作为分割点,确保每个块内的句子在语义上高度相关。这种方法可以使用Llama index中的SemanticSplitterNodeParser。对于英文文本,可以利用bge-large-en-v1.5模型,对于中文文本,则使用bge-base-zh-v1.5模型。通过调整相似度阈值来控制文本块的大小。
也可以直接利用大模型来进行分块,例如LumberChunker,利用LLMs的推理能力来预测文本中合适的分割点,例如使用具有15亿和72亿参数的Qwen2模型,设置为全精度。
对应的prompt如下:
进一步的,可以看一个新思路,《Meta-Chunking: Learning Efficient Text Segmentation via Logical Perception,designed two strategies based on LLMs: Margin Sampling Chunking and Perplexity Chunking》,https://arxiv.org/abs/2410.12788,提出关于chunk的方案,Meta-Chunking是指在句子和段落之间的粒度,包含段落内具有深度语言逻辑连接的句子集合,通过引入Meta-Chunking,可以在文本分块过程中更好地保持逻辑连贯性。
设计了两种基于LLMs的策略,一种是边际采样分块(Margin Sampling Chunking):通过LLMs对连续句子是否需要分割进行二元分类,基于边际采样得到的概率差异来做出决策;
另一种是困惑度分块(Perplexity Chunking):通过分析困惑度分布特征来精确识别文本块边界。这种方法通过计算每个句子的困惑度,并分析这些困惑度的分布特征来确定文本块的边界。
先说结论:Meta-Chunking通过识别句子间的深层语言学和逻辑联系,生成逻辑上更加连贯的文本块,这个符合直觉,但也存在一些局限性,特别是在模型依赖性和计算资源需求方面,此外,性能在很大程度上依赖于LLMs的质量和能力,如果模型本身对某些类型的文本理解不足,可能会影响分块的效果。
来看下其实现步骤:
Meta-Chunking的整个过程概述如下图所示:
每个圆圈代表一个完整的句子,句子长度不一致。垂直线表示分段的位置。图底部的两侧揭示了Margin Sampling Chunking和Perplexity Chunking。具有相同背景颜色的圆圈代表一个元块,动态组合以使最终块长度满足用户需求。
1、Margin Sampling Chunking
Margin Sampling Chunking的核心思想是利用LLMs对连续句子是否需要分割进行二元分类,并基于分类结果中的概率差异来决定是否进行分块。
步骤如下:
1)句子分割:首先将文本分割成一系列句子,记为 (x_1, x_2, ..., x_n)。
2)二元分类:对于每个句子 (x_i),使用LLMs进行二元分类,判断它是否应该与前一个句子 (x_{i-1}) 分开,对应的prompt如下:
3)概率差异计算:通过边际采样(Margin Sampling)方法计算出两个分类(是/否分割)的概率差异,记为 (MarginM(x_i))。
4)阈值比较:将计算出的概率差异 (MarginM(x_i)) 与预设的阈值 (\theta) 进行比较。如果 (MarginM(x_i)) 大于 (\theta),则将 (x_i) 与 (x_{i-1}) 分开;否则,将它们合并为一个块。
5)动态阈值调整:阈值 (\theta) 可以动态调整,初始值设为0,然后根据历史的概率差异 (MarginM(x_i)) 计算平均值来更新 (\theta)。
2、Perplexity Chunking
Perplexity Chunking的出发点是通过分析句子的困惑度(Perplexity,PPL)分布特征来精确识别文本块的边界。
困惑度是衡量语言模型对文本预测能力的一个指标,困惑度越低,表示模型对文本的预测越准确。对于大规模文本处理任务,增加上下文长度有助于LLMs做出更有效的逻辑推理和语义理解,从而降低了PPL。这表明高PPL可能反映了LLMs对真实内容的认知幻觉,这些部分不应被分块。
步骤如下:
1) 句子分割:与Margin Sampling Chunking类似,首先将文本分割成一系列句子;
2)困惑度计算:对于每个句子 (x_i),基于前面的文本来计算其困惑度 (PPLM(x_i));
3)寻找最小值:通过分析困惑度序列 (PPLseq = (PPLM(x_1), PPLM(x_2), ..., PPLM(x_n))) 的分布特征,尤其是寻找序列中的最小值点。这些最小值点被视为潜在的分块边界;
4) 确定分块边界:如果某个句子 (x_i) 的困惑度 (PPLM(x_i)) 小于其前一个和后一个句子的困惑度(即 (PPLM(x_{i-1})) 和 (PPLM(x_{i+1}))),并且差异超过设定的阈值 (\theta),则将 (x_i) 作为分块的边界;
5) 处理长文本:对于超出LLMs处理范围的长文本,引入关键值(KV)缓存机制。在计算困惑度时,适时移除前面部分文本的KV对,以避免GPU内存溢出,同时尽量保持上下文连贯性。
第二种思路很符合直接,很有趣,我们来清洗预训练数据时候,也经常用到这种思路。
二、关于多模态文档RAG思路VisRAG
多模态的文档RAG目前也出现了许多思路,而现有的RAG系统主要基于文本,无法有效利用视觉信息如布局和图像,这些信息在现实世界中的多模态文档中起着至关重要的作用,因此一种思路是采用基于视觉的RAG方法(VisRAG),通过使用视觉语言模型(VLM)直接处理文档图像,从而保留原始文档中的所有信息。
例如下图所示:
文本检索增强生成(TextRAG)在左侧,与基于视觉的检索增强生成(VisRAG)在右侧的对比。传统的基于文本的检索增强生成(TextRAG)依赖于解析后的文本进行检索和生成,这在多模态文档中会丢失视觉信息。
一个具体的例子如下:
最近的工作《VisRAG: Vision-based Retrieval-augmented Generation on Multi-modality Documents》(https://arxiv.org/abs/2410.10594, https://github.com/openbmb/visrag)可以看看,核心在于如何做多模态数据检索,并融合做生成,从实现思路上,包括两个阶段:
一个是检索阶段: VisRAG-Ret使用双编码器范式,但采用VLM而不是LLM来编码查询和文档。具体来说,查询和文档分别作为文本和图像输入到VLM中,生成一系列隐藏状态,然后通过位置加权平均池化得到最终的嵌入。相似度得分通过余弦相似度计算,优化使用InfoNCE损失。
另一个是生成阶段: VisRAG-Gen使用VLM生成答案。为了处理多个检索到的页面,提出了三种机制:页面拼接、加权选择和多图像VLM。页面拼接将所有页面水平拼接成一个图像;加权选择为每个页面生成一个答案,并根据置信度选择最终答案;多图像VLM可以直接接受多个图像作为输入,适用于跨图像推理。
我们来详细看下具体实现细节:
1、检索(Retrieval)
VisRAG的检索阶段(VisRAG-Ret)的目标是给定一个查询q,从文档库D中检索出一组页面。这一阶段采用了双编码器(dual-encoder)范式,但与基于文本的密集检索模型不同,VisRAG使用VLM而不是LLM来编码查询和页面。
编码过程:查询和页面在VLM中分别作为文本和图像进行编码,生成一系列隐藏状态;
嵌入获取:为了得到最终的嵌入,采用了位置加权平均池化(position-weightedmeanpooling)在最后一层VLM隐藏状态上,给予后续的token更高的权重;
相似性评分:通过余弦相似度计算查询和页面嵌入之间的相似性得分;
优化损失:VisRAG-Ret使用InfoNCE损失进行优化,该损失函数考虑了正文档和负文档集合。
2、生成(Generation)
VisRAG的生成阶段(VisRAG-Gen)关注于根据用户查询和检索到的页面使用VLM生成答案。针对多页检索结果,VisRAG提出了以下机制:
页面拼接(PageConcatenation):将检索到的所有页面在DR中拼接成单个图像,以适应大多数只接受单个图像输入的VLM。这通常通过水平拼接实现;
加权选择(WeightedSelection):对于从top-k页面中生成的每个页面的答案,选择置信度最高的答案作为最终答案。最终置信度定义为生成答案的概率的加权和;
接受多个图像的VLM:一些最新的VLM,如MiniCPM-V2.6和Qwen-VL2,被设计和训练为接受多个图像输入以执行跨图像推理。这对于生成可能是有益的,因为所需信息可能位于检索文档集DR的单个页面上,或者对于多跳问题,信息可能分布在多个页面上。
这一步可以看看模型的微调思路,采用的是GPT-4o:
也适用GPT4-O来做图像内容描述:
总结
本文主要介绍了两个工作,一个是知识图谱用于RAG查询扩展的思路,属于知识图谱与RAG的结合范畴,一个是关于RAG发展的一个阶段性综述,提到的几个演化的点和未来的方向,值得看看。
参考文献
1、https://arxiv.org/abs/2410.12788
2、https://arxiv.org/abs/2410.10594
关于我们
老刘,NLP开源爱好者与践行者,主页:https://liuhuanyong.github.io。
对大模型&知识图谱&RAG&文档理解感兴趣,并对每日早报、老刘说NLP历史线上分享、心得交流等感兴趣的,欢迎加入社区,社区持续纳新。
加入会员方式:关注公众号,在后台菜单栏中点击会员社区->会员入群加入