AI知识库

53AI知识库

学习大模型的前沿技术与行业应用场景


一文彻底搞懂Self-RAG【上】:自省式RAG的原理与应用
发布日期:2024-04-10 18:49:57 浏览次数: 2374


点个蓝字深入大模型应用


之前我们探讨过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]<paragraph>

通过微调给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应用。


53AI,企业落地应用大模型首选服务商

产品:大模型应用平台+智能体定制开发+落地咨询服务

承诺:先做场景POC验证,看到效果再签署服务协议。零风险落地应用大模型,已交付160+中大型企业

联系我们

售前咨询
186 6662 7370
预约演示
185 8882 0121

微信扫码

与创始人交个朋友

回到顶部

 
扫码咨询