当前位置:   article > 正文

前沿重器[40] | 高级RAG技术——博客阅读

rag rouge

前沿重器

栏目主要给大家分享各种大厂、顶会的论文和分享,从中抽取关键精华的部分和大家分享,和大家一起把握前沿技术。具体介绍:仓颉专项:飞机大炮我都会,利器心法我还有。(算起来,专项启动已经是20年的事了!)

2023年文章合集发布了!在这里:又添十万字-CS的陋室2023年文章合集来袭

往期回顾

最近几篇文章给大家介绍了很多RAG相关的基础技术和调优手段,今天给大家解读一篇写的还不错的文章,介绍了一些通用的高级RAG技术,这里很多模块都可以参考,加入到整个RAG流程中。

最近的RAG文章可以看这里:

今天聊的是这篇外文博客:

  • https://pub.towardsai.net/advanced-rag-techniques-an-illustrated-overview-04d193d8fec6

  • 有对应的翻译:https://zhuanlan.zhihu.com/p/674755232

这篇更多是方法论和思路了,当然,这篇会比较简单,更多是对技术进行介绍,了解内部可能会有哪些可优化点,方便大家进行调优,同时也配合llamaindex和langchain文章有一些进一步的技术建议。(卖个关子,下一篇会配合综述讲一些更加前沿的方案)

最简RAG

所谓的最简RAG,其实就是RAG最简单的形态,之前我已经有把最简RAG的形式用代码给大家展示:(心法利器[105]  基础RAG-大模型和中控模块代码(含代码)),其实核心就是检索和大模型两个模块,把问答内容输入到数据库中,给定query,可以直接去数据库中搜索,搜索完成后把查询结果和query拼接起来送给模型即可,就如下图所示。

4d1cda52f2d945fd7f336abf97d30649.jpeg
img

然而现实情况可能远不如这个这么简单,例如数据源可能就不是问答对的形式,此时无法进行检索,需要分块或者预处理,例如检索效果不足需要调优等,此时就有了高级的RAG。

高级RAG

直接看下图,下图给出了内部比较重要的几个组件及其使用方法。

51bee66dc3df19d71b4509a2d6b788bc.jpeg
img

图还是这个图,内容的讲解方式我想用自己的理解来讲,行文上和原文略有差异,也会多一些自己在现实应用下的经验。

离线的文档处理

文档的处理在很大程度会影响最终的检索效果,而检索效果的好坏基本决定了最终大模型生成效果,检索一旦错了,最终生成的结果就没什么希望能好了。

一般常见的就是长文本了,因为检索效果的限制,以及最终大模型的长度限制,我们是需要对长文本进行分段的,最简单的分段方法,就是移动窗口切,有关文章切分的一些细节技巧,建议大家看看这篇:https://www.pinecone.io/learn/chunking-strategies/,我还没深读和尝试,不过感觉还是有些用的。

文档内容增强

说起检索,大家所致力于的是,让query和doc之间尽可能逼近,这里有相当多的技巧值得大家学习,文章内的技术方案都很有启发性。

  • 句子摘要和拓展。索引的句子(用于被检索到的句子)和用于模型生成的句子可以不是一句,为了让q和d尽可能接近,用于召回的句子可以是通过文段提取的关键句(关键句抽取)、摘要(内容摘要)、问题(问答生成)。

  • 文档合并。基于上一条,如果检索出多个相似的内容,可以将其进行合并摘要(可以用大模型合并也可以不用)。

索引构建和选择

然而更多我们遇到的情况是,我们搜集到的文档的形式并不固定而且变化多样。最简单的应该就是问答对了,我们不需要做很多的预处理,就可以进行qq匹配,qq匹配因为两者在语义空间上非常接近,所以难度骤降,但实际上,我们要面对的可能是结构化的数据,例如各种商品的结构化信息,生产日期、产品类别、重量、产地等,也可能非结构化的文段,文本可长可短,短到几个字,长到一本很厚书、一串晦涩的法律、专利、医学材料,甚至有表格、图像甚至公式等目前技术仍旧不容易解析的结构,我们需要做的,就是把他们转化为“可以检索”的模式。

