欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 汽车 > 维修 > 一文彻底搞懂Self-RAG【上】:自省式RAG的原理与应用

一文彻底搞懂Self-RAG【上】:自省式RAG的原理与应用

2024/10/25 4:21:42 来源:https://blog.csdn.net/2401_84204413/article/details/139749430  浏览:    关键词:一文彻底搞懂Self-RAG【上】:自省式RAG的原理与应用

之前我们探讨过RAG Flow,其实很难有完美的RAG范式匹配所有需求,毕竟业务需求是复杂的:有的需要绝对的准确性,有的则更看重灵活性;有的用来搜索,有的用来聊天,也有的用来服务其他Agent。后续我们会选择一些典型的RAG研究项目做深入实践,希望对大家在应用时提供更多的参考价值。

Self-RAG,很多朋友或许听过,即自省式RAG。其原始Paper与开源项目很容易看的云里雾里,被一些数学符号与公式吓到,且其中有大量内容是关于算法与模型微调,而应用层面介绍较少。本文将尽量的去繁从简,尽量深入浅出的来说清Self-RAG,相信即使你没有足够的技术背景,也能了解其基本原理。

我们将分成上下两篇细说以下内容:

  1. 为什么会有Self-RAG?

  2. **Self-RAG的工作原理
    **

  3. Self-RAG的实践 - 模型测试

  4. Self-RAG的实践 - 应用测试

  • 基于LlamaIndex

  • 基于LangChain/LangGraph

01

为什么会有Self-RAG

SPRING HAS ARRIVED

Self-RAG是由来自华盛顿大学、IBM人工智能研究院等机构技术专家提出的一种增强的RAG范式,并在基于此理论的原型项目(开源)及其测试中取得了明显优于其他商业大模型或者传统RAG的测试成绩。那么其设计动机来自哪里呢?

这源自于:尽管RAG给LLM带来了一种借助外部知识的补充,来减少知识密集型任务中的事实性错误的方法。但即使抛开上下文长度与响应时间等技术面的顾虑,其在结果输出上也同时带来了一些负面因素,而这正是Self-RAG试图优化的问题:

  • **过度检索。**经典RAG不加区分的对输入问题进行相关知识检索(前K个),可能会反而引入无用甚至偏离的内容,并影响输出结果。

  • **输出一致性问题。**无法确保输出与检索知识中的事实保持一致,因为大模型本身不能保证绝对的遵循;更何况知识的相关性也会存疑。

我们用更通俗白话的方式描述这两个问题。如果说RAG就是允许一个优秀学生(LLM)在考试时查阅参考书,那么这两个问题就是:

  • 不管考试的题目如何,都去翻书,这显然不是效率最高的方法。正确的方法应该是熟悉的问题快速回答,不熟悉的才求助。

  • 虽然翻阅了很多参考知识,但是有时大脑并不会严格的遵循它来回答(甚至知识也可能翻错了),最终仍然会解答错误。

当然,在实际构建RAG应用时,我们一般也会通过Workflow的设计以及Prompt的精心调优在一定程度上尝试优化这两个问题。比如:

  • 在检索之前借助LLM来评判是否需要检索

  • 在Prompt指令中要求LLM严格遵循参考知识进行回答

  • 借助LLM来评估答案,并通过多次迭代来提高答案质量

尽管这些方案在很多时候也能工作的不错,但也会带来诸如复杂度、响应性能以及引入更多的不可控等潜在问题。那么Self-RAG又是怎么做的呢?

02

Self-RAG的工作原理

SPRING HAS ARRIVED

Self-RAG的基本工作原理并不复杂。其最大的不同之处在于:Self-RAG通过在模型层面的微调,让大模型本身直接具备了判断按需检索与自我评判的能力,并进而通过与应用层的配合,达到提升生成准确性与质量的问题。

让我们一步步的来认识Self-RAG的不同。

Self-RAG的基本流程

Self-RAG的基本工作流程用这张图简单说明:

**1. 检索判断。**相对于经典RAG中直接用输入问题检索知识文档,在Self-RAG中首先由模型来决定是需要检索,还是直接输出。

2. 按需检索:

  • 如果无需检索(比如”给我创作一首歌颂母爱的诗歌“),则由模型直接生成。

  • **如果需要检索(**比如”介绍我公司最受欢迎的产品“),则让应用执行检索动作,检索出最相关的Top_K知识。

**3. 增强生成。**使用检索出的K个相关知识与输入问题组装Prompt,一起生成K个输出。(作为对比,在经典RAG中通常是把排序后的K个知识一起组装到Prompt后交给LLM做一次生成输出)。

