RAG 的优化方案及评估

RAG 的优化方案及评估

笔者大概在2-3个月前开始进行 RAG 项目并学习RAG,通过查看相关资料和论文,并结合笔者的个人应用体验,总结了目前的一些针对RAG框架的优化方案。希望能帮助到和我一样的初学者。

一、RAG Definition

由于通用的 LLM 预训练数据存在限制,缺乏实时知识或者垂直知识,而不断地 fine-tuning又存在较大的成本。因此一种解决该问题的方式出现了。

首先通过 Retrieve 外部知识库的文档来为 LLM 提供补充信息的上下文,并与最初的问题一起被合并成一个 Augmentative 的提示,而后输入LLM 使 LLM 能够 Generate 更有效的回答。顾名思义这就是 RAG (Retrieve Augmentation Generation)

二、General RAG Framework

通用的 RAG 框架如下:

  1. 多文档切分成 chunks;

  2. 将 chunks 索引化并存储,目前基于LLM 对文本进行embedding 从而实现向量化储存的方式比较热门;

  3. query 进入并进行索引匹配,从而检索到相关的chunks(如果是向量化索引,则通过计算向量间的相似度来进行匹配);

  4. 将chunks 内容作为 context 与 query 包装成 prompt 输入LLM,并生成为回答;

  5. 目前大部分对 RAG 的优化都是在如下框架的基础上对环节进行优化,从而提高response的质量。当然也有将 RAG 进行模块化包装,从而使 RAG 组合更加灵活(Langchain 和 LlamaIndex 就是典型的例子)。下一章将详细介绍关于 RAG 的一些优化方式;

三、Advanced RAG

对于 RAG 的优化,下面将结合自身的实践经验以及参考的论文进行说明。

3.1 Query 环节优化

  1. 由于单一的 Query 可能存在噪音和随机性;因此在query 进行检索前,可以对query进行如下操作:
  • 使用 LLM 对 query 进行改写,使之更加规范;

  • 使用 LLM 理解query 意图并生成多个 queries 并行检索;

  • 使用 LLM 将 query 分解成多个 sub query,并进行并行检索。

  • 在查询中加入多轮对话,形成聊天引擎,多次上下文连续查询。

  • ContextChatEngine: 首先检索与用户查询相关的上下文,然后将其与内存缓冲区中的聊天历史记录一起发送给LLM,以便LLM在生成下一个答案时了解先前的上下文。

  • CondensePlusContextMode:在每次交互中,聊天历史记录和最后一条消息都会经过LLM进行融合判断并压缩为一个新查询(如果不相关则直接查询,如果相关则进行融合),然后该查询转到索引,检索到的上下文与原始用户消息一起传递给LLM,以生成一个回答。

个人评价:笔者认为这一环节有一个很重要的目的是为 rerank 而生,以减少 raw 问题检索造成的弱鲁棒性。

3.2 Retrieve 环节的优化(以下的优化都是单独说明,可以进行随意组合)

  1. 总分层级索引(总→细,提高搜索的效率)

创建多层级索引,如第一层索引由摘要组成,另一层由摘要对应的一或多个文档块组成,并分两步检索,首先将query与摘要匹配过滤掉不相关的文档,并只在相关组内检索第二层文档块。

个人评价:这种方式虽然能够通过快速缩小范围的方式来减少检索时间,但是可能考虑到摘要的信息的完整性,这种方式可能会在第一层匹配时忽略掉文档的细节信息,从而导致检索的准确性降低。个人认为,当是知识库巨大,而且文档块的内容较为单一时可以使用;

  1. 父子层级索引(细→总,提高搜索精确问题的准确性)

同样创建多层级索引。如:先将文档按一定方式切分成较大的文本块,形成 parent chunks;在对每个parent chunk 按更细的方式切分成 child chunks,每个child chunk 都有一个其所对应的 parent index。query 检索时,在 sub chunks 中进行检索,后依据被检索到的sub chunks 所对应的 parent index 回至父段块(目的是为了获得更完整完整的上下文),以父段作为最终的增强信息获得答案。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

个人评价:这种方式在匹配时完全依据语义和关键词,能够减少噪音,尤其能够优化当query 所对应的有效信息(或有效提示)较为简短时 parent 所面临的匹配不敏感问题。

  1. 融合或混合搜索(权衡语义和词义的关系)

