本章提供了一整套题目,用于检验和巩固你对本书所讲内容的理解。每道题目都瞄准一个关键概念、算法或系统设计决策——正是这种知识把表面熟悉与真正的专长区分开来。请将这些题目用于自我检验:先尝试自己作答,再阅读详细解答。题目从基础概念(LLM 架构、强化学习基础)逐步推进到核心算法(PPO、DPO、GRPO),最终覆盖高级系统设计与智能体(Agent)AI 主题。

基础题

Q0a:在 decoder-only Transformer 中,attention 机制的作用是什么?为什么它是因果的?

解答

attention 机制允许每个 Token 关注(即对其表示做加权组合)其他 Token 的表示。在 decoder-only Transformer 中,attention 是 因果的(也称为自回归):Token t 只能关注 Token 1,…,t,绝不能关注未来 Token t+1,…,T。

为什么是因果的?因为模型从左到右生成文本。推理时,未来 Token 字面意义上还不存在。训练时的因果掩码模拟了这一约束,使模型学会仅用左侧上下文预测每个 Token。在数学上,attention 矩阵被掩盖:

Attention​(Q,K,V)=softmax​(Q​K⊤dk+M)​V

其中对 j>i(未来位置)有 Mi​j=−∞,强制将这些 attention 权重置零。

实践含义:这使得推理时的 KV-cache 优化成为可能——由于过去 Token 的 keys 和 values 永远不变,可被缓存复用,将每个新 Token 的生成代价从 O⁡(T2) 降至 O⁡(T)。

复习:第 1 章(LLM 架构与优化方法)。

Q0b:解释 FlashAttention。它解决什么问题,又是怎么解决的?

解答

标准 attention 会计算完整的 T×T attention 矩阵,需要 O⁡(T2) 显存,并且是 受显存带宽约束的——GPU 大部分时间都花在 HBM(慢、大)与 SRAM(快、小)之间搬运数据,而不是做真正的计算。

FlashAttention 的洞见:永远不要在 HBM 中物化完整的 attention 矩阵。相反,把计算切分成可放进 SRAM 的分块,用在线 Softmax(Online Softmax)算法 逐块计算 attention,并只把最终输出写入 HBM。

关键技术:

  1. 分块(Tiling):将 Q、K、V 拆成大小为 Br×Bc 的块,可装入 SRAM
  2. 在线 Softmax:维护一个滑动的 max 和 sum,以增量方式计算 softmax,无需访问完整一行
  3. 重算(Recomputation):在反向传播时,从 Q、K、V 重新计算 attention(开销小),而不存储 T×T 矩阵(开销大)

结果:HBM 显存复杂度为 O⁡(T)(而非 O⁡(T2)),墙钟(wall-clock)时间加速 2–4×,数值输出完全一致(并非近似)。

复习:第 1–2 章(LLM 架构;系统基础)。

Q0c:从高层次看,SFT、RLHF 与 DPO 有什么区别?分别在什么场景下使用?

解答

  • SFT(监督微调,Supervised Fine-Tuning):训练模型去模仿高质量示范。Loss:在精选数据上做下一个 Token 预测。教会模型 格式与 风格。
  • RLHF:从人类偏好训练一个 reward 模型,然后用 RL(PPO)针对它优化 policy。模型会探索示范数据之外的空间。教会模型 人类偏好什么。
  • DPO(直接偏好优化):跳过 reward 模型。直接在偏好对 (yw,yl) 上用对比 loss 优化 policy。目标与 RLHF 相同,但流水线更简单。

典型流水线:先做 SFT(提供良好起点),再做 RLHF 或 DPO(细化偏好)。仅做 SFT 倾向产出冗长、过度模棱两可的回答。RLHF/DPO 让输出更直接、更贴合人类意图。

各自适用场景:有黄金标准输出时用 SFT。有偏好对但算力有限时用 DPO。需要极致质量且能承担基础设施成本时用 RLHF(PPO)。

复习:第 5、6 与 10 章(PPO;DPO;SFT 最佳实践)。

Q0d:什么是 reward 模型?它如何训练,可能出什么问题?

解答

reward 模型(Reward Model, RM)是一个神经网络,输入 (prompt, response) 对,输出一个表示质量的标量分数。它在人类偏好数据上训练:给定 (yw,yl) 对(其中 yw 被偏好),RM 学习赋予 R⁡(yw)>R⁡(yl)。

训练:Bradley-Terry loss:ℒ=−log⁡σ⁡(R⁡(yw)−R⁡(yl))。架构:通常与 policy 共用同一个 Transformer,将 LM head 替换为标量投影。

可能出什么问题:

  1. Reward hacking:policy 找到了在 RM 上得分很高但实际质量很差的输出(例如过度冗长、重复,或包含 RM 存在偏好的特定短语)
  2. 分布漂移(Distribution Shift):RM 是在更早的 policy 输出上训练的。随着训练推进,当前 policy 生成的是 RM 无法准确打分的分布外输出
  3. 标签噪声:人类标注者意见不一致、疲劳,或使用不一致的标准。这种噪声会传播到 RM 的预测中
  4. 过度自信:RM 对从未见过的输出赋予极端分数,提供具有误导性的梯度信号

复习:第 9 章(Reward 模型训练)。

Q0e:解释 RL 中的探索-利用(exploration-exploitation)权衡。它在 LLM 训练中如何体现?

解答

在 RL 中,Agent 必须在以下两者间取得平衡:

  • 利用(Exploitation):选择已知能产生高 reward 的动作(贪婪行为)
  • 探索(Exploration):尝试可能带来更高 reward(但也可能失败)的新动作

在 LLM 训练中:policy 就是语言模型。“动作”是 Token 的选择。“利用”指生成与已得高分相似的回答;“探索”指尝试新颖的措辞、结构或推理路径。

表现形式:

  • 生成时的温度:温度越高 = 探索越多。GRPO 使用温度 1.0 以在每个 group 内获得多样的样本。
  • KL 惩罚:作为一种反探索的刹车——防止 policy 偏离参考模型太远。没有它,policy 可能坍缩到单一高 reward 模板(模式坍缩)。
  • GRPO 中的组采样:每个 prompt 生成 G 个 response,显式探索输出空间,然后强化高于平均的 response。

张力:探索太少 → 模型陷入局部最优(总是给出同样的安全回答)。探索太多 → 训练不稳定,质量剧烈波动。

复习:第 3 与 7 章(RL 导论;GRPO)。

核心算法题

Q1:解释 PPO 的裁剪目标。为什么它比朴素 PG 效果更好?

解答

朴素策略梯度:∇J=𝔼⁡[∇log⁡π​(a|s)⋅A^]。问题:一个幸运/不幸的样本可能产生巨大的梯度 → policy 跳到糟糕的区域 → 生成垃圾 → 下一个梯度让它更糟 → 无法恢复的“死亡螺旋”。

PPO 的解法:将概率比 r=πnew/πold 裁剪到 [0.8,1.2]。

机制:对于好动作(A^>0):目标是 min⁡(r​A^,1.2​A^)。一旦 r 超过 1.2,不再有额外收益——阻止 policy 过度押注于单个样本。对于坏动作(A^<0):目标是 min⁡(r​A^,0.8​A^)。一旦 r 降到 0.8 以下,惩罚不再增长——防止灾难性遗忘。

关键洞见:它是 TRPO 的 KL 约束的一阶近似,但无需昂贵的二阶优化。每次更新对 policy 的改变最多为 ±20%。

具体到 LLM:Token 级的比 rt=πθ​(yt|y<t)/πold​(yt|y<t) 防止任何单个 Token 的概率变化过于剧烈,从而保持生成的连贯性。

复习:第 5 章(PPO)。

Q2:从第一性原理推导 DPO。它做了哪些假设?

解答

从 RLHF 目标出发:maxπ𝔼[r(x,y)]−βDKL[π∥πref]。

第 1 步:写出 KKT 条件。最优 policy 有闭式解:π∗​(y|x)∝πref​(y|x)​exp⁡(r⁡(x,y)/β)。

第 2 步:反解出 reward:r⁡(x,y)=β​log⁡(π∗/πref)+β​log⁡Z⁡(x)。

第 3 步:代入 Bradley-Terry 模型 P⁡(yw≻yl)=σ⁡(r⁡(yw)−r⁡(yl))。配分函数 Z⁡(x) 相互抵消(同一 prompt)。

第 4 步:用 πθ 替换 π∗(我们正在训练的参数化 policy):ℒ=−𝔼⁡[log⁡σ⁡(β​log⁡πθ​(yw)πref​(yw)−β​log⁡πθ​(yl)πref​(yl))]。

假设:

  1. Bradley-Terry 偏好模型(成对、无平局、可传递)
  2. 最优 policy 可由 πθ 实现(容量充足)
  3. 偏好数据与训练数据来自同一分布(无分布漂移)
  4. 参考模型固定且合理

假设被打破时:真实偏好不具有可传递性,训练期间数据发生漂移,标签含噪 → 这正是 Online DPO 与 IPO 存在的原因。

复习:第 6 章(DPO)。

Q3:GRPO 与 PPO — 分别在什么情况下选择哪一个?权衡是什么?

解答

GRPO 的优势:

  • 不需要价值函数:省下一个模型的内存与复杂度
  • 更简单:超参数更少,更直观(高于均值 = 好,低于均值 = 坏)
  • 更适合可验证 reward:数学/代码场景中 r∈{0,1} 能给出清晰信号
  • DeepSeek-R1 证明了仅用二元 reward 就能教会模型涌现推理

PPO 的优势:

  • 逐 Token 的信用分配:价值函数为每个 Token 分配 reward,而不只是序列级
  • 样本效率更高:GAE 用价值预测估计优势,无需生成 G 个样本
  • 更适合细腻的 reward:当 reward 是连续的、且在不同 Token 间差异显著时
  • 更成熟:已在 OpenAI、Anthropic 等经过实战检验

经验法则:如果 reward 可验证(对/错)→ GRPO。如果 reward 细腻(RM 分数)且需要极致质量 → PPO。如果算力有限 → GRPO(无需训练 critic)。

算力对比:GRPO 每个 prompt 生成 G 个 response(生成量多 8×),但跳过了价值函数训练。净效果:总算力相近,但分布不同(更多生成,更少训练)。

复习:第 5 与 7 章(PPO;GRPO)。

Q4:GAE 是如何工作的?为 LLM 走一遍具体示例。

解答

GAE = n 步 TD 误差的加权和:A^t=∑l=0T−t(γ​λ)l​δt+l。

具体示例:response 有 5 个 Token。只在末尾有 reward(r5=0.8)。价值预测:V1=0.5,V2=0.55,V3=0.6,V4=0.65,V5=0.7。

TD 误差(γ=1):δ1=0+V2−V1=0.05,δ2=0+V3−V2=0.05,……,δ5=0.8+0−0.7=0.1。

取 λ=0.95 时:A^5=0.1(就是最终的 TD 误差),A^4=0.05+0.95×0.1=0.145,A^3=0.05+0.95×0.145=0.188,等等。

解读:Token 3 得到的优势是 0.188,因为它对一个获得高于预期 reward 的序列有贡献。更早的 Token 通过指数衰减获得信用。

对 LLM 而言:γ=1.0(所有 Token 都重要,有限时域)。Token t 处的优势回答了:“考虑到这个 Token 之后发生的内容,这个 Token 的选择比预期更好还是更差?”

复习:第 5 章(PPO)。

Q5:如何防止 reward hacking?给出一套分层防御策略。

解答

检测信号:RM 分数上升但胜率持平/下降。response 长度单调增长。KL 散度 > 15。多样性(唯一 n-gram)下降。阅读高 reward 输出能发现漏洞。

分层防御(按优先级排序):

  1. KL 惩罚(主要手段):自适应控制器将 KL 目标设为 ≈ 6。如果 KL 上升,β 会自动增大。防止偏离参考模型太远。
  2. Reward 模型集成(3–5 个模型):取分数的最小值或均值。单个模型有不同的盲区——能骗过一个模型的漏洞很少能骗过所有模型。
  3. 长度惩罚:r′=r−c⋅max⁡(0,length−Ltarget)。防止“只要生成得更长 = 分数更高”的漏洞。
  4. 定期刷新 RM:每 2000 步,用当前 policy 生成数据,重新标注,加入 RM 训练集。在模型发现漏洞的同时将其封堵。
  5. 基于胜率的停止准则:跟踪相对 SFT baseline 的胜率。如果 RM 分数上升但胜率停滞超过 200 步,就停止训练。模型在钻漏洞,而不是在改进。

检测后的恢复:回滚到最后一个“干净”的 checkpoint。将 β 增大 2×。把发现的漏洞作为负样本加入 RM。

复习:第 9 与 11 章(Reward 模型训练;系统架构)。

系统设计题

Q6:为训练 70B 模型设计一个 RLHF 系统。逐一走查每个组件。

解答

在 72 张 A100-80GB GPU 上的三集群解耦架构:

集群 1 — 生成(32 张 GPU):

  • 8 个 vLLM 实例,每个 TP=4。PagedAttention + 投机解码(1B 草稿模型)。
  • 连续批处理(Continuous Batching),最多 256 条序列同时进行。为了带宽使用 INT8 权重。
  • 输出:(prompt, response, 逐 Token log-prob)。吞吐:∼500 个 response/分钟。
  • 无状态:只需从共享存储加载最新权重。恢复轻而易举。

集群 2 — 打分(8 张 GPU):

  • Reward 模型(70B,INT8 = 70GB)装在 4 张 GPU 上(TP=4)。
  • 参考模型(70B,INT8)装在 4 张 GPU 上(TP=4)。为 KL 计算逐 Token log-prob。
  • 输出:reward 分数 + 每个 Token 的 KL。轻量、批量推理。

集群 3 — 训练(32 张 GPU):

  • policy 模型使用 FSDP(ZeRO-3)。Flash Attention 2。梯度检查点(Gradient checkpointing)。
  • 从 buffer 消费已打分的经验。PPO 更新:在大小为 16 的 mini-batch 上做 4 个 epoch。
  • 每 50 步把更新后的权重推送到共享存储(异步、后台传输)。
  • 每 100 步异步 checkpoint(非阻塞写入 NVMe + S3 备份)。

连接网络:

  • 生成 → 打分:Ray/Redis 队列(∼每批 10 MB:Token ID + log-prob)
  • 打分 → 训练:经验池(Experience Pools,环形,保留最近 500 步)
  • 训练 → 生成:共享并行 FS(Lustre/GPFS)上的权重存储。每 50 步推送 140GB,异步。

重叠:当训练处理第 N 步时,生成已经在为第 N+1 步产出数据。这隐藏了生成延迟,相比单体架构达到 1.3–1.5× 的吞吐。

复习:第 11 章(大规模系统架构与基础设施)。

Q7:如何处理生成瓶颈?定量说明各种解决方案。

解答

生成占 RLHF 总墙钟时间的 60–70%。根因:自回归解码受显存带宽约束(算术强度 ≈1 FLOP/byte,而 A100 的 roofline 为 156 FLOP/byte)。

按影响力排序的解决方案:

1. 将生成与训练解耦(端到端 1.3–1.5×):在独立硬件上运行生成,与训练重叠。这是最大的单项架构收益。

2. 使用 PagedAttention 的 vLLM(2–4×):消除由内部碎片造成的 60–80% KV cache 内存浪费。支持大 3–4× 的 batch,即更好的带宽利用。

3. 连续批处理(1.5–2×):不要等最长序列结束。在腾出的槽位立即启动新序列,让 GPU 保持忙碌。

4. 投机解码(2–3×):1B 草稿模型提出 5 个 Token。70B 模型在一次前向中验证全部 5 个(并行!)。平均接受 3–4 个 → 每次前向 3–4 个 Token,而不是 1 个。

5. 生成权重使用 INT8/FP8(2×):将每个 Token 的 140GB 权重读取减半。质量损失很小,因为 (a) 我们本来就在带 temperature 采样,(b) 只有生成使用 INT8,训练仍保持 BF16。

6. CUDA graph + kernel 融合(1.1–1.3×):消除 Python/CUDA 启动开销。将 layernorm+attention+MLP 融合为更少的 kernel。

组合起来:相对朴素实现 1.5×3×1.5×2.5×2×1.2=40×。实践中,收益递减使总量限制在朴素实现的 ∼10–20×。

复习:第 2 与 11 章(系统基础;系统架构)。

