时长 7–8 小时:§1 测试时缩放是什么(0.5h)· §2 并行:采样多个再挑(1.5h)· §3 过程奖励与搜索(1h)· §4 计算最优的测试时缩放(1h)· §5 第 3 周整合与出关测试(2.5h)· §A–§B 穿插进行
对应正课 Lecture 6 的后半部分:缩放(推理时的缩放)。学习计划点名要会的:“推理时多花算力换准确率的几种方式——更长 CoT、best-of-n、多数投票、过程奖励模型(PRM)引导搜索。以及它和训练时 scaling 的关系。”
配套代码
w3day6_checks.py(纯 numpy):pass@n、多数投票、best-of-n、加权投票随 n 的变化;可被欺骗的验证器下 best-of-n 先升后降;PRM 逐步搜索 vs ORM best-of-n;按难度自适应分配预算;小模型多采样 vs 大模型采一次§B 参考实现(
code/目录):w3d6_tts.py(多数投票、按置信度加权投票、pass@n;加法玩具上 SFT 模型与 GRPO 模型的测试时缩放曲线;GSM8K 上的同样实验,可接 Day 5 的 GRPO 适配器)。今天的目标:能说出测试时缩放的两大类方法和各自的上限;能解释为什么多数投票会饱和、best-of-n 会被验证器的缺陷拖垮;能说清 PRM 为什么比 ORM 更适合做搜索;能讨论测试时算力和训练时算力怎么换算;完成第 3 周的出关测试。
§0 今天的主线
Day 5 §1.1 提到,o1 展示了两条曲线:准确率随训练时的 RL 算力和测试时的思考算力都在增长。Week 2 Day 1 讲的缩放律全是关于训练算力的;今天讲另一条:模型训练好之后,在推理时多花算力,能换来多少准确率?
其实你已经见过它的最简单形式:Week 2 Day 3 §5.3 的自洽性(采样多条思维链、投票)。今天把它系统化:怎样花这些算力(§2 并行采样、§3 逐步搜索)、怎样按题目分配它(§4.1)、它和训练时的算力怎么比较(§4.2)。
最后是第 3 周的整合与出关测试(§5)。
今天要用到的旧结论:自洽性投票的成立条件(Week 2 Day 3 §5.3);best-of-n 的过度优化与 KL(Day 2 §3.2);PagedAttention 的前缀共享(Day 1 §3.3);pass@k 与”磨尖”(Day 5 §5);缩放律与 (Week 2 Day 1 §3);roofline 与解码的访存瓶颈(Week 1 Day 4 §1.5)。
§1 测试时缩放是什么
1.1 两大类
| 类别 | 做法 | 例子 | 需要什么 |
|---|---|---|---|
| 并行 | 采样多个独立的回答,再聚合或挑选 | 多数投票、best-of-n、加权投票 | 一个聚合规则或验证器 |
| 串行 | 让单个回答更长、更深入 | 长思维链、自我检查与修正、“再想想” | 一个会利用额外长度的模型(推理模型) |
| 搜索(两者结合) | 逐步生成,每步展开多个候选、打分、剪枝 | PRM 引导的 beam search、树搜索 | 一个能给部分解答打分的过程奖励模型 |
推理模型(Day 5)主要走串行这条路:RL 把”想得更久就更准”的能力练进了模型本身。并行和搜索则可以套在任何模型外面。
1.2 覆盖率随样本数增长
一个基础事实(Brown et al. 2024,“Large Language Monkeys”):只要有一个完美的验证器(比如能跑单元测试),重复采样的覆盖率(pass@n,Day 5 §5.1)在好几个数量级的样本数上近似对数线性地增长。小模型采足够多次,覆盖率能超过大模型只采一次。
但”完美的验证器”是一个很强的前提。 数学题的最终答案、代码的单元测试可以验证;开放式问题没有。没有验证器时,你能拿到的是 §2 里那些打了折扣的方法。
§2 并行:采样多个再挑
2.1 四种挑法
采 个回答之后:
- pass@n(有完美验证器时):只要有一个对就算对。这是天花板。
- 多数投票(自洽性):取最常见的最终答案。不需要验证器。
- best-of-n:用一个验证器(奖励模型、ORM)给每个回答打分,取最高的。
- 加权投票:同一个答案的验证器分数(或模型自己的置信度)加起来,取总分最高的答案。
w3day6_checks.py 第 1 组:2000 道题,单次正确率平均 0.406;错误答案有 2–11 种,有的题有一个”很有吸引力”的错误答案;验证器给对的回答打分 、错的 (AUC ≈ 0.86):
| pass@n | 多数投票 | best-of-n | 加权投票 | |
|---|---|---|---|---|
| 1 | 0.404 | 0.404 | 0.404 | 0.404 |
| 4 | 0.686 | 0.523 | 0.598 | 0.590 |
| 16 | 0.862 | 0.518 | 0.735 | 0.707 |
| 64 | 0.934 | 0.516 | 0.812 | 0.744 |
| 256 | 0.979 | 0.523 | 0.875 | 0.763 |
2.2 多数投票为什么饱和
多数投票在 时收敛到”正确答案是不是所有答案里最常见的那个”(Week 2 Day 3 §5.3 推过这个条件)。对那些”一个错误答案比正确答案更常见”的题,采再多次也是错的。所以上表里多数投票从 起就停在 0.52 左右,而 pass@n 还在往上走。两者之间的差距,就是一个好验证器最多能帮你捞回来的部分。
2.3 best-of-n 与加权投票
有验证器时,best-of-n 能利用”正确答案不常见但看起来更好”的信息,上表里它明显高于多数投票。加权投票介于两者之间:它仍然会被”很常见的错误答案”拖累(很多个中等分数加起来可以压过一个高分),但它对验证器的缺陷更稳健(§2.4)。
没有外部验证器时,可以用模型自己的置信度(比如回答的平均 token 概率)做加权,参考代码 --gsm8k 就是这样做的。它通常比纯多数投票略好,但不可靠:模型常常对错误答案也很自信。
2.4 验证器也会被钻空子
第 2 组:同样的题,但 5% 的错误回答能”骗过”验证器(得分 ,比大部分正确回答还高):
| best-of-n | 加权投票 | 多数投票 | |
|---|---|---|---|
| 1 | 0.412 | 0.412 | 0.412 |
| 4 | 0.572 | 0.566 | 0.525 |
| 16 | 0.597 | 0.634 | 0.527 |
| 64 | 0.495 | 0.641 | 0.528 |
| 256 | 0.361 | 0.665 | 0.529 |
| 1024 | 0.252 | 0.656 | 0.528 |
best-of-n 先升后降, 时比只采一次还差: 越大,越几乎一定能采到一个骗过验证器的错误回答,而它恰好得分最高。这和 Day 2 §3.2 的 best-of- 过度优化是同一件事:在测试时,选择压力就是优化压力。加权投票要求骗过验证器的错误答案还得是同一个、并且足够多,所以更抗这种攻击。
意义:用奖励模型做 best-of-n 时, 不是越大越好;验证器越不可靠,最优的 越小。
§3 过程奖励与搜索
3.1 ORM 与 PRM
- 结果奖励模型(ORM):只看完整的解答,判断最终是否正确。
- 过程奖励模型(PRM):给解答的每一步打分,判断”到这一步为止是否还正确”。
Lightman et al. 2023(Let’s Verify Step by Step)用人工标注了 80 万个步骤级的标签(PRM800K),发现在 best-of-n 的设定下,PRM 比 ORM 更可靠:它能指出错在哪一步,而 ORM 只能从最终结果反推,容易被”过程错了、答案碰巧对了”的解答骗过。
自动构造过程标签(Math-Shepherd 等):人工标注步骤太贵。替代做法是从每个中间步骤出发做若干次蒙特卡洛展开(继续生成到底),用”从这一步出发最终做对的比例”当作这一步的标签。这其实就是在估计这一步的价值(Day 3 §2.1)。
3.2 PRM 引导的逐步搜索
有了 PRM,就可以边生成边剪枝:保留 条部分解答,每一步为每条生成 个候选的下一步,用 PRM 打分,只保留最好的 条。
第 3 组:每道题 8 步,每步做对的概率 0.6–0.95,一步错整题就错(单次采样平均只有 0.190 能做对)。ORM 的 best-of-N 要写完 N 个完整解答;PRM 搜索每步展开 4 个候选。两者用同样的生成预算(按生成的步数算),打分的噪声也一样:
| 预算(步数) | ORM best-of-N | PRM 逐步搜索 |
|---|---|---|
| 32 | 0.372(N = 4) | 0.685(b = 1) |
| 128 | 0.563(N = 16) | 0.975(b = 4) |
| 512 | 0.718(N = 64) | 0.997(b = 16) |
同样的预算,逐步搜索把算力花在”还没出错”的路径上:错误在它发生的那一步就被剪掉;best-of-N 则要为每个第 2 步就错了的解答把剩下 6 步也写完。步骤越多、每一步越容易出错,PRM 的优势越大。
3.3 代价与局限
- PRM 难训练:步骤级的标签贵,自动构造的标签有噪声;“一步”的边界本身就不好定义。
- PRM 也会被钻空子(§2.4),而且搜索的优化压力比 best-of-n 还大。
- 搜索会降低多样性:beam 很快收敛到几条相似的路径上。
- 推理模型出现之后,一部分”搜索”被内化进了模型的长思维链(自己检查、自己回溯)。DeepSeek-R1 的报告也提到,他们尝试过 PRM 和蒙特卡洛树搜索,在大规模训练中没有取得理想的效果。PRM 引导的搜索仍然有用,但不再是唯一的路。
§4 计算最优的测试时缩放
4.1 按难度分配
Snell et al. 2024(Scaling LLM Test-Time Compute Optimally…)的核心结论:最好的测试时策略取决于题目的难度。容易的题,采几次、做一点修正就够了;中等的题,搜索和更多的样本收益最大;太难的题,花多少测试时算力都没用。按难度选择策略和预算(“计算最优”),比统一的 best-of-N 效率高 4 倍以上。
第 4 组的一个简化版本:5000 道题,有完美的验证器;平均分配是每道题采 次;自适应分配先每题采 4 次,已经解出的题不再花钱,剩余预算一个样本一个样本地贪心分给”这一次最有可能是第一次解出”的未解题:
| 平均每题预算 | 平均分配 | 自适应分配 |
|---|---|---|
| 4 | 0.480 | 0.484(预算只够探测,两者本质相同;差别是抽样噪声) |
| 8 | 0.587 | 0.639 |
| 16 | 0.678 | 0.737 |
| 32 | 0.752 | 0.801 |
自适应分配用 16 次的预算,解出的题(0.737)接近平均分配用 32 次的(0.752)。难度要从模型自己的表现里估计,这里用的就是前 4 次采样的结果。
4.2 测试时算力 vs 训练时算力
学习计划的问题:“它和训练时 scaling 的关系”。
算力账:推理的 FLOPs 约为 (生成的 token 数)(Week 1 Day 2 §5.2 的前向部分),所以 7B 模型采 10 次和 70B 模型采 1 次的推理算力差不多。第 5 组(有完美验证器,正确率是示意用的假设值):
| 难度 | 7B 单次 | 7B 采 10 次(pass@10) | 70B 单次 | 哪个划算 |
|---|---|---|---|---|
| 容易 | 0.600 | 1.000 | 0.900 | 7B × 10 |
| 中等 | 0.200 | 0.893 | 0.500 | 7B × 10 |
| 较难 | 0.050 | 0.401 | 0.300 | 7B × 10 |
| 很难 | 0.005 | 0.049 | 0.100 | 70B × 1 |
小模型”偶尔能做对”的题,多采样就能捞出来;小模型几乎做不对的题,只能靠更大的模型。 Snell et al. 2024 的实测结论与此一致:在小模型有一定成功率的题上,匹配 FLOPs 的测试时算力可以胜过一个大 14 倍的模型;在最难的题上,预训练算力仍然更有效。
这和 Day 5 §5.2 是同一个故事:测试时采样和 RL 都只能把模型”已有但不稳定”的能力变成可用的,它们磨尖分布;真正”拓展”能力边界的,主要还是预训练(和从更强模型的蒸馏)。三种算力是互补的:
| 算力花在哪 | 作用 | 什么时候划算 |
|---|---|---|
| 预训练 | 拓展能力边界 | 当前模型根本做不对的题 |
| RL(训练时) | 把偶尔做对变成稳定做对,一次付费、之后每次推理都受益 | 题型固定、调用量大 |
| 测试时 | 每道题按需多付一些 | 调用量小、题目难度差异大、有可靠的验证器 |
4.3 串行:让模型想得更久
- 推理模型的思考长度本身就是测试时算力:o1 的曲线显示,准确率随思考 token 数近似对数线性增长。
- Budget forcing(s1,Muennighoff et al. 2025):只用 1000 条精选的长推理数据 SFT,推理时在模型想结束思考时追加一个”Wait”强迫它继续想,或在超预算时强行结束。一个很简单的控制思考长度的办法,就能画出测试时缩放曲线。
- 想得更久不总是更好:推理模型会”过度思考”简单的题,浪费 token,甚至把对的改成错的。有时错误的回答反而更长(部分原因可能是 Day 5 §4.1 的长度偏置)。
§5 第 3 周整合
5.1 全景图:从 SFT 模型到推理模型
| 阶段 | 要回答的问题 | 本周的工具 | 出处 |
|---|---|---|---|
| 期中 | 前两周学扎实了吗 | 真题、模拟卷、错题溯源;补漏:标签平滑、推测解码、PagedAttention | Day 1 |
| 收集偏好 | 怎样表达”A 比 B 好” | 成对比较、排序、单点好 / 坏 | Day 2 §2.1、Day 4 §4.2 |
| 奖励模型 | 把偏好压缩成一个分数 | Bradley-Terry、最后一个 token 的标量头 | Day 2 §2.2–2.3 |
| 在线 RL | 在自己的分布上最大化奖励 | 策略梯度、基线、GAE、PPO 的裁剪、每 token 的 KL | Day 3 |
| 离线偏好优化 | 能不能跳过奖励模型和 RL | 闭式最优解、DPO、IPO / KTO / SimPO / ORPO | Day 4 |
| 推理 | 让模型学会长思维链 | RLVR、GRPO、Dr. GRPO、DAPO | Day 5 |
| 推理时 | 花更多算力换准确率 | 多数投票、best-of-n、PRM 搜索、计算最优分配 | 今天 |
每一行你都应该能说出”为什么这么做、不这么做会怎样、用哪个数字来判断”。
5.2 贯穿一周的四条主线
一个目标,三种解法。 Day 2 §3.3 的 有闭式最优解 (Day 4 §1.2)。PPO 用采样和梯度去逼近它(Day 3 §3.5,KL(π‖π*) ≈ 0.01);DPO 利用它把奖励换成策略的对数比,直接做监督学习(Day 4 §2,KL(π_θ‖π*) = 0.002);best-of- 在测试时用采样近似”按奖励重新加权”(Day 2 §3.2,KL ≤ )。看到任何偏好优化方法,先问它在逼近哪个分布、用什么手段逼近。
基线与方差。 BT 奖励只确定到一个常数(Day 2 §2.2)→ 策略梯度减去基线不改变期望、却让方差降低几百倍(Day 3 §1.3)→ GAE 用 λ 在价值网络的偏差和回报的方差之间插值(Day 3 §2.3)→ GRPO 用同组回答的均值做基线,代价是全对 / 全错的组没有信号(Day 5 §3.2)。RL 里大部分工程技巧都是在降方差。
代理与 Goodhart 定律。 奖励模型的过度优化(Day 2 §3.2)→ PPO 去掉 KL 就坍缩到代理奖励最高的回答(Day 3 §3.5)→ DPO 在确定性偏好上把间隔推向无穷(Day 4 §3.5)→ GRPO 的长度归一化让错误的回答变长(Day 5 §4.1)→ 测试时 best-of-n 被验证器的缺陷拖垮(今天 §2.4)。优化压力越大,代理的缺陷越致命;每一个方法都要问:它在优化的那个量,和我真正想要的有什么差别?
磨尖与拓展。 RL 让 pass@1 几乎翻倍,但 pass@256 下降(Day 5 §5.2)→ 蒸馏比小模型自己做 RL 更有效(Day 5 §5.3)→ 测试时采样只能捞回模型偶尔能做对的题(今天 §4.2)。RL 和测试时算力把已有的能力变得可用;拓展能力边界主要靠预训练和更强的老师。
5.3 Week 3 出关测试(2.5h,闭卷)
理论(90 分钟,纸笔)
- SFT 缺了什么?为什么偏好数据更容易收集?
- 从”效用 + Gumbel 噪声”推出 Bradley-Terry 模型,写出奖励模型的损失和梯度。为什么奖励模型测试准确率只有 70% 并不一定说明它差?
- 画出 RLHF 三阶段的数据流,标出每一步训练哪个模型、用什么数据、哪些模型冻结。
- 推出策略梯度,说明基线为什么不改变期望。写出 GAE,解释 λ。
- 写出 PPO 的裁剪目标,分四种情况说明它对 ρ 的梯度。说出 LLM 上的 PPO 里四个模型各自的作用,算出 7B 时的显存。
- KL 惩罚去掉会发生什么?、 两个 KL 估计量的区别是什么?
- 推出 KL 约束目标的闭式最优解,再推出 DPO 损失。 求它的梯度,解释权重。
- DPO 相比 PPO 省了什么、丢了什么?什么时候选 PPO?说出 IPO、KTO、SimPO、ORPO 各修了什么。
- 什么是 RLVR?为什么它在数学和代码上特别有效?边界在哪?
- 写出 GRPO 的目标,回答”为什么省显存、为什么在可验证任务上够用”。它的两个归一化带来什么偏置?
- RL 后的模型 pass@1 高很多、pass@256 却比基座模型低,你怎么解释?写出 pass@k 的无偏估计。
- 比较多数投票、best-of-n、PRM 引导的搜索:各自需要什么、上限在哪、会怎样失败。测试时算力和训练时算力怎么权衡?
实战(60 分钟)
- 不看资料写出 Bradley-Terry 损失和一个”主干 + 最后一个 token 的标量头”的奖励模型前向。
- 写出 GAE 和 PPO 的裁剪损失,通过 λ = 0、λ = 1 与裁剪梯度的单元测试。
- 写出 DPO 损失(给定四个序列 log 概率),并在一个表格策略上验证它收敛到 。
- 写出 GRPO 的组内优势与 pass@k 的无偏估计。
通过线:理论 12 题至少 10 题讲清推导过程和动机,实战 4 项全部通过。达不到的项回到对应的 Day 重读。
5.4 进入第 4 周之前
- 保留这一周的模型:Day 4 的 DPO 适配器、Day 5 的 GRPO 适配器和加法玩具。第 4 周 Lecture 8 做评测时,它们是现成的”对比对象”。
- 把本周的实验整理成一页笔记:奖励模型的准确率与长度相关(Day 2)、有无 KL 的 PPO 对比(Day 3)、DPO 的 β 对比与 chosen / rejected 的 log 概率(Day 4)、GRPO 的 pass@1 / pass@16(Day 5)、测试时缩放曲线(今天)。每个实验一张表加三句结论。
- 第 4 周是应用层:Lecture 7 讲检索增强(RAG)、工具调用和智能体,Lecture 8 讲评测与 LLM-as-a-judge。LLM 当评委,本质上就是一个奖励模型:Day 2 §2.5 的偏见(偏爱长回答、谄媚)和今天 §2.4 的”验证器被钻空子”,在那里会以”评委偏差”的名字再出现一次。
§A 测试时缩放:API 用法与边界
A.1 一次采多个回答
# HF:同一个提示采 n 个
out = model.generate(**enc, do_sample=True, temperature=0.8, num_return_sequences=16, max_new_tokens=512,
output_scores=True, return_dict_in_generate=True)
lp = model.compute_transition_scores(out.sequences, out.scores, normalize_logits=True) # 每个生成 token 的 log 概率
- 用推理引擎:vLLM 的
SamplingParams(n=16, temperature=0.8, logprobs=1)一次请求返回 16 个回答,而且同一个提示的 KV Cache 只算一次、在 16 个回答之间共享(Day 1 §3.3 的前缀共享)。采样很多次时,这比 HF 的generate快一个数量级以上。 - 温度:太低时 16 个回答几乎一样,投票没有意义;太高时每个回答的质量下降。数学题上 0.6–1.0 常见。
- 成本: 个样本就是 倍的生成 token。报告测试时缩放的结果时,横轴要写成”生成的 token 数”或 FLOPs,而不只是 。
A.2 聚合时的细节
- 答案要先规范化再投票:
"72"、"72.0"、"$72"是同一个答案。参考代码的extract_answer做了最基本的规范化。 - 抽不出答案的回答(被截断、格式错误)不参与投票,但要计入成本。
- 平票规则要固定下来(参考代码取最先出现的),否则结果不可复现。
A.3 评测时的 pass@k
报告 pass@k 时采 个样本、用无偏估计(Day 5 §5.1),并注明温度。比较两个模型时要用同一个 、同一个温度:一个模型在温度 0 的 pass@1 和另一个模型在温度 1 的 pass@1 不可比。
§B 实操
- 跑通
w3day6_checks.py,5 组结论都看懂。第 2 组改变”骗过验证器”的比例(1%、5%、20%),找 best-of-n 的最优 。 - 加法玩具上的测试时缩放(0.5h):先跑
w3d5_grpo.py --toy,再跑python code/w3d6_tts.py --toy。SFT 模型要多数投票到多少个样本才赶上 GRPO 模型的单次准确率? 大的时候谁的 pass@n 更高? - GSM8K 上的测试时缩放(1.5h,GPU 更好):
--gsm8k --n-max 16,再加--adapter w3d5_out在 GRPO 后的模型上跑一次。画出两条”准确率 vs 生成 token 数”的曲线。 - 做 §5.3 的出关测试(2.5h)。
- 读论文:Snell et al. 2024 的第 1、5 节;Lightman et al. 2023 的第 2–3 节;挑读 Brown et al. 2024(Large Language Monkeys)。
参考实现:code/w3d6_tts.py。
出关标准
- 能说出测试时缩放的三类方法(并行、串行、搜索)和各自需要什么
- 能解释多数投票为什么饱和、best-of-n 为什么会被验证器拖垮
- 能说清 PRM 与 ORM 的区别,以及逐步搜索为什么更省预算
- 能讨论按难度分配测试时算力,以及测试时算力、RL、预训练三者的关系
- 在加法玩具上画出 SFT 与 GRPO 模型的测试时缩放曲线
- 通过 §5.3 的 Week 3 出关测试