← 返回目录 模块 7 / 8

模块概览

概览
  • 概念总数: 50+ 个核心概念
  • 概念分类: 8 大子模块(训练范式、模型评估指标、GPU 架构基础、RAG、AI Agent 与工具使用、多模态、模型压缩与优化、生产部署)
  • 来源说明: 基于 Phase 2 中 5 个搜索 agent 的 219 个唯一来源,以及 vLLM 源代码和主流 AI 文献
  • 覆盖深度: 每个概念包含定义、工作原理(含公式/代码/配置)、应用场景、对比表格、与其他概念的关系

7.1 训练范式(Training Paradigms)

7.1.1 Pretraining(预训练)

核心概念

预训练(Pretraining)是大语言模型生命周期的第一阶段,其目标是在海量无标注语料上通过自监督学习训练模型掌握语言的基本规律、知识和推理能力。预训练阶段产生的模型称为"基座模型"(Base Model),具备通用的文本理解和生成能力,但不具备特殊的指令遵循或任务执行能力。

语言建模目标

预训练的核心训练目标是语言建模(Language Modeling),即最大化模型对训练文本的预测概率。根据模型架构的不同,有两种主要变体:

因果语言建模(Causal Language Modeling, CLM):用于自回归解码器模型(如 GPT、LLaMA、Qwen)。模型只能根据当前 token 之前的 token 来预测当前 token:

\mathcal{L}_{\text{CLM}} = -\sum_{t=1}^{T} \log P(x_t | x_{<t}; \theta)

其中 \theta 是模型参数,x_{<t} 是位置 t 之前的所有 token。这种单向建模是自回归生成的基础。

掩码语言建模(Masked Language Modeling, MLM):用于编码器模型(如 BERT、RoBERTa)。输入序列中随机遮盖 15% 的 token,模型需要根据上下文(包括左右两侧)预测被遮盖的 token:

\mathcal{L}_{\text{MLM}} = -\sum_{t \in \mathcal{M}} \log P(x_t | x_{\setminus \mathcal{M}}; \theta)

其中 \mathcal{M} 是被遮盖位置的集合,x_{\setminus \mathcal{M}} 是未遮盖的上下文 token。

预训练数据

预训练数据的规模和质量直接决定模型能力:

数据类别占比来源说明
Web 文本60-80%Common Crawl, RefinedWeb规模最大但噪声多
高质量文章10-20%Wikipedia, Books知识密度高
代码5-15%GitHub提升推理和编程能力
多语言数据5-10%各语言维基百科、新闻覆盖低资源语言

训练数据规模演进:GPT-1 (5GB) → GPT-3 (570GB) → LLaMA-2 (2TB) → DBRX (12TB) → DeepSeek-V3 (14.8T tokens)。每一代模型的数据量增长约 3-10 倍。

计算成本

预训练是计算成本最高的环节。以 DeepSeek-V3(671B 总参/37B 活跃参数)为例:

  • 训练数据:14.8T tokens
  • 计算消耗:约 280 万 H800 GPU 小时
  • 硬件成本:约 557 万美元(按租赁价格)
  • 训练时间:约 2 个月(使用 2048 块 H800)

与后续阶段的关系

预训练是微调和对齐的基础。预训练向模型"注入"了世界知识和语言能力,而后续的微调和对齐则负责"塑造"模型的行为方式。没有充分的预训练,后续微调的效果将受到根本制约。

7.1.2 Fine-tuning(微调)

核心概念

微调(Fine-tuning)是在预训练基座模型的基础上,使用特定领域或特定任务的数据进行有监督训练的进阶过程。微调的核心思想是:预训练模型已经学习了通用的语言表示,微调只需在此基础上进行"定向调整"即可适应下游任务。

全量微调(Full Fine-tuning)

全量微调更新模型的所有参数。对于 70B 参数的模型,全量微调需要使用约 560GB 的 GPU 显存(FP16 精度),通常需要 8-16 张 A100-80G 或 H100-80G 显卡。

数学形式:

\theta^* = \arg\min_{\theta} \frac{1}{N}\sum_{i=1}^{N} \mathcal{L}(f(x_i; \theta), y_i)

其中 \theta 是模型的所有参数,N 是训练样本数,\mathcal{L} 是任务相关的损失函数(如交叉熵),f(x_i; \theta) 是模型输出,y_i 是目标标签。

优点:理论上可达到最优适应效果。
缺点:训练成本极高,每个下游任务需要训练并存储完整的模型副本,不便于多任务部署。

参数高效微调(PEFT)

PEFT(Parameter-Efficient Fine-Tuning)只更新一小部分额外参数,冻结预训练参数不变。典型方法包括:

LoRA(Low-Rank Adaptation):

W = W_0 + BA, \quad \text{其中 } B \in \mathbb{R}^{d \times r}, A \in \mathbb{R}^{r \times k}, r \ll \min(d, k)

W_0 是冻结的预训练权重,BA 是低秩分解的增量矩阵,秩 r 通常取 8、16 或 32。训练时只更新 B 和 A,W_0 保持不变。推理时可将 BA 合并入 W_0 中,不增加推理延迟。

AdaLoRA:动态分配参数预算到不同层,重要层分配更多参数,不重要层分配更少。

Prefix Tuning:在输入序列前添加可学习的连续向量(soft prompt),只更新这些向量。

全量微调 vs PEFT 对比

特性全量微调LoRAAdaLoRAPrefix Tuning
可训练参数量100%0.1-1%0.1-1%<0.1%
显存需求100%(基线)30-40%30-40%20-30%
模型存储每个任务一个完整副本共用基础模型 + 小权重同 LoRA共用基础模型
推理延迟无增加可合并为原始权重同 LoRA需拼接 prefix
任务适应能力最强接近全量微调优于 LoRA略弱于 LoRA
适用场景重要任务、资源充足多适配器部署资源优化快速实验

在 vLLM 中的微调部署支持

vLLM 支持动态加载多个 LoRA 适配器,无需重启服务:

# 启动 vLLM 服务,支持 LoRA
python -m vllm.entrypoints.openai.api_server \
    --model meta-llama/Llama-2-7b-hf \
    --enable-lora \
    --max-loras 4 \
    --max-lora-rank 64

# 请求时指定 LoRA 适配器
curl http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d '{
        "model": "meta-llama/Llama-2-7b-hf",
        "messages": [{"role": "user", "content": "翻译成英文:今天天气很好"}],
        "extra_body": {"lora": "path/to/translation-adapter"}
    }'

vLLM 的 LoRA 支持基于 punica kernel 实现批量 LoRA 计算,同一 batch 中的不同请求可以使用不同的 LoRA 适配器,互不干扰。

7.1.3 Instruction Tuning(指令微调)

核心概念

Instruction Tuning(指令微调)是一种特殊的微调方法,通过在大量"指令-回答"对(instruction-response pairs)上训练模型,使其具备理解和遵循人类指令的能力。这是从基座模型(Base Model)到对话模型(Chat Model / Assistant Model)的关键转变。

对话格式训练

指令微调的训练数据采用对话格式,通常包含多轮交互。最常用的格式是 ChatML(Chat Markup Language):

<|im_start|>system
你是一个乐于助人的 AI 助手。
<|im_end|>
<|im_start|>user
请解释量子计算的基本原理。
<|im_end|>
<|im_start|>assistant
量子计算利用量子力学中的两个核心原理——叠加(superposition)和纠缠(entanglement)...
<|im_end|>

ChatML 格式的关键元素:

  • <|im_start|>:标记角色(system/user/assistant)的开始
  • <|im_end|>:标记对话回合的结束
  • 特殊 token ID:这些控制 token 在词汇表中分配特定 ID,训练时它们的 logits 不计入损失函数