Q8:解释解耦系统中的权重同步。你能容忍多大的陈旧度(staleness)?

解答

问题:生成集群使用 policy 权重产出 response。训练集群更新这些权重。它们位于不同的硬件上。如何保持同步?

为什么完美同步是浪费:70B BF16 的完整同步 = 140GB。在 InfiniBand 400Gb/s(50GB/s)下:每次同步 2.8 秒。如果每一步都同步(每 50–90 秒),会花掉 3–5% 的时间在权重传输上。可以接受,但没有必要。

陈旧度容忍分析:

  • 每步 policy 变化:∼0.1%(以参数变化的均值衡量)
  • 50 步:∼5% 累积漂移
  • PPO 裁剪范围:可处理最多 20% 的概率比偏差
  • 经验值:50 步陈旧度 →<2% 质量下降(以胜率衡量)

生产策略:

  1. 每 50 个训练步:将完整 BF16 checkpoint 推送到共享存储(传输 2.8 秒)
  2. 生成集群:在批次之间非阻塞地重新加载权重
  3. 增量压缩(可选):只发送发生变化的参数(INT8 增量 ≈ 5GB),作为偏移量应用。带宽减少 10×。
  4. 对于超大规模(256+ GPU):流式同步——在后台持续发送小块数据。平均陈旧度:5–10 步。

重要细节:生成期间计算的 log-prob 使用的是陈旧权重。PPO 的比 πnew/πold 用这些陈旧 log-prob 计算 πold。这没有问题,因为 PPO 本就是为离策略修正而设计的。

复习:第 11 章(大规模系统架构与基础设施)。

Q9:在 512 张 GPU 上你会如何做容错?

解答

在 512 张 GPU 上,MTBF 为 4–8 小时。一次 5 天的训练会遭遇 15–30 次故障。

架构级韧性:

  • 生成集群 = 无状态。故障实例在 <60 秒内重启(只需加载权重,无状态)。
  • 训练集群 = 有状态。需要基于 checkpoint 的恢复。
  • 打分集群 = 无状态。与生成相同。

Checkpoint 策略:

  • 频率:每 50–100 步(5–10 分钟训练)。
  • 方式:异步(非阻塞)。后台线程在下一步推进的同时写入。使用 FSDP 的分布式保存(每个 rank 并行保存自己的分片)。
  • 内容:模型权重、优化器状态(Adam m/v)、LR 调度器、RNG 状态、KL 自适应系数、全局步计数器、replay buffer 指针。
  • 存储:本地 NVMe(快,70B 需 30 秒)+ 异步复制到 S3/共享 FS(持久)。
  • 保留:保留最近 3 个 checkpoint。自动删除更早的。

检测与恢复流程:

  1. NCCL 集合通信超时(60 秒)或心跳丢失(10 秒)→ 检测到故障。
  2. 通过 NVML 健康检查识别故障节点。
  3. 选项 A(快,<2 分钟):Torch Elastic 收缩 world size,重新分配分片,用 N−1 个节点继续。在后台申请替换节点。
  4. 选项 B(干净,∼5 分钟):启动替换节点,重建进程组,加载最近的 checkpoint,恢复。
  5. 经验池已持久化——无需重新生成。

预防:预筛选压力测试(GEMM、内存、NVLink)。ECC 错误监控(错误激增时抢先迁移)。热备节点(预加载环境)。双轨 InfiniBand 实现网络冗余。

复习:第 11 章(大规模系统架构与基础设施)。

Q10:如何从 7B 扩展到 70B 再到 405B?每个规模下有什么变化?

解答

7B(单台 8 卡节点,数小时):

  • 架构:单体(TRL 默认)。所有模型都放在同一批 GPU 上。
  • 内存:LoRA + INT8 参考模型/RM 轻松装入 8×80GB。
  • 并行:节点内 DP=8 或 FSDP。无网络通信。
  • 超参数:LR=5×10−6,激进的 β=0.02,50K–100K 步。
  • 时间:每次运行 4–12 小时。迭代快。

70B(32–64 张 GPU,2–5 天):

  • 架构:半解耦。vLLM 生成 + FSDP 训练。
  • 内存:ZeRO-3 必不可少。梯度检查点。INT8 参考模型/RM。
  • 并行:节点内 TP=8(生成),节点间 FSDP(训练)。
  • 超参数:LR=1.5×10−6,中等的 β=0.05,10K–30K 步。
  • 容错:异步 checkpoint、监控,但可以手动管理。

405B(256–512 张 GPU,1–3 周):

  • 架构:完全解耦。独立集群。权重存储 + 队列。
  • 内存:训练使用 ZeRO-3 + TP=8 + PP=2。INT4 生成。
  • 并行:3D 并行(TP×PP×DP = 8×2×16 = 256 张 GPU 训练)。
  • 超参数:LR=5×10−7,非常保守的 β=0.1,2K–5K 步。
  • 容错:必须。弹性训练、冗余 checkpoint、热备节点。
  • 关键变化:所需的 RL 训练少得多(模型经过预训练已经非常强大)。但每一步都贵 50×,所以不稳定是灾难性的。

悖论:更大的模型实际上 每一步更容易做 RL 训练(更稳定,loss 地形更平滑)。但不稳定的代价随模型规模放大——在 405B 上一次失败的运行会浪费 $100K+ 的算力。

复习:第 11 章(大规模系统架构与基础设施)。

实战与调试题

Q11:reward 分数在上升,但模型质量在下降。诊断并修复。

解答

典型的 reward hacking / 古德哈特定律。

诊断流程:

  1. 检查 response 长度:绘制训练过程中的平均长度。单调增长?= 长度漏洞(RM 给更长的 response 打更高分)。
  2. 检查 KL 散度:>15?= policy 偏离参考模型太远,丢失了能力。
  3. 检查多样性:每个 response 的唯一 trigram 数。在下降?= 模式坍缩(重复同样的高 reward 模式)。
  4. 人工检查:阅读 20 条最高 reward 的 response。它们有什么共同的模式?(例如全部以“这个问题问得好!”开头、全部使用项目符号、过度模棱两可)。
  5. 胜率:在留出的 prompt 上相对 SFT baseline 评估。如果 RM 上升而它持平/下降 = 漏洞确认。

立即修复:

  • 回滚到胜率仍在改善的最后一个 checkpoint
  • 将 β 增大 2–3×(更强的 KL 惩罚)
  • 加入显式长度惩罚:r′=r−0.001⋅max⁡(0,len−500)

结构性修复(防止再次发生):

  • RM 集成:在不同数据划分上训练 3–5 个 RM。取最小值或均值。漏洞是模型特有的。
  • RM 刷新:每 2000 步,用当前 policy 生成,获取人工标注,重新训练 RM。
  • 多目标 reward:用相互独立的 RM 组合有用性 + 无害性 + 简洁性。
  • 基于胜率(而非 RM 分数)的早停。你所优化的指标应当不同于训练信号。

复习:第 9 与 11 章(Reward 模型训练;系统架构)。

Q12:如何决定 RL 训练的 prompt 分布?

解答

Prompt 质量是 RLHF 中最被低估的因素。差的 Prompt = 没有学习信号。

组成(我的默认配比):

  • 40% 真实用户流量(代表实际用例)
  • 30% 合成(LLM 生成,填补覆盖空白——稀有主题、边角情况)
  • 20% 课程式(渐进难度——先易,随模型变强提升复杂度)
  • 10% 对抗式(red-team prompt、越狱尝试、含糊指令)

关键:Goldilocks 过滤器:

  1. 对每个候选 prompt,用当前模型生成 4–8 个回答。
  2. 用 RM 打分。计算通过率(超过阈值的比例)。
  3. 仅保留通过率在 20–80% 的 prompt:•<20%:太难。模型几乎总是失败 → 全是负 advantage → 无有效梯度。•>80%:太易。模型几乎总是成功 → 全是正 advantage → 无对比。•20–80%:完美。成功与失败兼有 → 关于「什么有效」的清晰信号。
  4. 每 500 训练步重新过滤(模型在进步,难度分布也在漂移)。

主题多样性:确保没有单一主题主导(每个类别 <10%)。用 Embedding 聚类验证覆盖度。否则模型会过度优化主导主题。

复习:第 7 与 9 章(GRPO;Reward 模型训练)。

Q13:RLHF 中 LoRA vs 全量微调。各自在什么情况下使用?

解答

LoRA(Low-Rank Adaptation,r=64,α=16):

  • 可训练参数:∼模型的 0.2%(70B 对应 200M)
  • 显存节省:无需独立的参考模型(base 模型 = 参考模型)!节省 140GB。
  • 稳定性:天然更稳定(低秩约束限制了 policy 的漂移幅度)
  • 速度:每步更快(需要更新的参数更少),但可能需要更多步
  • 质量天花板:通常达到全量微调质量的 90–95%

全量微调:

  • 所有参数都会更新。表达力最强。
  • 需要独立的参考模型副本(70B 为 140GB)。或者通过非常频繁的 checkpoint 来「锚定」。
  • 灾难性遗忘的风险更高。需要更低的 LR(3× 比 LoRA 低 3×)以及更强的 β。
  • 更适合:需要大幅分布漂移(新语言、迥异风格),LoRA 触及容量上限的情况。

我的决策框架:

  1. 先用 LoRA(r=64)。它便宜 3× 且更稳定。
  2. 监控 LoRA 矩阵上的梯度范数。如果持续 >1.0(相对于参数量很大):LoRA 已到容量上限。
  3. 仅当胜率停滞且梯度分析提示容量受限时,才切换到全量微调。
  4. 对全量微调:使用 LR/3、β×2、更频繁的 checkpoint,以及基于胜率的早停。

混合:LoRA 用于对齐/安全(小行为漂移)+ 全量微调用于能力/推理(需要大漂移)。

复习:第 1 与 10 章(LLM 架构;SFT 最佳实践)。

Q14:过程奖励模型(Process Reward Model, PRM)vs 结果奖励模型(Outcome Reward Model, ORM)。设计一个 PRM 系统。

解答

ORM:只给最终答案打分。「整体回答好不好?」简单,但无法定位推理在何处出错。

PRM:为每个中间步骤打分。「这个推导的第 3 步对吗?」信息量大得多,但更难训练。

PRM 对推理任务的优势:

  • 准确定位推理失败的位置(步骤级信用分配)
  • 支持树搜索:只展开步骤分数高的分支
  • reward hacking 更难:错误步骤 + 侥幸正确答案拿不到高分
  • 在 MATH 基准上,PRM + best-of-N 比 ORM + best-of-N 高 10–20%

训练 PRM:

  1. 数据收集(蒙特卡洛方法):•对每道题,逐步生成推理轨迹•在每一步 k,从该点出发把解完整补全 M 次(M=32)•步骤分数 = 抵达正确答案的补全比例•分数明显下降的步骤 = 「出错」的步骤
  2. 标注:如果某一步的补全率 > 50%,则标为「正确」;< 20% 的标为「错误」。
  3. 模型:与 base 模型同架构 + 每个 Token 位置上的分类头。用步骤标签做二元交叉熵训练。
  4. 推理:为每步打分。若任一步骤的分数 <0.3,则将该轨迹标记为有缺陷。

在 RLHF 中使用 PRM:PRM 给出的逐 Token reward 直接喂入 GAE。每个 Token 都获得即时反馈,而非仅在序列末端。这极大改善了长推理链上的信用分配。

复习:第 9 与 13 章(Reward 模型训练;大型推理模型的 RL)。

Q15:如何评估 RL 是否真的改进了模型?

解答

多面向评估(单一指标无法捕捉「质量」):

1. 胜率(最重要、最可靠):

  • 500+ 条多样 prompt。用 LLM judge(GPT-4 或 Claude)在盲测 A/B 对比中相对 SFT baseline 选出胜者。
  • 目标:>55% 胜率 = 有意义的改进。>65% = 强改进。
  • 使用位置去偏(交换 A/B 顺序并取平均)。报告置信区间。

2. 能力基准(回归检测):

  • MMLU(知识)、HumanEval(代码)、MATH(推理)、MT-Bench(多轮)。
  • 任何 >2% 的下降 = 值得警惕的对齐税。排查哪些类别出现了退化。

3. 分类别评估:

  • 安全:有害 prompt 上的拒答率(应上升)
  • 真实性:TruthfulQA 分数(应上升或持平)
  • 有用性:指令遵循基准上的任务完成率

4. 分布指标:

  • 回答长度分布(不应出现剧烈偏移)
  • 词汇多样性(每条回答的 unique token 数)
  • 格式合规性(若针对特定格式训练过)

5. 人工评估(黄金标准,成本高昂):

  • 每个样本由 3+ 名熟练标注员做盲测 A/B。标注员间一致性 > 70%。
  • 仅用于最终模型选择,不在训练过程中使用(太慢/太贵)。

危险信号:RM 分数上升 + 胜率持平 = reward hacking,而非真正的改进。胜率上升 + 基准下降 = 对齐税过高,降低 RL 强度。

复习:第 14 章(LLM 评估)。

Q16:端到端描述 reward 模型的训练流水线。

解答

阶段 1 —— 数据生成:

  • 收集 50K–100K 条多样 prompt(真实流量 + 合成)
  • 对每个 prompt,以不同 temperature(0.3、0.7、1.0)并从多个模型生成 4–8 个回答(多样性是关键——如果所有回答都很相似,偏好就没有信息量)
  • 合计:200K–800K 个候选回答

阶段 2 —— 偏好收集:

  • 方案 A(昂贵,质量最佳):由人工标注员比较成对回答。每对 3 名标注员。成本:每次比较 $2–5。
  • 方案 B(便宜,与人类的一致率 85–90%):LLM judge(GPT-4/Claude)。便宜 10×。适合规模化。
  • 格式:(prompt, chosen response, rejected response)。标注员意见不一致(<70% 一致性)的样本对被丢弃。
  • 最终数据集:100K–500K 个样本对。

阶段 3 —— 训练:

  • 架构:与 base LLM 相同 + 标量头(每个序列一个回归输出)。
  • 损失:ℒ=−𝔼⁡[log⁡σ⁡(r⁡(x,yw)−r⁡(x,yl))](Bradley-Terry)。
  • 训练:只训 1 个 epoch! RM 过拟合极快。验证准确率 68–75% 就算好(更高往往意味着过拟合到标注伪影)。
  • 技巧:把 reward 居中到 0 附近(减去滑动均值)。检查长度偏差(若长度与分数的相关性 > 0.3,则在训练中加入长度惩罚)。

阶段 4 —— 验证:

  • 留出的偏好样本对:准确率应在 68–75%。
  • 在新数据上与人类的一致率:> 80%。
  • 长度偏差检查:回答长度与 RM 分数之间的相关性应 < 0.2。
  • 一致性检查:同一 prompt 下,改写后的回答应得到相近的分数。

复习:第 9 章(Reward 模型训练)。

Q17:KL 散度爆炸时会发生什么?根因与修复。

解答

KL 衡量的是什么:当前 policy 与参考模型之间的平均对数比:DKL=𝔼y∼πθ​[log⁡(πθ​(y|x)/πref​(y|x))]。KL=0 表示与参考模型完全相同。KL=10 表示 policy 在其偏好的输出上多放了 10 nats 的概率。

健康范围:训练期间为 3–10。缓慢上升没问题。突然飙升 = 有问题。

KL 爆炸的根因:

  1. 学习率过高:policy 迈出一大步,偏离参考模型。修复:把 LR 降低 2–5×。
  2. Reward hacking:找到了一个远离参考行为却能拿到高 reward 的漏洞。修复:提高 β,加入 RM 集成。
  3. Mode collapse:policy 集中到某一个回答模板上。KL 在该模板处很高,其他处都很低。修复:提高熵奖励,提高 temperature。
  4. 坏 batch:某个运气不好的 batch 带着极端 advantage 把 policy 推偏了。修复:梯度裁剪,减小 mini-batch 大小。
  5. 价值函数发散:错误的 advantage 估计导致错误的更新。修复:降低价值函数的 LR,或切换到 GRPO(无价值函数)。

恢复流程:

  1. 检测:KL > 15 持续 50+ 步,或 KL 在一步内跳升 >5。
  2. 立即:加载最后一个干净的 checkpoint(KL < 10)。
  3. 调整:把 LR 降低 50%。把 β 提高 2×。把 cliprange 降到 0.1。
  4. 恢复训练:前 200 步密切监控。

复习:第 5 与 7 章(PPO;GRPO)。