正因为问题的多样性,我们不能局限在向量化然后向量召回这一个方案里(这对我而言是一个很惨痛的教训,3个月死磕向量召回的效果难以追平一周就完成的在字面匹配,这个论点我会专门写文章在展开说),一方面我们要包容现在可能提及并不多但在特定问题下很有用的索引方式。我这里举几个不好做向量召回的例子及其解决方案吧。

  • 数字信息的检索,并不适合用向量召回。某些政策性的材料,例如“年龄>30岁”,或者是生产日期、库存之类的检索,向量召回肯定都不合适,一方面本身数字的向量其实非常接近,另一方面,用数字索引会很方便,文档可以通过特定的实体识别来获取,并进行结果结构化存储,query也类似,有约束后直接查符合条件的文段或者是产品,会非常方便,准召都很高。

  • 地理方面的检索。“故宫附近的美食”,类似这种,向量召回肯定就不那么合适了。此时会有一些地理方面的索引会比较好做,一般都是通过经纬度转化而来,例如geohash等。

  • 某些专有名词性质比较高的检索,高频的例如音乐、电影等场景,然后类似医疗、机器设备等比较专的领域,例如“周杰伦的音乐”、“阿尔兹海默症”、“reno8”,一方面向量不好学,另一方面很容易出现类似“周杰”(你们熟悉的尔康),向量调起来真的很困难,此时文档进行结构化,抽取关键词,对给定query用实体抽取,必要的时候挖掘一些同义词,准确率的提升会非常明显,召回率虽会有所下降,但这类型的问题,保准肯定是更好的选择。

向量索引并非不重要,他确实是一个更加泛用的选择,大部分问题都能有一定的解决,因此仍建议大家认真了解,之前写过几篇相关文章,大家可以了解一下里面的细节:

检索策略多样性与合并方法

类似前面提到的索引构建可以多样性,检索策略也可以多样性。这点在推荐系统里表现的非常明显,开荒期基本结束后的推荐系统,基本都会有多种召回方式,即我们常说的“多路召回”,通过多个渠道来源召回物料,检索这块也是如此,我们可以从很多角度来划分不同的召回链路,提升召回的多样性和完整性。来说几个比较常见的分路方法。

  • 根据索引方法,可以有字面召回、向量召回等。

  • 根据召回的字段和特征,也可以有不同的召回链路,例如即使都是向量召回,向量的构造也可以多样化,例如基于用户点击的偏好向量,基于语义的语义向量,语义向量有对称和不对称的(qa/qq)等等。

  • 数据库的差异召回。例如百科中可能会有不同的数据来源或者数据库,音乐库、百科库等,对query“周杰伦”,可以去不同的数据库进行召回。

  • query改写前后的召回。很多时候我们会对query做改写,例如之前分享过的一篇文章:前沿重器[38] | 微软新文query2doc:用大模型做query检索拓展,对query进行改写后,也可以单独形成一路。

  • 特别地,用于做广告推广的库,做搜索广告(为了盈利)。

方法有很多,各种方法都有各自的优势,根据具体场景可以进行灵活选择,增加召回链路的目标就是尽可能保证希望找到的那一条数据在这个召回池子里。

而在多路召回之后,我们就要面对新的问题——合并,合并在推荐系统中逐步被演化成“排序”,在检索中也是如此,召回的多了,合并是目标之一,但最终是要从中再筛选出TOPN的,此处就变成了一个排序任务。一般而言,会划分为这两个流派:

  • 规则。在项目前期,或者是没有太多用户反馈数据(例如点击、转化等)的时候,我们往往会选择用规则来进行排序,简单的可以直接按照优先级,例如字面召回的可以排在前面,召回链路交集多的,可以放一起等等,复杂的,可以进行加分,或者多个相似度进行加权求和(字面、语义、热度等等)。

  • 模型。项目后期,有足够的数据或者用户反馈信息下,可以开始考虑用模型,简单的可训练模型往往是基于语义的相似度,但大家在逐步迭代后会慢慢发现,语义相似度不是唯一的指标,很多时候还有一些别的要素,例如内容质量、内容风格,在RAG领域某些大模型对知识的采纳程度可能都是十分重要的因素,此时语义相似度模型可能会不够,对于多特征的方案,比较容易想到的是一些机器学习模型,例如逻辑斯蒂回归、XGBOOST等,而更高级的,可以参考一些魔改深度学习模型的方案。

注意,时刻关注项目迭代的节奏和现状,一方面,方案的选型要把握住最近的关键问题聚焦解决,例如召回都没召回回来,或者压根没有标注数据,此时需要关注的就不可能是排序层的优化,一定是先确保召回池子里有,逐步构造一些用于模型的数据,才能开始考虑模型的迭代,另一方面,短期的方案选型要为后续的长期目标做准备,例如多路召回是后续的预期形态,那短期的设计就要考虑把每个召回链路的逻辑设计好,例如可拓展性、并行性等,有多个向量召回链路,则需要把离线训练和在线推理的pipeline设计好。