损失掩码(Loss Masking):在指令微调的损失计算中,只对 assistant 回复部分的 token 计算损失,对 user 输入和 system prompt 部分进行掩码:

\mathcal{L}_{\text{inst}} = -\sum_{t \in \mathcal{A}} \log P(y_t | x, y_{<t}; \theta)

其中 \mathcal{A} 是 assistant 回复部分的 token 位置集合。这种掩码防止模型在训练中"学习"复述用户的输入,确保模型只学习如何做出有用的回复。

数据构成

高质量的指令微调数据通常包含:

数据类型示例占比作用
通用问答知识性问题、解释30-40%知识检索与解释能力
创作任务写作、翻译、改写15-20%文本生成能力
推理任务数学推理、逻辑分析10-15%推理能力
编程任务代码生成、调试10-15%代码能力
多轮对话上下文连贯交互10-15%对话管理能力
安全对齐拒绝不当请求5-10%安全与无害性

典型数据集

  • OpenAssistant:~16K 人工标注对话
  • ShareGPT:~90K 用户与 GPT 的真实对话
  • Alpaca:52K GPT-4 生成的指令数据
  • Dolly:15K 人工标注指令数据
  • UltraChat:1.5M 多轮对话

与 RLHF 的关系

Instruction Tuning 是 RLHF 的前置步骤。在完整的 RLHF 流程中,Stage 1 就是指令微调(SFT)。基座模型在指令微调后虽然能遵循指令,但输出的"风格"可能不正确——缺乏对齐、容易胡编乱造。RLHF 的后续阶段(Reward Modeling + RL Optimization)负责进一步将模型输出与人类偏好对齐。

7.1.4 RLHF(Reinforcement Learning from Human Feedback)

核心概念

RLHF(基于人类反馈的强化学习)是当前最有效的 LLM 对齐技术之一。它将人类偏好信息通过奖励模型引入强化学习流程,使模型生成结果与人类期望(有用性、诚实性、无害性)保持一致。OpenAI 的 InstructGPT/ChatGPT、Anthropic 的 Claude 等最早采用了这一范式。

四阶段流程

RLHF 包含以下四个阶段:

Phase 1: SFT(监督微调)
  预训练模型 + 高质量指令数据 → 指令遵循模型

Phase 2: 偏好数据收集
  从 SFT 模型采样多个回复 → 人工标注偏好 (good/bad)

Phase 3: Reward Model 训练
  SFT 模型 + 偏好比较数据 → 奖励模型
  数据格式: (prompt, completion_A, completion_B, preference)

Phase 4: RL 优化(PPO)
  SFT 模型 + 奖励模型 → 对齐人类偏好的最终模型
  目标: 最大化奖励,同时保持与 SFT 模型的 KL 散度约束

Bradley-Terry 模型(奖励模型训练)

奖励模型的训练目标是最大化人类偏好数据的似然。给定一个 prompt x 和两个输出 y_w(被偏好)、y_l(不被偏好),Bradley-Terry 模型假设人类偏好概率与奖励值的差异呈逻辑斯蒂分布:

P(y_w \succ y_l | x) = \sigma(r_\phi(x, y_w) - r_\phi(x, y_l))

其中 r_\phi(x, y) 是奖励模型(通常基于 SFT 模型,去掉最后的 unembedding 层,加上一个线性层输出标量),\sigma 是 sigmoid 函数。

训练损失:

\mathcal{L}_{\text{RM}} = -\mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \log \sigma(r_\phi(x, y_w) - r_\phi(x, y_l)) \right]

这个损失函数的直觉是:最大化偏好回复与不偏好回复之间的奖励差距。

PPO 阶段

PPO(Proximal Policy Optimization)是 RLHF 中使用的强化学习算法。其目标函数为:

\mathcal{L}_{\text{PPO}}(\theta) = \mathbb{E}_{t} \left[ \min\left( \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_\text{old}}(a_t|s_t)} A_t,\ \text{clip}\left( \frac{\pi_\theta(a_t|s_t)}{\pi_{\theta_\text{old}}(a_t|s_t)}, 1-\epsilon, 1+\epsilon \right) A_t \right) \right]

对于 LLM 的 RLHF 场景,PPO 损失进一步包含两个约束:

  1. 奖励信号:R(x, y) = r_\phi(x, y) - \beta \cdot D_{\text{KL}}(\pi_\theta(y|x) \| \pi_{\text{ref}}(y|x))
  2. KL 散度惩罚:防止模型过度偏离 SFT 模型,避免奖励黑客(reward hacking)问题:
    D_{\text{KL}}(\pi_\theta \| \pi_{\text{ref}}) = \mathbb{E}_{y \sim \pi_\theta} \left[ \log \frac{\pi_\theta(y|x)}{\pi_{\text{ref}}(y|x)} \right]

完整 PPO 损失:

\mathcal{L}(\theta) = \mathcal{L}_{\text{PPO}}(\theta) + \alpha \cdot \mathcal{L}_{\text{KL}}(\theta)

其中 \beta 控制 KL 惩罚的强度,\alpha 决定了两种损失之间的权衡。

在 vLLM 中的奖励模型支持

vLLM 原生支持奖励模型推理(用于 RLHF 训练中的奖励计算或评估):

# 加载奖励模型
python -m vllm.entrypoints.openai.api_server \
    --model Qwen/Qwen2.5-Math-RM-72B \
    --task token_classify \
    --pooler-config '{"pooling_type": "ALL", "step_tag_id": null}'

# 使用 Score API 获得奖励分数
curl http://localhost:8000/v1/score \
    -H "Content-Type: application/json" \
    -d '{
        "model": "Qwen/Qwen2.5-Math-RM-72B",
        "text_1": "What is 2+2?",
        "text_2": "The answer is 4."
    }'
# 返回: {"score": 2.34}  (越高表示回复越好)

过程奖励模型(PRM)的 StepPool 实现:

class StepPool(AllPool):
    def forward(self, hidden_states, pooling_metadata):
        # 1. 调用 AllPool 获得全 token 输出
        pooled_data = super().forward(hidden_states, pooling_metadata)
        # 2. 只提取 step_tag_id 位置的隐藏状态
        step_mask = (input_ids == step_tag_id)
        return pooled_data[step_mask]

RLHF 的挑战

  1. 训练不稳定:PPO 对超参数敏感,KL 惩罚系数 \beta 的调节需要大量实验
  2. 奖励黑客:模型学会通过"取巧"获得高奖励而非真正改善质量
  3. 奖励泄露:奖励模型可能学到表面特征(如偏好更长回复)而非真正的质量信号
  4. 计算开销大:需要同时运行策略模型、参考模型、奖励模型和价值模型,共 4 个模型

7.1.5 DPO(Direct Preference Optimization)

核心概念

DPO(直接偏好优化)由 Rafailov 等人于 2023 年提出,是一种无需独立奖励模型的偏好优化方法。DPO 的核心洞察是:RLHF 中的奖励函数可以表示为策略模型和参考模型的概率比,因此可以直接在偏好数据上优化策略模型,无需训练单独的奖励模型。

数学推导

DPO 的出发点是将 RLHF 的最优策略解表示为闭式形式。经典的 RLHF 目标是:

\max_{\pi_\theta} \mathbb{E}_{x \sim \mathcal{D}, y \sim \pi_\theta(y|x)} \left[ r(x, y) \right] - \beta \cdot D_{\text{KL}}(\pi_\theta(y|x) \| \pi_{\text{ref}}(y|x))

这个优化问题有已知的闭式解:

\pi^*(y|x) = \frac{1}{Z(x)} \pi_{\text{ref}}(y|x) \exp\left( \frac{1}{\beta} r(x, y) \right)

其中 Z(x) 是配分函数。反过来,奖励函数可以用策略比率表示:

r(x, y) = \beta \log \frac{\pi^*(y|x)}{\pi_{\text{ref}}(y|x)} + \beta \log Z(x)

将奖励函数代入 Bradley-Terry 偏好模型:

P(y_w \succ y_l | x) = \sigma\left( r(x, y_w) - r(x, y_l) \right)

配分函数 Z(x) 消掉了!得到:

P(y_w \succ y_l | x) = \sigma\left( \beta \log \frac{\pi_\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)} \right)

最终 DPO 损失函数:

\mathcal{L}_{\text{DPO}}(\theta) = -\mathbb{E}_{(x, y_w, y_l) \sim \mathcal{D}} \left[ \log \sigma\left( \beta \log \frac{\pi_\theta(y_w|x)}{\pi_{\text{ref}}(y_w|x)} - \beta \log \frac{\pi_\theta(y_l|x)}{\pi_{\text{ref}}(y_l|x)} \right) \right]

DPO vs RLHF 对比

特性RLHF (PPO)DPO
需要独立奖励模型是否
训练计算成本高(需同时运行 4 个模型)低(只需策略模型 + 参考模型)
训练稳定性超参数敏感,容易崩溃相对稳定
数学基础强化学习(策略梯度)直接偏好优化(闭式解)
对数据质量要求中等高(偏好数据需要更精确)
性能天花板理论上更高可能受限于闭式解假设
代表模型GPT-4, Claude-3Llama-3, DBRX, Qwen-2

局限性

DPO 的一个关键假设是存在一个在偏好数据上表现良好且无需进一步 KL 正则化的最优策略。当偏好数据存在噪声或不一致时,DPO 可能不如 PPO 稳健。此外,DPO 不支持在线采样——它只能从已有的偏好数据中学习,无法像 PPO 那样通过与环境的交互动态采样和优化。

7.1.6 GRPO(Group Relative Policy Optimization)

核心概念

GRPO(Group Relative Policy Optimization)是 DeepSeek-R1 中使用的强化学习方法,是 PPO 的一种变体。它的核心创新是:在组/群组内对多个采样回复进行相对比较,替代了 PPO 中需要价值网络(critic/value model)来估计优势函数的方法。

工作原理

GRPO 的工作流程如下:

1. 给定 prompt x,从当前策略 π_θ 采样 G 个回复 {y_1, y_2, ..., y_G}
2. 为每个回复计算奖励 r(x, y_i)
3. 在组内计算优势函数:
   A_i = (r(x, y_i) - mean(r)) / std(r)
4. 使用组内优势更新策略 π_θ
5. 加入 KL 散度约束,防止偏离参考模型

核心优势函数

GRPO 的优势函数基于组内统计量,而非价值网络的估计:

A_i = \frac{r(x, y_i) - \mu_G}{\sigma_G}

其中 \mu_G = \frac{1}{G}\sum_{j=1}^G r(x, y_j),\sigma_G = \frac{1}{G}\sum_{j=1}^G (r(x, y_j) - \mu_G)^2 是组内奖励的均值和标准差。

关键洞察:通过组内标准化,GRPO 消除了对价值网络的需求。价值网络是 PPO 中最易崩溃的组件之一,因为它需要为每个 token 位置估计未来回报的期望值。GRPO 将这个复杂问题简化为组内比较,显著提高了训练稳定性。

GRPO 目标函数

\mathcal{L}_{\text{GRPO}}(\theta) = -\frac{1}{G} \sum_{i=1}^{G} \left[ A_i \cdot \min\left( \frac{\pi_\theta(y_i|x)}{\pi_{\theta_\text{old}}(y_i|x)},\ \text{clip}\left( \frac{\pi_\theta(y_i|x)}{\pi_{\theta_\text{old}}(y_i|x)}, 1-\epsilon, 1+\epsilon \right) \right) - \beta \cdot D_{\text{KL}}(\pi_\theta \| \pi_{\text{ref}}) \right]

为什么 DeepSeek-R1 选择 GRPO

  1. 价值网络是 PPO 的薄弱环节:价值网络需要准确估计任意状态下的预期回报,这在 LLM 的庞大状态空间中极为困难。GRPO 完全消除了这一依赖。
  2. 组内比较天然消除偏差:同一组内的回复共享相同的 prompt,它们的奖励差异直接反映了生成质量差异,不受跨 prompt 的奖励波动影响。
  3. 计算效率更高:无需维护价值网络,节省了一半的 GPU 显存和计算量。
  4. 扩展性好:增加组大小 G 可以降低优势估计的方差,提供简单的扩展路径。DeepSeek-R1 论文中使用了 G=64 的组大小。

GRPO vs PPO vs DPO 对比

特性PPODPOGRPO
需要价值网络是否否
需要奖励模型是否是
在线采样是否(离线)是
组内比较否否是
KL 正则形式显式隐式(通过参考模型对比)显式
训练稳定性低中高
代表实现InstructGPTLlama-3DeepSeek-R1

7.1.7 训练范式对比总表

对比总结
范式训练目标数据需求计算成本输出模型类型典型应用
Pretraining语言建模(最小化 PPL)海量无标注文本(TB 级)极高(百万 GPU 时)基座模型通用语言理解与生成
Full Fine-tuning任务损失最小化任务标注数据(万-百万级)高(全参数更新)任务专用模型分类、NER、翻译
LoRA / PEFT任务损失最小化少量标注数据低(约 30% 显存)可插拔适配器多任务部署、个性化
Instruction Tuning对话损失最小化指令-回答对(万-百万级)中等指令遵循模型对话助手、客服
RLHF (PPO)奖励最大化 + KL 约束偏好数据 + 奖励模型极高(4 个模型同时运行)对齐模型ChatGPT, Claude
DPO隐式偏好优化偏好数据(无需奖励模型)中等对齐模型Llama-3
GRPO组内偏好优化 + KL 约束偏好数据 + 奖励模型较高(在线采样)对齐模型DeepSeek-R1

7.2 模型评估指标(Evaluation Metrics)

7.2.1 Perplexity(PPL)

核心概念

Perplexity(困惑度)是语言模型最基础、最常用的内在评估指标。它衡量模型对测试文本的"惊讶程度"——perplexity 越低,模型对文本的预测越准确。

定义公式

对于包含 T 个 token 的测试序列 x = (x_1, x_2, \ldots, x_T):

\text{PPL}(x) = \exp\left( -\frac{1}{T} \sum_{t=1}^{T} \log P(x_t | x_{<t}) \right)

等价地,perplexity 是平均交叉熵损失的指数:

\text{PPL} = \exp(\mathcal{L}_{\text{CE}})

其中 \mathcal{L}_{\text{CE}} = -\frac{1}{T} \sum_{t=1}^{T} \log P(x_t | x_{<t})。

信息论解释

交叉熵与编码长度:交叉熵 H(P_{\text{data}}, P_{\text{model}}) 表示使用模型 P_{\text{model}} 的编码方案来编码真实分布 P_{\text{data}} 中的数据所需的平均比特数。Perplexity 是将这个比特数转换为"有效选择数"的结果。

Perplexity 作为分支因子:

  • PPL = 100 意味着模型在预测下一个 token 时,面对的有效选择数相当于从 100 个等概率选项中挑选
  • PPL = 2 意味着模型几乎能确定下一个 token(类似二元选择)

与信息量的关系:

\log_2(\text{PPL}) = \frac{1}{T} \sum_{t=1}^{T} (-\log_2 P(x_t | x_{<t}))