Q18:比较单体式与解耦式 RLHF 架构。各自在什么情况下合适?

解答

单体式(TRL 默认:单进程,所有模型放在同一批 GPU 上):

  • 优点:代码简单。没有分布式系统的复杂性。调试容易。
  • 缺点:GPU 有 60% 的时间闲置(生成时算力闲置,训练时带宽闲置)。超过 ∼16 张 GPU 后无法高效扩展。所有模型争抢同一块显存。
  • 适用场景:模型 ≤ 13B,单节点,研究/原型开发。

半解耦(vLLM 生成 + FSDP 训练,同一集群):

  • 优点:利用率更好(生成与训练可以部分重叠)。可扩展到 64 张 GPU。
  • 缺点:仍然共享硬件,无法独立优化。比单体式更复杂。
  • 适用场景:13B–70B,2–8 个节点,生产环境实验。

完全解耦(由队列连接的独立集群):

  • 优点:每个集群针对自身负载优化。生成可以独立于训练扩展。生成集群是无状态的(容错轻而易举)。可扩展到数百张 GPU。
  • 缺点:分布式系统的复杂性。权重过时。队列管理。网络开销。
  • 适用场景:≥ 70B 生产训练。需要规模、容错和高利用率。

关键洞见:生成受带宽约束,训练受算力约束。同一套硬件无法同时为两者优化。解耦让生成节点可以拥有:更大的显存带宽、INT8 权重、大 batch。训练节点则拥有:完整 BF16 精度、Flash Attention、FSDP 分片。

复习:第 11 章(系统架构与大规模基础设施)。

Q19:如何为 RL 训练搭建课程学习?

解答

课程 = 难度逐步递增,让模型循序渐进地学习。

为什么重要:如果把最难的 prompt 直接丢给一个弱模型,它得到的全是负 reward → 没有学习信号(一切都同样糟糕)。如果从容易的开始,模型会先发展出基本能力,再在此基础上进阶。

实现方式:

  1. 难度评分:按当前模型的通过率对每个 prompt 评级(来自 Goldilocks 过滤)。易 = >80% 通过率,中 = 30–80%,难 = <30%。
  2. 排期:第 0–1000 步:70% 易、20% 中、10% 难。第 1000–5000 步:30% 易、50% 中、20% 难。第 5000+ 步:10% 易、40% 中、50% 难。
  3. 动态调整:每 500 步重新评估难度分布。模型已「掌握」的 prompt(通过率 > 95%)会被淘汰。同时引入新的、更难的 prompt。
  4. 具体到 GRPO:课程学习确保每个组里始终混合着成功与失败。没有课程学习,难 prompt 会给出全零的组(无用)。

证据:DeepSeek-R1 使用了隐式课程学习——从简单的数学/代码题开始,模型发展出基本推理能力,随后在没有任何显式排期的情况下解决了逐步变难的问题。

复习:第 7 与 12 章(GRPO;LLM 智能体训练)。

Q20:你有 64 张 A100-80GB GPU 的预算,需要 RL 训练一个 70B 模型。设计分配方案。

解答

8 个节点 × 8 张 GPU = 共 64 张。需要在生成、打分和训练之间划分。

我的分配方案:

  • 生成:24 张 GPU(3 个节点)。6 个 vLLM 实例,TP=4。INT8 权重 = 70GB/模型,为 KV cache 留出空间。连续批处理,batch ≈ 合计 128。
  • 打分:8 张 GPU(1 个节点)。同一节点上放 RM(INT8,TP=4)+ 参考模型(INT8,TP=4)。或者共用 4 张 GPU,以 TP=4 在 RM 与参考模型之间轮流使用。
  • 训练:32 张 GPU(4 个节点)。FSDP 横跨全部 32 张。每张 GPU 持有 ∼70B/32 = 2.2GB 参数 + 优化器分片。激活值有充足的余量。为保险起见使用梯度检查点。

预期吞吐:

  • 生成:6 个实例 ×∼80 个回答/分钟 = 480 个回答/分钟
  • 训练:batch 为 128,每 ∼15 秒一步(仅训练,不等待生成)
  • 重叠:在训练一步 N(15 秒)期间,生成会产出 ∼120 个回答,供第 N+1 步使用。完美的流水线。

瓶颈分析:生成 128 个回答需要 ∼45 秒。训练需要 ∼15 秒。打分需要 ∼5 秒。生成是瓶颈。可以把 8 张 GPU 从训练挪到生成(40 生成、24 训练)以求平衡,但那样训练又成了瓶颈。当前分配接近最优。

显存紧张时的替代方案:把打分移到训练节点上(分时复用:生成时打分,训练时训练)。省下 8 张 GPU。流水线略差,但可行。

复习:第 2 与 11 章(系统基础;系统架构)。

GRPO 变体与高级 RL 题

Q21:什么是 DAPO,它相对标准 GRPO 有哪些改进?

解答

DAPO(Dynamic Adaptive Policy Optimization)引入了 5 项关键修改:

1. Clip-Higher(非对称裁剪):标准 PPO/GRPO 在两个方向上以 ϵ=0.2 等量裁剪。DAPO 使用 ϵlow=0.2,却用 ϵhigh=0.28。这允许模型更激进地 提高 好动作的概率,同时仍限制它对坏动作的压制幅度。直觉:探索需要比利用更大的空间。

2. 过长过滤(Overlong Filtering):如果一条回答触及最大长度上限(被截断,没有 EOS token),它会被完全从损失中屏蔽掉。理由:被截断的回答不含自然的停止信号——在它们上面训练会教模型认为「说到一半就停」是可以接受的。

3. Token 级损失:损失按所有序列的 Token 总数归一化,而不是按序列数量。这防止较长的序列主导梯度。

4. 软过长惩罚(Soft Overlong Punishment):不再做二元截断过滤,而是在回答接近最大长度时施加渐进惩罚。rsoft=−c⋅max(0,len−Lsoft)/(Lmax−Lsoft)。

5. 动态采样(Dynamic Sampling):训练期间对 prompt 重新采样,确保每个 batch 都混合着成功/失败(TRL 中尚未实现)。

何时使用:需要最大化探索和长补全(32K+ token)的大规模推理 RL。非对称裁剪尤其有价值。

复习:第 7 与 8 章(GRPO;偏好优化变体)。

Q22:解释 vLLM 的训练-推理不一致问题。它为什么会发生,TIS/MIS 又如何修复它?

解答

问题:当用 vLLM 做生成、用训练框架(DeepSpeed/FSDP)做更新时,同一个模型、同样的权重却会产出 不同 的 Token 概率。原因如下:

  • 数值 kernel 不同(vLLM 使用为吞吐优化的自定义 CUDA kernel)
  • attention 实现不同(训练中为 Flash Attention,vLLM 中为 PagedAttention)
  • 精度处理不同(vLLM 用 FP8/INT8,训练用 BF16)
  • 批处理差异影响层归一化的数值

这会悄无声息地破坏 PPO 的 on-policy 假设:我们用来自 vLLM 的 πold 和来自训练框架的 πθ 来计算比率 πθ/πold。这个比率从第零步起就是错的!

TIS(Truncated Importance Sampling,截断重要性采样):通过乘以 min⁡(πtrain/πinference,C) 来校正梯度。带上限 C 的 min 可防止极端校正破坏训练稳定性。典型值 C=2.0。

MIS(Masked Importance Sampling,掩码重要性采样):更激进——凡是 πtrain/πinference>C 的 Token 直接丢弃。对梯度零贡献。防止任何估计不准的 Token 影响更新。

序列级 vs Token 级:序列级 IS 在理论上正确(无偏);Token 级 IS 有偏但方差更低。实践中,带截断的序列级表现最好。

复习:第 7 与 11 章(GRPO;系统架构)。

Q23:GSPO vs GRPO——根本区别是什么,什么时候重要?

解答

GRPO:逐 Token 计算重要性比率:wi,t=πθ​(oi,t|q,oi,<t)/πold​(oi,t|q,oi,<t),然后对每个 Token 独立裁剪。

GSPO:在 序列级 计算重要性比率:si​(θ)=(πθ​(oi|q)/πold​(oi|q))1/|oi|——即 Token 概率的几何均值。对这个单一的序列级比率进行裁剪。

为什么重要:GRPO 的逐 Token 裁剪把每个 Token 当作独立的,但在语言中它们高度相关。序列早期一处微小的逐 Token 变化会随众多 Token 指数级累积。GSPO 通过考察完整的序列概率来捕捉这一点。

长度归一化:1/|oi| 次幂确保在不同长度的序列之间进行公平比较。没有它,较长的序列总会得到更低的概率比率。

何时使用 GSPO:当训练走向 off-policy 时(steps_per_generation > 1 或 num_iterations > 1)。如果完全 on-policy(比率 ≈1),GRPO 与 GSPO 等价。

复习:第 7 与 8 章(GRPO;偏好优化变体)。

Q24:论文「It Takes Two」表明 G=2 就能匹敌 G=16。这怎么可能?

解答

关键洞见在于,GRPO 的有效性并非来自准确的 advantage 估计(那需要很大的 G),而是来自一个 隐式对比目标。

当 G=2、reward 为二值(一个正确、一个错误)时:A^correct=+1,A^wrong=−1(归一化后)。损失变为:提高正确回答的概率,降低错误回答的概率。这本质上就是一个 DPO 式的对比损失!

为什么更大的 G 帮助不大:归一化后的 advantage A^i=(ri−μ)/σ 已经在好与坏之间造出了对比。更多样本能给出更好的 μ 估计,但梯度方向由最好与最差之间的 对比 主导,而非均值准确率。

算力节省:G=2 意味着生成算力比 G=16 少 8×。由于生成占训练时间的 60%,这相当于训练快 ∼4×。

注意事项:通过率在 30–70% 时效果最好。如果通过率非常低(<10%),G=2 常常给出两个失败样本(无信号)。对难题需要更大的 G。

复习:第 7 章(GRPO)。

Q25:什么是 SAPO,它的软门控与硬裁剪有何不同?

解答

标准 PPO/GRPO 使用硬裁剪:clip​(r,1−ϵ,1+ϵ)。在边界处,梯度会突然降到零。这造出了一个「死区」,模型在其中得不到任何学习信号。

SAPO 用平滑的 sigmoid 门控取代它:随着比率偏离 1,梯度被逐步衰减,绝不会突然归零。它使用非对称 temperature:

  • τ+=1.0 用于正 advantage(标准衰减)
  • τ−=1.05 用于负 advantage(为抑制而略更激进的衰减)

好处:(1)梯度地形中没有「悬崖」。(2)略微落在裁剪范围之外的 Token 仍有贡献(被衰减,而非归零)。(3)优化轨迹更稳定。(4)序列连贯——考虑完整的序列上下文。

取舍:信任域比硬裁剪略宽松,因此需要仔细调 temperature。但总体上对超参数选择更稳健。

复习:第 7 与 8 章(GRPO;偏好优化变体)。

DPO 扩展题

Q26:比较 f-DPO 的散度选择。什么时候用前向 KL、JS 或反向 KL?

解答

标准 DPO 隐式地使用反向 KL(DKL[πθ∥πref]):

  • 反向 KL(默认):模式寻求(mode-seeking)。policy 把概率集中到参考模型概率高的地方。避免生成参考模型不会生成的文本。适合安全场景(保守)。
  • 前向 KL:覆盖全域(mass-covering)。policy 试图覆盖参考模型的所有模式,甚至低概率的模式。有利于多样性,但可能生成低质量输出。
  • Jensen-Shannon:前向与反向之间的对称折中。在模式覆盖与模式寻求之间取得平衡。通用对齐场景往往最优。
  • Alpha 散度(α=0.5):在前向(α=0)与反向(α=1)之间插值。可调。

实践建议:从反向 KL 开始(标准 DPO)。如果模型过于保守(不愿尝试有创意的解法),改用 JS 散度。如果多样性至关重要(创意写作、头脑风暴),试试前向 KL。

复习:第 6 与 8 章(DPO;偏好优化变体)。

Q27:你的 DPO 偏好数据有 15% 的标签噪声。你会怎么做?

解答

按复杂程度递增有三种方案:

1. Robust DPO(噪声率已知时最佳):解析地对损失去偏:ℒrobust=(1−ε)​ℒDPO​(yw,yl)−ε​ℒDPO​(yl,yw)1−2​ε。设 ε=0.15。这可以证明在期望意义上恢复干净的 DPO 目标。TRL:loss_type="robust", label_smoothing=0.15。

2. IPO(噪声率未知时最佳):带目标间隔的平方损失。被错误标注的样本对影响有界(平方损失不会发散)。对任意噪声模式都更稳健,且无需知道 ε。TRL:loss_type="ipo"。

3. TR-DPO(分布漂移时最佳):训练期间通过 EMA 更新参考模型。即使早期数据有噪声,不断演进的参考模型也能帮助模型自我纠正。TRL:sync_ref_model=True, ref_model_mixup_alpha=0.6。

数据侧修复:(1)过滤掉标注员间一致性 <70% 的样本对。(2)用 RM 给样本对打分;丢弃 RM 与标签不一致的样本对。(3)主动学习:重新标注最不确定的样本对。

复习:第 6 与 8 章(DPO;偏好优化变体)。

Q28:什么是 SimPO?为什么「无参考模型」是优势?

解答

SimPO 用回答的平均对数概率作为隐式 reward 信号:r⁡(x,y)=1|y|​∑tlog⁡πθ​(yt|x,y<t)——无需参考模型。

loss 中加入目标 margin γ:chosen 回答的平均 log-prob 应至少比 rejected 高 γ。

为什么「无参考」重要:

  1. 显存:无参考模型 = 70B 模型节省 70–140GB。可在同样硬件上训练更大的模型。
  2. 简洁性:无需管理/加载/服务第二份模型副本。
  3. 无陈旧参考:DPO 的参考随着训练推进越来越不相关。SimPO 没有这个问题。
  4. 内置长度归一化:1/|y| 天然防止长度偏差(DPO 需显式处理)。

权衡:没有参考锚点,模型有更多自由去塌缩或漂移。γ margin 和长度归一化部分缓解了这一点,但在激进训练时 SimPO 可能不如 DPO 稳定。

复习:第 8 章(偏好优化变体)。

Q29:解释 Iterative RPO。为何在推理任务中把 DPO 与 NLL loss 结合?

解答

用于推理的标准 DPO 有一种微妙的失效模式:它学会判别(给正确轨迹更高的隐式 reward),但不一定学会生成它们。

为什么:DPO 的梯度推高 chosen 的概率、压低 rejected 的概率。但 chosen 回答可能与模型自身会生成的东西差异巨大,以至于提升其概率并不能教会模型产出类似的推理模式。

RPO 的修复:在 chosen 回答上添加负对数似然(NLL/SFT)loss:ℒ=ℒDPO+α⋅ℒNLL​(yw)。

NLL 项显式训练模型逐步生成获胜回答。DPO 项确保模型同时学会避免落败回答。结合起来:模型同时学到「如何正确推理」(NLL)与「该避免什么」(DPO)。

迭代:生成回答 → 检查正确性 → 构造对 → 用 RPO 训练 → 重复。每次迭代,模型更擅长生成正确推理,为下一轮提供更高质量的训练数据。

TRL:loss_type=["sigmoid", "sft"], loss_weights=[1.0, 1.0]

复习:第 8 与 13 章(偏好优化变体;大型推理模型的 RL)。

GPU 架构与硬件题

Q30:解释 GPU 内存层次结构。它对 LLM 推理为何重要?

解答

从最快到最慢:

  1. 寄存器(Registers):线程私有,∼256 KB/SM。即时访问(0 周期延迟)。
  2. SRAM(共享内存):每 SM 私有,∼192–228 KB/SM(A100:164 KB 可配置)。带宽:∼19 TB/s(聚合)。延迟:∼20 周期。
  3. L2 缓存:跨整张 GPU 共享,40–60 MB(H100:50 MB)。带宽:∼5 TB/s。延迟:∼200 周期。
  4. 高带宽内存(HBM):GPU 主显存,80 GB(A100)。带宽:2–3.35 TB/s。延迟:∼400 周期。
  5. CPU DRAM:通过 PCIe,512 GB+。带宽:32–64 GB/s。延迟:∼10K 周期。

对 LLM 为何重要:自回归生成在每个 Token 都要读取完整模型权重(70B 约 ∼140 GB)。以 2 TB/s 的 HBM 带宽,仅流式读权重就要 70ms。实际计算(一次矩阵-向量乘法)只要 0.5ms。GPU 有 99% 的时间在等数据。