目前的索引构建有多种方式,包括 sparse 检索和 dense 检索。embedding 向量化索引是 dense 检索的代表,而TF-IDF则是 sparse 检索的代表。dense 检索的方式更专注于query 和 chunks 的语义关系,这就可能导致某些存在明显关键词的chunks 由于语义的不足导致并没有被检索出来,稳健性较弱。因此这时候如果同时使用 sparse 检索方式进行ensemble,增强稳健性(下图是融合的方式表现)。

个人评价:这种融合的方式可以是并行或加权或递进(递进则有点类似与rerank),但是如何达到语义和词义关系的平衡,需要根据实际的运用场景进行调整。(Langchain中的Ensemble Retriever 有类似的实现,LlamaIndex 也可以使用实现可以根据相似度得分、关键词、元数据过滤结果。)Github上也有个专门用于多种混合检索的 python 包:

castorini/pyserini

https://github.com/castorini/pyserini

  1. 多种切分方式并行查询,提高查询的稳健性和全面性

向量检索中chunks的大小以及部分符号会对相似度结果产生较大影响(这种影响在chunks内容相似时尤其明显)。当chunks过小时,没有上下文信息,可能导致宽泛性query 匹配不准确,但能够匹配精准的问题;当chunks过大时,chunk涵盖的信息多,将导致精确的问题匹配时存在噪音,而忽略了chunks中的准确答案,因此为了增加稳健性,采用机器学习中的 ensemble方式,可以同时构建多个chunks 数据集,每个数据集的chunks大小不同(一般依据文档的内容数量选择2~3个切分方式即可),采用并行的方式进行同时匹配。并进行集中排序,选择 top_k 个文本块作为增强内容。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

个人评价:这种方式能够显著提升检索的准确率和鲁棒性,但是也会消耗存储资源和匹配时间,更适合文档数量级较小的情况下,当文档量级非常大,将大大增加资源的消耗。

  1. Rerank

由于检索得到的chunks 并没有经过细致信息的筛选,同时LLM 的输入token长度具有限制,因此一般而言有必要使用更准确的方式对 chunks 与 query 的关系进行rerank,以此增加MMR以及命中率。

一般而言 Rerank 是使用 cross encoder 模型对query 和召回的 chunk 进行逐个排序,由于cross encoder 相对普通的embedding 模型而言更耗资源,推理花费的时间远大于一般模型,因此通常放在最后环节,只对最终的候选 chunks 进行排名。Rerank 模型的效果排名可以参考 MTEB 排行榜。

个人评价:当然考虑到资源和成本,以及大部分cross encoder 模型只能接受不超过512 长度的输入。Rerank 也可以使用embedding 方式或者openai chatgpt,亦或其它简单算法模型进行重排(其中上述递进方式的混合搜索也可以当作 rerank)。本人参考资料写了一个基于chatgpt 的 rerank.py,在实际运用中具有一定的效果,有兴趣的可以联系我。

  1. Embedding|Cross encoder|Retrieve模型微调

由于一般检索过程中使用的模型都是通用型,因此在面对垂直领域运用时效果不一定很好,但是由于这些模型的参数量相比通用的 LLM 小很多很多,因此在条件成本允许的情况下,可以适当地对它们进行微调,从而提升其在垂直领域地检索效果。以下是部分文档中介绍的微调方式。

  • LlamaIndex Embedding 微调方式:https://github.com/run-llama/finetune-embedding/blob/main/evaluate.ipynb

  • Retrieval Augmentation 微调:https://docs.llamaindex.ai/en/stable/examples/finetuning/knowledge/finetune_retrieval_aug.html#fine-tuning-with-retrieval-augmentation

  • cross-encoder 交叉编码微调:https://docs.llamaindex.ai/en/latest/examples/finetuning/cross_encoder_finetuning/cross_encoder_finetuning.html#

个人评价:在成本和数据允许的情况下可以构建pairs 数据进行微调,但是笔者参考了一些相关的项目以及自己的小小经验,不同的 embedding 模型对效果的影响并不会很大。如果chunks很大,建议直接调用 Openai 的text-embedding-ada-002(能够接受8192tokens,看openai官网2024.1.25,已经出了第三代embedding 模型,并且在MTEB 排名top,感兴趣的朋友也可以使用看看。)

  1. 基于 LLM 实现噪声过滤&信息压缩

考虑到最终检索到的 chunks 内容一般会存在无关的上下文,以及LLM的输入有max token的限制,因此可以基于并行的方式;

  • 使用query 分别和检索得到 chunk 输入LLM 进行相关性判断,过滤掉不相关的chunks;

  • 适用 LLM 保留 chunk 中的有用信息,以此减少 augmentative context 的长度。

