论文:Self-RAG: Learning to Retrieve, Generate, and Critique through Self-Reflection
⭐⭐⭐⭐⭐
arXiv.2310.11511
地址:https://selfrag.github.io/
文章目录
论文速读
以往 RAG 的缺点:以往的 RAG 方案是不加区分地检索文档并使用固定数量的几个文档,而不管问题是否需要检索,以及检索的文档是否有用。
本工作提出了“自我反思检索-增强生成”(Self-RAG)的框架,通过检索增强和自我反思来提高 LLM 生成文本的质量和事实性。
Self-RAG 框架包括两个模型:
- LLM Generator:就像 GPT 一样做 next token prediction
- Critic Model:用来对 LLM 的行为进行评判(不在 inference 阶段起作用,只用于训练阶段)
在 Self-RAG 的文字生成中,我们可以认为模型是一个文本段一个文本段地生成。在 LLM 每次准备生成一个文本段前,都会让判断一下“是否需要检索”,如果不需要检索,那让 Generator 就像 standard LM 一样继续 next token prediction 直到生成出一个文本段;而如果需要检索的话,就先让 Retriver 进行检索得到多个外部候选文档,接下来并行的针对每个候选文档把 prompt + document
输入给 LLM 让其生成一个“回答问题”的候选文本段,然后再评判检索的候选文档与问题是否相关以及 LLM 的生成回答是否合适,这样每个检索到的外部候选文档以及对应的候选生成文本段都可以得到一个评分,根据评分排序,从多个 LLM 输出的候选文本段中选出一个最合适的作为这一轮输出的文本段。重复上面步骤继续得到下一个文本段,一直循环直到回答结束。整个过程的图示如下:
右边的就是 Self-RAG,整个流程就是我们上面解释的那一段。
具体详细的介绍可以参考后面的“inference 阶段”的介绍
为了实现“检索”和“自我反思”,引入了特殊标记 reflection tokens,也就是上图中那些带颜色的方块,分为如下两类:
- retrieval token:指示了是否需要进行检索,有如下三种取值:
yes
:表示接下来需要进行检索,因此会下面会触发 Retriver 来检索相关的文档no
:表示接下来不需要检索,因此接下来会像标准的 LM 一样做 next token predictioncontinue
:代表模型可以继续使用之前检索到的信息片段。这通常发生在一个检索到的段落包含丰富的事实信息,可以用于生成多个文本段的情况下。在这种情况下,模型不需要检索新的信息片段,而是继续利用已有的检索结果来生成文本。
- critique token:用来评估检索的结果和 LLM 生成的文本的好坏,具体来说,ctrique token 又分成了三类:
- IS_REL:根据问题 x 和检索到的文档 d,指示了 d 是否为解决 x 提供了有用的信息。取值集合:
{relevant, irrelevant}
- IS_SUP:根据问题 x、检索到的文档 d、LLM 生成的回答 y,指示了 y 是否被文档 d 支持了。取值集合:
{fully supported, partially supported, no support}
- IS_USE:根据问题 x 和 LLM 生成的回答 y,指示了 y 是否对 x 有用。取值集合:
{5, 4, 3, 2, 1}
- IS_REL:根据问题 x 和检索到的文档 d,指示了 d 是否为解决 x 提供了有用的信息。取值集合:
这些 reflection token 的值其实就是通过 Critic Model 评判出来的。原论文对这些 reflection token 的解释如下:
从上面的介绍可以看出,Self-RAG 有如下的优点:
- 按需检索:没有说固定要检索多少个文档,而是根据具体问题来决定是否检索、检索多少次、对检索的文档是否使用。
- 对 LLM 生成的质量进行二次检查:每次 LLM 生成一个文本段结束后,Critic Model 都会对其生成内容进行检测并评分,每一轮会从多个候选文本段中选出一个最合适的作为本论生成的文本段。
- 为生成的每个段落提供引文:因为我们是每次检索后生成一个文本段,这样就很容易地匹配一个文本段的参考文档,进而可以为用户生成引文。
如下是 Self-RAG 的 input 与 output 的示例:
实现细节
1. 问题的形式化概述
形式上,将用户的问题输入记为 x x x,我们训练一个 LLM Generator M M M 去顺序生成含有多个文本段的文本输出 y = [ y 1 , y 2 , … , y T ] y = [y_1, y_2, \dots, y_T] y