Flash Attention 利用了这一点:通过把中间结果(QK 分数、softmax)保留在 SRAM(19 TB/s)而非写到 HBM(2 TB/s),消除了 attention 的 90% 内存流量。计算量未变,但 HBM 的读写降低 10×。

复习:第 2 章(LLM 的系统基础)。

Q31:Flash Attention 如何工作?什么是 online softmax 技巧?

解答

问题:标准 attention 在 HBM 中物化 n×n 的 attention 矩阵。n=8192:每个 head 81922×2=134 MB,32 头每层 4.3 GB。必须写到 HBM 再读回做 softmax 与乘法——3 次完整的 HBM 往返。

Flash Attention 方案:从不存储完整的 n×n 矩阵。以可放进 SRAM 的分块(tile)处理。

算法:

  1. 将 Q 拆为 Br 行的块,K/V 拆为 Bc 行的块。
  2. 对每个 Q 块:遍历所有 K 块,计算部分 attention 分数。
  3. online softmax 技巧:维护滑动 max m 与滑动 sum ℓ 以做 softmax 归一。处理新的 K 块时更新:mnew=max⁡(mold,max⁡(scores)),将上一累加器按 emold−mnew 重新缩放,再加上新的贡献。
  4. 输出以增量方式累加——从不需要完整的 n×n 矩阵。

关键洞见:softmax 本来是全局操作(对所有元素取 max 和 ∑)。online 技巧将其分解为带修正因子的局部更新。数学上精确——并非近似。

结果:显存 O⁡(n) 而非 O⁡(n2)。速度提升 2–4×(更少 HBM 访问,更多时间在 SRAM)。

Flash Attention 2:在 warp 之间做更好的工作划分,将非矩阵乘的 FLOPs 减少 2×。

Flash Attention 3(H100/Hopper):使用张量内存加速器(Tensor Memory Accelerator, TMA)做异步加载、warp 专门化(生产者/消费者 warp)、支持 FP8。

复习:第 1 与 2 章(LLM 架构;系统基础)。

Q32:解释 PagedAttention。它如何解决键值缓存(KV cache)问题?

解答

问题:生成过程中,每条序列都需要键值缓存(存储所有先前 Token 的 K 与 V 张量)。对 70B 模型:每个 Token 需要 2×nlayers×dmodel×2 字节 = 2×80×8192×2≈2.5 MB。2048 Token 的序列:∼5 GB 的键值缓存。

传统分配方式:为每条活跃序列预分配 max_sequence_length。若 max=2048 但平均为 500,就浪费了已分配内存的 75%。若有 50 条并发序列,就是数百 GB 的浪费。

PagedAttention:受操作系统虚拟内存启发:

  1. 键值缓存被拆分为固定大小的 块(block)(页),每块保存 16 个 Token 的 KV。
  2. 一张 block table(类似页表)把逻辑 Token 位置映射到物理内存块。
  3. 块随着序列增长按需分配。没有预分配浪费。
  4. 序列结束后,释放的块立即归还到池中。

额外好处:

  • 前缀共享:共享同一 system prompt 的多条序列共用键值缓存块(写时复制)。对聊天应用节省 30–50% 内存。
  • 抢占:可以把低优先级序列的块「换出」到 CPU,为更高优先级的请求释放 GPU 显存。
  • 近乎零碎片:内部碎片仅限最后一个块(<16 个 Token)。外部碎片被消除(任何空闲块都可用在任何位置)。

结果:同样的内存下可多容纳 3–5× 条并发序列 → 服务吞吐提升 3–5×。

复习:第 2 章(LLM 的系统基础)。

Q33:比较 NVLink 与 InfiniBand。在 RLHF 训练中各自何时使用?

解答

NVLink(节点内,GPU 到 GPU):

  • 带宽:600 GB/s(A100),900 GB/s(H100)——双向总和
  • 延迟:∼1 μs
  • 范围:单个物理节点内(8 张 GPU 通过 NVSwitch 互联)
  • 使用场景:张量并行(Tensor Parallelism)(TP=8)。每层的矩阵乘被拆分到多张 GPU 上,每层之后都需要 AllReduce。需要超高带宽 + 低延迟。

InfiniBand NDR(节点间,node-to-node):

  • 带宽:每端口 400 Gb/s = 50 GB/s。使用 8 个端口(GPUDirect RDMA):每节点聚合 400 GB/s。
  • 延迟:∼1–5 μs(RDMA)
  • 范围:集群中各节点之间。需要交换机(fat-tree 拓扑)。
  • 使用场景:数据并行(Data Parallelism)/ FSDP 的梯度同步。梯度的 AllReduce 每个训练步只发生一次(而非每层一次),因此对延迟的容忍度更高。

具体到 RLHF:

  • 生成:节点内通过 NVLink 做 TP=8。跨节点的多个 vLLM 实例之间不通信(易并行)。
  • 训练:节点内通过 NVLink 做 TP=8 + 节点间通过 InfiniBand 做 FSDP。梯度在完整反向传播后同步。
  • 权重同步:训练 → 生成使用 InfiniBand(传输 140 GB,异步,50 GB/s 下约需 ∼3s)。

复习:第 2 与 11 章(系统基础;系统架构)。

优化与训练题

Q34:解释 Adam 与 AdamW 的区别。这一差异对 LLM 为何重要?

解答

带 L2 正则化的 Adam:θt+1=θt−α⋅(m^t/(v^t+ϵ)+λ​θt)。权重衰减项 λ​θt 位于自适应缩放的内部。梯度较大的参数(vt 较大)获得更少的权重衰减(除以 vt)。这不是真正的权重衰减——它依赖于尺度。

AdamW(解耦权重衰减):θt+1=(1−α​λ)​θt−α⋅m^t/(v^t+ϵ)。权重衰减在自适应更新之外、之前施加。无论梯度历史如何,每个参数都获得相同比例的衰减。

对 LLM 为何重要:

  1. LLM 的参数横跨多个数量级(embedding 层 vs attention vs FFN)。Adam 的耦合 L2 实际上对小梯度参数的惩罚比对大梯度参数更重——这是错误的行为。
  2. 解耦的 WD 在所有层上提供统一的正则化,防止某些层无限增长而另一些层过度收缩。
  3. 经验上:在长预训练任务中,与相同有效正则化强度的 Adam+L2 相比,AdamW 的 perplexity 好 2–5%。

具体到 RL:通常用 λ=0(无权重衰减)。KL 惩罚提供了正则化。但对 SFT:用 AdamW 配合 λ=0.01–0.1 是标准做法。

复习:第 1 章(LLM 架构与优化方法)。

Q35:为什么学习率预热是必要的?没有它会怎样?

解答

问题:Adam 的二阶矩估计 vt=β2​vt−1+(1−β2)​gt2 从 v0=0 开始。偏差校正 v^t=vt/(1−β2t) 在数学上做了补偿,但实践中:

  • 最初几步:vt 基于 1–5 个梯度样本。对真实方差的估计极不准确。
  • 若某参数在初始阶段恰好得到很小的梯度,vt 就极小 → 有效 LR 巨大 → 灾难性的更新。
  • 偏差校正会放大早期更新:在第 1 步,v^1=v1/(1−0.999)=1000⋅v1。

不做预热:最初的 10–100 步常出现梯度尖峰,永久性地损害模型。在优化器稳定之前,早期表示就被打乱了。

预热的修复:从 LR ≈0 开始,在 W 步内线性增至目标值(通常为训练的 3–10%)。等到 LR 达到满值时,vt 已累积了足够多的样本而变得准确。

典型设置:

  • 预训练:2000 步预热(∼200K 步的 1%)
  • SFT:100 步预热(∼2000 步的 5%)
  • RL(PPO/GRPO):20–50 步预热(较短,模型已因 SFT 而稳定)

复习:第 1 与 10 章(LLM 架构;SFT 最佳实践)。

Q36:比较各种学习率调度。对 RL 微调你会选哪一种?

解答

余弦衰减:ηt=ηmin+12​(ηmax−ηmin)​(1+cos⁡(π​t/T))。预训练与 SFT 的标准做法。平滑衰减,大部分时间处于中等 LR。

线性衰减:ηt=ηmax​(1−t/T)。更简单,短程训练下结果与余弦相近。

WSD(Warmup-Stable-Decay):预热 → 80% 阶段保持恒定 LR → 最后 20% 快速衰减。预训练的新标准。「稳定」阶段带来一致的学习;最后的衰减榨出残余收益。

恒定调度:不衰减。预热后保持 ηt=ηmax。

对 RL 微调(PPO/GRPO),我会选择:恒定调度 + 短预热。理由:

  1. RL 训练长度高度不可预测(依据胜率而非 epoch 决定何时停止)。
  2. 余弦/线性衰减假设你事先知道总步数。
  3. LR 本就已经很低(10−6),进一步衰减会让更新几乎不可见。
  4. PPO 的自适应 KL 控制器已经在调节有效步长。
  5. 若必须衰减:在宽裕的预算上使用线性衰减,指标进入平台期就提前停止。

复习:第 1 与 5 章(LLM 架构;PPO)。

Q37:为什么梯度裁剪对 RL 训练至关重要,而对 SFT 不那么重要?

解答

SFT:监督 loss 平滑且行为良好。梯度范数在各 batch 间保持一致(通常为 0.1–1.0)。在 1.0 处裁剪很少被触发——它只是一张安全网。

RL(PPO/GRPO):梯度范数高度多变,原因如下:

  1. 奖励方差:一个 batch 可能全是高 reward 的回答,下一个可能全都很低。advantage A^ 剧烈波动。
  2. 比值爆炸:若某个稀有 Token 的概率变化很大,rt=πnew/πold 可能非常大 → 在裁剪起作用前就产生很大的梯度。
  3. 稀疏奖励:在二值 reward 的 GRPO 中,有些 prompt 的结果全对(advantage ≈0),随后一个难题 prompt 突然给出极端 advantage。
  4. KL 项:当策略发生偏离时,KL 惩罚的梯度可能突增。

不做裁剪:一个坏 batch 就能产生 100× 于正常量级的梯度 → 一步摧毁模型。无法恢复(对全部预训练的灾难性遗忘)。

典型设置:max_grad_norm=1.0。有些在 RL 训练早期用 0.5 以求更安全。范数是跨所有参数全局计算的(而非逐层)。

监控:如果裁剪在超过 20% 的步上被触发,你的 LR 可能太高,或 batch size 太小。

复习:第 5 与 7 章(PPO;GRPO)。

Q38:训练中 BF16 与 FP16 的对比。这一选择何时重要?

解答

FP16:1 位符号 + 5 位指数 + 10 位尾数。范围:±65504。精度:∼3.3 个十进制有效位。

BF16:1 位符号 + 8 位指数 + 7 位尾数。范围:±3.4×1038(与 FP32 相同!)。精度:∼2.4 个十进制有效位。

为什么 BF16 对 LLM 更优:

  1. 无需 loss scaling:FP16 的范围小(±65K),意味着梯度与激活经常上溢/下溢。需要动态 loss scaling(把 loss 乘 1024,再对梯度除回来)。BF16 拥有 FP32 的范围——上溢基本不可能。
  2. 更简单的代码:没有 loss scaler,无需检查 inf/nan,无需动态调整 scaling。
  3. 对 RL 至关重要:RL 的梯度比 SFT 更嘈杂、更尖锐。FP16 的 loss scaling 经常失败(选错 scale,导致 NaN)。BF16「就是能用」。

何时 FP16 可能更好:如果你需要最高精度(某些科学计算任务),并且能管理好 loss scaling。FP16 多 3 位尾数 = 结果略更精确。

FP32 主权重:即便前向/反向用 BF16,也要用 FP32 累积梯度更新,防止舍入误差在成千上万个小步中累积。这是所有 LLM 训练的标准做法。

复习:第 2 章(LLM 的系统基础)。

Reward 模型与 SFT 题

Q39:推导 Bradley-Terry 奖励模型 loss。它有哪些局限?

解答

Bradley-Terry 模型:给定两个回答,较好的那个(yw)被偏好的概率:P⁡(yw≻yl|x)=σ⁡(r⁡(x,yw)−r⁡(x,yl)),其中 σ 是 sigmoid。

MLE 推导:给定 N 个偏好对,最大化似然:∏iP⁡(ywi≻yli)。取负对数:ℒ=−∑ilogσ(r(xi,ywi)−r(xi,yli))。

局限:

  1. 无法处理平局:BT 无法建模「同样好」——它强制给出严格偏好。
  2. 传递性:假设若 A>B 且 B>C,则 A>C。人类并不具备传递性。
  3. 与上下文无关:无论当时有哪些备选,reward 都相同。
  4. 标量坍缩:把所有质量维度压缩成一个数。一个回答可能安全但无帮助——RM 必须做权衡。
  5. 长度偏置:更长的回答得到更高分(信息更多 = 更可能包含标注者想要的内容)。必须显式去相关。

缓解措施:margin loss(要求最小间隔 δ)、reward 中心化(减去滑动均值)、训练时的长度惩罚、多头 RM(对 helpfulness/safety/accuracy 分别打分)。

复习:第 9 章(奖励模型训练)。

Q40:SFT 中的序列打包是什么,为何重要?

解答

问题:训练样本长度不一。标准 batching 会把所有样本填充到 max_length。若 max=4096 但平均为 500,就有 88% 的算力浪费在 padding Token 上(它们贡献零梯度)。

打包方案:把多个短样本拼接成一条 max_length 序列,用 EOS token 分隔。同时训练所有样本。

示例:与其把 4 条序列填充到 4096(16K token,14K padding),不如打包成 1 条 4096 的序列,让 4 个样本首尾相接(4096 个真实 token,0 padding)。效率高 4×。

关键细节——块对角 attention mask:没有特殊处理时,样本 2 会 attend 到样本 1 的 token(交叉污染)。必须使用块对角 attention mask,限制每个样本只 attend 自身的 token。

在 TRL 中:SFTConfig(packing=True, max_seq_length=4096)。会自动处理 mask。

注意事项:(1)较长的样本仍需各自独占 batch 条目(不能在序列中间切开)。(2)position embedding 的实现略有复杂度(每个样本需重置)。(3)有人认为打包改变了有效 batch size(每步样本更多)——需相应调整 LR。

复习:第 10 章(SFT 最佳实践与技术)。

Q41:解释 SFT 的 completion-only masking。若不用它会怎样?

解答

在 chat 格式的 SFT 数据中:[system] + [user message] + [assistant response]。标准 NLL loss 会在包括 system prompt 与 user message 在内的所有 token 上计算 loss。

不做掩码的问题:模型浪费容量去学习预测 user 的消息(推理时根本不需要生成它)。更糟的是:若训练数据里的 user 消息五花八门,模型会对「现在轮到谁」感到困惑。

completion-only masking:把 prompt 中所有 token(system + user)的 loss 权重设为 0。只在 assistant 回答的 token 上计算 loss。

TRL:DataCollatorForCompletionOnlyLM(response_template="<|assistant|>")

影响:在指令遵循 benchmark 上通常好 5–15%。收敛更快(梯度信号集中在有用的 token 上)。计算成本不变。

微妙之处:必须把回答模板 token 计入 loss(教会模型开始作答),但要排除它之前的一切。

复习:第 10 章(SFT 最佳实践与技术)。

Q42:SFT 质量如何影响 RL 的上限?什么是 pass@k 诊断?

解答

上限定理(非正式):RL 只能强化模型已经能以不可忽略概率产生的行为。如果 SFT 模型生成正确解的概率为 0%,RL 永远找不到它。

为什么:GRPO/PPO 从当前策略采样并强化好的样本。若分布中不存在好样本,就没有可强化的东西。RL 的探索受限于基座策略的支撑集。

pass@k 诊断:每个 prompt 生成 k 个回答,检查是否有任何一个正确:

  • pass@1:模型的典型表现(贪婪/低 temperature)。
  • pass@8:GRPO 在 G=8 下能达到的上界。
  • pass@64:激进 Best-of-N 的上界。
  • pass@256:RL 提升的近似上限。

解读:

  • pass@1=20%、pass@64=80%:很好!RL 有 4× 的提升空间。预期收益显著。
  • pass@1=20%、pass@64=25%:几乎没有提升空间。RL 帮助不大。需要先做更好的 SFT。
  • pass@1=5%、pass@64=60%:模型能够解出但很少做到。这是 RL 的完美场景(强化那些稀有的成功)。