prompt = f"""You are an information retrieval system,
your task is to identify valuable information in response to a query,
you must exclusively respond with the original sentences selected from the provided paragraph,
o not explain or add any of your own words.
"""
messages = {"role":"system", "content":prompt,
"role":"user", "content": f"the query is:{query}\\n, the paragraph is: {paragraph}"}
openai.Chatcompletion.create(messages=messages, model=model, temperature=0)
  • 根据不同的上下文块生成多个答案,然后将它们连接或总结。

个人评价:这种方法虽然具有一些效果,但是鲁棒性不强,很容易受到 prompt 的影响,稍有不慎可能过滤掉有效的信息,因此当query 真实对应的 chunks 数目较多时,谨慎使用。

  1. DeepMemory

Deep Memory 通过从针对应用程序定制的标记查询中学习索引,将 Deep Lake 的矢量搜索精度显着提高高达 +22%,而不会影响搜索时间。只需几百个提示嵌入示例对和向量存储中最相关的答案就可以实现这些结果。

个人评价:这个优化方式,我还没尝试过,感兴趣的人可以参考 Llamaindex 文档以及https://www.activeloop.ai/resources/use-deep-memory-to-boost-rag-apps-accuracy-by-up-to-22/

  1. 添加元数据

元数据搜索是指在生成响应之前利用额外的信息(元数据)来帮助检索过程,从而提高生成内容的相关性和质量。元数据可以包括各种类型的信息,如文档的标题、作者、发布日期、标签或任何其他描述性数据,这些数据用来提高检索系统的准确性和效率。

Knowledge Graph 知识图谱就是元数据的一种,知识图谱通过提供结构化的、关系丰富的信息,帮助系统更好地理解和处理查询(如实体),从而增强生成内容的相关性和准确性。但是由于构建KG的过程较为复杂,质量波动较大,并且维护成本较为麻烦,应用门槛较高,相对而言使用起来不太方便。

个人评价:这种方式能够增加信息检索的准确性以及相关性,但是实体、关系的提取和构建需要花费一些成本,当然目前已经可以通过LLM 更好地提取相关实体关系,有兴趣的朋友也可以深入研究看看。

以上的方式可以进行多次组合,不同的应用场景所适用的方法也不同。

2.3 RAG 框架的优化

对于以下内容笔者目前只处于了解部分,还没有进行过实验,待笔者项目实验后将再细讲相关体验。

  1. RAG Module(RAG Agent)

RAG Module 将各个功能进行包装,集成了各种方法来增强功能模块,形成工具链,使整个RAG框架更加灵活。目前Langchain 和 LlamaIndex 在这个方面已经做的非常不错,以下为一些常见的模块:

  • Search module: 针对特定场景量身定制,并在语料库上直接搜索。这种集成是使用 LLM 生成的代码、查询语言(例如 SQL 或 Cypher)和其他自定义工具实现的。搜索的数据源可能包括搜索引擎、文本数据、表格数据和知识图;

  • Memory module: 该模块利用LLM的内存能力来指导检索。该方法涉及识别与当前输入最相似的内存。通过使用自己的输出来改进自身的检索增强生成模型,文本在推理过程中与数据分布更加一致。

  • Fusion module: 通过使用 LLM 将用户查询扩展到多个不同视角的多查询方法来解决它们的局限性,从而增强了传统的搜索系统。融合过程涉及对原始查询和扩展查询的并行向量搜索、重新排序以优化结果,并将最佳结果与新查询配对。

  • Routing module: 查询路由决定对用户查询的后续操作,选项范围从摘要、数据库或将不同的路径合并为单个response。Routing Module还为查询选择合适的数据存储,可能包括向量存储、图数据库等,同时也选择索引的层次结构。如,用于多文档存储的摘要索引和文档块向量索引。查询路由器的决策是通过llm调用预定义和执行的,它将查询引导到所选索引。

  • Predict module: 该模块不是直接从数据源检索,而是利用LLM生成必要的上下文。与通过直接检索获得的内容相比,LLM 生成的内容更有可能包含相关信息。(个人目前感觉用处不大)

  1. 自适应检索&递归检索
  • Recursive Retrieval

递归检索通常用于信息检索以此提高搜索结果的深度和相关性。该过程涉及根据先前搜索获得的结果迭代地细化搜索查询。递归检索旨在通过反馈回路逐渐收敛到最相关的信息来增强搜索体验。在复杂搜索场景中,用户的需求从一开始就不完全清楚,或者所寻求的信息是高度专业化或微妙的。该过程的递归性质允许对用户的需求进行持续学习和适应,通常会导致对搜索结果的满意度提高。

  • Adaptive Retrieval

