Files
2026-05-16 17:16:51 +08:00

18 KiB
Raw Permalink Blame History

title, draft, tags
title draft tags
RAG检索增强生成的数学体系 false
RAG
Retrieval-Augmented-Generation
检索
知识库
大语言模型

RAG检索增强生成的数学体系


一、RAG 的核心问题

1.1 语言模型的参数知识局限

语言模型的参数知识

语言模型 P_\theta(y|x) 中的知识以参数权重的形式存储:

\theta \rightarrow \text{参数化的知识} \rightarrow P_\theta(y|x) \tag{1.1}

问题

  1. 知识陈旧:训练数据有截止日期,无法回答"今天天气如何"
  2. 知识不准确:模型可能产生"幻觉"hallucination生成看似合理但错误的内容
  3. 不可追溯:无法提供答案的来源,用户无法验证

1.2 非参数知识 vs 参数知识

参数知识parametric knowledge

  • 存储在模型权重中
  • 通过训练获得
  • 难以快速更新

非参数知识non-parametric knowledge

  • 存储在外部数据库中
  • 通过检索获得
  • 可以实时更新

核心思想

RAG 将两者结合:让模型学会使用外部检索系统来获取知识,而不是完全依赖参数记忆。

RAG 标准流水线

文档 → 分块(Chunking) → 编码 → 向量库
                    ↓
查询 → 编码 → 检索 → 重排序(Rerank) → 拼接 → LLM生成

**文本分块Chunking**是 RAG 第一步必备流程:

  1. 固定长度分块:按 token 数切分(如 512 tokens
  2. 语义分块:按句子/段落边界切分,保持语义完整
  3. 重叠滑动窗口:相邻块重叠 10%~20%,避免语义割裂

RAG知识融合边界:区分「检索知识优先」与「模型原生知识优先」的 Prompt 调控策略。当二者冲突时,优先保证检索内容的事实性,模型原生知识作为补充参考。

1.3 RAG 的形式化问题

定义RAG 目标)

给定输入 $x$,从外部知识库 \mathcal{K} 中检索相关文档 $z \in \mathcal{K}$,然后基于检索结果生成回答:

P(y | x) = \sum_{z \in \mathcal{K}} P(y | x, z) \cdot P(z | x) \tag{1.2}

或者使用 top-k 检索近似:

P(y | x) \approx P(y | x, z_1, \ldots, z_k) \quad \text{where } z_i = \text{TopK}(x, i) \tag{1.3}

与标准 LM 的区别

标准 LMP(y|x) RAGP(y|x, z_{1:k}) where z_{1:k} = \text{Retrieve}(x, k)


二、检索系统的数学框架

2.1 检索任务的定义

定义(检索任务)

给定查询 x 和文档集合 $\mathcal{K} = {d_1, \ldots, d_N}$,学习一个检索函数:

\text{score}(x, d) = s \in \mathbb{R} \tag{2.1}

使得相关文档的分数高于不相关文档。

数学目标

\arg\max_{d \in \mathcal{K}} \text{score}(x, d) \approx \arg\max_{d \in \mathcal{K}} P(\text{relevant}(d, x)) \tag{2.2}

2.2 稠密检索Dense Retrieval

稠密检索的核心思想

将查询和文档都编码为稠密向量,然后在向量空间中做相似度检索。

定义(编码器)

  • 查询编码器:q = \text{Enc}_q(x) \in \mathbb{R}^d
  • 文档编码器:d = \text{Enc}_d(z) \in \mathbb{R}^d

定义(相似度分数)

\text{score}(x, z) = \langle q, d \rangle = q^\top d = \|q\| \|d\| \cos\theta \tag{2.3}

其中 \theta 是向量夹角。

使用余弦相似度

s = \frac{q^\top d}{\|q\| \cdot \|d\|} \tag{2.4}

2.3 双编码器架构

架构Bi-Encoder