规则:若 pass@64 < 1.5× pass@1,就先投入更好的 SFT 数据,再开始 RL。

复习:第 7 与 10 章(GRPO;SFT 最佳实践)。

Q43:为聊天模型设计一个多目标 reward 系统。你如何平衡 helpfulness 与 safety?

解答

架构:为每个目标使用独立的 reward 模型:

  • rhelpful:在 helpfulness 偏好上训练(质量、准确性、完整性)
  • rsafe:在 safety 偏好上训练(拒答、无害、无幻觉)
  • rformat:基于规则(遵循指令、格式规范、长度适当)

组合策略:

  1. 加权求和(最简单):r=w1​rhelpful+w2​rsafe+w3​rformat。问题:safety 可能被 helpfulness 压过。
  2. 约束法(更安全):最大化 rhelpful,约束条件为 rsafe>τ。通过以下方式实现:r=rhelpful−λ⋅max⁡(0,τ−rsafe),其中 λ 很大。
  3. GDPO 归一化(最适合 GRPO):在组内对每个 reward 独立归一化,然后组合:A^=w1​A^helpful+w2​A^safe。防止某个 reward 因尺度差异而主导。
  4. 字典序:safety 是硬约束(必须通过),然后再优化 helpfulness。分阶段训练:先做 safety 对齐,再做 helpfulness。

实用权重:从 wsafe=2.0,whelpful=1.0,wformat=0.5 开始。safety 的权重是 2×,因为它的失效模式(有害内容)比 helpfulness 失效(回答平庸)糟糕得多。

复习:第 9 与 12 章(奖励模型训练;LLM 智能体训练)。

系统架构扩展题

Q44:投机解码如何工作?它在 RLHF 中何时有用?

解答

问题:大模型每次前向只生成一个 token(70B 约 ∼70ms)。慢。

投机解码:

  1. 草稿:小模型(1–7B)快速生成 k 个候选 token(∼5ms 完成全部 k)。
  2. 验证:大模型做一次前向,并行给全部 k 个 token 打分。接受满足 plarge​(ti)≥pdraft​(ti) 的 token(总是接受),其余的按概率接受。
  3. 结果:平均每次验证步骤接受 3–4 个 token。加速比:2–3×。

关键性质:输出分布与单独从大模型采样完全相同。没有质量损失。draft 模型只影响速度,不影响输出。

具体到 RLHF:生成占 60% 的算力。生成上 2–3× 的加速 = 端到端 1.5–2× 的加速。结合 vLLM + INT8:生成从瓶颈变为与训练持平。

局限:(1)draft 模型必须共享 tokenizer。(2)在高温下效果较差(draft 模型不够准确)。(3)draft 模型需要额外的 GPU 显存。(4)超过 k=5 后收益递减(接受率下降)。

复习:第 2 章与第 11 章(系统基础;系统架构)。

Q45:解释 roofline 模型。如何判断一个 kernel 是计算受限还是内存受限?

解答

roofline 模型把可达到的性能(FLOPS)画成算术强度的函数(每字节内存流量对应的 FLOPS)。

两种区域:

  • 内存受限(拐点左侧):性能受限于向计算单元喂数据的速度。实际 FLOPS = 带宽 × 算术强度。GPU 利用率 < 100%。
  • 计算受限(拐点右侧):性能受限于峰值 FLOPS。内存足够快。GPU 达到最大利用率。

拐点:峰值 FLOPS / 峰值带宽。对 A100:312 TF / 2 TB/s = 156 FLOP/byte。

LLM 操作:

  • 自回归生成(batch=1):读取 140GB 权重,做 140G FLOPs = 1 FLOP/byte。极度内存受限(比拐点低 156×)。GPU 利用率仅 0.6%。
  • 训练前向(batch=128,seq=2048):算术强度 ≈200+ FLOP/byte。计算受限。接近峰值利用率。
  • Attention(长序列):O⁡(n2​d) FLOPs / O⁡(n2+n​d) 字节。n 长时:计算受限。n 短时:内存受限。FlashAttention 无论如何都让其留在 SRAM。

实用法:若 kernel 内存受限,减少内存流量(量化、缓存、分块)。若计算受限,减少 FLOPs(剪枝、蒸馏、降低精度)。

复习:第 2 章(LLM 的系统基础)。

Q46:连续批处理(Continuous Batching)如何工作?为何它对 RLHF 生成至关重要?

解答

静态批处理:启动 B 条序列。等所有序列结束。若一条生成 500 Token、另一条只生成 50 Token,那 50 Token 序列的 GPU 槽位会闲置 450 Token 的时间。

连续批处理(迭代级调度):每个生成步后检查哪些序列已完成。立即在腾出的槽位插入新序列。GPU 槽位从不闲置。

为何对 RLHF 至关重要:

  1. RLHF 生成多样输出(高 temperature)。长度方差巨大——有些回答 50 Token,有些 2000+。
  2. 无连续批处理:平均利用率 ∼40–50%(等最慢的序列)。
  3. 有连续批处理:利用率 >90%。吞吐高 2–3×。
  4. RLHF 需要大 batch(每步 128+ 回答)。用静态批处理生成 128 个回答需要 max_tokens × 128 个串行步。连续批处理摊销了这一开销。

实现:vLLM 的调度器在每个解码步后检查。抢占:若有新的高优先级请求到达且显存已满,可将低优先级序列的 KV cache 换出到 CPU,稍后恢复。

复习:第 2 章与第 11 章(系统基础;系统架构)。

Transformer 架构问题

Q:为什么在现代 LLM 中 RoPE 的主导地位胜过可学习的绝对位置嵌入?

解答

RoPE 通过旋转矩阵将相对位置直接编码到 Q/K 点积中。关键优势:

  1. Attention 分数只依赖于相对距离 i−j,而不依赖绝对位置——这能更好地泛化到未见过的序列长度。
  2. 可通过频率缩放(NTK-aware、YaRN)扩展到超出训练长度,无需重新训练。
  3. 无需额外参数(旋转由位置索引确定性地给出)。
  4. 可学习的绝对嵌入固定到训练长度,无法外推——在 4K 上下文训练的模型在 8K 时会失败。

复习:第 1 章(LLM 架构与优化方法)。

Q:解释 SwiGLU,以及它为何在现代 Transformer 中取代了 ReLU。

解答

SwiGLU:FFN​(x)=W2​(Swish​(W1​x)⊙W3​x),其中 Swish​(x)=x⋅σ​(x)。

为什么它更好:

  • 该门控机制(⊙W3​x)让网络可以有选择地抑制或放大维度——比逐点 ReLU 更具表达力。
  • Swish 是平滑的(不存在 ReLU 零梯度区那样的死神经元)。
  • 经验上:在相同 FLOP 预算下,语言建模基准上提升 1–2%。
  • 权衡:需要 3 个权重矩阵而非 2 个(通过将隐藏维度从 4​d 降到 8​d/3 来解决)。

复习:第 1 章(LLM 架构与优化方法)。

Q:什么是分组查询注意力(Grouped Query Attention, GQA),Llama-3 为何采用它?

解答

标准 MHA:H 个 query 头、H 个 key 头、H 个 value 头。GQA:H 个 query 头但只有 G<H 个 key/value 头(在 query 组间共享)。

Llama-3 70B:64 个 query 头、8 个 KV 头(每个 KV 头被 8 个 query 头共享)。

优势:

  • KV cache 大小缩小 H/G=8×——对推理至关重要(长序列下 KV cache 是主导的显存开销)。
  • 质量损失极小(基准上 <0.5%),因为 KV 模式在不同头之间高度相关。
  • 推理吞吐与 KV cache 的减少成比例增长(更多序列能装进显存 = 更大的 batch size)。

复习:第 1 章(LLM 架构与优化方法)。

Q:为何 decoder-only 架构在 LLM 中胜过了 encoder-decoder?

解答

  1. 统一目标:预训练 = 微调 = 推理,都使用下一个 Token 预测。不存在架构不匹配。
  2. 参数效率:所有参数都对生成有贡献。在 encoder-decoder 中,纯生成任务下 encoder 参数被“浪费”。
  3. 扩展更简单:一个模型、一个损失函数、一套超参数需要调。
  4. KV cache 效率:decoder-only 只有一份 KV cache;encoder-decoder 有两份(encoder + decoder 的交叉注意力)。
  5. 涌现的少样本:decoder-only 天然支持上下文学习(把示例前置到 Prompt 中)。

对于固定输入长度的 seq2seq 任务(如翻译),encoder-decoder 仍然占优,但这部分在 LLM 用例中占比正在缩小。

复习:第 1 章(LLM 架构与优化方法)。

FlashAttention 问题

Q:FlashAttention 计算的结果与标准 attention 相同,但快 2–4×。如果 FLOPs 数相同,这怎么可能?

解答

FlashAttention 之所以更快,是因为它减少了 HBM 显存流量,而非 FLOPs。标准 attention 在 HBM(慢)中物化 n×n 的 attention 矩阵,再读回来做 Softmax,再读一次做 P​V 乘法——总共在 O⁡(n2) 数据上有 4 次 HBM 往返。

FlashAttention 对计算进行分块,使 n×n 矩阵完全在 SRAM(快,19 TB/s)中计算并消费,从不写入 HBM(2 TB/s)。“在线 Softmax”技巧通过维护滚动统计量来实现这一点。

结果:HBM 流量从 O⁡(n2​d) 降到 O⁡(n2​d/M),其中 M 为 SRAM 大小。相同 FLOPs,显存流量减少 10–50×,→ 实际墙钟加速 2–4×。

复习:第 1 章与第 2 章(LLM 架构;系统基础)。

Q:为什么 FlashAttention 对 FFN 层没有帮助?

解答

FFN 层是计算受限的,而非内存受限。它们的算术强度(大 batch GEMM 下为 I≈300 FLOP/byte)已经高于 roofline 的峰值拐点(A100 上为 156 FLOP/byte)。

FlashAttention 对 attention 有帮助,是因为 attention 深度内存受限(I≈1–60 FLOP/byte)。通过把数据留在 SRAM 中,它消除了内存瓶颈。

对 FFN 而言:瓶颈已经是张量核心(Tensor Core)(而非内存带宽),因此减少显存流量无济于事。相反,FFN 受益于量化(缩小权重体积 → 提高算术强度)以及更大的 batch size。

复习:第 1 章与第 2 章(LLM 架构;系统基础)。

Q:解释 online softmax 技巧,以及它为何对 FlashAttention 至关重要。

解答

标准 softmax 在计算任何输出之前需要全局最大值 m=maxj⁡xj——这要求先看到全部 n 个 attention 分数,从而被迫物化完整的 n×n 矩阵。

online softmax 技巧按块顺序处理,维护一个滚动的 (m,ℓ,O) 状态:

  1. 处理新块 →更新滚动最大值:mnew=max⁡(mold,max⁡(snew))
  2. 重新缩放旧的求和:ℓnew=emold−mnew⋅ℓold+new terms
  3. 重新缩放输出:Onew=rescaled​(Oold)+new contribution

这在数学上精确——没有近似。它使逐块处理成为可能,每个块都能装进 SRAM,从不需要把完整的 n×n 矩阵放进内存。

复习:第 1 章与第 2 章(LLM 架构;系统基础)。

LoRA 与 PEFT 问题

Q:LoRA 为何有效?有什么理论洞见能解释低秩更新?

解答

Aghajanyan 等人 [3] 表明,微调运行在极低的内在维度上——微调任务的有效参数空间远小于模型的总参数量。一个 175B 模型对某个给定任务的内在维度可能只有 <10,000。

LoRA 直接利用了这一点:通过把更新约束到秩 r(W′=W+B​A、B∈ℝd×r),它把学习限制在每个权重矩阵的 r 维子空间内。由于真实的任务子空间是低维的,这样做几乎不损失什么,同时把可训练参数减少 100–1000×。

直觉:微调不改变模型“知道”什么(满秩的 W 保持冻结);它只调整如何把已有知识组合起来用于新任务——一个低秩扰动。

复习:第 1 章(LLM 架构与优化方法)。

Q:对 70B 模型比较 QLoRA、完整 LoRA 与全量微调。各自应在何时选用?

解答

决策树:(1)若任务需要深度改变知识 → 全量微调。(2)若适配新的风格/格式 → LoRA。(3)若显存受限或需快速迭代 → QLoRA。(4)若关心秩:从 r=16 开始;若训练损失在高于全量微调的水平上停滞,则增秩。

复习:第 1 章与第 10 章(LLM 架构;监督微调最佳实践)。

Q:什么是 DoRA,它为何优于标准 LoRA?

解答

DoRA(Weight-Decomposed Low-Rank Adaptation)把 W 分解为幅度 ‖W‖ 与方向 W/‖W‖,然后只对方向分量应用 LoRA:

W′=m⊙W+B​A‖W+B​A‖

其中 m(幅度)也可训练,但只是每个输出神经元上的一个简单标量。

为何有帮助:全量微调会自然地独立更新幅度与方向。标准 LoRA 把二者耦合在一起(低秩更新以一种受限的方式同时改变两者)。DoRA 将它们解耦,使 LoRA 获得与全量微调相同的“自由度”结构。结果:在推理时无额外计算量(合并适配器)的情况下,推理任务上提升 1–3%。

复习:第 1 章(LLM 架构与优化方法)。

模型压缩问题

Q:解释 AWQ。为什么保护 1% 的权重就能保住 99% 的质量?

解答

AWQ(Activation-Aware Weight Quantization)观察到权重重要性高度不均匀:与大幅激活值相乘的权重对输出的贡献不成比例地大。

关键洞见:‖W⋅X‖ 同时取决于 W 与 X。一个小权重乘以大幅激活值,比一个大权重乘以接近零的激活值更重要。

AWQ 找出前 1% 的“显著”通道(在校准数据上激活幅度始终很大的那些),并通过缩放来保护它们:量化前把显著通道乘以因子 s>1(然后在激活中除以 s)。这降低了重要通道的相对量化误差。

结果:在 70B 模型上实现 4-bit 量化,质量损失 <1%,因为 99% 的非显著权重可以承受激进的量化。

复习:第 1 章与第 2 章(LLM 架构;系统基础)。

Q:什么时候该用 FP8、4-bit 量化或 BF16?

解答

  • BF16:训练(RLHF 中的策略模型),精度重要时使用。任何被梯度更新的模型的默认选择。
  • FP8(E4M3):配合 Transformer Engine 在 H100 上训练(2× 吞吐,<0.5% 质量损失)。也用于在 H100 上需要最大吞吐量的推理。
  • INT8/FP8 推理:RLHF 中的冻结模型(参考模型、奖励模型)——不被训练,因此降低精度是安全的。
  • 4-bit(AWQ/GPTQ):规模化推理服务。部署时显存/质量的最佳权衡。也用于 QLoRA 的基座模型。
  • 2-bit:实验性;显存极度受限的边缘部署。质量损失 5–10%。

规则:推理时尽可能激进地量化,训练时保持 BF16(H100 上可用 FP8)。

复习:第 2 章(LLM 的系统基础)。

Q:解释 NVIDIA 2:4 结构化稀疏。加速比和约束是什么?

解答

2:4 稀疏意味着:每 4 个连续元素中,恰好有 2 个必须为零。这在权重层面强制执行。

硬件支持:A100/H100 的张量核心拥有专用的 2:4 稀疏 GEMM 指令,会跳过零元素,恰好实现 2× 吞吐,且没有软件开销。

约束:你必须在这种特定模式下实现恰好 50% 的稀疏度。不能是 30% 或 70% 的稀疏度;也不能是任意的稀疏模式。剪枝必须遵守 4 元素分组结构。

如何实现:训练后(或微调期间),对每组 4 个权重,把绝对值最小的 2 个置零。然后微调数百步以恢复质量。质量损失:对大型模型(70B+)通常为 <1%。

复习:第 2 章(LLM 的系统基础)。

专家混合(Mixture of Experts)问题

Q:Mixtral 8x7B 总参数 47B,但每个 Token 只有 13B 处于激活状态。解释这如何工作,以及它为何高效。

解答

Mixtral 把每个 FFN 层替换为 8 个并行的专家 FFN(每个在 FFN 部分约 ∼7B 参数)。一个路由网络为每个 Token 选择 Top-2 专家。