自适应检索指使 LLM 能够主动确定检索的最佳内容从而细化 RAG 框架,提高信息来源的效率和相关性。如 AutoGPT、Self-RAG等模型。Self-RAG 能够判断是否需要检索并且进行自我反思,在检索过程中,其Generator 跨多个段落进行片段级波束搜索,以得出最连贯的序列,如下图(来源于Self-RAG论文)。但是这种方式需要消耗较大的资源成本。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

四、RAG 的评估体系(参考于相关论文)

以下参考论文《Retrieval-Augmented Generation for Large Language Models: A Survey》

  1. 检索质量的评价:
  • MMR(平均倒排率)是一个用于评估推荐系统排序性能的指标。它考虑了用户实际点击的推荐项在推荐列表中的位置。MRR 的计算方式是取用户的每个查询(或推荐请求)的倒数排名的平均值。这个指标更加关注推荐项的排名,越靠前的推荐项影响越大。

  • Hits Rate(命中率)前k项中,包含正确信息的项的数目占比;

  • NDCG(归一化折损累积增益)评估推荐系统排序性能的指标,但相比于 MRR,NDCG考虑了推荐项的相关性。它通过考虑推荐列表中每个位置上的推荐项的相关性分数,以及位置权重,计算一个归一化的累积增益。

  1. 生成质量的评价:

噪声的鲁棒性、信息融合能力、噪声的拒绝能力、反事实的稳健性。

  1. 评价RAG model 的框架

大模型时代,火爆出圈的LLM大模型让程序员们开始重新评估自己的本领。 “AI会取代那些行业?”“谁的饭碗又将不保了?”等问题热议不断。

不如成为「掌握AI工具的技术人」,毕竟AI时代,谁先尝试,谁就能占得先机!

但是LLM相关的内容很多,现在网上的老课程老教材关于LLM又太少。所以现在小白入门就只能靠自学,学习成本和门槛很高

针对所有自学遇到困难的同学们,我帮大家系统梳理大模型学习脉络,将这份 LLM大模型资料 分享出来:包括LLM大模型书籍、640套大模型行业报告、LLM大模型学习视频、LLM大模型学习路线、开源大模型学习教程等, 😝有需要的小伙伴,可以 扫描下方二维码领取🆓↓↓↓

👉[CSDN大礼包🎁:全网最全《LLM大模型入门+进阶学习资源包》免费分享(安全链接,放心点击)]()👈

学习路线

在这里插入图片描述

第一阶段: 从大模型系统设计入手,讲解大模型的主要方法;

第二阶段: 在通过大模型提示词工程从Prompts角度入手更好发挥模型的作用;

第三阶段: 大模型平台应用开发借助阿里云PAI平台构建电商领域虚拟试衣系统;

第四阶段: 大模型知识库应用开发以LangChain框架为例,构建物流行业咨询智能问答系统;

第五阶段: 大模型微调开发借助以大健康、新零售、新媒体领域构建适合当前领域大模型;

第六阶段: 以SD多模态大模型为主,搭建了文生图小程序案例;

第七阶段: 以大模型平台应用与开发为主,通过星火大模型,文心大模型等成熟大模型构建大模型行业应用。

在这里插入图片描述

👉学会后的收获:👈

• 基于大模型全栈工程实现(前端、后端、产品经理、设计、数据分析等),通过这门课可获得不同能力;

• 能够利用大模型解决相关实际项目需求: 大数据时代,越来越多的企业和机构需要处理海量数据,利用大模型技术可以更好地处理这些数据,提高数据分析和决策的准确性。因此,掌握大模型应用开发技能,可以让程序员更好地应对实际项目需求;

• 基于大模型和企业数据AI应用开发,实现大模型理论、掌握GPU算力、硬件、LangChain开发框架和项目实战技能, 学会Fine-tuning垂直训练大模型(数据准备、数据蒸馏、大模型部署)一站式掌握;

• 能够完成时下热门大模型垂直领域模型训练能力,提高程序员的编码能力: 大模型应用开发需要掌握机器学习算法、深度学习框架等技术,这些技术的掌握可以提高程序员的编码能力和分析能力,让程序员更加熟练地编写高质量的代码。

在这里插入图片描述

1.AI大模型学习路线图
2.100套AI大模型商业化落地方案
3.100集大模型视频教程
4.200本大模型PDF书籍
5.LLM面试题合集
6.AI产品经理资源合集

👉获取方式:
😝有需要的小伙伴,可以保存图片到wx扫描二v码免费领取【保证100%免费】🆓

  • 4
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值