这是每个 token 的平均信息量(以比特计),也称为模型的压缩率。

典型模型的 Perplexity

模型参数量数据集Perplexity
GPT-2117MWikiText-2~29
GPT-3175BVarious~20
LLaMA-2 7B7BWikiText-2~12
LLaMA-3 8B8BVarious~10
DeepSeek-V3671BVarious~8-9

注意:perplexity 与词汇表大小和 tokenizer 密切相关,不同模型之间的 perplexity 比较必须在相同 tokenizer 和相同测试集上进行才有意义。

局限性

  • 只衡量概率建模能力,不衡量生成质量、事实准确性或有用性
  • 对短序列敏感,少量 token 的预测错误会显著影响整体值
  • 无法捕捉语义连贯性和逻辑一致性
  • 低 perplexity 不一定意味着高生成质量(如模型可能只学会了"安全"但无用的预测)

7.2.2 BLEU / ROUGE

核心概念

BLEU(Bilingual Evaluation Understudy)

BLEU 最初用于机器翻译评估,通过比较模型输出与参考翻译的 n-gram 重叠来衡量质量。

修正精度(Modified Precision):

p_n = \frac{\sum_{\text{n-gram} \in \text{candidate}} \min(\text{count}_{\text{candidate}}, \text{count}_{\text{reference}})}{\sum_{\text{n-gram} \in \text{candidate}} \text{count}_{\text{candidate}}}

简短惩罚(Brevity Penalty, BP):

\text{BP} = \begin{cases} 1 & \text{if } c > r \\ e^{1 - r/c} & \text{if } c \leq r \end{cases}

最终 BLEU 分数:

\text{BLEU} = \text{BP} \cdot \exp\left( \sum_{n=1}^{N} w_n \log p_n \right)

通常 N=4,w_n = 1/N(即 BLEU-4)。

ROUGE(Recall-Oriented Understudy for Gisting Evaluation)

ROUGE 主要用于文本摘要评估,侧重于召回率而非精确率。

ROUGE-N:

\text{ROUGE-N} = \frac{\sum_{\text{n-gram} \in \text{reference}} \text{count}_{\text{match}}}{\sum_{\text{n-gram} \in \text{reference}} \text{count}_{\text{reference}}}

ROUGE-L(基于最长公共子序列):

\text{ROUGE-L} = \frac{(1 + \beta^2) R_{\text{LCS}} P_{\text{LCS}}}{R_{\text{LCS}} + \beta^2 P_{\text{LCS}}}

BLEU vs ROUGE

特性BLEUROUGE
主要用途机器翻译文本摘要
侧重精确率(Precision)召回率(Recall)
N-gram 连续性要求连续 n-gram同 BLEU(ROUGE-N)或 LCS(ROUGE-L)
简短惩罚有(BP)通常无
多参考支持是是

局限性

  • 语义盲区:只关注表面 n-gram 重叠,"汽车"和"车辆"被视为完全不匹配
  • 同义词惩罚:语义等价但词汇不同的表达会被低分
  • 无法评估创造性:对于开放式生成任务(如创意写作、对话),n-gram 重叠几乎无意义

7.2.3 MMLU(Massive Multitask Language Understanding)

核心概念

MMLU 由 Hendrycks 等人于 2021 年提出,覆盖 57 个学科约 15,908 道选择题(4 选 1),是评估 LLM 知识和推理能力的权威基准。

学科覆盖

  • STEM:数学、物理、化学、生物、计算机科学
  • 人文:历史、哲学、法律、政治学
  • 社会科学:经济学、心理学、社会学
  • 其他:医学、会计、地质学等

测试方式:格式化选择题 prompt → 模型选择 A/B/C/D → 计算正确率。

分数解读

分数区间水平
~25%随机猜测(4 选 1)
40-50%高中水平
60-70%大学入门水平
80-90%专家水平
>90%超越人类专家

代表性模型分数:

模型MMLU (5-shot)
GPT-3 (175B)43.9%
LLaMA-2 70B69.8%
GPT-486.4%
Gemini Ultra90.0%
DeepSeek-V388.5%
GPT-4o88.7%

批评

  • 选择题格式限制了评估范围,不适用于开放式推理
  • 部分题目可能泄漏到训练数据中(数据污染)
  • 不同模型的 prompt 工程差异可能导致不公平比较

7.2.4 HumanEval / MBPP(代码生成评估)

核心概念

HumanEval

HumanEval 由 OpenAI 于 2021 年提出,包含 164 个手写 Python 编程问题,每个问题包含函数签名、docstring 和测试用例。

评估方式:Pass@k 指标——生成 k 个候选代码,至少有一个通过所有测试用例即算成功:

\text{Pass@k} = \mathbb{E}_{\text{Problems}} \left[ 1 - \frac{\binom{n-c}{k}}{\binom{n}{k}} \right]

其中 n 是生成样本数,c 是通过测试的样本数。

MBPP(Mostly Basic Python Programming)

MBPP 包含约 974 个 Python 编程问题,相比 HumanEval 更基础(涉及字符串操作、列表处理等)。

MBPP vs HumanEval:

特性HumanEvalMBPP
题目数164974
难度中等偏难中低
函数类型算法题为主编程基本功
测试用例每个问题 7-10 个每个问题 3 个
数据污染风险低(手写)中

局限

  • 只有 Python,不涵盖其他语言
  • HumanEval 题目数量少(164 道),统计方差大
  • 后续出现了更大规模的评估集:MultiPL-E(多语言)、SWE-bench(真实仓库级)、Codeforces(竞赛级)

7.2.5 GPQA / MATH(推理能力评估)

核心概念

GPQA(Graduate-Level Google-Proof Q&A)

GPQA 由纽约大学等机构于 2023 年发布,包含 448 道研究生级别的多项选择题。题目由领域专家撰写,覆盖物理、化学、生物学等。

特点:

  • 问题难度极高(人类专家准确率约 65%)
  • 题目不能被 Google 搜索直接解答("Google-proof")
  • 需要真正的领域知识而非信息检索

MATH

MATH 包含 12,500 道数学竞赛题目,覆盖代数、几何、微积分等 7 个类别。

评估方式:5 levels of difficulty。每个问题需要模型生成带最终答案的完整解题过程。评估时提取最终答案与标准答案精确匹配。

GSM8K

GSM8K 包含约 8,500 道小学数学应用题,每道题需要 2-8 步推理。使用 CoT(Chain-of-Thought)可显著提升分数:

模型GSM8K (CoT)
GPT-3.5~57%
GPT-4~92%
DeepSeek-V3~90%

7.2.6 MT-Bench / Chatbot Arena(对话质量评估)

核心概念

MT-Bench

MT-Bench 由 LMSYS 组织于 2023 年提出,包含 80 个高质量的多轮对话问题,覆盖 8 个类别(写作、推理、数学、编程、提取、STEM、人文、角色扮演)。

评估方式:使用 LLM-as-a-Judge(通常是 GPT-4)对模型回复进行 1-10 分的打分。每个问题包含两轮对话,更考验模型的对话连贯性。

局限性:

  • LLM Judge 本身可能带有偏见(偏好特定风格或长度)
  • 评价标准不完全透明
  • 不同 LLM-as-Judge 模型可能给出不同结果

Chatbot Arena

Chatbot Arena(又称 LMSYS Chatbot Arena)是一个众包的 LLM 评估平台,采用匿名 A/B 测试 + ELO Rating 的方式进行模型排名。

