
深入浅出RAG详解:语言模型的“开卷考试”——让模型答案锚定现实的外部“记忆” 精华
引言
大型语言模型(LLMs)彻底革新了自然语言处理领域,但其对静态内部知识的依赖,在事实准确性和时效性方面暴露出根本性局限。检索增强生成(RAG)作为一种强大的范式应运而生,它构建了一种混合架构,将模型输出动态锚定于外部可验证信息。本文将深入探讨RAG框架的核心机制——从检索器与生成器组件到参数化记忆与非参数化记忆的关键区别,揭示其在知识密集型应用中实现前沿性能的奥秘。
一、深入解析检索增强生成(RAG)
RAG范式:参数化记忆与非参数化记忆的融合
大型语言模型(LLMs)在自然语言理解与生成领域实现了重大突破,但其单纯依赖内部知识的模式存在根本缺陷,尤其在对事实准确性和时效性要求极高的任务中更为明显。检索增强生成(RAG)范式通过创建一种融合内部与外部知识源的混合架构,直击这些痛点。
标准语言模型的局限性
标准LLMs将其世界知识完全封装在网络参数中,这种知识存储形式被称为参数化记忆,形成于预训练阶段。可以将其视为模型训练数据的高度压缩隐式摘要。尽管强大,这种模式存在固有缺陷:
- 知识静态化:模型知识在训练结束时便已固化,无法获取训练后新增的信息或事件,导致回答过时。例如,向2022年训练的模型询问2024年超级碗冠军,只能得到猜测或无法回答。
- 更新成本高:修改或更新模型的事实性知识堪称艰巨任务,需要对新的综合数据集进行成本高昂、资源密集的重新训练或微调。对单一事实进行小范围定向更新几乎不可能,且会影响模型的整体知识基础。
- 事实性偏差(幻觉):由于参数化记忆是训练数据的有损压缩,模型无法实现完美记忆。当面对缺乏精确信息的查询时,LLM可能生成听起来合理但事实错误的陈述,这种现象被称为“幻觉”,严重影响模型在法律研究、医疗总结等知识密集型场景中的可靠性。
核心思路:通过外部知识增强生成能力
检索增强生成(RAG)引入了一种更动态、更可靠的方法。RAG系统不再单纯依赖内部的参数化记忆,而是在生成回答前,先从外部知识源检索相关信息。这一核心思路彻底改变了生成过程。通过将输出建立在及时、真实的文档基础上,RAG模型能够产出更具体、准确且可验证的回答。这种增强使系统能够有效访问和利用训练参数之外的知识,缓解了传统LLMs的静态性缺陷。
对比示例:
- 查询:“Django Web框架最新版本引入了哪些关键安全特性?”
标准LLM回答:可能列出通用的网络安全特性(如CSRF保护、XSS预防),因其知识具有通用性,可能未包含最新发布说明。
RAG系统回答:
- 检索:扫描Django官方文档和近期发布博客的语料库。
- 生成:将检索到的信息综合成精准回答,例如:“最新Django版本在密码哈希器中加强了对潜在时序攻击的防护,并增加了对……的支持。”该回答直接基于源文档。
参数化记忆 vs. 非参数化记忆的定义
理解RAG需要区分其采用的两种记忆类型,这一区别是其强大灵活性的核心。
- 参数化记忆:这是编码在神经网络权重(参数)中的隐式知识,通过预训练从海量文本数据中学习而来。这种记忆为模型提供核心能力:通用语言理解、语法规则、推理技巧以及广泛但静态的世界知识基础,是模型流畅性和智能的源泉。
- 非参数化记忆:这是一种显式的外部知识源,如文档集合、数据库或知识图谱。这种记忆不存储在模型权重中,可轻松即时更新,其主要优势包括:
时效性:无需重新训练LLM,即可通过实时信息保持更新。
可验证性:系统可引用来源,使用户能够验证信息并建立信任。
可控性:开发人员可直接控制模型允许访问的信息,降低使用不良或无关数据的风险。
RAG系统巧妙地将参数化记忆的生成流畅性与非参数化记忆的事实准确性和时效性结合在一起。
实用类比:开卷考试
理解RAG的一个有效方式是将其类比为开卷考试:
- 标准LLM类似参加闭卷考试的优秀学生,只能依赖已记忆的知识(参数化记忆),虽可能对学科有深刻理解,但可能遗忘细节或不知新发现。
- RAG系统则如同同一学生参加开卷考试,既利用自身智力与理解(参数化记忆)构建答案,又可查阅指定教材或笔记(非参数化记忆)获取具体事实、数据和引语,最终产出更准确、详细且可信的回答。
二、高层架构:检索器与生成器的双重奏
RAG架构从根本上由两个核心组件按顺序协同工作构成:检索器(Retriever)和生成器(Generator)。
1. 检索器:信息搜索引擎
给定输入提示,检索器的任务是搜索外部知识语料库并获取最相关的信息。这一过程并非简单的关键词搜索,而是旨在理解查询背后语义的语义搜索。
工作原理:
- 索引构建:外部知识语料库(如PDF、文本文件、数据库记录)经过预处理,被分割为可管理的块,每个块通过专门的嵌入模型转换为数值向量(“嵌入”)。这些向量存储在高效的可搜索索引中,即向量数据库(如Pinecone、Chroma、FAISS)。
- 检索过程:用户提交查询时,使用同一嵌入模型将其转换为向量。检索器通过相似度搜索(如余弦相似度)查找索引中与查询向量最接近的文档向量。
- 输出传递:检索器将原始提示和匹配度最高的文档块文本传递给生成器。
检索器的质量至关重要:若获取的文档无关,生成器将产出低质量、不相关的回答。
2. 生成器:综合语言大师
生成器是预训练的LLM(如GPT-4、Llama 3或T5),擅长理解上下文并生成类人文本。它接收原始输入提示和检索器获取的丰富事实性上下文。
工作原理:
检索到的上下文经过格式化后,被添加到原始查询之前,形成增强提示。
# 生成提示的概念结构
retrieved_context = """Document 1: RAG检索器通过将文档和查询转换为嵌入向量工作...
Document 2: 像Pinecone这样的向量数据库使用近似最近邻算法..."""
user_query = "RAG系统中的检索器如何工作?"
final_prompt = f"""使用以下上下文回答问题。若答案不在上下文中,请说明未知。
上下文: {retrieved_context}
问题: {user_query}"""
生成器利用此增强提示,综合出最终连贯且基于知识的回答。其输出不仅以用户查询为条件,还以检索器提供的事实信息为基础,显著降低幻觉风险,确保回答基于可靠来源。
本部分核心要点
- LLM局限性:标准LLMs因依赖固定的内部参数化记忆,存在知识静态化、更新困难和易产生幻觉等问题。
- RAG目标:通过在生成回答前为LLM提供外部最新知识源(非参数化记忆),解决上述局限性。
- 参数化与非参数化对比:参数化记忆是模型权重中的隐式知识,提供通用智能;非参数化记忆是显式、外部且易更新的数据源,提供事实依据。
- 核心组件:RAG系统由检索器(通过向量数据库中的语义搜索查找相关信息)和生成器(基于原始查询和检索上下文综合回答的LLM)组成。
三、底层技术:RAG模型架构与训练
RAG的高层架构融合了检索器和生成器,但构建稳健的系统需关注这些组件的具体模型及其训练方法。RAG框架采用复杂方法确保组件协同优化,将标准语言模型转化为动态知识注入系统。
检索器:密集段落检索(DPR)与FAISS快速搜索
检索器的目标是从海量知识语料库中筛选出最可能包含查询答案的文档。RAG通过高效的双编码器架构——密集段落检索(DPR)实现这一目标。
双编码器架构
DPR使用两个独立的基于Transformer的编码器(通常源自BERT),为文本创建有意义的向量表示:
- 查询编码器(Query Encoder):为输入查询
x
计算单个密集向量嵌入。“密集”指其为连续多维向量,每个维度代表文本的学习特征。 - 段落编码器(Passage Encoder):为知识语料库中的每个文档
d
执行相同操作。关键在于,这些文档嵌入预先计算并存储在索引中,使推理时的检索过程极快。
使用FAISS实现高效搜索
面对数百万文档向量,暴力搜索最高点积相似度在计算上不可行。RAG集成向量搜索库(如FAISS,Facebook AI相似性搜索)解决此问题。FAISS根据预计算的文档向量构建专用数据结构(索引),利用量化和分区等技术实现最大内积搜索(MIPS),其速度远快于穷举搜索,使即使用海量语料库,检索器也能在亚线性时间内找到前k个最相似文档向量,实现实时检索。
# 使用DPR和FAISS构建检索器的核心逻辑示例
import torch
from transformers import DprContextEncoder, DprContextEncoderTokenizer
from transformers import DprQuestionEncoder, DprQuestionEncoderTokenizer
import faiss
# 1. 加载预训练DPR模型和分词器
ctx_tokenizer = DprContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
ctx_encoder = DprContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
question_tokenizer = DprQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
question_encoder = DprQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
# 2. 创建虚拟知识语料库
knowledge_corpus = [
"埃菲尔铁塔是巴黎战神广场上的锻铁格子塔。",
"中国长城是一系列由石头、砖块和其他材料建造的防御工事。",
"光合作用是植物用来将光能转化为化学能的过程。"
]
# 3. 预计算文档嵌入(实际应用中仅需计算一次并存储)
with torch.no_grad():
ctx_inputs = ctx_tokenizer(knowledge_corpus, return_tensors="pt", padding=True, truncatinotallow=True)
passage_embeddings = ctx_encoder(**ctx_inputs).pooler_output
print(f"文档嵌入形状: {passage_embeddings.shape}") # (文档数量, 嵌入维度)
# 4. 构建FAISS索引
embedding_dim = passage_embeddings.shape[1]
index = faiss.IndexFlatIP(embedding_dim) # 精确最大内积搜索索引
index.add(passage_embeddings.numpy()) # 向索引添加文档向量
# 5. 执行搜索
query = "什么是埃菲尔铁塔?"
with torch.no_grad():
question_inputs = question_tokenizer(query, return_tensors="pt")
question_embedding = question_encoder(**question_inputs).pooler_output
D, I = index.search(question_embedding.numpy(), k=2) # 搜索前2个最相似段落
print("检索结果:")
for i in range(len(I[0])):
print(f"排名 {i+1}: 文档 '{knowledge_corpus[I[0][i]]}',得分 {D[0][i]}")
生成器:使用BART综合信息
检索器获取前k个相关文档后,生成器的任务是将其综合为单一连贯回答。RAG通常采用预训练的序列到序列(seq2seq)模型,BART是常用且有效的选择。BART的架构(双向编码器+自回归解码器)非常适合此任务,其在去噪任务上的预训练使其擅长从复杂输入(如查询与多个检索文档的拼接)中重建信息。生成器的输入通过将原始查询x
添加到每个检索文档的内容前构建,组合后的文本被馈入BART模型:
[CLS] 查询 [SEP] 文档1标题 [SEP] 文档1文本 [SEP] 文档2标题 [SEP] 文档2文本 ...
BART解码器逐 token 生成最终答案,每一步均关注完整输入序列,使其既能从原始查询中提取上下文,又能将回答锚定在检索文档的事实信息上。这种对外部知识的直接依赖,使RAG输出比标准LLMs更具事实性,显著降低幻觉率。
# 使用Hugging Face RAG分词器准备生成器输入的示例
from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration
tokenizer = RagTokenizer.from_pretrained("facebook/rag-sequence-nq")
query = "什么是埃菲尔铁塔?"
retrieved_docs = [
{"title": "Eiffel Tower", "text": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris."},
{"title": "Champ de Mars", "text": "The Champ de Mars is a large public greenspace in Paris, France, located in the seventh arrondissement."}
]
retrieved_doc_texts = [doc['text'] for doc in retrieved_docs]
retrieved_doc_titles = [doc['title'] for doc in retrieved_docs]
# 分词器处理查询与文档拼接
prepared_inputs = tokenizer.prepare_seq2seq_batch(
src_texts=[query] * len(retrieved_doc_texts), # 每个文档均关联同一查询
doc_texts=retrieved_doc_texts,
return_tensors="pt"
)
# 查看解码后的输入格式
for i in range(len(retrieved_doc_texts)):
print(f"\n--- 生成器输入(文档 {i+1}) ---")
print(tokenizer.decode(prepared_inputs['input_ids'][i], skip_special_tokens=False))
模型变体:RAG-Sequence vs. RAG-Token
RAG框架有两种主要变体,区别在于生成过程中利用检索文档的方式:
- RAG-Sequence:每个查询仅检索一次,获取前k个文档后,使用同一组文档生成整个输出序列,最终回答基于所有检索段落的联合上下文。
- 适用场景:问答等短格式生成,单一聚焦的证据集已足够。
- 优势:计算高效,实现简单。
- RAG-Token:采用更动态的“逐token”检索方式,生成每个token时均可重新检索一组新的前k个文档,使上下文随答案构建而动态变化,适用于主题可能演变的长复杂回答生成。
- 适用场景:撰写段落或总结等长格式生成,答案不同部分可能需要不同证据。
- 优势:复杂任务中可能更准确、细致。
- 缺点:因重复检索,计算成本显著更高。
两种变体的选择是性能与计算资源间的典型权衡。
幕后揭秘:RAG模型架构与训练
RAG的高层架构融合了检索器和生成器,但要构建一个强大的系统,这些组件的具体模型及其训练方法至关重要。RAG框架采用了一种复杂的方法,以确保这两个组件经过优化后协同工作,将标准语言模型转变为一个动态的、注入知识的系统。
检索器:用于快速搜索的密集段落检索(DPR)和FAISS
检索器的目标是在庞大的知识语料库中筛选,找出最有可能包含给定查询答案的文档。检索增强生成(RAG)通过一种称为密集段落检索(DPR)的高效双编码器架构来实现这一目标。
双编码器架构
DPR使用两个独立的、基于Transformer的编码器(通常源自BERT)来创建有意义的文本向量表示:
- 查询编码器(Query Encoder):为输入查询
x
计算一个单一的、稠密向量嵌入。“稠密”是指它是一个连续的多维向量,其中每个维度都代表文本的一个学习特征。 - 段落编码器(Passage Encoder):对知识语料库中的每个文档
d
执行相同的操作。至关重要的是,这些文档嵌入是预先计算并存储在索引中的,这使得推理时的检索过程极其快速。
其核心思想是训练这些编码器,将语义相关的查询和文档映射到共享向量空间中相近的点。训练目标是最大化查询嵌入与其相关段落嵌入之间的点积相似度,同时最小化其与所有其他不相关段落的相似度。这确保了查询向量将与包含其答案的文档向量“最接近”。
使用FAISS进行高效搜索
由于文档向量可能多达数百万个,通过暴力搜索来寻找点积相似度最高的向量在计算上是不可行的。检索增强生成(RAG)集成了诸如FAISS(Facebook AI相似度搜索)之类的向量搜索库来解决这个问题。FAISS会根据预先计算好的文档向量构建一种专门的数据结构——索引。该索引采用量化和分区等技术,实现最大内积搜索(MIPS),其速度比穷举搜索快得多。它使检索器能够在亚线性时间内找到前k个最相似的文档向量,即便处理大规模语料库,也能实现实时检索。
# 此示例演示了使用FAISS设置基于DPR的检索器的核心逻辑
# 注意:需要安装`transformers`、`datasets`和`faiss-cpu`
import torch
from transformers import DprContextEncoder, DprContextEncoderTokenizer
from transformers import DprQuestionEncoder, DprQuestionEncoderTokenizer
import faiss
# 1. 加载预训练DPR模型和分词器
# 段落编码器用于处理文档/段落
ctx_tokenizer = DprContextEncoderTokenizer.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
ctx_encoder = DprContextEncoder.from_pretrained("facebook/dpr-ctx_encoder-single-nq-base")
# 问题编码器用于处理用户查询
question_tokenizer = DprQuestionEncoderTokenizer.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
question_encoder = DprQuestionEncoder.from_pretrained("facebook/dpr-question_encoder-single-nq-base")
# 2. 创建虚拟知识语料库
knowledge_corpus = [
"The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris.",
"The Great Wall of China is a series of fortifications made of stone, brick, and other materials.",
"Photosynthesis is a process used by plants to convert light energy into chemical energy."
]
# 3. 预计算文档嵌入(实际应用中只需计算一次并存储)
with torch.no_grad():
ctx_inputs = ctx_tokenizer(knowledge_corpus, return_tensors="pt", padding=True, truncatinotallow=True)
passage_embeddings = ctx_encoder(**ctx_inputs).pooler_output
print(f"文档嵌入形状: {passage_embeddings.shape}") # (文档数量, 嵌入维度)
# 4. 构建FAISS索引(用于高效搜索)
embedding_dim = passage_embeddings.shape[1]
# 使用IndexFlatIP进行精确的最大内积搜索
index = faiss.IndexFlatIP(embedding_dim)
index.add(passage_embeddings.numpy()) # 向索引中添加文档向量
# 5. 执行搜索
query = "What is the Eiffel Tower?"
with torch.no_grad():
question_inputs = question_tokenizer(query, return_tensors="pt")
question_embedding = question_encoder(**question_inputs).pooler_output
# 搜索FAISS索引,获取前k个最相似的段落(此处k=2)
D, I = index.search(question_embedding.numpy(), k=2) # D: 距离(点积值), I: 索引
print("检索结果:")
for i in range(len(I[0])):
print(f"排名 {i+1}: 文档 '{knowledge_corpus[I[0][i]]}',得分 {D[0][i]}")
生成器:使用BART合成信息
一旦检索器获取到前k个相关文档,生成器的任务就是将它们整合为一个连贯的答案。检索增强生成(RAG)为此采用了预训练的序列到序列(seq2seq)模型,BART是一种常用且有效的选择。BART的架构具有双向编码器和自回归解码器,非常适合这项任务。它在去噪任务上的预训练使其在从损坏或复杂的输入(如与多个检索到的文档连接的查询)中重建信息方面表现出色。
生成器的输入是通过将原始查询x
前置到每个检索到的文档d_i
的内容中创建的。然后,将这个组合文本输入到BART模型中:
[CLS] 查询 [SEP] 文档1标题 [SEP] 文档1文本 [SEP] 文档2标题 [SEP] 文档2文本 ...
BART解码器逐个生成最终答案的标记。在每一步中,它会关注完整的输入序列,使其能够从原始查询中获取上下文,同时将其回答基于检索到的文档所提供的事实信息。这种对外部知识的直接依赖,使得RAG的输出更具事实性,与标准大语言模型相比,显著降低了幻觉率。
# 此示例展示了如何使用Hugging Face RAG分词器准备生成器的输入
from transformers import RagTokenizer, RagRetriever, RagSequenceForGeneration
# 实际应用中,需初始化包含所有组件的完整RAG模型
# 此处仅使用分词器演示输入准备步骤
tokenizer = RagTokenizer.from_pretrained("facebook/rag-sequence-nq")
query = "What is the Eiffel Tower?"
# 假设这些是从之前步骤的FAISS索引中检索到的文档
retrieved_docs = [
{"title": "Eiffel Tower", "text": "The Eiffel Tower is a wrought-iron lattice tower on the Champ de Mars in Paris."},
{"title": "Champ de Mars", "text": "The Champ de Mars is a large public greenspace in Paris, France, located in the seventh arrondissement."}
]
retrieved_doc_texts = [doc['text'] for doc in retrieved_docs]
retrieved_doc_titles = [doc['title'] for doc in retrieved_docs]
# RagTokenizer处理查询+文档的复杂格式,为每个检索到的文档准备一个输入序列
prepared_inputs = tokenizer.prepare_seq2seq_batch(
src_texts=[query] * len(retrieved_doc_texts), # 每个文档均关联同一查询
doc_texts=retrieved_doc_texts,
return_tensors="pt"
)
# 查看解码后的输入格式(模型将处理这些输入以生成答案)
for i in range(len(retrieved_doc_texts)):
print(f"\n--- 生成器输入(文档 {i+1}) ---")
print(tokenizer.decode(prepared_inputs['input_ids'][i], skip_special_tokens=False))
模型变体:RAG-Sequence vs. RAG-Token模型
RAG框架主要有两种变体,它们的区别在于在生成过程中如何利用检索到的文档。
1. RAG-Sequence
- 机制:每次查询执行一次检索,获取前k个文档后,使用同一组文档生成整个输出序列,最终回答基于所有检索段落的联合上下文。
- 适用场景:问答等短文本生成任务,一组单一、有针对性的证据即可满足需求。
- 优势:计算效率高,实现简单。
2. RAG-Token
- 机制:采用更动态的“逐token”检索方式,生成每个token时均可重新检索一组新的前k个文档,使上下文随答案构建而动态变化。
- 适用场景:撰写段落或总结等长格式生成任务,答案不同部分可能需要不同证据。
- 优势:复杂任务中可能更准确、细致。
- 缺点:因重复检索,计算成本显著更高。
两种变体的选择是性能与计算资源间的典型权衡。
端到端训练:联合优化检索器和生成器
RAG最强大的功能之一是它能够进行端到端的训练。这意味着检索器和生成器并非孤立训练,而是在下游任务上一起进行微调。这是通过将检索到的文档z
视为一个潜在变量来实现的。
由于检索步骤(从索引中选择最佳文档)是离散且不可微的,我们无法将最终损失直接反向传播到检索器。RAG论文提出了一个巧妙的解决方案:模型不再选择一个‘最佳’文档,而是对前k个检索到的文档进行边缘化处理。
公式拆解
反向传播机制
通过优化此求和式,最终输出的损失会通过以下两个部分进行反向传播:
- 生成器更新:梯度更新生成器参数,使其更擅长利用提供的上下文(( P(y|x, z) ))。
- 检索器更新:梯度还更新查询编码器的参数(( E_Q )),训练检索器获取生成器可用于产出更好答案的文档,即学习检索使( P(y|x, z) )最大化的段落
z
。
实际训练注意事项
在典型的微调设置中,段落编码器(( E_P ))和文档索引保持冻结状态。这是因为在每个训练步骤中重新计算整个语料库的嵌入向量并重建索引的成本过高。因此,训练信号仅用于微调查询编码器和生成器,创建一个高度协同的系统——检索器精准学习生成器所需的信息类型。
关键技术要点
- 检索器:使用双编码器(DPR)将查询和文档高效映射到共享向量空间,由FAISS提供亚线性时间相似性搜索。
- 生成器:采用像BART这样的序列到序列模型,以原始查询和检索到的文档的连接输入为条件,生成基于事实的答案。
- 模型变体:RAG-Sequence每次查询检索一次(速度快),而RAG-Token为每个生成的标记进行检索(更具动态性,但成本高)。
- 端到端训练:RAG的关键创新在于将检索到的文档视为潜在变量,通过对前k个检索文档的概率边缘化实现联合优化,使梯度能反向传播到生成器和检索器的查询编码器。
RAG实战:性能与应用
在确立了检索增强生成(RAG)的核心架构后,我们现在来探讨它的实际性能和应用。一个模型只有在实际任务中能转化为卓越的成果,其理论上的精妙之处才有价值。检索增强生成(RAG)在多个知识密集型领域展示了其能力,凸显出它的混合存储系统如何带来切实的、最先进的优势。
知识密集型任务中的顶尖性能
RAG在多个开放域问答(ODQA)基准测试中取得了新的最先进成果,包括自然问题(Natural Questions)、网络问题(WebQuestions)和琐事问答(TriviaQA)。与必须从其固定参数记忆中回答问题的标准大语言模型不同,RAG系统可以在推理时查阅庞大的最新知识语料库。这种将回答基于检索到的、可验证证据的能力是其成功的主要推动力。
在开放域问答(ODQA)中,目标是从大量文档中找到问题的准确答案。RAG在这方面表现出色,因为其两阶段过程与该任务完美契合:
- 检索器:密集段落检索器(DPR)首先将搜索空间从数百万个文档缩小到少数几个高度相关的段落。这一步对于效率和准确性至关重要。
- 生成器:基于BART的生成器随后会仔细阅读问题及提供的段落,以合成准确的自然语言答案。
这种方法始终优于仅依赖参数化记忆的模型,后者更容易出现事实性不准确问题,并且如果不进行完全重新训练,就无法适应新信息。使用检索增强生成(RAG),更新知识库就像更新文档索引一样简单,这是一个高效得多的过程。
减轻幻觉并增强事实一致性
标准大语言模型的一个关键故障模式是“幻觉”,即生成看似合理但事实上不正确的信息。检索增强生成(RAG)通过使生成器基于外部可验证的知识来直接缓解这一问题。这使其成为事实准确性至关重要的应用场景中的强大工具。
1. 事实核查(Fact Verification)
在这项任务中,模型必须根据证据来源判断某一陈述的真实性。检索增强生成(RAG)的架构天生适合此项任务,其过程如下:
- 将输入的陈述作为查询内容,检索相关文档。
- 生成器根据证据是否证实该陈述,合成一个判定结果(例如,“支持”或“反驳”)。在诸如FEVER(事实提取与核查)这样的基准测试中,这种基于事实依据的机制显著提高了可靠性。
2. 抽象生成与摘要(Abstractive Generation & Summarization)
对于诸如总结复杂文档之类的长篇生成任务而言,保持事实一致性颇具挑战。RAG-Token模型变体在这方面尤为有效。通过为其生成的每个标记重新检索文档,该模型能够动态转移其关注点。示例:设想创作一篇传记:
- 在撰写有关研究对象早年生活的内容时,RAG-Token会检索有关其童年和教育的文档。
- 当内容过渡到其职业生涯时,它会重新检索,收集有关职业成就的文章。这使其能够构建一个全面且基于事实的叙述,反映源材料的细微差别,而在这项任务上,标准的大语言模型可能会偏离主题或编造细节。
检索器的关键作用:协同合作关系
检索增强生成(RAG)系统的性能在很大程度上取决于其检索器的质量。如果检索器未能找到相关文档,生成器就只能使用质量不佳或不相关的上下文,从而导致答案错误或笼统。整个系统的有效性取决于检索器在正确的时间提供正确知识的能力。
- ( x ) 是输入查询,( y ) 是目标输出(如正确答案),( z ) 是检索到的文档。
- ( P(z|x) ) 是检索器为查询 ( x ) 选择文档 ( z ) 的概率,( P(y|x, z) ) 是生成器在给定查询 ( x ) 和文档 ( z ) 时生成正确输出 ( y ) 的概率。
该公式允许梯度不仅流向生成器,还流向检索器的查询编码器。实际效果是强大的:查询编码器经过微调,生成能够检索帮助生成器产生正确最终答案概率最高的文档的嵌入。简而言之,检索器学会了预测生成器的需求,创建了一个高度协同的系统。
实现权衡:速度、准确性和解码
实现RAG需要进行实际的权衡,主要是在速度和准确性之间。这些选择体现在模型架构和解码策略中。
1. 架构变体
功能 | RAG-Sequence | RAG-Token |
检索节奏 | 每个生成序列检索一次 | 每个生成的标记检索一次 |
上下文 | 静态;整个答案使用同一组文档 | 动态;上下文可随答案构建而变化 |
最适合场景 | 短格式生成(如问答、事实查询) | 长格式生成(如摘要、传记) |
速度 | 高;计算效率高 | 低;由于重复检索,计算成本高 |
准确性 | 对于聚焦查询准确性高 | 对于复杂、多方面的答案可能更高 |
2. 解码策略
生成最终文本序列的方法也对性能有重大影响:
- 贪心解码(快速):在每一步,模型选择单个最可能的标记。这是最快的方法,但可能导致次优或重复的输出,因为它不考虑整体序列质量。
- 波束搜索(全面):波束搜索不只是选择一个标记,而是维护一组 ( k )(“波束宽度”)个最可能的部分序列。它探索更广泛的搜索空间,通常会产生更连贯和高质量的输出。然而,其计算成本随着波束宽度的增加而增加。
- RAG特定解码:在RAG中,生成概率以检索到的文档 ( z ) 为条件。一些高级实现使用“全面”解码方法,其中使用不同的检索文档生成不同的波束假设,最终输出是整体得分最高的那个。这在计算上很昂贵,但可以最大限度地利用检索到的知识。
总结
- 性能优势:RAG通过将生成器基于外部检索证据,在自然问题等知识密集型基准测试中取得了最先进的结果,使其知识库可更新,答案可验证。
- 应用多样:其架构对开放域问答、事实核查(通过根据证据检查陈述)和复杂摘要非常有效,其中RAG-Token变体可防止事实偏差。
- 检索器的重要性:检索器的性能至关重要。RAG的端到端训练将文档视为潜在变量,创造了一种独特的协同作用,使检索器学会查找对生成器任务最有用的文档。
- 实际权衡:实现需要平衡速度和质量。关键决策包括在快速的RAG-Sequence和全面的RAG-Token变体之间进行选择,以及选择解码策略,如快速贪心搜索或更健壮但较慢的波束搜索。
结论
总之,检索增强生成(RAG)代表了从单一、静态的语言模型向动态、知识基础系统的关键转变。通过将参数化记忆的生成流畅性与外部非参数化知识源的事实可靠性相结合,RAG直接解决了大语言模型的关键局限性,如信息过时和幻觉。其优雅的检索器-生成器架构不仅提供了最先进的性能,还为构建更可信、准确和可验证的AI应用提供了实用框架。随着数字信息格局的不断扩展,RAG范式将成为有效和负责任地利用知识的不可或缺的工具。
本文转载自柏企阅文,作者:tailet