查询后处理

在完成检索后,我们能拿到我们最需要的若干个文档,再把他们扔进大模型之前,我们是可以有后处理的机会的。来举几个例子:

  • 文档多、内容长,此时可以先进行一次摘要,再进大模型。

  • 配合文档,可以对query进行一次更新。

  • 通过先询问一次模型,查看回复中那些信息更有利于回答问题,或者没有合适的信息利于回答问题,提前进行拒识。

文章里有给一些langchain和lammaindex的例子,大家可以直接回到原文去看。

多轮与聊天引擎

这里提到的是一个特定的产品形态——对话引擎,而多轮的关键,其实就在于对上下文的理解和使用,比较简单可以实践的方式这里推荐两个:

  • 直接拼接历史对话,供大模型参考。这个可以说是最粗暴的了,但问题是,长对话肯定是吃不消的,而移动窗口,也不那么合适。

  • 对前面的对话进行摘要,配合后续的生成。这个是比较轻便而且通用的方式。

当然,更为复杂或者定制的,可以是一些实体或者意图的提取然后通过显性的方式往下继承。

查询路由与智能体

原文是把这俩分开讲的,但此处我更想合在一起,两个其实有很强的关联性。

这里提到一个查询路由的概念,这个在多轮对话里,其实有点像DP(dialogue policy),即对话策略,这个模块主要决定机器的回复模式,例如拒识、追问、回答问题、索要评价等,简单的可以配合意图识别和规则,就能够完成。当然复杂的,可以结合大模型实现,让大模型来推理对话策略。

能让大模型来决策,其实就已经是agent的范畴了,但当然地agent不止于此,还会有很多应用。就RAG这块,其实很多位置都可以构造agent协助进行各种策略的选择:

  • 最优文档的筛选。

  • 查询策略(查哪个文档,怎么查,信息完整性)、回复策略决策(是否回复,回复什么内容)。

e01c80b41aeea8a24926cdd1d0fc2e59.jpeg

响应合成

最后,就是形成最终的回复了。

最直接的方案,就是把查询得到的文档,配合query以及各种辅助信息(意图实体、对话策略、历史对话)进行有机组合(例如prompt),文章中提到的文档上下分块拓展、提示选择、答案合并,其实都是这么回事,结合实际情况,从简单到丰富迭代升级即可。

模型微调

文章中主要讲的向量召回编码器和大模型的微调,虽然具体场景不止这些,但我先展开聊这俩。

具体的方案,现在的论文挺多的,把编码器和大模型一起微调无疑是最酷的,但实际上也有一些独立训练的模型,效果也还可以,例如编码模型上BGE是还不错的(论文有提及,我个人的角度,可以作为新baseline,但是如果原来就有,切换的收益不见得很高),大模型侧就是sft之类的基本操作了,联合训练这个,文章里专门提了这篇论文:RA-DIT:Retrieval Augmented Dual Instruction Tuning,有兴趣可以去看看。

评估

在效果评估上,对于整个RAG系统,是有端到端的评估方案的,例如答案相关性、答案基础性、忠实度等,当然也可以用和文本生成类似的方案去评估,例如用BLEU、Rouge之类的评估和标准答案的相关性了。

但是,正因为RAG本身是一个系统,内部每个步骤也是可以评估的,例如:

  • 检索层,基本的对答案召回的准确和召回率。

  • 对向量模型,因为一般向量模型的训练都是基于分类的训练策略,所以其本身的评估也可以考虑准确率召回率。

  • 大模型的文本生成,BLEU之类的指标是可以直接使用的。

一般的,系统的效果是存在很明显的短板效应的,某一个模块质量不行对整体的影响会很大,一般而言对整个流程,越偏上游的问题影响越大,毕竟大部分情况下游对前面的容错能力都挺一般的,另一个规律是接近效应,两个模块越接近,两者的影响程度肯定越高。精准、合理的评估方案对问题的定位肯定会有很大帮助。

小结

本文是基于一篇外网大佬的博客进行总结提炼的,同时也带来一些自己的理解,希望能对大家在RAG的日常开发和研究都有帮助吧。不过值得注意的是,本文挺多内容还是偏实战,可能和科研的前沿还有些差距,有些方案很实用但是从前沿技术视角可能不合适能放到论文里,后续还会有文章聊科研方面的一些方案,以综述为窗口来聊这方面的技术,敬请期待。

6120c94e261b1ee66684da5ede52b57a.png

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/81328
推荐阅读
相关标签
  

闽ICP备14008679号