ELO Rating 系统:

  1. 用户匿名比较两个模型的输出,选择更好的一方
  2. 基于比赛结果更新双方 ELO 分数:
    E_A = \frac{1}{1 + 10^{(R_B - R_A) / 400}}
    R_A' = R_A + K \cdot (S_A - E_A)
    其中 R_A、R_B 是当前评分,E_A 是 A 获胜的期望概率,S_A 是实际结果(1 表示胜,0 表示负,0.5 表示平),K 是 K 因子(控制评分更新幅度)。
  3. 经过大量配对比较后,ELO 评分收敛到反映模型相对质量的水平

特点:

  • 亚马逊 Mechanical Turk + 网站用户参与,数据量大
  • 与实际使用场景高度一致
  • 不受单一评估者偏见影响
  • 但是评估者的偏好可能不代表目标用户群体

7.2.7 各评估基准对比总表

对比总结
基准测试内容评估方式题目数局限性
Perplexity语言概率建模交叉熵指数任意文本不反映生成质量
BLEU翻译准确性n-gram 精确率翻译测试集语义盲区,低相关性
ROUGE摘要内容覆盖n-gram 召回率摘要测试集同 BLEU
MMLU多学科知识选择题正确率15,908 道选择题限制,数据污染
HumanEvalPython 代码Pass@k164 道单一语言,样本少
MBPPPython 基础编程Pass@k974 道难度较低
GPQA研究生级推理选择题正确率448 道样本少
MATH数学竞赛推理答案精确匹配12,500 道仅数学
GSM8K数学应用推理答案精确匹配8,500 道小学难度
MT-Bench多轮对话质量LLM 评分 1-1080 道LLM Judge 偏差
Chatbot Arena综合对话质量众包 A/B + ELO持续收集众包质量参差

7.3 GPU 架构基础

7.3.1 CUDA Core vs Tensor Core

核心概念

CUDA Core

CUDA Core 是 NVIDIA GPU 中的通用标量计算单元。每个 CUDA Core 可以执行一个浮点或整数运算(如加法、乘法、逻辑运算)。它们基于 SIMT(Single Instruction, Multiple Threads)架构,32 个线程组成一个 warp,以 warp 为单位执行相同的指令。

典型规格:A100 有 6,912 个 CUDA Core,H100 有 16,896 个 CUDA Core。CUDA Core 的算力通常以 TFLOPS(FP32)衡量:A100 约 19.5 TFLOPS,H100 约 67 TFLOPS。

Tensor Core

Tensor Core 是 NVIDIA 从 Volta 架构(V100,2017 年)引入的专用矩阵计算单元,专门加速矩阵乘加运算(D = A \times B + C)。Tensor Core 可以在一个时钟周期内完成 4x4 矩阵的乘加操作,在 AI 训练和推理中发挥关键作用。

精度支持演进:

架构Tensor Core 代际支持精度
Volta (V100)第 1 代FP16
Turing (T4)第 2 代FP16, INT8, INT4
Ampere (A100)第 3 代FP16, BF16, TF32, INT8, INT4
Hopper (H100)第 4 代新增 FP8 (E4M3/E5M2)
Blackwell (B200)第 5 代新增 FP4, FP6

Tensor Core 关键算力(以 FP16 FMA 计算,TFLOPS):

GPUFP32 (CUDA Core)FP16 (Tensor Core)FP8 (Tensor Core)INT8 (Tensor Core)
A100 (SXM)19.5312N/A624
H100 (SXM)679891,9791,979
B200902,2504,5004,500

关键差异:Tensor Core 的 FP16 算力是 CUDA Core FP32 的 15-30 倍。这意味着当运算可以被量化为低精度矩阵乘法时(如 Attention 的 QK^T 和 PV 计算),性能可以提升 1-2 个数量级。

在 LLM 推理中的实际影响

在 vLLM 中,KV Cache 量化(FP8)和模型权重量化(FP8/INT4)依赖于 Tensor Core 的高效低精度计算:

# vLLM 中的 FP8 量化推理
# 使用 torch._scaled_mm(底层调用 Tensor Core 的 FP8 MMA)
import torch

# 假设 weight 和 input 都被量化为 FP8
weight_fp8 = weight.to(torch.float8_e4m3fn)
input_fp8 = input.to(torch.float8_e4m3fn)

# Tensor Core 的 FP8 矩阵乘法
# Hopper GPU 上比 FP16 快 2x
output = torch._scaled_mm(input_fp8, weight_fp8.t())

vLLM 的 float8_e4m3fn 支持需要 Hopper GPU(H100/H200)的 Tensor Core。在 Ampere GPU(A100)上只支持 INT8 Tensor Core 加速。

7.3.2 HBM(High Bandwidth Memory)

核心概念

HBM(高带宽显存)是 GPU 使用的主要内存技术,与传统的 GDDR(Graphics DDR)显存相比,HBM 通过 3D 堆叠技术和更宽的内存总线实现远超 GDDR 的带宽。

技术原理

HBM 通过硅通孔(Through-Silicon Via, TSV)技术将多个 DRAM 芯片垂直堆叠,并通过中间层(interposer)连接到 GPU 核心。这种 3D 堆叠架构实现了:

  1. 超宽总线:HBM2e 有 1024-bit 的内存总线(GDDR6 为 32-bit),但运行频率较低
  2. 高带宽:通过宽总线弥补低频的不足
  3. 小体积:堆叠设计节省 PCB 空间

各代 HBM 规格对比

规格HBM2eHBM3HBM3e
带宽/堆叠~460 GB/s~819 GB/s~1.2 TB/s
最大容量/堆叠24 GB24-64 GB24-144 GB
运行频率2.0-2.4 Gbps6.4 Gbps9.8 Gbps
总线宽度/堆叠1024-bit1024-bit1024-bit
使用 GPUA100H100H200, B200

实际 GPU 中的 HBM 配置:

GPUHBM 版本显存容量HBM 带宽带宽提升
A100 (SXM)HBM2e80 GB2.0 TB/s基线
H100 (SXM)HBM380 GB3.35 TB/s+67%
H200 (SXM)HBM3e141 GB4.8 TB/s+140%
B200HBM3e192 GB8.0 TB/s+300%

HBM 与 LLM 推理的关系

HBM 带宽是 LLM 推理最重要的硬件瓶颈。Decode 阶段是典型的内存带宽密集型操作:每次前向传播需要读取完整的模型参数(如 70B 模型约 140GB FP16 权重),而计算量却很小。在 A100(2 TB/s)上,理论最小 TPOT 约为 70ms/token(70B 模型,无 batching 时)。

这就是为什么 H200(4.8 TB/s)相比 H100(3.35 TB/s)在 LLM 推理中可获得 30-50% 的 token 生成速度提升——更高的 HBM 带宽直接缩短了每次读取权重的时间。

7.3.3 SRAM vs HBM vs DRAM:GPU 内存层次结构

核心概念

三级存储层次

GPU 的内存层次从上到下依次为:

寄存器 (Register)
  ↓  延迟: <1ns, 带宽: ~50 TB/s
SRAM (共享内存 / L1 缓存)
  ↓  延迟: ~5-10ns, 带宽: ~10-20 TB/s
HBM (高带宽显存)
  ↓  延迟: ~200-300ns, 带宽: 2-8 TB/s
DRAM (系统主内存, CPU 端)
  ↓  延迟: ~100-200ns(通过 PCIe/NVLink), 带宽: 50-200 GB/s
SSD (磁盘存储)
  ↓  延迟: ~10-100μs, 带宽: 2-14 GB/s

各层级关键参数