为何总计 47B:Attention 层是共享的(不复制)= ∼5B。FFN 专家:8 ×∼5.25B = 42B。总计:∼47B。

为何激活 13B:每个 Token 只有 2 个专家被激活。激活参数 = attention(∼5B)+ 2 个 FFN 专家(∼2 × 5.25B)≈ 13B。

为何高效:计算成本随激活参数(13B)扩展,与 13B 的稠密模型相当。但容量(存储的知识)随总参数(47B)扩展,与远更大的模型相当。结果:Mixtral 以 13B 的计算成本达到 Llama-2 70B 的质量。

显存成本:仍然需要把全部 47B 参数放在显存中(所有专家都要加载),因此显存 = 47B 模型,但计算 = 13B 模型。

复习:第 1 章(LLM 架构与优化方法)。

Q:MoE 中的负载均衡问题是什么,如何解决?

解答

若无约束,路由器倾向于把大多数 Token 送给 1–2 个“热门”专家(富者愈富的动态)。这会导致:

  • 容量浪费:8 个专家中有 6 个未被使用,模型实际上退化为 2 个专家的规模。
  • 计算不均衡:若每个专家位于不同的 GPU 上,热门专家成为瓶颈,而其他专家闲置。

解决方案:辅助负载均衡损失:ℒbal=α⋅N∑i=1Nfi⋅pi,其中 fi = 路由到专家 i 的 Token 比例,pi = 专家 i 的平均路由概率。这会惩罚不均匀的分布。

替代方案:专家容量因子——对每个 batch 中每个专家的最大 Token 数设硬上限。溢出的 Token 会被丢弃或重新路由。

典型的 α:0.01–0.1(小到不损害主损失,大到能防止坍缩)。

复习:第 1 章(LLM 架构与优化方法)。

训练中的多样性问题

Q:如果 GRPO 组内全部 N 个回答完全相同,会发生什么?

解答

若全部 N 个回答完全相同:所有奖励 ri 都相等,因此 σG=0 与优势 A^i=(ri−μG)/σG 无定义(除以零)。实践中,实现会为所有项设置 A^i=0,意味着 零学习信号——这一步被浪费了。

预防:

  1. Temperature:生成时使用 τ=0.7–1.0(不要贪心)。
  2. 较大的 N:N=8–16 提高出现多样回答的概率。
  3. 重复拒绝:DAPO 的做法——拒绝重复的回答并重新采样。
  4. 频率惩罚:生成时惩罚重复出现的 n-gram。
  5. 监控:跟踪每组的唯一回答比例。若 <50%,则提高 temperature。

复习:第 7 章(GRPO)。

Q:解释 RLHF 中的多样性—质量权衡。如何检测模式坍缩?

解答

权衡:高多样性(高熵/temperature)= 回答多样但可能随机/低质量。低多样性 = 一致但重复、被奖励作弊的回答。

检测模式坍缩(这些都应在训练中监控):

  1. 回答熵:计算每个 Token 的熵 H=−∑pilogpi。若迅速下降 → 坍缩。
  2. 唯一 n-gram 比例:对同一 Prompt 的回答中唯一 4-gram 的占比。健康值:>0.6。
  3. 奖励分布宽度:若 σ⁡(rewards) 收缩到接近零 → 所有回答质量相同 → 很可能完全相同。
  4. KL 散度:若 DKL[πθ∥πref] 迅速增长,说明策略正在远离参考 → 通常走向一个狭窄的模式。
  5. 长度直方图:若所有回答收敛到相同长度 → 模板化行为。

修复:增大 KL 系数 β,增大熵奖励,提高采样 temperature,或回滚到更早的 checkpoint。

复习:第 7 章与第 9 章(GRPO;奖励模型训练)。

推测解码(Speculative Decoding)问题

Q:投机解码声称“无质量损失”。用不同的方式生成 Token 怎么可能产生相同的输出分布?

解答

接受/拒绝机制保证了分布等价性:

对每个草稿 Token x^,其草稿概率为 q⁡(x^)、目标概率为 p⁡(x^):

  • 以概率 min⁡(1,p⁡(x^)/q⁡(x^)) 接受
  • 被拒绝时:从 残差分布∝max⁡(0,p⁡(x)−q⁡(x)) 中采样

这在数学上等价于直接从 p(目标分布)采样。证明梗概:输出 Token x 的概率为 q⁡(x)⋅min⁡(1,p⁡(x)/q⁡(x))+P⁡(reject)⋅max⁡(0,p⁡(x)−q⁡(x))∑ymax⁡(0,p⁡(y)−q⁡(y))=p⁡(x)。

加速来自于摊销:当草稿质量好(接受率高)时,一次目标前向就能确认多个 Token。该保证与草稿质量无关——草稿差只会带来更低的加速(更多拒绝),而不会降低质量。

复习:第 2 章(LLM 的系统基础)。

Q:在投机解码中比较 Medusa 与 Eagle。各自应在何时选用?

解答

Medusa:向目标模型添加 k 个并行预测头。每个头独立地预测位置 t+i 上的 Token。优点:无需单独的模型,显存开销 <1%。缺点:各头独立预测——无法把位置 t+2 建立在位置 t+1 上已预测的内容之上。接受率:60–80%。

Eagle:在目标模型的隐藏状态上接一个轻量级自回归解码器。草稿 Token 以自回归方式生成(每个都以前一个为条件)。优点:捕捉 Token 间的依赖关系 → 85–95% 的接受率。缺点:显存略多(小型解码器),且草稿生成是串行的。

选择 Medusa 的情形:显存极其紧张;集成简单;适度加速即可(2–2.5×)。

选择 Eagle 的情形:需要最大加速(3–4×);能承受额外的小模型;延迟关键的单流生成。

选择 N-gram 的情形:输出重复(代码、结构化数据);零成本;无需训练。

复习:第 2 章(LLM 的系统基础)。

Q:为什么投机解码在大 batch size 下没有帮助?

解答

在大 batch size(≥64)下,自回归生成已经是计算高效的:权重读取成本被许多序列摊销。算术强度接近 roofline 的峰值拐点。

投机解码引入了额外开销:

  1. 草稿生成成本(即使是小模型,在大 batch 下也不是免费的)
  2. 验证前向每序列要处理k 个额外的 Token(batch ×k Token)
  3. 草稿模型或 Medusa 头的显存占用
  4. 被拒绝的 Token 浪费计算

在 batch=1(延迟受限、内存受限)时:投机把每步 1 个 Token 变成每步 3–4 个 Token——收益巨大。

在 batch=128(已经计算高效)时:投机带来的额外 Token 对吞吐几乎没有帮助,因为 GPU 已接近饱和。开销甚至可能降低吞吐。

规则:投机解码针对延迟(小 batch);批处理针对吞吐(大 batch)。不要把两者结合。

复习:第 2 章(LLM 的系统基础)。

Agent 强化学习问题

Q:为什么标准 RLHF(单轮 PPO/DPO)对多步智能体(Agent)失效?

解答

标准 RLHF 优化单轮质量:给定一个 Prompt,产出一个好的回答。多步智能体面临根本不同的挑战:

  1. 信用分配:在 50 步的轨迹中,是哪一步导致了失败?单轮奖励把信用均匀分配给整个回答;多步需要逐步的信用。
  2. 稀疏奖励:只有轨迹结束时才有成功/失败信号。PPO 的广义优势估计(GAE)假设存在中间奖励;没有它们,优势估计会很嘈杂。
  3. 动作空间:动作是结构化的 tool 调用(JSON),而不只是 Token 序列。模型必须同时学习语法、语义与策略。
  4. 非平稳性:环境随每个动作而改变(tool 输出会修改状态)。每一步都有不同的“Prompt”,不像单轮那样输入固定。
  5. 探索:智能体必须发现新颖的 tool 使用策略,而不仅仅是改写文本。

解决方案:轨迹级 GRPO(对完整轨迹排序)、过程奖励模型(PRM)(逐步反馈),或对成功轨迹做过滤后的 SFT。

复习:第 12 章(LLM 智能体训练)。

Q:解释 GRPO 如何适配智能体训练。与单轮 GRPO 的关键区别是什么?

解答

单轮 GRPO:对一个 Prompt 生成 N 个回答,按奖励排序,计算优势。

智能体 GRPO 的区别:

  1. 生成单位:完整的轨迹(10–100 步),而非单个回答。每条轨迹是组内的一个“样本”。
  2. 奖励(Reward):终止式(任务成功/失败)或轨迹级(各步奖励之和),而非逐 Token。
  3. 掩码(Masking):只在智能体的输出(推理 + tool 调用)上计算策略损失。把 tool 输出(环境响应)从梯度计算中屏蔽掉。
  4. 组大小:通常更小(N=4–8),因为轨迹开销很大(每条轨迹需要多次前向传播)。
  5. KL 惩罚:逐步施加,以防止在每个决策点偏离 SFT 策略。
  6. 长度归一化(Length normalization):按智能体的 动作数量(而非 Token 数量)归一化,以免惩罚充分的推理。

复习:第 7 与 12 章(GRPO;LLM 智能体训练)。

Q:比较用于智能体的 STaR、Reflexion 与 ReAct。

解答

STaR(Self-Taught Reasoner,自学推理者):生成推理链 → 按正确性过滤 → 在正确的链上微调。适用场景:你拥有可验证任务(数学、代码),并希望在不使用 RL 的情况下从基础模型自举出推理能力。

Reflexion:失败后生成言语化反馈(“哪里出错了?”)→ 带着上下文中的反思重试。不更新权重。适用场景:推理时改进;可用于训练的算力有限;能够自我诊断的任务。

ReAct:在结构化循环中交替进行推理(思考)与行动(tool 使用)。适用场景:多步 tool 使用任务;你需要透明度(推理轨迹可解释);智能体必须自行决定是思考还是行动。

关键差异:

复习:第 12 与 18 章(LLM 智能体训练;智能体设计模式)。

Q:为什么研究型智能体更偏好 GRPO 而非 PPO?

解答

对于轨迹长度为 20–100 步的研究型智能体:

PPO 需要价值模型:V⁡(st) 必须从当前状态预测期望总奖励。对于研究任务(此处状态 = 128K Token 的上下文,包含论文、代码与结果),训练准确的价值函数极其困难——“读完 3 篇论文并写了部分代码”的价值很难预测。

GRPO 完全避开价值估计:它为每个研究问题生成 N 条完整轨迹,并用组内排序作为优势。无需预测中间价值——只需比较结果。

其他原因:

  • 研究质量大致是二元的(报告好 vs. 报告差)——排序是自然的。
  • 轨迹长且昂贵;GRPO 的 N=4 尚可承受;PPO 则需要大量 rollout 才能得到稳定的价值估计。
  • 终止奖励稀疏;在稀疏奖励下,GAE(广义优势估计)给出的逐步优势同样是嘈杂的。

复习:第 7 与 12 章(GRPO;LLM 智能体训练)。

Q:为编码智能体设计一个奖励函数。存在哪些奖励作弊风险?

解答

奖励设计:

R=0.5⋅Rtests+0.2⋅Rquality+0.2⋅Refficiency+0.1⋅Rsafety
  • Rtests:单元测试通过比例(0–1)。真值可验证。
  • Rquality:由 LLM 评判代码风格、文档与可维护性。
  • Refficiency:max⁡(0,1−steps/30) —— 快速完成的奖励。
  • Rsafety:不允许危险操作(rm -rf、访问 sandbox 之外的网络)。

奖励作弊风险:

  1. 硬编码输出:智能体学会直接打印期望的测试输出,而不去真正计算。修复:随机化测试输入;在留出用例上测试。
  2. 删除测试:智能体修改或删除失败的测试。修复:把测试在 sandbox 中设为只读。
  3. 平凡解:智能体写出能通过测试但不泛化的最小代码。修复:大型、多样化的测试集;基于属性的测试。
  4. 效率作弊:智能体为最大化效率奖励而跳过推理步骤。修复:先满足最低质量阈值,效率奖励才生效。

复习:第 9、12 与 19 章(Reward 模型训练;LLM 智能体训练;智能体环境)。

列表式 Reward 与高级 RM 问题

Q:解释 Plackett-Luce 模型。它如何推广 Bradley-Terry?

解答

Bradley-Terry 对成对偏好建模:P⁡(y1≻y2)=σ⁡(r⁡(y1)−r⁡(y2))。

Plackett-Luce 把 K 个项目的完整排序建模为顺序选择:

P⁡(π)=∏i=1Ker⁡(yπ⁡(i))∑j=iKer⁡(yπ⁡(j))

解释:依次挑选剩余项中最好的。位置 1 = 对全部 K 做 Softmax;位置 2 = 对剩余的 K−1 做 Softmax;以此类推。

推广关系:当 K=2 时,PL 恰好退化为 BT:P⁡(y1≻y2)=er⁡(y1)er⁡(y1)+er⁡(y2)=σ⁡(r⁡(y1)−r⁡(y2))。

优势:K=8 个项目的排序提供 (82)=28 个隐式成对比较,外加相对差距信息——比单个成对样本丰富得多的训练信号。

复习:第 9 章(Reward 模型训练)。

Q:什么是过程奖励模型(Process Reward Model, PRM),它在什么情况下优于结果奖励模型(Outcome Reward Model, ORM)?

解答

ORM:仅对最终输出打分。r⁡(x,yfinal) = 整个回答一个标量。

PRM:对推理的每一个步骤打分。r⁡(x,ystep ​t) = 每一中间步一个标量。

PRM 更好的场景:

  1. 长推理链:10+ 步的数学题。ORM 无法判断哪一步出错;PRM 提供逐步的信用分配。
  2. 搜索/验证:PRM 支持树搜索(对推理步做束搜索(beam search),剪掉步奖励低的分支)。
  3. 训练信号密度:PRM 每条轨迹给出 T 个奖励(每步一个),而 ORM 只有一个奖励 → 更低方差的优势估计。

ORM 更好的场景:任务短(单轮);步骤边界不清晰;每步标注的成本过高。

PRM 标注:可通过“Math-Shepherd”方法自动化:对每一步,从该点多次补全整个解。如果从步骤 t 出发的补全成功而从步骤 t+1 出发的补全失败,那么步骤 t+1 很可能是错的。

复习:第 9 与 13 章(Reward 模型训练;大型推理模型的 RL)。

大型推理模型的 RL 问题

Q:DeepSeek-R1 在长推理链上训练,却为何不使用过程奖励模型?

解答

DeepSeek-R1 仅使用基于结果的奖励(准确率 + 格式),原因如下:

  1. 可验证任务:数学和代码有确定的真值答案。即便是长链,二元的准确率奖励也能提供足够的信号。
  2. PRM 失效模式:步骤级奖励模型自身会引入奖励作弊——模型可以学到产出“在 PRM 看来正确”但实际并不正确的步骤。
  3. GRPO 的组归一化:通过为每个 Prompt 采样 G 个补全并在组内归一化优势,GRPO 即使没有每步奖励,也能自然提供关于哪些推理 策略 有效的相对信号。
  4. 涌现的自我纠正:在仅有结果奖励时,模型学会在链内自我纠正(“顿悟时刻”),如果每步奖励对推理过程微观管理,这种行为将无法涌现。

关键洞见:任务领域的可验证性使 PRM 变得不必要——对于主观任务(创意写作),仅有结果奖励可能不够。

复习:第 13 章(大型推理模型的 RL)。

Q:解释测试时计算扩展律(Test-Time Compute Scaling Law)及其对模型部署的启示

解答

测试时计算扩展律表述为:

Accuracy​(Ctrain,Ctest)≈f⁡(α​log⁡Ctrain+β​log⁡Ctest)

启示:

  1. 算力等价:在推理任务上,使用 64× 推理 Token 的 7B 模型可以与使用 1× Token 的 70B 模型相匹敌。
  2. 自适应分配:简单问题用短链(便宜);困难问题用长链(贵)。平均成本低于始终使用大模型。
  3. 部署灵活性:不再部署一个大模型,而是部署一个较小的推理模型,并按查询难度对推理算力进行扩展。
  4. 收益递减:对数关系意味着测试时计算翻倍带来的准确率提升递减——训练与推理算力之间存在一个最优分配。

“过度思考”失败模式:非常长的链可能因错误累积和 Attention 稀释而降低准确率。最优链长取决于问题难度。

复习:第 13 章(大型推理模型的 RL)。

Q:MCTS(蒙特卡洛树搜索,Monte Carlo Tree Search)如何应用于 LLM 推理?

解答