**4. 评判、选择与输出。**对上一步中增强生成的K个输出响应进行评估打分,并选择分数最高的一个作为最终结果。

Self-RAG中的四种评判指标

仔细看上面的流程,会发现一共会涉及到两个环节需要借助LLM进行评判:

  • 是否需要知识检索以实现增强?

  • 如何对多个输出的响应结果计算评分?

在这两个环节中Self-RAG共设计了四种类型的评判指标,在原文中用了比较严谨的科学化定义:

这里用简单的方式先来理解这四种评判指标,后续再看如何生成这些指标:

1. Retrieve:是否需要知识检索

表示LLM后续的内容生成是否需要做额外知识检索。取值:

  • [No Retrieval]:无需检索,LLM直接生成

  • [Retrieval]:需要检索

  • [Continue to Use Evidence]:无需检索,使用之前内容

2. IsRel:知识相关性(知识 => 问题)

表示检索出来的知识是否提供了解决问题所需的信息。取值:

  • **[Relevant]:**检索出来的知识与需要解决的问题足够相关

  • **[Irrelevant]:**检索出来的知识与需要解决的问题无关

3. IsSup:响应支持度(知识 => 响应)

表示生成的响应内容是否得到检索知识的足够支持。取值:

  • [Fully supported]:输出内容陈述被检索的知识完全支持。

  • [Partially supported]:输出内容陈述只有部分被检索的知识所支持。

  • [No support / Contradictory]:输出内容不被检索的知识所支持(即编造)。

一个例子

比如提供的知识中只有“中国的首都是北京”,而输出内容中有“北京是中国的首都,北京最受欢迎的景点是长城。",那么这里的后半部分输出在提供的知识中就没有得到支持。所以属于部分支持即[Partially supported]。

4. IsUse:响应有效性(响应 => 问题)

**表示生成的响应内容对于回答/解决输入问题是否有用。**取值:

  • [Utility : x]:按有效的程度x分成1-5分,即最高为[Utility:5]

如何生成评判指标?

那么这四种类型的评判指标如何生成呢?又是在什么时候生成?

一种容易想到的方式是借助LLM与Prompt来判断,比如把输入问题与检索知识交给大模型,要求其判断两者相关性,从而得出IsRel(相关性)指标。这种方式的好处是完全在应用层实现,但缺点是:

  • 过多的LLM交互会带来响应性能下降与tokens成本升高

  • 生成的评判指标只能定性的判断,难以量化

Self-RAG采用了一种不同的方法:通过微调训练LLM,让LLM在推理过程中实现自我反省,直接输出代表这些指标的标记性Tokens,即“自省Tokens”。

比如,LLM在生成的时候,可能会发现需要额外的知识补充,就会输出**[Retrieval]并暂停,表示需要知识检索;在获得足够的知识与上下文后,会在输出答案时做自我评估与反省,并插入[Relevant],**[Fully supported]等****这样的标记性token。我们看两个例子:

1.以下LLM的输出内容中携带了相关性等几个指标

Response:****[Relevant] 字节调动的Coze是一个大语言模型的应用开发平台,其提供了一站式开发LLM应用的相关工具、插件与编码环境. [Partially supported] [Utility:5]

2. 以下LLM输出中携带了[Retrieval],表示需要”求助“外部知识

Response: 当然![Retrieval]

通过微调给LLM引入新的Tokens词汇,Self-RAG让LLM自身更加智能并适应后续流程的需要。

当然,这样的模型需要特殊的训练(关于模型的训练我们在后面介绍)。在Self-RAG的开源项目中提供了一个基于llama微调的模型selfrag_llama2_7b。后续我们将借助这个模型来进行Self-RAG的实际应用测试。

如何参考指标来计算评分?

有了LLM输出的这些标记性tokens,后续还需要做量化的比较与评估,用来在多个输出中选择最优答案。但显然上面我们看到的标记tokens并非量化指标,因此这里需要借助到LLM推理输出结果的一个字段 – logprobs,也就是对数概率。LLM输出信息中的大部分在展示给使用者时被应用过滤掉,通常只展示最重要的输出文本结果

一起来理解这个字段与相关算法。

**【**logprobs - 对数概率】

LLM的输出其实就是根据提示预测下一个词元(token)并不断循环,直到全部完成的过程。那么它是怎么预测下一个token呢?并非它明确的知道下一个词元(如果是那样,每次输出就是确定的结果),而是经过一系列复杂运算与神经网络处理,最终输出含有多个可能的下一个token及其概率的列表,然后LLM会从其中选择一个来输出。过程类似(简化掉最复杂的推理部分)下图:

LLM最后从多个候选tokens中选择“机器”这个词输出,并将其附加到输入提示,进入下一次生成。而logprobs就是用来保存这里每一步预测时的多个可能的token概率(取对数,所以叫对数概率)。

【评判算法】

对于上面所说的Self-RAG模型中输出的标记性tokens,也一样可以找到对应的概率。**比如一次输出中出现了[Fully supported]这个token,那么说明LLM推理的时候计算出了[Fully supported]、[Partially supported]等可能的token输出的概率,但最后选择了[Fully supported]。****因此,在评估这次输出的IsSup(响应支持度)的分数时,就可以基于logprobs中这些tokens的概率来计算(**上面例子中,显然[Fully supported]这个token的概率越高,说明支持度越高)。

Self-RAG给出了上面三种评判类型(Retrival类型无需量化)的评估算法:

  • 【IsRel】:知识相关度

即用“relevant”token的概率占本类型两种token的概率和的比例。

  • 【IsSup】:响应支持度

即用“fully supported”token的概率占本类型三种类型token概率和的比例,加上“partially supported”token的概率所占比例。但后者要乘以权重0.5。

  • 【IsUse】:响应有效性

(w = {−_1, −_0_.5,_ 0_,_ 0_.5,_ 1_})_

即用本类型的5种类型token的概率占总概率的比例乘以对应的权重(分别为从-1到1不等),然后求和。

这里以IsSup为例,参考官方的基准测试代码,可以模拟对应的算法实现:

#响应支持度类型的三种标记token  
_IS_SUPPORTED_TOKENS = [  "[Fully supported]",  "[Partially supported]",  "[No support / Contradictory]",  
]  #计算响应支持度得分(IsSup)  
def calc_is_supported_score(  pred_tokens: List[int], pred_log_probs_dict:  List[Dict[str, float]]) -> float:  #最终的的得分  is_supported_score = 0  #首先找到输出的标记token所在的位置,找到就可退出,这个类型的标记token  #只有一个  token_appear_id = -1  for tok_idx, token in enumerate(pred_tokens):  if token in _IS_SUPPORTED_TOKENS:  token_appear_id = tok_idx  break  #如果找到了token位置 ,比如为[fully supported]的位置  if token_appear_id > -1:  #在这个位置上查找所有本类型的三种标记token的输出概率  #保存到issup_score_dict这个字典中  issup_score_dict = {}  for token in _IS_SUPPORTED_TOKENS:  prob = pred_log_probs_dict[token_appear_id][token]  issup_score_dict[token] = np.exp(float(prob))  #用上面的计算公式,来计算最终分数  is_supported_score = (  issup_score_dict["[Fully supported]"]  + 0.5 * issup_score_dict["[Partially supported]"]  ) / np.sum(list(issup_score_dict.values()))  return is_supported_score

整个算法还是比较清晰的:在大模型输出中找到需要的标记性token的位置,然后找到此位置的token预测时的对应概率,然后按照公式计算即可。

需要说明两点:

  • 由于logprobs为对数概率,所以在计算时用指数函数exp转化为正常概率

  • 实际使用时,需要参考使用的推理工具(比如是vLLM或者Llama_cpp)文档,找到其输出参数中的pred_tokes与pred_log_probs_dict这两个内容,作为这里算法输入

至此,我们已经把除模型微调之外的Self-RAG基本原理介绍完。下篇中我们将基于selfrag_llama2_7b这个模型来实现真正的Self-RAG应用。

可能大家都想学习AI大模型技术,也想通过这项技能真正达到升职加薪,就业或是副业的目的,但是不知道该如何开始学习,因为网上的资料太多太杂乱了,如果不能系统的学习就相当于是白学。为了让大家少走弯路,少碰壁,这里我直接把全套AI技术和大模型入门资料、操作变现玩法都打包整理好,希望能够真正帮助到大家。

👉AI大模型学习路线汇总👈
大模型学习路线图,整体分为7个大的阶段:(全套教程文末领取哈)
在这里插入图片描述

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

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

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

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

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

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

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

👉大模型实战案例👈
光学理论是没用的,要学会跟着一起做,要动手实操,才能将自己的所学运用到实际当中去,这时候可以搞点实战案例来学习。
在这里插入图片描述

👉大模型视频和PDF合集👈
观看零基础学习书籍和视频,看书籍和视频学习是最快捷也是最有效果的方式,跟着视频中老师的思路,从基础到深入,还是很容易入门的。
在这里插入图片描述

在这里插入图片描述

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

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

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

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

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

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com