层级典型大小延迟带宽位置
寄存器256 KB / SM<1 ns>50 TB/s芯片内
SRAM (L1/Shared)128-256 KB / SM~5-10 ns10-20 TB/s芯片内
L2 Cache40-60 MB (GPU 全局)~50-100 ns5-10 TB/s芯片内
HBM80-192 GB~200-300 ns2-8 TB/s芯片封装内
DRAM (CPU)256-2048 GB~100-200 ns50-200 GB/s主板
SSD1-30 TB~10-100 μs2-14 GB/s磁盘

FlashAttention 如何利用内存层次

FlashAttention 是 HBM-SRAM 层次利用的典范。传统 Attention 的计算模式是"从 HBM 读取 → 计算 → 写回 HBM",而 FlashAttention 通过 Tiling(分块)技术将计算限制在 SRAM 中:

# 伪代码:FlashAttention 的 Tiling 策略
def flash_attention(Q, K, V, block_size):
    # 将 Q, K, V 切分为 B_m 和 B_n 大小的块
    for i in range(0, n, B_m):   # Q 块
        for j in range(0, n, B_n): # K, V 块
            # 将 Q_i, K_j, V_j 从 HBM 加载到 SRAM
            qi = load_to_sram(Q[i:i+B_m])
            kj = load_to_sram(K[j:j+B_n])
            vj = load_to_sram(V[j:j+B_n])

            # 在 SRAM 中进行矩阵乘法和 softmax
            s_ij = qi @ kj.T          # SRAM 运算
            p_ij = softmax(s_ij)      # SRAM 运算
            o_i += p_ij @ vj          # SRAM 累积

            # 最终结果写回 HBM
            save_to_hbm(o_i)

IO 复杂度对比:

  • 标准 Attention:O(n^2 \cdot d) HBM 访问
  • FlashAttention:O(n^2 \cdot d / M) HBM 访问,其中 M 是 SRAM 大小

实际中通常获得 2-4 倍的 attention 计算加速。

Memory Wall(内存墙)

Memory Wall(内存墙) 是指计算速度增长远快于内存带宽增长导致的性能瓶颈。在 LLM 推理中,Memory Wall 意味着:GPU 的计算能力远远超过其从 HBM 读取数据的能力,因此大部分推理时间花在数据搬运上,而非计算上。

定量分析(以 H100 + LLaMA-70B 为例):

  • 模型参数:140 GB(FP16)
  • HBM 带宽:3.35 TB/s
  • 读取所有参数的理论时间:140 GB / 3.35 TB/s ≈ 42 ms
  • 而 H100 的计算能力:989 TFLOPS(FP16 Tensor Core)

一次 forward pass 的计算量约为 2 \times (L \times n \times d \times 4) \approx 2 \times 80 \times 4096 \times 8192 \times 4 \approx 21.5 TFLOPs

计算时间:21.5 TFLOPS / 989 TFLOPS ≈ 22 ms

实际时间 = max(42ms, 22ms) ≈ 42ms → 受限于内存带宽!

这就是为什么增加 HBM 带宽(如 H100→H200,带宽从 3.35→4.8 TB/s)比增加计算能力(H100→B200)对 LLM 推理的收益更直接。

7.3.4 典型 GPU 规格对比总表

对比总结
规格A100 (SXM)H100 (SXM)H200 (SXM)B200
架构Ampere (GA100)Hopper (GH100)Hopper (GH100)Blackwell (GB200)
CUDA Core6,91216,89616,896~20,000+
Tensor Core432 (第 3 代)528 (第 4 代)528 (第 4 代)第 5 代
FP32 (CUDA)19.5 TFLOPS67 TFLOPS67 TFLOPS90 TFLOPS
FP16 (Tensor)312 TFLOPS989 TFLOPS989 TFLOPS2,250 TFLOPS
FP8 (Tensor)N/A1,979 TFLOPS1,979 TFLOPS4,500 TFLOPS
显存容量80 GB HBM2e80 GB HBM3141 GB HBM3e192 GB HBM3e
显存带宽2.0 TB/s3.35 TB/s4.8 TB/s8.0 TB/s
NVLink 带宽600 GB/s900 GB/s900 GB/s1,800 GB/s
互联方式NVLink 3NVLink 4NVLink 4NVLink 5
TDP400W700W700W1,000W
支持 FP8否是是是

7.3.5 Compute Capability(计算能力)

核心概念

Compute Capability(计算能力)是 NVIDIA 用来标识 GPU 硬件特性版本的编号系统,格式为 X.Y,其中 X 是主要架构代际,Y 是同一代内的特性变体。它决定了 GPU 支持哪些 CUDA 特性(如硬件功能、精度格式、指令集等)。

主要版本对照

Compute Capability架构代表 GPU关键特性
7.0VoltaV100第 1 代 Tensor Core
7.5TuringT4, RTX 2080INT8/INT4 Tensor Core
8.0AmpereA100BF16, TF32, 第 3 代 Tensor Core
8.6AmpereRTX 3090消费级 Ampere
8.9Ada LovelaceRTX 4090FP8 转换支持
9.0HopperH100FP8 Tensor Core, Dynamic Programming
10.0BlackwellB200FP4/FP6, 第 5 代 Tensor Core

在 vLLM 中的影响

vLLM 在编译和运行时检查 Compute Capability 来决定启用哪些优化:

# vLLM 中的 Compute Capability 检查(简化)
import torch

capability = torch.cuda.get_device_capability()  # e.g., (8, 0) for A100

if capability >= (9, 0):  # Hopper
    # 启用 FP8 量化
    use_fp8 = True
elif capability >= (8, 0):  # Ampere
    # 使用 BF16 和 TF32
    use_bf16 = True
    allow_tf32 = True

if capability >= (8, 0):
    # 启用 FlashAttention(需要 Ampere 以上架构)
    use_flash_attn = True

7.3.6 RoCE / InfiniBand:分布式训练的网络互联

核心概念

在分布式训练中,GPU 服务器之间需要高速网络传输梯度和模型参数。两种主流的高速互联方案是 InfiniBand 和 RoCE(RDMA over Converged Ethernet)。

InfiniBand

InfiniBand 是为高性能计算(HPC)设计的专用网络技术,提供极低延迟和高带宽:

代际单链路速率典型配置有效带宽
InfiniBand EDR25 Gbps4x EDR100 Gbps
InfiniBand HDR50 Gbps4x HDR200 Gbps
InfiniBand NDR100 Gbps4x NDR400 Gbps
InfiniBand XDR200 Gbps4x XDR800 Gbps

特点:

  • RDMA(Remote Direct Memory Access):无需 CPU 干预,GPU 之间直接读写
  • 低延迟:亚微秒级(~0.5-1μs)点对点延迟
  • 无损网络:内置流量控制和拥塞管理,零丢包
  • 成本高:专用交换机、网卡和线缆

RoCE(RDMA over Converged Ethernet)

RoCE 是在标准以太网上实现 RDMA 的协议。RoCEv2 将 RDMA 数据包封装在 UDP 中,运行在标准以太网上。

版本封装延迟部署复杂度成本
RoCEv1链路层低低低
RoCEv2UDP/IP中等中等中等

特点:

  • 共享基础设施:与普通以太网共享交换机和线缆
  • 需要 PFC(Priority Flow Control):RoCE 依赖以太网的流量控制来保证无损传输
  • 成本低:相比 InfiniBand,无特殊硬件需求
  • 延迟略高:约 1-3μs 点对点延迟

在分布式训练中的对比

维度InfiniBandRoCE
延迟~0.5μs~1-3μs
带宽400-800 Gbps100-400 Gbps
成本高(2-3x)中
部署复杂度低(专用网络)高(需要 PFC 配置)
可用性需要专用硬件标准以太网交换机
生态支持NVIDIA NCCL 原生支持NCCL 支持(需配置)

在 vLLM 分布式推理中的影响