Query x → Enc_q → q ∈ R^d
Doc z   → Enc_d → d ∈ R^d
         ↓
    score = q · d

独立编码

查询和文档使用独立的编码器,这使得预计算文档 embedding 成为可能。

训练损失

使用对比损失训练编码器:

\mathcal{L} = -\log \frac{\exp(\text{score}(q_i, d_i^+))}{\exp(\text{score}(q_i, d_i^+)) + \sum_{j} \exp(\text{score}(q_i, d_j^-))} \tag{2.5}

其中 d_i^+ 是正例文档,d_j^- 是负例文档。

2.4 交叉编码器 vs 双编码器

交叉编码器Cross-Encoder

[Query; Doc] → CrossEncoder → score ∈ R

将查询和文档一起输入,输出它们的相似度分数。

对比

维度 双编码器 交叉编码器
速度 快(预先计算 doc embedding 慢(实时编码)
精度 中等
适合场景 大规模检索 重排序Rerank

TF-IDF 公式

词频-逆文档频率:

\text{tf-idf}(t, d) = \tf(t, d) \cdot \log\frac{N}{df_t} \tag{2.5}

其中 \tf(t, d) 是词 t 在文档 d 中的词频,df_t 是包含词 t 的文档数。

2.5 稀疏检索BM25

稀疏检索的核心思想

使用词频统计来表示查询和文档。

BM25 公式

\text{score}_{\text{bm25}}(x, d) = \sum_{i=1}^n \log\left(\frac{N - df_i + 0.5}{df_i + 0.5}\right) \cdot \frac{tf_i \cdot (k_1 + 1)}{tf_i + k_1 \cdot \left(1 - b + b \cdot \frac{|d|}{\text{avgdl}}\right)} \tag{2.6}

其中:

  • $N$:文档总数
  • $df_i$:包含词 i 的文档数
  • $tf_i$:词 i 在文档 d 中的出现次数
  • $|d|$:文档长度
  • $\text{avgdl}$:知识库内所有文档平均长度
  • $k_1, b$:超参数(英文通常 $k_1=1.5, b=0.75$;中文通常 $k_1=2.0, b=0.8$

优点:无需训练,可解释性强

2.6 混合检索

混合检索

结合稠密检索和稀疏检索:

\text{score}_{\text{fusion}} = \alpha \cdot \text{score}_{\text{dense}} + (1-\alpha) \cdot \text{score}_{\text{bm25}} \tag{2.7}

其中 \alpha \in [0, 1] 是权重。通用场景 $\alpha=0.5$;语义类问题调高稠密权重 $\alpha=0.7$;实体关键词检索调高 BM25 权重 $\alpha=0.3$。

优势

  • 稠密检索捕捉语义相似性
  • BM25 捕捉词汇匹配
  • 两者互补

2.7 ANN 近似最近邻检索

问题:向量库规模庞大(百万/亿级)时,全量计算相似度开销巨大。

解决方案近似最近邻ANN检索在精度和速度之间做权衡。

常用 ANN 算法

算法 核心思想 特点
HNSW 多层跳表结构,逐层收缩搜索区域 速度快,内存占用中等
IVF 倒排索引,将向量聚类后先定位簇 构建快,适合动态更新
PQ 乘积量化,将高维向量压缩为短编码 内存占用极低,精度依赖码本

HNSW 检索过程

输入:查询向量 q搜索参数 ef, m
输出Top-k 近邻

1. 从最上层开始,在当前层贪心搜索
2. 找到当前层的最近邻后,进入下一层
3. 重复直到最底层
4. 使用 ef 参数做更大范围的贪婪搜索

检索质量评估指标

  • 召回率Recall@kANN 返回的 Top-k 中有多少落在真实 Top-k 中
  • QPS:每秒查询数,衡量检索速度

2.8 混合检索的实战流程

查询 → 编码 → 并行检索(稠密 + 稀疏)
                  ↓
            结果融合RRF 或 加权)
                  ↓
            重排序Rerank
                  ↓
           Top-k 送入 LLM

倒数排名融合RRF

score_{\text{RRF}}(d) = \sum_{i=1}^K \frac{1}{k + \text{rank}_i(d)} \tag{2.8}

其中 k 是常数(通常 $k=60$\text{rank}_i(d) 是文档 d 在第 i 个检索系统的排名。


三、RAG 的生成框架

3.1 序列生成模型

RAG-SequenceLewis et al., 2020

整个生成序列只使用一个检索结果:

P(y|x) = \sum_{z \in \mathcal{K}} P(z|x) \cdot \prod_{t=1}^T P(y_t | x, z, y_{<t}) \tag{3.1}

RAG-Token

每个 token 生成时都可以使用检索结果:

P(y|x) = \prod_{t=1}^T \sum_{z \in \mathcal{K}} P(z|x) \cdot P(y_t | x, z, y_{<t}) \tag{3.2}

区别

  • RAG-Sequence整个回答基于同一个检索文档
  • RAG-Token每个词可以参考不同的检索文档

3.2 生成器的数学形式

定义(生成器)

给定查询 x 和检索文档 $z$,生成器 G 输出回答:

y = G(x, z) \tag{3.3}

典型实现是 seq2seq 模型(如 T5、BART

注意:检索文档 z 接到 x 后面作为输入:

\text{input} = [x; \text{sep}; z] \tag{3.4}

3.3 端到端训练的挑战

问题:同时训练检索器 \text{Enc} 和生成器 G 非常困难。

解决方案:两阶段训练

阶段 1独立训练检索器

  • 使用对比学习等方法预训练检索器
  • 或使用预训练的稠密检索模型(如 DPR

阶段 2固定检索器训练生成器

  • 冻结检索器参数
  • 只更新生成器参数

3.4 推理时的 RAG 流程

Algorithm: RAG Inference

输入:查询 x知识库 K
输出:生成回答 y

1. 检索阶段:
   q = Enc_q(x)                          # 编码查询
   scores = [q · d_i for d_i in K]      # 计算相似度
   top_k = argmax_k(scores)              # 取 top-k 文档

2. 生成阶段:
   for each retrieved doc z_i:
       input_i = [x; SEP; z_i]           # 拼接输入
       y_i = G(input_i)                  # 生成回答
       p_i = P(y_i | x, z_i)             # 计算概率

3. 聚合阶段:
   y* = argmax_i P(y_i | x)              # 选择概率最高的
   # 或者使用 token-level 聚合RAG-Token

四、检索器的训练

4.1 对比学习的框架

定义(对比学习目标)

对于查询 q 和相关文档 $d^+$、不相关文档 $d^-$,损失函数为:

\mathcal{L} = -\log \frac{\exp(\text{score}(q, d^+))}{\exp(\text{score}(q, d^+)) + \sum_{d^-} \exp(\text{score}(q, d^-))} \tag{4.1}

物理意义:最大化正例的相似度,同时压制负例的相似度。

4.2 DPR 的训练

DPRDense Passage RetrievalKarpukhin et al., 2020的训练目标

\mathcal{L} = -\log \frac{\exp(q \cdot d^+)}{\exp(q \cdot d^+) + \sum_{i=1}^k \exp(q \cdot d_i^-)} \tag{4.2}

其中 \{d_i^-\}_{i=1}^k 是 batch 内负例。

DPR 温度系数

检索时使用温度参数控制相似度分布的锐度:

P(d | q) = \frac{\exp(\text{score}(q, d) / \tau)}{\sum_{d'} \exp(\text{score}(q, d') / \tau)} \tag{4.3}

其中 \tau 是温度系数:

  • $\tau \to 0$:近似 argmax只返回最相关的文档
  • $\tau = 1$:保持原始相似度分布
  • $\tau > 1$:分布更平滑,增加检索多样性

批量负采样

从同一个 batch 中选取其他查询的正例作为当前查询的负例。

4.3 难例挖掘

难例Hard Negative

简单的负例(与查询完全不相关)对训练帮助有限。需要挖掘"难例"——与查询相关但不正确的内容。

方法

  1. BM25 负采样BM25 返回的相关文档作为难例
  2. 在线难例挖掘:训练过程中动态选择难例
  3. 跨批次难例:使用其他 GPU 上的正例作为负例

4.4 训练中的问题

问题 1检索器与生成器的目标不一致

  • 检索器优化检索相关性
  • 生成器优化生成质量
  • 两者可能不匹配

解决方案

  • 使用生成器的反馈来更新检索器rewards from generator
  • 或使用端到端训练但冻结检索器

问题 2知识库的覆盖度

如果知识库不包含正确答案,检索无法找到正确文档。

解决方案

  • 定期更新知识库
  • 使用多个知识库

四、检索器的训练(续)

4.5 无监督冷启动方案

问题:新知识库没有相关性标注数据,如何启动检索器?

解决方案:无监督冷启动

方法 1反向推理生成伪标签

1. 从知识库中采样文档对 (d_i, d_j)
2. 用预训练语言模型判断:如果 "d_i 相关于 d_j",生成伪标签
3. 用伪标签训练初始检索器

方法 2BM25 作为伪监督信号

  • 用 BM25 检索结果作为"弱标签"
  • 假设 BM25 返回的 Top-1 是相关的(噪声较大但可作为起点)

方法 3批量预训练编码器

  • 在大规模无标注文本上用对比学习预训练编码器
  • 再在任务相关数据上微调

方法 4领域自适应

  • 使用领域内无监督数据做对比学习
  • 如医疗领域:医学教科书 + 医学问答对

4.6 端到端联合训练

问题:两阶段训练的检索器和生成器目标可能不一致。

联合训练目标

\mathcal{L} = \mathcal{L}_G + \lambda \cdot \mathcal{L}_R \tag{4.4}

其中 \mathcal{L}_G 是生成器损失,\mathcal{L}_R 是检索器损失。

挑战

  • 检索器的梯度难以反向传播(离散的最近邻操作)
  • 解决方案:使用软化近似(如软最大相似度)

REPLUGLesci et al., 2023的做法

P(z | x) = \text{softmax}_z(\text{score}(q, d) / \tau) \tag{4.5}

将硬最近邻替换为软概率分布,使检索器可微。


五、RAG 与 LLM 的上下文适配

5.1 LLM 上下文长度适配

问题:检索返回的文档可能超出 LLM 的上下文窗口限制。

主流解决方案

方法 核心思想 适用场景
截断法 直接截断到最大长度 简单快速,丢失尾部信息
摘要压缩 用 small LLM 将文档摘要后再输入 保留核心信息,需额外模型
分层检索 先检索章节,再检索段落 大型文档,知识密集型
令牌平铺 将文档分割后并行处理再聚合 需模型支持长上下文

摘要压缩的具体做法

z_{\text{compressed}} = \text{Summarizer}(z, \text{max\_tokens}) \tag{5.1}

其中 \text{max\_tokens} 是 LLM 上下文能容纳的最大令牌数。

分层检索流程

1. 文档库预先建立篇章结构索引
2. 检索时先定位相关章节(粗粒度)
3. 再在章节内检索具体段落(细粒度)
4. 只将最相关的段落送入 LLM

5.2 重排序架构

背景:混合检索后返回的候选文档可能存在相关性排序不准确的问题。

重排序Re-ranking

检索阶段 → 候选文档 Top-100
                ↓
         Cross-Encoder 打分
                ↓
         重排后 Top-k
                ↓
           送入 LLM

Cross-Encoder 的评分公式

\text{score}_{\text{cross}}(x, d) = \text{CrossEncoder}([x; \text{SEP}; d]) \tag{5.2}

其中 [x; \text{SEP}; d] 是查询和文档的拼接输入。

与双编码器的对比

维度 双编码器 Cross-Encoder 重排
速度 快(预先计算 embedding 慢(实时编码)
精度 中等
适合场景 大规模初筛 精确排序

BGE-Reranker 等模型是典型的 Cross-Encoder 架构,在 HuggingFace 上可直接调用。


六、RAG 的评估

6.1 检索质量的评估

命中率Hit Rate

\text{HitRate}@k = \frac{\text{正确相关文档出现在Top-k内的样本数}}{\text{总查询样本数}} \tag{6.1}

平均倒数排名MRR

\text{MRR} = \frac{1}{|Q|} \sum_{q \in Q} \frac{1}{\text{rank}(q)} \tag{6.2}

NDCGNormalized Discounted Cumulative Gain

\text{NDCG}@k = \frac{1}{\text{IDCG}@k} \sum_{i=1}^k \frac{2^{\text{rel}_i} - 1}{\log_2(i+1)} \tag{6.3}

其中 \text{IDCG}@k 是理想归一化折损累计增益Ideal DCG

6.2 生成质量的评估

端到端评估

在问答、摘要等任务上评估生成质量:

  • Exact MatchEM
  • F1 Score
  • ROUGE-L
  • BLEU

6.3 幻觉问题

RAG 减少幻觉

RAG 通过提供真实文档作为上下文,显著减少了模型编造内容的幻觉问题。

但 RAG 不是万能的

模型仍可能:

  1. 误解检索结果:检索到的文档不包含答案,但模型强行从中提取
  2. 忽视不匹配的检索:检索结果相关但模型没有正确使用

七、数学公式速查

7.1 RAG 核心公式

RAG-Sequence

P(y|x) = \sum_{z} P(z|x) \cdot \prod_t P(y_t | x, z, y_{<t}) \tag{7.1}

RAG-Token

P(y|x) = \prod_t \sum_z P(z|x) \cdot P(y_t | x, z, y_{<t}) \tag{7.2}

7.2 检索公式

余弦相似度

\text{score}(x, z) = \frac{q^\top d}{\|q\| \|d\|} \tag{7.3}

BM25

\text{score} = \sum_i \log\frac{N-df_i+0.5}{df_i+0.5} \cdot \frac{tf_i(k_1+1)}{tf_i+k_1(1-b+b|d|/avgdl)} \tag{7.4}

TF-IDF

\text{tf-idf}(t, d) = \tf(t, d) \cdot \log\frac{N}{df_t} \tag{7.5}

7.3 DPR 对比损失

\mathcal{L} = -\log \frac{\exp(q \cdot d^+)}{\exp(q \cdot d^+) + \sum_j \exp(q \cdot d_j^-)} \tag{7.6}

八、总结

RAG 的核心价值

  1. 扩展知识边界:可以接入实时更新的知识库
  2. 减少幻觉:提供可追溯的真实来源
  3. 知识可更新:无需重训练即可更新知识

关键组件

组件 核心方法 挑战
检索器 双编码器 + 对比学习 检索器与生成器目标对齐
生成器 seq2seq 模型(如 T5 如何有效融合检索内容
知识库 向量数据库 知识覆盖度和更新

RAG 与其他方法的对比

方法 知识更新 可解释性 计算成本
参数 LM 需要重训练 高(训练)
RAG 更新数据库 中等
Fine-tuning 需要重训练 高(训练)

延伸阅读

  1. Lewis et al., "Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks" (NeurIPS 2020)
  2. Karpukhin et al., "Dense Passage Retrieval for Open-Domain Question Answering" (EMNLP 2020)
  3. Izacard & Grave, "Distilling Dense Retrieval for Open-Domain Question Answering" (TACL 2021)
  4. Gao et al., "Precise Zero-shot Dense Retrieval without Relevance Labels" (ICLR 2023)
  5. Khattab et al., "Demonstrate- Search-Predict: Knowledge Retrieval + Language Model" (2023)