Self-RAG:论文个人学习总结

Self-RAG 是一种创新的端到端 RAG(Retrieval-Augmented Generation)框架,通过整合自检索、自生成和自反思机制,赋予语言模型强大的“元认知”能力。本文深入剖析 Self-RAG 的架构设计、算法流程、训练方法以及实验结果,展示了其在动态检索和自我纠错方面的突破性进展。与传统 RAG 和 CRAG 相比,Self-RAG 凭借内生智能和可学习特性,在多任务场景下显著提升了生成质量和准确性,为未来大模型研究提供了新思路。

1. 论文概述(Motivation & Contribution)

1.1. 研究背景

传统的 RAG(Retrieval-Augmented Generation)框架在生成前会检索外部知识,但存在两个关键问题:

  1. 检索不可控:检索器固定,无法在训练中被优化;
  2. 生成不可监督:模型可能依赖错误检索信息而产生幻觉(hallucination)。

1.2. Self-RAG 的核心思想

Self-RAG(自注意 RAG)引入了自反思机制(Self-Reflection),让模型在训练中同时学习“检索、生成、评价”三种能力:

  • 学会何时需要检索;
  • 学会如何基于检索生成;
  • 学会如何自我批评与修正输出;
  • 代码介绍页



2. 架构与技术核心

把“判断/反思”变成语言模型的输出:训练阶段用少量高质量反思监督训练 Critic,再用 Critic 标注大规模数据训练 Generator;推理阶段 Generator 边写边产生反思 token,按需检索,并把反思概率作为段级奖励与语言模型似然合并进行解码选择。

2.1 前提符号

设输入为 $x$,目标生成序列为 $y=[y_1,\dots,y_T]$,Generator(生成器)为 $M$,Critic(反思判别器)为 $C$,检索器为 $R$。

2.2 Critic 训练目标

    训练 Critic 使其学会在给定 $(x,y)$ 条件下生成反思 token $r$:
    $$\max_C \mathbb{E}_{(x,y,r) \sim D_{\text{critic}}} \log p_C(r \mid x, y).$$

    2.3 Generator 训练目标

    将反思 token 插入到目标序列得到 $(y,r)$,训练 Generator 同时生成内容和反思(训练时屏蔽被检索到的证据文本,对其不计损失):
    $$\max_M \mathbb{E}_{(x,y,r) \sim D_{\text{gen}}} \log p_M((y,r) \mid x). $$

    2.4 段级打分

    在第 $t$ 段生成 $y_t$ 并考虑证据 $d$ 时,使用语言模型似然与反思奖励的加权和作为分数:
    $$
    f(y_t,d) = \log p(y_t\mid x,d,y_{<t}) + S(\text{Critique}).
    $$

    2.5 反思奖励的定义

    反思奖励由若干反思组(例如 ISREL、ISSUP、ISUSE)按线性权重组合:
    $$
    S(\text{Critique}) = \sum_{G\in{\text{ISREL},\text{ISSUP},\text{ISUSE}}} w_G s^t_G,
    $$
    其中组内得分 $s^t_G$ 采用“组内归一化后某理想取值的概率”:
    $$
    s^t_G = \frac{p_t(\hat r)}{\sum_{i=1}^{N_G} p_t(r_i)}.
    $$
    这里 $\hat r$ 是该组中我们期望的“最优”取值(例如 ISREL = relevant),$N_G$ 是组内可能取值数,$w_G$ 为推理时可调权重。该归一化避免因组内类别数不同带来的尺度偏差。




    3. 训练流程(高层)

    • 用 GPT-4 或人工为少量样本制作高质量反思标注,构建 $D_{\text{critic}}$。
    • 在 $D_{\text{critic}}$ 上微调 Critic $C$,学会生成反思 token。
    • 用 $C$ 为大规模指令-输出数据自动标注反思,得到 $D_{\text{gen}}$。
    • 在 $D_{\text{gen}}$ 上微调 Generator $M$,训练目标为 Eq.2(训练时屏蔽证据文本,避免模型“记忆”证据内容)。

      训练要点
      Critic 主要用于离线打标;Generator 的训练目标仍旧是条件语言模型(交叉熵),使模型学会同时生成正文与反思 token。屏蔽(mask)检索文本,保证模型学会把检索作为可读资源,而非生成的文本。




      4. 推理与可控解码

      • 对当前上下文 $x,y_{<t}$,Generator 先输出一个 $Retrieve$ 决策($yes/no/continue$)。
      • 若 $Retrieve = \text{yes}$,调用检索器 $R$ 得到前 $K$ 条证据 ${d_1,\dots,d_K}$。对每个证据并行生成候选续写,并同时产出 ISREL/ISSUP/ISUSE 反思 token 的概率分布。
      • 对每个候选使用公式 $f(y_t,d)$(Eq.3)计算评分,选取最高分段加入输出。
      • 若 $Retrieve = \text{no}$,则直接生成段落并给出 ISUSE 等反思报告。

      注:可控项(推理超参)
      检索阈值:对 $p(\text{Retrieve=yes})$ 设阈值决定是否触发检索。
      组权重 $w_G$:例如增大 $w_{\text{ISSUP}}$ 会提升证据支持优先级但可能影响流畅性。
      段长度、段级 beam 大小 $B$、检索条数 $K$ 等影响性能与延迟的工程参数。




      5. 伪代码

      def generate_segment(model, retriever, context, beam_size=4, K=5, weights):
          # 决定何时检索
          p_retrieve = model.predict_reflection(context, token='Retrieve')
          if p_retrieve['yes'] > RETRIEVE_THRESHOLD:
              docs = retriever.top_k(context, k=K)
          else:
              docs = [None]
      
          candidates = []
          for d in docs:
              beams = model.beam_gen(context, evidence=d, beam_size=beam_size)
              for y_t, probs in beams:
                  # 获取各种标注的概率
                  p_ISREL = model.predict_reflection_prob(context + y_t, 'ISREL')
                  p_ISSUP = model.predict_reflection_prob(context + y_t, 'ISSUP')
                  p_ISUSE = model.predict_reflection_prob(context + y_t, 'ISUSE')
      
                  # 计算分数
                  s_ISREL = p_ISREL['relevant'] / sum(p_ISREL.values())
                  s_ISSUP = p_ISSUP['fully'] / sum(p_ISSUP.values())
                  s_ISUSE = p_ISUSE['5'] / sum(p_ISUSE.values())
      
                  critique_score = (weights['ISREL']*s_ISREL +
                                    weights['ISSUP']*s_ISSUP +
                                    weights['ISUSE']*s_ISUSE)
      
                  f_score = probs.log_likelihood + critique_score
                  candidates.append((y_t, d, f_score))
      
          best = max(candidates, key=lambda c: c[2])
          return best.y_t, best.d

      发表回复

      您的邮箱地址不会被公开。 必填项已用 * 标注