vLLM 使用 NCCL(NVIDIA Collective Communications Library)进行 GPU 间通信。NCCL 自动选择最快的通信路径:

NVLink (同节点 GPU 间) > InfiniBand (跨节点) > RoCE (跨节点) > TCP/IP (兜底)

在多节点场景下(节点间通过 InfiniBand/RoCE),带宽大幅下降(典型 100-400 Gbps = 12.5-50 GB/s),TP 的通信开销会显著增加,因此通常限制 TP size 不超过单节点 GPU 数量。跨节点的分布式策略通常使用 PP(流水线并行)或 DP(数据并行),而非 TP(张量并行)。

7.4 RAG(检索增强生成)

7.4.1 RAG 架构

核心概念

RAG(Retrieval-Augmented Generation,检索增强生成)是一种将信息检索与文本生成相结合的架构。它在 LLM 生成过程中引入外部知识库的检索结果,使模型能够基于检索到的相关信息进行回答,而不是仅依赖其训练时学到的参数化知识。

三阶段流程

RAG 的核心流程为 Retrieve → Augment → Generate:

输入查询
    │
    ▼
[检索阶段] → Query Encoding → Vector Search / BM25 Search → 获取 Top-K 文档
    │
    ▼
[增强阶段] → 将检索文档与原始查询拼接为增强 prompt
    │
    ▼
[生成阶段] → LLM 基于增强 prompt 生成回复

详细步骤:

Step 1: Retrieve(检索)

Query: "什么是 LoRA 微调?"
  → Embedding Model 编码查询向量
  → 向量数据库近似最近邻搜索 (ANN)
  → 返回 Top-3 最相关文档:
    doc_1: "LoRA(Low-Rank Adaptation)..."
    doc_2: "Parameter-Efficient Fine-Tuning..."
    doc_3: "QLoRA: 4-bit 量化的 LoRA..."

Step 2: Augment(增强)

{{context}}
根据以下资料回答问题:
{doc_1}
{doc_2}
{doc_3}

问题:什么是 LoRA 微调?

Step 3: Generate(生成)

LLM 基于增强 prompt 生成:
"LoRA 微调是一种参数高效微调方法..."

RAG 的核心优势

优势说明与纯 LLM 对比
知识更新修改知识库即可,无需重新训练纯 LLM 需重新训练或微调
幻觉缓解提供具体引用来源,减少胡编乱造纯 LLM 完全依赖参数化记忆
事实准确性可验证每个声称的来源纯 LLM 无法追溯信息来源
长尾知识可检索不常见或领域特有知识纯 LLM 在大训练数据之外表现差
隐私合规可控制知识库访问权限纯 LLM 可能记忆并泄露训练数据

7.4.2 Chunking 策略

核心概念

Chunking(文本分块)是将知识库文档切分为适合检索和嵌入处理的文本片段。分块策略直接影响检索效果:分块太大会增加噪声和计算成本,且可能超过 LLM 的上下文窗口;分块太小会导致语义不完整,检索时缺乏上下文信息。

主要策略对比

策略方法优点缺点适用场景
固定大小按字符/token 数切分,可重叠实现简单、性能稳定可能切断语义边界结构简单的文档
语义分块基于 embedding 相似度分割保持语义完整性计算成本高需要高质量检索的场景
递归分块按段落→句子→短语层次切分自动适应文档结构依赖分割规则质量结构清晰的文档
基于文档结构按 Markdown 标题/HTML 标签保持自然逻辑单元依赖输入格式结构化文档

固定大小分块

最简单的方法,按固定的 token 数(如 256、512 或 1024)切割文档:

# 固定大小分块(带重叠)
def chunk_fixed(text, chunk_size=512, overlap=50):
    tokens = tokenizer.encode(text)
    chunks = []
    for i in range(0, len(tokens), chunk_size - overlap):
        chunk = tokens[i:i + chunk_size]
        chunks.append(tokenizer.decode(chunk))
    return chunks

重叠(overlap) 参数(通常为 chunk_size 的 10-20%)用于缓解切割点处语义断裂的问题。

基于文档结构的分块