用于推理的 MCTS 把每个部分解视为一个树节点:

每次迭代四个阶段:

  1. 选择:用 UCB 从根开始导航:UCB​(s)=Q​(s)+c​ln⁡N⁡(parent)N⁡(s)
  2. 扩展:从 LLM 生成新的推理步(子节点)
  3. 模拟:从新节点完成解(rollout)
  4. 反向传播:根据最终正确性更新路径上的 Q 值

与博弈 MCTS 的关键差异:

  • 分支因子:推理具有巨大的分支因子(任何下一句都可能)。实际实现使用 LLM 的 top-k 输出来限制分支。
  • 价值函数:训练好的 PRM 估计部分解的质量,替代随机 rollout。
  • 步骤粒度:每个“步”可能是一句话、一个方程或一次逻辑推断——粒度选择很关键。

使用案例:AlphaProof(数学奥林匹克),以及据推测 OpenAI o1/o3 的隐藏推理。

复习:第 13 章(大型推理模型的 RL)。

Q:比较通过蒸馏 vs 直接 RL 来打造小型推理模型

解答

蒸馏(DeepSeek-R1-Distill 路线):

  • 从大模型(R1-671B)生成推理链
  • 在这些链上对小模型做 SFT
  • 结果:小模型模仿大模型的推理 格式
  • 优点:便宜(仅 SFT)。缺点:可能学到表层模式而非真正推理。

直接对小模型做 RL:

  • 用 GRPO/PPO 在可验证奖励上训练小模型
  • 模型发现自己的推理策略
  • 优点:真实能力。缺点:算力消耗大得多;对于非常小的模型可能不收敛。

经验发现:R1-Distill-7B(蒸馏)在大多数基准上优于 direct-RL-7B。大模型给出的推理链提供了如此强的监督,以至于仅靠 SFT 就极具竞争力。不过,蒸馏模型对真正新颖的问题类型的泛化能力较弱。

最佳实践:先做蒸馏(便宜的基础方案),再视情况在蒸馏模型上跑 RL 以获取进一步提升(Qwen 采用的“distill + RL”组合)。

复习:第 13 章(大型推理模型的 RL)。

LLM 评估问题

Q:推导 ELO 评分更新规则,并解释 Chatbot Arena 为何使用它

解答

ELO 推导:

选手 A 对 B 的期望得分:EA=11+10(RB−RA)/400(logistic 模型)。

一场实际得分为 SA∈{0,0.5,1} 的比赛之后:RA′=RA+K⁡(SA−EA)

K 因子控制更新幅度(K 越大 = 对近期结果越敏感)。

为什么 Chatbot Arena 使用 ELO:

  1. 传递性:如果模型 A 胜 B、B 胜 C,ELO 预测 A 胜 C。这从成对比较中得到一个全序。
  2. 在线更新:无需重新评估所有配对即可加入新模型。每次新的比较都会增量更新评分。
  3. 置信度:经过 N 次比较后,评分不确定性以 O⁡(1/N) 的速率收缩。标准误:SE≈400N。
  4. 捕获人类偏好:真实用户无需阐明评判标准即可提供诚实的偏好。聚合起来即可揭示真实的模型质量。

Chatbot Arena 的具体做法:使用 Bradley-Terry 极大似然估计(MLE,在收敛时等价于 ELO),并配以自举置信区间。风格受控的 ELO 去除了长度/格式偏置。

复习:第 14 章(LLM 评估)。

Q:代码生成中的 pass@k 指标是什么?为什么无偏估计量很重要?

解答

pass@k = k 个生成样本中至少有一个通过全部测试用例的概率。

朴素(有偏)估计量:生成 k 个样本,检查是否有通过的。问题:方差高、开销大(每个问题都需要多次试验)。

无偏估计量(Chen et al., 2021):生成 n≥k 个样本,统计其中通过的个数 c:

pass@​k=1−(n−ck)(nk)

为什么无偏很重要:

  1. 只需生成 n 个样本一次(例如 n=200),即可从同一批样本计算 pass@1、pass@10、pass@100
  2. 无需把整个评估重复 k 次
  3. 统计上精确(组合论证:不含正确样本的 k 子集占比)
  4. 通过对数空间实现数值稳定的计算:pass@​k=1−exp⁡(∑i=0k−1log⁡(n−c−i)−log⁡(n−i))

直觉:如果 200 个样本中有 50 个通过(c=50,n=200),则 pass@1 ≈0.25,pass@10 ≈0.94。该估计量统计的是:大小为 k 的抽样中有多大比例会包含至少一个成功样本。

复习:第 14 与 19 章(LLM 评估;智能体环境)。

Q:如何检测并缓解基准污染?

解答

污染:训练数据中包含基准测试样本(或其近似改写),从而虚高分数。

检测方法:

  1. N-gram 重叠:检查训练数据中是否包含与测试样本完全相同或近乎相同的匹配。8-gram 重叠且覆盖率 >80% 即可疑。
  2. 金丝雀串(Canary strings):在测试集中插入唯一标识符,检查模型能否复现它们。
  3. 改写版基准:创建语义等价但文本不同的基准版本。准确率大幅下降说明存在记忆。
  4. 时间分析:模型在训练截止前与截止后测试样本上的表现。在旧样本上异常高的表现说明存在污染。
  5. 成员推断(Membership Inference):用统计检验判断特定样本是否在训练数据中。

缓解:

  • 动态基准:定期生成新的测试样本(LiveCodeBench、Chatbot Arena)
  • 私有测试集:对测试样本保密(LMSYS)
  • 训练期间去污染:从训练数据中移除检测到的重叠部分
  • 报告污染分析:在基准分数之外一并披露重叠指标

复习:第 14 章(LLM 评估)。

Q:解释 LLM-as-Judge 中的位置偏置以及如何缓解它

解答

位置偏置:当用 LLM 评判两个回答(A vs B)时,模型会系统性地偏好处于特定位置(通常是第一个或最后一个)的回答,而不管其质量如何。

经验幅度:GPT-4 表现出 10–15% 的位置偏置;Claude 为 5–10%。更小的模型偏置更大。

缓解策略:

  1. 位置交换:对每一对评判两次(A-B 与 B-A)。最终决定 = 多数。若不一致,则标记为“平局”。这消除了系统性的位置偏置,但成本翻倍。
  2. 多评委小组:使用 3 个以上不同的模型作为评委。多数投票可降低单个模型的偏置。
  3. 参考引导式:提供评分细则或参考回答。评委依据评分细则独立地为每个回答打分,再比较分数(完全消除成对比较)。
  4. 校准式 Prompt:加入明确指令:“呈现顺序是随机的,不应影响你的判断。”

其他偏置:冗长偏置(偏好更长的回答)、自我增强偏置(模型偏好自己的输出)、权威偏置(顺从引用来源的回答)。

复习:第 14 章(LLM 评估)。

Agent 记忆问题

Q:比较四种智能体记忆类型,并说明各自何时关键

解答

关键洞见:这四者并非彼此独立——它们相互作用。情景记忆为语义记忆提供输入(从具体经历泛化出事实)。程序性记忆由情景反馈不断精炼(学习哪些 tool 序列有效)。工作记忆则统筹对其它各类记忆的检索。

MemGPT 类比:工作记忆 = 热(在上下文中),情景/语义记忆 = 温(向量库),程序性记忆 = 冷(归档的策略)。智能体自行决定何时把信息换入/换出。

复习:第 16 章(智能体记忆系统)。

Q:记忆检索中的时间衰减如何工作,为什么它很重要?

解答

时间衰减在检索时降低较旧记忆的权重:

score​(m)=α⋅similarity​(q,m)+(1−α)⋅recency​(m)

其中 recency(m)=e−λ⋅Δt,Δ​t = 距上次访问的时间。

为什么重要:

  1. 相关性衰减:用户偏好会变化。6 个月前的偏好可能已经过时。
  2. 矛盾消解:当新旧信息冲突时,近因偏置会自然地偏向当前为真者。
  3. 检索效率:没有衰减,记忆会无界增长,检索也会返回越来越不相关的陈年条目。
  4. 认知合理性:人类也会遗忘——近期事件更易提取。这与间隔效应相呼应。

基于访问的刷新:当一条记忆被检索并使用后,其时间戳会更新(类似 LRU 缓存)。频繁访问的记忆无论创建于何时都保持“新鲜”。

衰减率调优:λ 取决于领域。客服:高衰减(偏好变化快)。法律/医疗:低衰减(事实持久)。可通过 RL 学习。

复习:第 16 章(智能体记忆系统)。

Q:如何用 RL 训练记忆操作?

解答

记忆操作(write/read/update/delete)可以作为智能体的马尔可夫决策过程(MDP)中的动作:

形式化:

  • 状态:当前上下文 + 记忆状态
  • 动作:标准动作 + memory_write(key/value)、memory_read(query)、memory_delete(key)
  • 奖励:任务成功(记忆是否起作用?)+ 记忆效率惩罚(读取越少越好)

RL 学到什么:

  1. 存储什么:重要信息(API key/用户偏好)vs 临时细节
  2. 何时检索:回答领域问题之前 vs 一般闲聊期间
  3. 压缩策略:何时摘要旧记忆,何时原样保留
  4. 遗忘:何时旧信息已过时、应被移除

训练信号:反事实——“如果智能体没有存储/检索这条记忆,它还会成功吗?”通过轨迹比较来实现:记忆使用得当的轨迹获得更高的奖励。

挑战:延迟奖励——现在存储的信息可能要到 100 步之后才起作用。需要长时序的信用分配(高 λ 的 GAE)。

复习:第 12 与 16 章(LLM 智能体训练;智能体记忆系统)。

Agent 编排问题

Q:解释上下文预算问题,以及如何用动态分配来解决它

解答

问题:智能体有 L 个 Token 的上下文窗口,但需要为以下内容留出空间:

C=S+M+T+H+R≤L

其中 S = 系统 Prompt,M = 记忆/检索到的上下文,T = tool 描述,H = 对话历史,R = 为回答预留。

随着对话增长,H 不断增加,把其它组件挤出去。

动态分配策略:

  1. 固定下限:Smin、Rmin 是不可让步的
  2. 自适应历史:当 H>Hmax 时摘要旧轮次。保留最近 k 轮为原文,其余摘要处理。
  3. 按需提供 tool:只包含与当前查询相关的 tool 描述(而不是全部 50 个 tool)。用分类器或嵌入相似度选出前 k 个 tool。
  4. 惰性记忆:只在需要时(分析完查询之后)检索记忆,而不是预先加载。

溢出处理:当压缩之后总量仍超过 L 时:

  • 丢弃最不重要的 tool 描述
  • 更激进地把历史摘要为每轮一句话
  • 减少记忆槽位
  • 若仍然超出:截断并向用户给出警告

飞行前检查:务必在调用 LLM 之前统计 Token 数。绝不要在推理时才发现溢出。

复习:第 17 章(Agent Harness —— 上下文管理与编排)。

Q:比较 ReAct 与 Plan-and-Execute 两种编排模式

解答

ReAct(Reason + Act):

  • 循环:思考 → 行动 → 观察 → 思考 → ……
  • 每一步都基于此前所有观察来决定下一个动作
  • 优点:自适应——可以根据 tool 输出改变方向
  • 缺点:短视——没有预先规划;可能陷入循环;每次 LLM 调用都要看到完整历史(昂贵)

Plan-and-Execute:

  • 阶段 1:生成完整计划(步骤列表)
  • 阶段 2:按序执行各步骤(执行器更简单;可使用更便宜的模型)
  • 阶段 3:执行失败时重新规划
  • 优点:高效(规划一次比每一步都推理更便宜);独立的步骤可以并行
  • 缺点:计划脆弱——早期步骤失败可能使整个计划失效。重新规划会增加延迟。

何时用哪种:

  • ReAct:探索性任务;未知环境;每一步的结果决定下一步的任务
  • Plan-and-Execute:定义明确的任务;已知的 tool 集合;可并行的子任务;对成本敏感的部署
  • 混合模式:先做高层规划,再在每个计划步骤内用 ReAct(LangGraph 推荐的模式)

复习:第 17 与 18 章(Agent Harness;智能体设计模式)。

Q:如何检测并防止智能体执行中的无限循环?

解答

当智能体重复同一动作却期待不同结果时,就会陷入无限循环。

检测方法:

  1. 最大迭代次数防护:硬性上限(例如 25 步)。简单,但在真正耗时的长任务上会丢失已完成的工作。
  2. 动作哈希窗口:对最近 k 个(动作/观察)对做哈希。若当前哈希与最近 w 步中的某个哈希匹配,则判定为检测到循环。
  3. 语义相似度:对近期动作做嵌入。若相邻动作之间的余弦相似度超过阈值(>0.95),则很可能卡住了。
  4. 进度监控:定义任务特定的进度指标。若 N 步内没有进展,则进行干预。

恢复策略:

  1. 注入提示:添加系统消息:“你似乎在重复动作。试试换一种方法。”
  2. 强制不同动作:在下一步的动作空间中屏蔽掉被重复的动作。
  3. 上报:带着部分结果返回给用户并请求指导。
  4. 回溯:重置到循环开始之前的检查点,并尝试替代路径。

最佳实践:把最大迭代次数(安全网)+ 基于哈希的检测(提前干预)+ 优雅上报(维护用户信任)组合起来。

复习:第 17 与 18 章(Agent Harness;智能体设计模式)。

MCP 协议问题

Q:解释 MCP 的 N+M 架构,以及它对智能体生态为何重要

解答

N×M 问题:没有 MCP 时,N 个智能体框架各自都要实现与 M 个 tool 的集成 = 总共 N×M 个集成。新增一个 tool 需要 N 个实现。

MCP 的 N+M 方案:标准化接口。每个 Agent 实现一个 MCP client(共 N 个)。每个 tool 实现一个 MCP server(共 M 个)。总集成数 = N+M。

具体例子:5 个 Agent 框架(LangChain/AutoGen/CrewAI/Claude/自定义)× 20 个 tool(GitHub/Slack/DB/filesystem/…)= 不使用 MCP 时需要 100 个集成。使用 MCP 时:5 个 client + 20 个 server = 25 个实现。

为什么重要:

  1. Tool 复用:只需构建一次 tool server,任何兼容 MCP 的 Agent 都能使用
  2. Agent 可移植性:从 Claude 切换到自定义 Agent 时无需重写 tool 集成
  3. 生态增长:添加新 tool 的门槛更低,激励社区构建更多 tool
  4. 可组合性:运行时可将多个 server 动态连接到一个 Agent

类比:USB 标准化了外设连接。USB 之前:每个设备都有专有接口。USB 之后:一个端口适配所有设备。MCP 对 agent-tool 连接做了同样的事。

复习:第 20 章(Model Context Protocol)。

Q:MCP 的四个核心原语是什么,各自在什么情况下使用?

解答

关键区别:

  • Tools 与 Resources:Tools 具有副作用(创建/修改/删除)。Resources 是只读的。这一区别对安全性很重要——Agent 可以自由读取 resources,但调用 tools 必须获得批准。
  • Sampling 反转了方向:通常由 client(Agent)调用 server(tool)。而在 Sampling 中,server 会请求 client 的 LLM 帮忙。用例:代码分析 server 需要 LLM 解释一段代码。
  • Prompts 是元数据(可复用模板),而非执行。它们帮助 Agent 构造更好的 tool 调用。

复习:第 20 章(Model Context Protocol)。

Agent 通信(A2A)问题

Q:Google 的 A2A 协议与 MCP 有何不同,什么时候需要两者同时使用?

解答

核心区别:

  • MCP:Agent ↔ Tool(具有既定 schema 的结构化函数调用)
  • A2A:Agent ↔ Agent(不透明的任务委派——你不知道对方 Agent 如何工作)

A2A 关键概念:

  • Agent Cards:描述 Agent 能力的 JSON(类似简历)。发现机制。
  • 不透明执行:请求者看不到受托方的内部推理。只是发送任务并获取结果。
  • 任务生命周期:submitted → working → completed/failed(通过 SSE 提供流式更新)

何时两者都需要:

  1. 编排 Agent 用 A2A 将“研究这个话题”委派给一个研究 Agent
  2. 研究 Agent 用 MCP 调用网页搜索、文件读取和数据库 tool
  3. 结果经 A2A 流回编排 Agent

架构:A2A 位于Agent 间层;MCP 位于Agent–tool层。完整系统两者并用:A2A 用于 Agent 间协调,MCP 用于每个 Agent 的 tool 访问。

