浅谈我对RAG的看法
作者: 关于NLP那些你不知道的事 来源: 关于NLP那些你不知道的事
原创作者:咸鱼王
原创地址:https://zhuanlan.zhihu.com/p/666233533
近期检索增强生成(RAG, Retrieved Augmented Generation)获得了业界与学界的广泛关注,但RAG本身并不算是非常新的概念。笔者认为,RAG逐渐升温的原因在于,经过对LLM长期、广泛、深度的探索,LLM主要问题逐渐暴露,从业人员对LLM的注意力也渐渐聚焦到如何让模型具备更可信的指令执行能力上,以使得LLM成为能真正、切实提高生产力的工具而非玩具。
01 RAG要解决的问题
幻觉问题
模型幻觉指模型输出的“事实性”内容中包含虚假、误导性信息,可以说是自LLM横空出世起就悬而未决的一个问题。模型幻觉极大影响了用户对LLM、LLM-based产品的信任度,能否解决幻觉问题、能从多大程度上缓解幻觉问题,都与LLM实际落地的深度、广度息息相关。
模型幻觉部分是LLM的“明知不可为而为之”。为什么这么确认呢?因为不少学者发现,在LLM生成后,让模型自行对结果进行真实性校验,往往能在一定程度上缓解模型的幻觉问题,即此时是模型在明知信息不真实的情况下仍然进行输出导致的幻觉。实际上这也是RL阶段主要在解决的问题:以honest为导向(之一)的Reward Model,在发现LLM输出幻觉结果时进行无情“痛击”,从根本上矫正模型的输出行为与风格。顺带一提,这也是LLAMA2中提到的RM要与chat model保持同源的原因:只有这样RM才能与chat model的认知一致,让chat model知道是因为“说谎”(或因为RM认为自己“说谎”)才挨的打。
但幻觉问题绝不能只归咎于模型本身,也存在部分模型“不知不可为”的情况,或许是因为训练数据中存在噪音或分布偏差,或许是因为知识的out-of-date,或许是因为部分内容的过拟合训练,或许是因为instruction中的误导,导致模型“自信满满”地输出了错误结果。这种情况比第一种更要命:模型在认知上认为这部分信息是无误的,所以很难通过RL或自省等方法进行矫正。
此时RAG的作用就得以显现:通过给定Reference,并限制LLM尽量在Reference的知识范围内进行指令执行:强化/引导模型正确输出的偏好(针对第1种情况),纠正模型错误或过时的认知(针对第2种情况)。
与真实世界实时交互
这个问题似乎和“不知不可为”的情况很像,都可以帮助模型对自身知识进行动态更新,除此之外还有一个作用也相当重要:帮助模型在执行指令时,实时补全空白知识。LLM的训练语料在时间(非实时)、空间(分布有限)上是受限的,LLM在训练完成后自身的认知会局限、固化在训练语料的时空内。RAG则可以帮助LLM突破原有的时空限制,在更广泛的场景下得到应用。即便OpenAI已经掌握了LLM持续更新的能力,这种与真实世界实时交互的需求仍然强烈。
02 检索系统
检索系统作为RAG的另一个核心组件,与LLM真正实现了1+1>2的效果:检索系统为LLM可信输出分担了压力,LLM的强大理解、甄别与推理能力缓解了检索系统高精确的需求。
向量检索
随着LM不断发展,向量检索在检索系统中的占比、权重也在不断提升,逐渐成为检索系统的核心之一。笔者认为,语义表征建模是一个相当吃数据量的场景,在绝大部分通用域或不那么垂的垂域场景下,重新训练embedding模型的成本较大、收益不高,一个参数够大、corpus够多的开源模型足以适配多数场景。此外,向量检索已经有很多基于树、图的近似检索方案,如Faiss、Hnswlib等开源工具也都比较成熟,只要计算资源充足,响应速度基本在几十毫秒甚至几毫秒级别。总体而言,向量检索基本属于开箱即用的水平。
那么哪些场景下需要做embedding模型定制化呢?笔者认为一种情况是知识欠缺,一种情况是语义评估标准漂移。前者很好理解,就是垂域与通用域分布gap太大,以至于很多垂域特有的实体、关系、表达等内容在通用域中鲜有体现,使得模型在这些分布下效果很差。后者是指,如果因为某些垂域化的需求,对语义是否相似的评价标准发生变动时,同样需要重新训练,以下图为例,不同的句子在不同场景或需求下,相似相关关系可能会发生改变。
embedding模型如何训练是个比较大的话题,此处不再展开。但值得一提的是,目前有一些LLM与embedding模型联合训练的方法,此时embedding模型以RAG系统的生成效果优化目标进行embedding模型训练,其目标比仅基于语义相似度的训练方式更加直接、深刻、本质,该目标背后的意义可能包含了语义相似,也可能包含了reference是否合理、常规、信息充足等等。
检索系统
检索系统作为NLP领域经久不衰的方向之一,同样是一个非常大的话题。一个成熟的检索系统包括但不局限于多路召回、粗排、精排等模块,embedding模型可以作为向量检索或rank方法参与到召回、排序的各个流程中。构建并完善检索系统的检索效果,可以说是提升RAG整体效果最直接、快捷的途径之一。
另外笔者想谈谈RAG中的准召平衡,笔者认为至少在RAG的场景下,检索系统的召回比准确相对重要。LLM本身就具备很强的语义理解能力,能够甄别出检索系统误召回的语义不相关负样本,这也是为何笔者认为,检索系统为LLM可分担压力的同时,LLM也缓解了检索系统高精确的需求。但模型的甄别能力仅限语义层面,如下图,譬如事实性负样本,模型就很难处理。
笔者认为,相比传统的检索系统,RAG中的检索系统应更加注重有效信息密度。尽管很多LLM都将MaxSeqLen提到数万token,但并不意味着我们可以肆无忌惮的将信息一股脑塞入Instruction中让模型自行处理,反而种种实验都表明,LLM在处理长文本指令时仍存在“顾此失彼”的现象。因此,为了提升有效信息密度,我们应该在尽量短的Instruction或Reference中,向模型提供尽量多的真实、丰富的信息。这就要求在处理好相关性指标的同时,还要做好chunk、尽量提高召回结果的内容时效性及丰富度、召回结果彼此之间的差异性。
但检索系统始终只是用于摘桃子的工具,往往桃子本身才是整个RAG系统的瓶颈。是否能构建与维护一个真实、可靠的知识库,直接影响到RAG的最终效果。
03 LLM
Reference嵌入策略
早期的reference嵌入策略以embedding融合为主,基于encoder将检索到的topK documents转化为embedding,并在generation阶段通过cross attention的方法与query进行交互,也即Fusion-in-Decoder方法。该方法更多是先前受限于计算资源、MaxSeqLen等条件的不得已而为之。由于embedding嵌入方案多半需要改变模型框架、或对模型进行微调;随着GPT-Like模型大行其道,LLM能支持更长、并能更好地支持更长的文本,In-context的融合策略逐渐成为主流。但不论是哪种融合策略,让模型“感知”到Reference的存在,并懂得依赖Reference进行生成仅仅算是迈出了RAG的第一步。
除非检索库的来源都是专家数据,我们总会面临数据的质量问题,更具体一点,包括数据是否真实、是否存在主观偏好、是否实时、表达或格式是否规范、内容是否翔实等等。因此,教会模型分辨、选择、结合最合适的Reference进行生成,才是RAG系统的核心。
在In-context方案中,通过Instruction细化+完善reference信息(如更新时间、来源、等级),显式、动态地限制、引导模型如何更好的结合Reference进行生成,就能初步达成目标。而embedding方案则需要大量的有监督数据去拟合这种规则。
RAG适配方案
如之前所说,为了让模型能够更好的利用Reference进行生成,我们需要向LLM提供更复杂的Instruction、维度更多的信息,对于参数量较大、更加well-trained的LLM基本不成问题,但参数量较小的LLM就难以理解或遵循复杂的指令信息。因此笔者认为,对于能够较好理解复杂instruction的大规模LLM,更适合prompt engineering的RAG方案;无法直接遵循复杂instruction的较小LLM,更适合fine-tune的方案。
04 现有的问题和挑战
事实冲突时,谁的优先级更高
通过检索系统引入外部信息的初衷是,对LLM进行知识补全或纠正,因此难免会遇到LLM与Reference知识发生冲突的情况。甚至更复杂的情况如Reference之间发生知识冲突时,LLM又应该如何判断?
笔者认为,从RAG的初衷考虑,外部知识优先级应高于LLM本身的知识。但这就对检索系统的检索效果、知识库的构建有较高要求。正如之前所说,检索系统本身难以处理事实性错误的误召回问题,如何通过完善相关信息提高LLM的分辨能力、妥善处理Reference之间发生冲突的生成方案,或许是RAG的一个问题之一。
裁判权要交给LLM吗
为了进一步提高LLM分析、解决问题的能力,从COT、TOT、GOT,到最近很火的self-rag、ReAct、agent等模式,是否调用、何时调用、怎么调用agent的权限被逐渐下放到LLM本身,随之而来的一个问题就是,当模型自以为知道某些信息时,可以选择不再调用检索系统,而实际上这部分知识可能是错误的或过时的。但如果让模型每遇到知识性问题的时候,都调用检索接口,又会造成计算资源极大浪费,总不能1+1=?也要搜一下吧。因此笔者认为,如何妥善处理检索系统裁决权限或调用时机的问题,或许是RAG/agents中的另一个问题。
如何处理多跳问题
多跳问题实际上和上一个问题剥离不开,想要比较好的处理多跳问题,难免需要LLM自行对任务进行分解、分步执行。多跳问题本质上不是单靠RAG就能彻底解决的问题,但又始终是RAG实际落地绕不开的路障。
如何让LLM真正学会RAG
如03节所提及的,让模型“感知”到Reference的存在,并懂得依赖Reference进行生成仅仅算是迈出了RAG的第一步,教会模型分辨、选择、结合最合适的Reference进行生成才是难点。
RAG是检索增强生成,而非检索增强抽取。因为Reference并不总是直接包含答案,也未必总是包含回答问题的所有信息,更未必总是正确,因此教会模型选择、分辨、融合Reference,必要时基于Reference进行汇总或推理,也是RAG的重点。如何基于Instruction或有监督数据影响LLM、需要借助哪些额外信息提高模型的分辨能力,或许都是值得关注的方向。
更多AI工具,参考Github-AiBard123,国内AiBard123