利用文档的标题层级(Markdown #、HTML <h1> 等)作为自然的分块边界:

# 递归字符文本分割器(LangChain 实现)
from langchain.text_splitter import RecursiveCharacterTextSplitter

text_splitter = RecursiveCharacterTextSplitter(
    chunk_size=512,
    chunk_overlap=50,
    separators=["\n\n", "\n", ".", "!", "?", ",", " ", ""],
)
chunks = text_splitter.split_text(document)

语义分块

基于语义相似度检测"主题边界"的分块策略:

# 语义分块(简化版)
def semantic_chunk(text, sentence_model, threshold=0.8):
    sentences = split_into_sentences(text)
    chunks = []
    current_chunk = [sentences[0]]

    for i in range(1, len(sentences)):
        # 计算当前句与 chunk 平均 embedding 的相似度
        sim = cosine_similarity(
            sentence_model.encode(sentences[i]),
            sentence_model.encode(" ".join(current_chunk))
        )
        if sim > threshold:
            current_chunk.append(sentences[i])
        else:
            chunks.append(" ".join(current_chunk))
            current_chunk = [sentences[i]]

    return chunks

Chunking 质量评估指标:

  • 检索命中率:与查询相关的文档是否被正确分割
  • 语义完整性:chunk 内部是否具有一致的语义主题
  • 信息密度:chunk 中有用信息的比例

7.4.3 Embedding 模型选型

核心概念

Embedding 模型(嵌入模型)将文本映射到连续向量空间 \mathbb{R}^d,在 RAG 中用于 query 和 document 的编码,是向量检索的基石。在 vLLM 中,嵌入模型通过 Pooling Model 的 embed 任务提供服务。

主流 Embedding 模型

模型维度最大长度架构特点
bge-large-en-v1.51024512BERT-large中文友好,BAAI 出品
e5-mistral-7b-instruct40964096Mistral-7B长文本支持,高质量
instructor-xl768512INSTRUCTOR任务感知嵌入
jina-embeddings-v310248192Jina BERT多语言,超长上下文
gte-large-en-v1.510248192GTE业界领先的双编码器

vLLM 支持的嵌入模型:

_EMBEDDING_MODELS = {
    "BertModel": ("bert", "BertEmbeddingModel"),
    "RobertaModel": ("roberta", "RobertaEmbeddingModel"),
    "RobertaForMaskedLM": ("roberta", "RobertaEmbeddingModel"),
    "JinaEmbeddingsV5Model": ("jina", "JinaEmbeddingsV5Model"),
}

选型考虑因素

  1. 嵌入维度:高维度(1024-4096)提高检索精度但增加存储和计算成本。可使用 Matryoshka 嵌入(如 intfloat/e5-mistral-7b-instruct)进行降维(如 1024→256),同时保持好的检索效果。
  2. 上下文长度:chunk 大小受限于嵌入模型的最大输入长度。bge/insstructor 的 512 token 限制对长文档分块构成约束,而 jina-embeddings-v3 和 gte 支持更长的上下文。
  3. 对比学习训练:e5 和 bge 使用对比学习(Contrastive Learning)训练,能更好地区分语义相关的正样本和无关的负样本。

7.4.4 向量数据库

核心概念

向量数据库(Vector Database)专门用于存储和检索高维向量数据,通过近似最近邻搜索(ANN)算法实现高效的相似性搜索。

主流方案对比

特性MilvusPineconeWeaviateQdrant
部署方式自托管 / 云云托管自托管 / 云自托管 / 云
索引算法IVF, HNSW, DiskANNHNSWHNSWHNSW
过滤能力标量过滤 + 向量搜索元数据过滤GraphQL 过滤Payload 过滤
多模态否否否否
分布式原生支持托管Kubernetes集群模式
持久化MinIO/S3自动文件系统/S3文件系统/S3
中文社区活跃(中文文档)一般一般一般
适合场景大规模生产快速原型知识图谱 + RAG高性能搜索

向量搜索算法

HNSW(Hierarchical Navigable Small World):当前向量数据库的主流 ANN 算法,构建多层图结构,高层图提供快速导航,低层图提供精确搜索。

# HNSW 搜索示意图
# 第 3 层(最高): 🟢 → 🟢 → 🟢  (稀疏连接,长距离跳跃)
# 第 2 层:       🟢 → 🟢 → 🟢 → 🟢
# 第 1 层:       🟢 → 🟢 → 🟢 → 🟢 → 🟢 → 🟢
# 第 0 层(最密集): 全连接图

HNSW 的搜索过程:从最顶层开始,贪婪地走向最近邻,然后下降到下一层重复,直到到达最底层。

IVF(Inverted File Index):将向量空间划分为 N 个 Voronoi 单元,搜索时只搜索查询向量所在的单元和邻近单元。需要训练一个 K-means 聚类器来定义单元中心。

vLLM 中的 RAG 集成

vLLM 本身不做检索(不包含向量数据库),而是作为生成引擎。典型的 vLLM + RAG 架构为:

RAG 系统
├── 检索层: Milvus/Pinecone 等向量数据库
│   ├── Chunking: 文档切分为检索单元
│   ├── Embedding: 调用 vLLM 的 embed 接口编码
│   └── Indexing: 向量索引构建 (HNSW/IVF)
├── 精排层: vLLM 的 Rerank Model (cross-encoder)
│   └── Score API 的 classify 任务
└── 生成层: vLLM 的 LLM 推理
    └── Chat Completions API + 检索上下文

两阶段检索策略(在 vLLM 中的 Score API 支持):

# 阶段 1: Bi-encoder 粗排(余弦相似度)
query_embedding = embed_model.embed([user_query])
doc_embeddings = embed_model.embed(doc_chunks)
scores = cosine_similarity(query_embedding, doc_embeddings)
top_k_indices = argsort(scores)[-50:]  # 粗排保留 Top-50

# 阶段 2: Cross-encoder 精排(vLLM Score API classify 任务)
pairs = [(user_query, doc_chunks[i]) for i in top_k_indices]
rerank_scores = rerank_model.score(pairs)  # cross-encoder 精排
final_indices = argsort(rerank_scores)[-5:]  # 精排保留 Top-5

7.4.5 Hybrid Search(混合检索)

核心概念

Hybrid Search 结合了密集检索(Dense Retrieval)和稀疏检索(Sparse Retrieval,BM25)的优点,在语义理解和精确关键词匹配之间取得平衡。

密集检索(Dense Retrieval)

使用神经网络嵌入模型(如 bge、e5)将文本编码为稠密向量,通过向量相似度搜索:

  • 优点:理解语义,同义词匹配(如"汽车"和"车辆")
  • 缺点:需要大量训练数据;对罕见词和精确匹配效果差

稀疏检索(BM25)

基于词频-逆文档频率(TF-IDF)的改进算法:

\text{BM25}(q, d) = \sum_{t \in q} \text{IDF}(t) \cdot \frac{\text{TF}(t, d) \cdot (k_1 + 1)}{\text{TF}(t, d) + k_1 \cdot (1 - b + b \cdot \frac{|d|}{\text{avgdl}})}
  • 优点:精确关键词匹配,无需训练,可解释性强
  • 缺点:无法处理同义词和语义相似

融合策略

Hybrid Search 通常使用加权融合或重排序融合:

# 加权融合
def hybrid_search(query, alpha=0.5):
    dense_scores = dense_search(query)   # 向量相似度
    sparse_scores = bm25_search(query)   # BM25 分数

    # 先对两种分数进行归一化
    dense_scores = min_max_normalize(dense_scores)
    sparse_scores = min_max_normalize(sparse_scores)

    # 加权融合
    final_scores = alpha * dense_scores + (1 - alpha) * sparse_scores
    return argsort(final_scores)

代表性重排序模型:RRF(Reciprocal Rank Fusion):

\text{RRF}(d) = \sum_{m \in \text{methods}} \frac{1}{k + \text{rank}_m(d)}

其中 \text{rank}_m(d) 是文档 d 在方法 m 中的排名,k 是常数(通常 60)。RRF 不需要分数归一化,对分数分布不敏感。

7.4.6 RAG 评估

核心概念

核心评估指标

指标全称含义计算方式
Hit Rate命中率检索结果是否包含至少一个相关文档\frac{\text{有相关文档的查询数}}{\text{总查询数}}
MRRMean Reciprocal Rank第一个相关文档在结果中的位置\frac{1}{N}\sum_{i=1}^{N}\frac{1}{\text{rank}_i}
NDCGNormalized Discounted Cumulative Gain考虑多级相关性和位置的加权指标\frac{\text{DCG}}{\text{IDCG}}
Recall@kTop-k 召回率前 k 个结果中相关文档的比例—
Precision@kTop-k 精确率前 k 个结果中相关文档的占比—

示例对比

假设有 3 个查询,每个查询的检索结果中相关文档的位置如下:

查询相关文档位置Hit RateMRR
Q1第 1 位11/1 = 1.0
Q2第 3 位11/3 ≈ 0.33
Q3未找到00

整体:Hit Rate = 2/3 ≈ 66.7%, MRR = (1.0 + 0.33 + 0) / 3 ≈ 0.44

NDCG 的额外价值:NDCG 考虑多个相关文档的位置,而非只关注第一个。例如如果 Q1 在位置 1 和 5 有相关文档,NDCG 会同时奖励两个位置(按折扣累加),而 MRR 只考虑位置 1。

7.4.7 Advanced RAG:Self-RAG, CRAG, RAPTOR, HyDE

高级概念
方法核心思想解决的问题原理
Self-RAG 模型自我判断是否需要检索 统一了"检索"和"不检索"的决策 训练模型输出反思 token(如 [Retrieve]、[No Retrieve]、[Relevant]、[Not Relevant]),让模型自主决定何时检索和如何使用检索结果
CRAG 检索后纠错和校正 检索结果质量不高时的兜底策略 对检索结果进行评估,如果检索结果差则触发大规模 web 搜索作为补充;如果检索结果好则保留和使用
RAPTOR 构建文档的层次摘要树 同时支持具体细节和宏观理解的检索 将文档递归摘要为层次结构(叶子=原文段落,内部节点=摘要),检索时同时搜索所有层级
HyDE 用假设文档编码查询 弥合查询和文档之间的语义鸿沟 先用 LLM 生成一个"假设文档"(hypothetical document),然后用其嵌入进行检索,而非直接用查询嵌入

HyDE 的直觉

Query: "What is the capital of France?"
  → LLM generates hypothetical document: "France's capital is Paris..."
  → Embed hypothetical document (not the query)
  → Search with this embedding
  → Better than query embedding because the embedding space alignment improves

各方法在 vLLM 生态中的定位

  • Self-RAG:需要训练支持反射 token 的模型,不属于 vLLM 的推理优化范畴
  • CRAG:对外部搜索的依赖超出了 vLLM 的能力边界
  • RAPTOR:主要是一个分块和索引策略,可以与 vLLM 的嵌入服务和 Prefix Caching 结合使用
  • HyDE:需要一个 LLM 来生成假设文档,可以直接使用 vLLM 的 Chat API 实现
← 上一模块
AI 通用概念
下一模块 →
高级 AI(下)