复习:第 20 章与第 22 章(MCP;Agent-to-Agent 通信)。

Q:什么是合同网协议(Contract Net Protocol),它如何应用于 LLM Agent?

解答

合同网协议(Contract Net Protocol,CNP)是来自分布式 AI 的任务分配机制:

步骤:

  1. 宣告:管理者向所有可用 Agent 广播任务描述
  2. 投标:Agent 评估自身能力并提交投标(置信度;预估成本;预估时间)
  3. 授标:管理者按标准(能力/成本/可用性)选出最佳投标
  4. 执行:中标 Agent 执行任务
  5. 回报:Agent 将结果报告给管理者

对 LLM Agent 而言:

  • 投标 = 自我评估:每个 Agent LLM 评估“我能把这个任务做好吗?”并给出置信度分数。这需要校准过的自我认知。
  • 专业化涌现:代码 Agent 在代码任务上出高价;研究 Agent 在研究任务上出高价。无需中心路由逻辑。
  • 负载均衡:若一个 Agent 忙(预估时间长),其他 Agent 胜出。
  • 失败处理:若中标 Agent 失败,则向剩余 Agent 重新宣告(自动故障切换)。

LLM 的局限:LLM 常常高估自身能力(幻觉置信度)。投标应纳入历史记录(相似任务的历史成功率),而不仅是自报置信度。

复习:第 22 章与第 23 章(A2A;多 Agent 系统)。

多 Agent 系统问题

Q:比较 LLM 多 Agent 系统的中心化 vs 去中心化架构

解答

中心化(Supervisor):

  • 一个编排 LLM 将任务路由给专家 worker
  • 控制流清晰;易于调试(检查 supervisor 决策)
  • 单点故障;supervisor 成为 token 瓶颈
  • 最适合:定义清晰的工作流;小型 Agent 团队(3–5 个 Agent)

去中心化(点对点):

  • Agent 直接通信;无中央协调者
  • 弹性(无单点故障);可水平扩展
  • 难以调试(涌现行为);可能出现冲突和死锁
  • 无结构时通信按 O⁡(n2) 扩展
  • 最适合:弹性系统;大量 Agent 群体;期望涌现行为的创造性任务

混合(层次化):带子管理者的树形结构。结合优点:组内本地自治 + 顶层全局协调。通信按 O⁡(n​log⁡n) 扩展。

决策框架:需要可预测性和可审计性时用中心化。需要弹性和创造性时用去中心化。大型(>10 个 Agent)系统用层次化。

复习:第 23 章(多 Agent 系统)。

Q:什么是 CTDE,为什么它对训练多 Agent LLM 系统重要?

解答

CTDE = 中心化训练;去中心化执行(Centralized Training; Decentralized Execution)。

问题:多 Agent RL 中,每个 Agent 的环境都是非平稳的(其他 Agent 同时在改变各自的 policy)。这使独立训练不稳定。

CTDE 方案:

  • 训练时:一个中心化 critic 可访问所有 Agent 的观察和动作:V⁡(s1,s2,…,sn,a1,a2,…,an)。这通过把非平稳性从 value 函数中剔除来稳定训练。
  • 执行时:每个 Agent 仅基于自身观察行动:ai=πi​(oi)。推理时没有通信开销。

对 LLM Agent 而言:中心化 critic 可以是一个 reward 模型,评估所有 Agent 的联合输出(例如,Agent 团队是否产出了一个正确的软件系统?),而每个 Agent 通过反事实功劳分配被训练以最大化其对团队 reward 的贡献。

实际挑战:完整 CTDE 要求所有 Agent 在共享状态下同时训练——对 LLM 而言代价昂贵。近似方法:分轮训练 Agent(冻结其余 Agent 训练一个),或使用具有周期同步的种群训练。

复习:第 23 章(多 Agent 系统)。

Agent 开发框架问题

Q:比较 LangGraph、AutoGen、CrewAI 用于构建多 Agent 系统

解答

选 LangGraph 当:需要细粒度控制;复杂条件流;带持久化和人机协同的生产部署。

选 AutoGen 当:多 Agent 对话的快速原型;代码执行 Agent;研究实验。

选 CrewAI 当:简单的基于角色的团队;顺序任务执行;快速演示;代码量最小。

都不选(自定义)当:需要最大性能/控制;不希望被框架锁定;或有非标准的编排模式。

复习:第 24 章(Agent 开发框架)。

Q:如何在生产中测试和评估一个 Agent 系统?

解答

Agent 测试遵循一个 测试金字塔:

第 1 层——单元测试(快;多):

  • 独立测试单个 tool(mock LLM;验证 tool 逻辑)
  • 测试 prompt 模板(给定上下文;验证正确的 prompt 构造)
  • 测试解析器(给定 LLM 输出;验证正确提取)

第 2 层——集成测试(中等速度):

  • 用确定性输入测试完整的 Agent 循环
  • “黄金轨迹”测试:已知良好的执行轨迹,必须能复现
  • tool 链测试:验证多 tool 序列能端到端工作

第 3 层——行为测试(慢;少):

  • Agent 是否遵守安全约束?(对抗性输入)
  • 它是否在适当时候请求澄清?
  • 它是否保持在 token/成本预算之内?

生产评估:

  • A/B 测试:将 5% 的流量路由到新 Agent 版本
  • 影子模式:让新 Agent 与旧 Agent 并行运行,比较输出但不对外服务
  • LLM 作为评判者:自动为 Agent 回复打质量分
  • 用户满意度:点赞/点踩;任务完成率;解决时长

关键指标:任务成功率(Task Success Rate,TSR)——Agent 在无人干预下正确完成的任务比例。

复习:第 14 章与第 24 章(LLM 评估;Agent 开发框架)。

Agent 环境问题

Q:为一个网页浏览 Agent 环境设计 reward 函数

解答

对于 WebArena 风格的任务(例如“找到 12 月 15 日从 NYC 到 SF 最便宜的航班”):

稀疏 reward(简单但难以学习):

r={1if final page/state matches ground truth0otherwise

稠密 reward(更适合训练;更难设计):

  1. 进度奖励:+0.1 每出现一个使 Agent 更接近目标的页面(通过对与目标状态的文本相似度衡量)
  2. 效率惩罚:−0.01 每个动作(鼓励更短的轨迹)
  3. 里程碑奖励:+0.3 达到中间目标(例如导航到航班搜索页面)
  4. 无效动作惩罚:−0.05 产生错误的动作(404;表单校验失败)

基于势函数的塑形(保持最优策略):

rshaped​(s,a,s′)=r⁡(s,a,s′)+γ​Φ​(s′)−Φ⁡(s)

其中 Φ​(s)=−min_steps_to_goal​(s)(由启发式或学习到的 value 函数估计)。

挑战:部分可观测性(无法总能判断自己是否更接近目标);随机环境(页面内容会变化);奖励作弊(Agent 找到满足奖励但不符合用户意图的捷径)。

复习:第 12 章与第 19 章(LLM Agent 训练;Agent 环境)。

Q:是什么让 SWE-bench 成为一个特别有挑战性的 Agent 基准?

解答

SWE-bench 在来自流行 Python 仓库的真实 GitHub issue 上测试 Agent:

为什么难:

  1. 仓库级上下文:Agent 必须理解 10 万行以上的代码库。它们放不进上下文窗口——必须探索、搜索和导航。
  2. 需求不明确的任务:issue 由人类撰写,带有隐含上下文。Agent 必须推断真正需要什么。
  3. 多文件编辑:解决方案往往跨越多个文件,且依赖关系层层级联。
  4. 测试验证:必须同时通过现有测试和验证该修复的新测试。
  5. 没有手把手引导:不同于 HumanEval(单个函数),SWE-bench 要求完整的软件工程工作流:阅读 issue → 探索代码 → 定位 bug → 实现修复 → 验证。

最新水平(2024–2025):最好的 Agent 能解决 SWE-bench Verified(精选子集)的 ∼50%。完整 SWE-bench:∼30%。

训练的关键洞见:SWE-bench 暴露了“编码能力”(写出正确的函数)与“软件工程能力”(理解系统;在代码库中导航;做最小改动)之间的差距。在 SWE-bench 风格的环境上进行 RL 训练,教会 Agent 的不仅是代码生成,还有探索与规划策略。

复习:第 19 章(Agent 环境与基准)。

Agent UI 框架问题

Q:比较面向 Agent 的对话式与画布式 UI 范式

解答

对话式(ChatGPT;Claude 默认):

  • 线性消息流:user → assistant → user → …
  • 优点:UX 熟悉;适合探索和问答;易于实现
  • 缺点:生成产物(代码/文档)淹没在对话中。难以针对某个具体产物迭代。长对话中上下文会丢失。

画布/产物式(Claude Artifacts;ChatGPT Canvas;Cursor):

  • 侧边面板显示生成内容;对话面板用于指令
  • Agent 可以创建、编辑并迭代持久化产物
  • 优点:产物独立于对话持久存在。用户可直接编辑。有版本历史。
  • 缺点:UI 更复杂;需要检测产物类型;更难实现向两个面板同时流式输出。

何时用哪种:

  • 对话式:头脑风暴;问答;快速任务;移动端界面
  • 画布式:代码生成;文档撰写;数据分析——任何带有需要迭代的持久化输出的任务
  • 混合(大多数现代 UI):默认对话;检测到代码/文档/可视化输出时自动升级到画布

对 Agent 训练而言:UI 范式会影响 reward 信号。画布式 UI 提供显式的编辑反馈(用户修改产物),可用于在线学习。

复习:第 25 章(Agent UI 框架)。

Q:如何为人机协同的 Agent 系统设计审批门(approval gate)?

解答

审批门在关键点暂停 Agent 执行,以供人类审查。

三层模型:

  1. 自动批准(无门):安全且可逆的动作。读操作;搜索;计算。
  2. 通知(软门):可能产生影响但可恢复。发送邮件;创建草稿;修改文件。Agent 会继续执行,但用户会收到通知并可撤销。
  3. 阻止(硬门):不可逆或高风险。删除数据;转账;发布内容;执行带副作用的代码。Agent 必须等待明确批准。

设计原则:

  • 尽量减少打断:门太多 = 用户会放弃这个 Agent。三层模型让大多数动作顺畅执行,同时拦截危险动作。
  • 展示上下文:在审批门显示:什么动作;为什么(Agent 的推理);将发生什么变化;如何撤销。
  • 批量批准:如果 Agent 需要 5 次文件写入,就把它们一起呈现,而不是逐个呈现。
  • 超时处理:如果用户在 T 分钟内未响应,则重试通知,或以安全默认值继续,或优雅中止。
  • 从审批中学习:跟踪批准/拒绝的模式。如果用户总是批准某类动作,可以考虑将其自动升级。

实现:tool 注解(MCP 的 destructiveHint 和 readOnlyHint)驱动自动门的分配。自定义规则可基于上下文覆盖。

复习:第 17 章与第 25 章(Agent Harness;Agent UI 框架)。

RAG 与 Agent 化 RAG 问题

Q:解释互逆排名融合(Reciprocal Rank Fusion,RRF),以及它为什么适用于混合检索

解答

RRF 结合多个检索系统的排名,无需分数校准:

RRF​(d)=∑r∈R1k+r⁡(d)

其中 r⁡(d) 是文档 d 在检索器 r 中的排名,k=60 是一个常数,用于防止高排名文档占据主导。

为什么有效:

  1. 无需分数归一化:BM25 分数无上界;稠密相似度位于 [−1,1] 区间。RRF 只使用排名,使它们可直接比较。
  2. 对异常值稳健:某个检索器给出异常高的分数也不会占据主导,因为 1/(k+1)≈0.016 即使对排名第 1 的文档也是如此。
  3. 信号互补:BM25 捕捉精确关键词匹配;稠密检索捕捉语义相似性。被两者都排在前列的文档会获得提升。

示例:文档 d 在 BM25 中排名第 3,在稠密检索中排名第 7。RRF 分数为 =1/(60+3)+1/(60+7)=0.0159+0.0149=0.0308。一个在其中一个检索器中排名第 1、在另一个中排名第 100 的文档得到 1/61+1/160=0.0226——尽管有 top-1 排名,得分却更低。

实践中:混合检索(BM25 + 稠密 + RRF)在 85% 以上的基准上都优于单独使用其中任一种。

复习:第 15 章(检索增强生成)。

Q:什么是 Agentic RAG,它与标准 RAG 有何不同?

解答

标准 RAG 遵循固定流水线:query → retrieve → generate。它没有能力:

  • 决定是否需要检索
  • 评估检索到的文档是否充分
  • 在检索失败时重新构造查询
  • 合并多个检索步骤的信息

Agentic RAG 将检索视为 Agent MDP 中的一个动作:

  • 是否检索的决策:Agent 评估自己是否已经知道答案(对训练数据中的事实性问题跳过检索)
  • 查询规划:将复杂问题分解为子查询(“X 发生在哪一年?”+“当时谁当总统?”)
  • 自我评估:检索后评估相关性。若不充分,则重构查询或尝试不同来源。
  • 多跳推理:检索 → 推理 → 识别知识缺口 → 再次检索
  • 来源路由:将查询路由到合适的知识库(时事用网页;公司信息用内部文档;编程用代码搜索)

关键架构差异:标准 RAG = 确定性流水线。Agentic RAG = 带条件转移的状态机(LangGraph 模式,含 retrieve/grade/rewrite/generate 节点)。

权衡:Agentic RAG 在复杂查询上更准确,但会增加延迟(路由/评分需要多次 LLM 调用)。简单的事实性查找用标准 RAG;多跳或含糊的查询用 Agentic RAG。

复习:第 15 章与第 17 章(RAG;Agent Harness)。

Q:比较 Self-RAG 与 CRAG 这两种提升检索质量的方法

解答

Self-RAG(Asai 等,2023):

  • 训练特殊的 reflection token,并将其加入 LLM 词表
  • 推理时,模型会输出 [Retrieve]、[IsRel]、[IsSup]、[IsUse] 之类的 token
  • 模型决定何时检索(并非每个查询都需要检索)
  • 检索后,模型自我评分:检索到的段落是否相关?我的答案是否由它推导而来?
  • 训练:在用 GPT-4 生成的 reflection 标签增强的数据上做 SFT
  • 优点:单个模型处理一切。缺点:需要自定义训练。

CRAG(Corrective RAG,Yan 等,2024):

  • 使用一个轻量的 检索评估器(独立模型)为检索到的文档打分
  • 基于置信度的三种动作:Correct(按原样使用)、Ambiguous(用网页搜索补充)、Incorrect(丢弃;回退到网页)
  • 增加一个 知识精炼步骤:只从检索到的文档中提取相关句子
  • 优点:可与任何冻结的 LLM 配合使用。缺点:多一个用于评估的模型;增加延迟。

关键区别:Self-RAG 将检索决策内嵌到 LLM 本身(需要训练)。CRAG 是一种流水线方法,可包装任意 LLM(无需训练)。Self-RAG 更优雅;CRAG 对使用现有模型的生产环境更实用。

复习:第 15 章(检索增强生成)。

Q:什么是“迷失在中间”问题,如何缓解?

解答

问题:当检索到的上下文很长(段落很多)时,LLM 会不成比例地关注上下文开头和末尾的信息,而忽略中间的信息。如果答案位于 10 个段落中的第 5 个,模型可能会漏掉它。

经验证据:Liu 等(2023)表明,在检索 20 个文档时,当相关文档位于第 5–15 位而不是第 1–3 位时,准确率会下降 15–20%。

缓解策略:

  1. 重排并截断:使用交叉编码器(cross-encoder)重排,然后只保留最相关的前 3 个段落(更少 = 更少的迷失在中间)。
  2. 策略性排序:把最相关的段落放在上下文的开头和末尾,低相关的放在中间。
  3. 上下文压缩:插入前将每个段落摘要为 1–2 句。文本更少 = 位置偏置更少。
  4. Map-reduce:独立处理每个段落(map),再合并答案(reduce)。完全消除位置效应。
  5. 引用提示:要求模型引用它使用了哪个段落。这会迫使它关注所有段落。
  6. 减小分块大小:更小的分块意味着覆盖答案所需的总分块数更少。

最佳实践:先检索很多(20+),重排到前 3–5,再按相关性排序(最好的在前)。对大多数用例而言,这完全绕开了该问题。

复习:第 15 章(检索增强生成)。