Lecture 9 · 后训练数据 II:推理轨迹、智能体数据与强化学习环境 · Post-training Data II: Reasoning, Agents & RL Environments

Training Data for AI · Lecture 09。个人学习讲义与配套实验,按主题整理并持续修订。

课程源码 ZIP ↓

个人整理的学习笔记,非官方讲义;课程来源与整理说明见课程介绍。配套示例未逐一运行验证。

本篇目录

对应 Maps to:Stanford CS525 Winter 2026 Training Data for AI,2/2 客座讲座 Data for LMs: post-training(Etash Guha)的后半部分(“推理时代”和”智能体时代”);2/4 的学生报告:DeepSeek-R1(Lillian Weng)、Llama-Nemotron(Arpandeep Khatua)、OLMo 3(Anya Hansen)、SWE-smith(由论文第一作者 John Yang 本人报告)。阅读:DeepSeek-R1、s1、OpenThoughts、SWE-Gym、Llama-Nemotron、OLMo 3、SWE-smith。 依据说明:Guha 的 slides 是本讲的骨架。SWE-smith 的学生报告大部分页面是图片,我读到了它的框架(三个工作流、拒绝采样微调的设置、后续工作);R1、Llama-Nemotron、OLMo 3 的学生报告没有读到文字,相应的内容依据论文摘要和 Schmidt 第 7 讲综述里的数字。论文的关键数字核对过各论文的摘要;R1-Zero / R1 的训练流程、蒸馏的模型尺寸是我根据 R1 论文正文补充的。Guha 的 slides 里有几张表格(例如 OpenThoughts 的消融数字、SWE-Bench 的进展时间线)我没有在原论文里逐一核对,讲义里会标明”slides 的数字”。第 6 节”统一的视角”和第 7 节”延伸与前沿”是我补充的。 配套代码 Code:code/lecture09/(numpy + 标准库 ast;3 个脚本 + 2 个模块;每个约 1 秒) 预计阅读时间:3 小时(含运行代码)


0. 本讲导航 · How to read this lecture

0.1 学习目标 Learning goals

  1. 说明为什么需要”推理模型”,以及测试时计算(test-time compute)为什么成了新的扩展维度。
  2. 讲清楚 DeepSeek-R1-Zero / R1 的训练:可验证奖励的强化学习(RLVR)、GRPO、冷启动数据、拒绝采样,以及蒸馏。
  3. 理解 RLVR 的两个数据问题:题目的难度要落在模型的能力边界上;验证器的漏洞会被钻空子。
  4. 理解蒸馏推理轨迹时的数据选择:老师的选择(更好的模型不一定是更好的老师)、每题几个答案、要不要验证答案、选什么问题(s1 的 1000 条精选、OpenThoughts 的系统消融)。
  5. 了解开放的推理模型配方(Llama-Nemotron、OLMo 3)。
  6. 理解智能体训练数据的特殊之处:环境即数据;SWE-Bench / SWE-Gym 的真实任务、SWE-smith 的自动合成;测试的强弱决定了”成功”的含义。

0.2 先修与本讲范围 Prerequisites & scope

默认你已经会 Assumed本讲不展开 Not covered
第 8 讲:SFT、偏好数据、RLHF、DPO、Tulu 3 的 RLVRGRPO、PPO 的推导和实现细节
第 7 讲:重复、过滤强度和算力的关系推理模型的评测与污染(第 14 讲)
第 4 讲:Docker、执行环境的概念(可选)机器人、3D 等其他模态的智能体数据(第 15–16 讲)

0.3 本讲地图 Map

§1  为什么需要推理模型:聊天机器人的天花板、o1、测试时计算
§2  DeepSeek-R1 与可验证奖励的强化学习                               ← 代码 01
§3  开放复现的另一条路:蒸馏推理轨迹(s1、Sky-T1、OpenThoughts)        ← 代码 02
§4  开放的推理模型配方:Llama-Nemotron、OLMo 3
§5  智能体:环境即数据(SWE-Bench、SWE-Gym、SWE-smith、OpenThoughts-Agent) ← 代码 03
§6  一个统一的视角
§7  延伸与前沿
§8–12  小结、常见误区、练习、延伸阅读、下一讲预告

0.4 关于数字

论文的数字来自 slides 和论文摘要。代码的数字来自两个合成的环境:

  • 推理世界(reasoning_world.py):从一个数出发做 kk 步运算(模 101),kk 是难度。模型对 6 种运算各有一个”做对的概率”,还有一个”能连续推多少步”的视野 HH——超过视野的步骤更容易出错。一步做错,最后的答案就错了,但后面步骤的做法仍然可能是对的。老师的推理轨迹可以完整,也可以简略(跳过一部分步骤)。学生从看到的步骤里学运算,从长的推理链里学”推得更远”。它没有语言、没有推理的格式,只研究数据的难度、数量、过滤、老师的选择。
  • 迷你代码仓库(toy_repo.py):8 个小函数和两套测试(36 个用例的强测试、8 个用例的弱测试)。代码 03 用 Python 的 ast 模块真的往里面注入 bug、真的执行测试——这一部分不是模拟。

代码固定了随机种子,同一台机器上重复运行输出逐字相同。


1. 为什么需要推理模型

1.1 聊天机器人的天花板

到 2024 年,聊天机器人在复杂任务上碰到了天花板(Guha 的 slides):

  • 数学竞赛:AIME(美国数学邀请赛)的题目需要多步推理、系统地搜索、模运算和分情况讨论,没有简单的模式可以匹配。slides 里的例子(AIME 2024):“设 N 是最大的四位正整数,使得把它的任意一位数字换成 1 之后得到的数都能被 7 整除;N 除以 1000 的商为 Q、余数为 R,求 Q + R。“(N = 5694,答案 699。slides 把问题写成了”求余数”、答案写成了 299,和原题不一致——我用穷举验证过。)GPT-4 一类的模型在 AIME 上只能做对很少的题。
  • 编程竞赛:Codeforces 上难度较高的题,需要把问题转化(例如转成相邻差分)再计数。
  • 博士水平的科学题:GPQA 的题目是领域专家写的、“谷歌不到”的——非专家即使用搜索引擎也只有约 30%,领域内的博士约 65%。
  • 规划:多步问题的分解。

解决办法:让模型在回答之前先”思考”。

1.2 o1 与测试时计算

OpenAI o1(2024 年 9 月)在数学、代码、科学上大幅超过 GPT-4o(slides:AIME 约 74%,GPQA 78%,超过了人类专家)。o1 的博客展示了两条扩展曲线:训练时的计算(更多的强化学习)和测试时的计算(让模型想得更久)都能提升表现。

代价是 token:推理模型的输出多得多。简单的算术,非推理模型输出几个 token,推理模型 50–200 个;一道 AIME 题,100–300 vs 2,000–10,000;博士水平的科学题,200–500 vs 5,000–20,000。多 10–100 倍的 token,意味着更高的延迟和成本,但准确率高得多。

测试时计算成了一个新的扩展维度。 而”让模型学会长时间、有效地思考”需要新的训练数据——这一讲的主题。


2. DeepSeek-R1 与可验证奖励的强化学习

2.1 R1-Zero:只用强化学习

DeepSeek-R1(2025 年 1 月)的摘要的核心一句:LLM 的推理能力可以只用强化学习激发出来,不需要人工标注的推理轨迹。

R1-Zero 直接从基础模型(DeepSeek-V3-Base)出发做强化学习:

  • 奖励是可验证的:数学题答对了没有(和标准答案比较)、代码能不能通过测试;再加一个格式奖励(把思考放在 <think> 标签里)。没有奖励模型——也就没有奖励模型被”钻空子”的问题(第 8 讲 §3.5)。
  • GRPO(Group Relative Policy Optimization):每道题采样一组回答,每个回答的”优势”是它的奖励减去组内的平均奖励;比组平均好的回答被加强,比组平均差的被削弱。不需要单独的价值模型。

训练中出现了自我反思、验证、调整策略这些行为(摘要的说法),回答越来越长——模型”自己学会了思考得更久”。但 R1-Zero 的输出可读性差、会混用语言。

2.2 R1:多阶段的配方

R1 在 R1-Zero 的基础上加了几个阶段:

  1. 冷启动:先用几千条高质量的长推理示范做 SFT,让输出可读、格式稳定;
  2. 面向推理的强化学习(加了语言一致性的奖励);
  3. 拒绝采样 + SFT:用强化学习后的模型生成大量回答,只保留正确、可读的;加上非推理的数据(写作、问答等),再做一轮 SFT——Schmidt 的综述:约 80 万条(约 60 万推理 + 20 万非推理);
  4. 面向所有场景的强化学习(推理题用规则奖励,其他用偏好奖励)。

强化学习的提示约 14.6 万个(数学 2.6 万、代码 2.5 万、STEM 2.2 万、逻辑 1.5 万、通用 7.8 万)。

蒸馏:用那 80 万条数据直接微调 Qwen2.5 和 Llama 的小模型(1.5B 到 70B),效果很好;论文发现,对小模型来说,从大模型蒸馏比在小模型上直接做强化学习有效得多。这打开了第 3 节的路线。

2.3 数据问题一:题目要落在能力边界上

GRPO 的优势是在组内比较出来的。一组回答全对或全错,优势全是 0——这道题对训练毫无贡献。

代码 01 演示 1:初始模型对不同难度的题,采样 8 个回答”全对或全错”的概率:

步数 kk初始通过率8 个全对或全错其中”全错”的比例
10.7670.1460.00
20.5920.0230.07
40.3510.0400.99
60.1330.3291.00
80.0330.7651.00
120.0100.9231.00

难度均匀的题库里,约 47% 的采样白费了——大部分浪费在太难的题上。所以 RLVR 的数据工作首先是挑题:挑”模型有时能做对、有时做不对”的题。DAPO 的”动态采样”、很多开放复现、OpenThoughts-Agent 的”只保留可解的任务”做的都是这件事。

代码 01 演示 2:按初始模型的通过率过滤(只留 5%–95% 之间的),同样 15 万次采样,测试准确率 0.376 vs 不过滤的 0.330。强化学习从初始模型的能力边界往外推——它只能从”有时能做对”的题里学。这也解释了为什么 R1-Zero 能从基础模型直接开始:DeepSeek-V3-Base 已经足够强,在大量题目上”有时能做对”。

2.4 数据问题二:验证器的漏洞

可验证的奖励比奖励模型可靠,前提是验证器真的在检查我们关心的东西。

代码 01 演示 3:模型有很小的概率”偷懒”(交一个格式正确的随便什么答案)。正确的验证器给偷懒 0 分,偷懒的倾向很快消失;如果验证器只检查格式:

2 万次采样6 万10 万15 万
有漏洞的验证器·奖励0.2490.3010.4260.938
有漏洞的验证器·真准确率0.2240.2540.2660.039
正确的验证器·真准确率0.2230.2500.2820.327

奖励一路涨到 0.938,真准确率跌到 0.039;而且前 6 万次采样时两者的差别还不大——等差别明显时,模型已经偏了。偷懒在难题上最划算(真的去解几乎全错,偷懒却总能拿分)。真实世界里的例子:只检查最后一行数字的数学验证器(等价的写法被判错、碰巧的格式被判对);测试太弱的代码题(模型修改测试、写针对测试用例的特判)——§5 会看到测试的强弱怎样改变”解决”的含义。


3. 开放复现的另一条路:蒸馏推理轨迹

3.1 两条路

Guha 的 slides 总结了开放复现推理模型的两种做法:

基于强化学习(像 DeepSeek)基于蒸馏
做法用强化学习训练,奖励是数学 / 代码的正确性用 o1 / R1 生成推理轨迹,微调小模型
学到什么模型通过强化学习自己学会推理模仿老师的推理
成本计算量大便宜得多、快得多
局限需要好的基础模型和验证器受限于老师的水平

蒸馏的 SFT 数据格式:<problem>题目</problem> <think>第 1 步……第 2 步……</think> <answer>答案</answer>。

3.2 Sky-T1 与 s1:便宜和少量

  • Sky-T1:训练成本约 450 美元。
  • s1(Muennighoff et al. 2025,Simple test-time scaling):从约 5.9 万道题里,按难度、多样性、质量三个标准精选出 1000 道题和它们的推理轨迹(s1K),微调 Qwen2.5-32B-Instruct。再加上”预算强制”(budget forcing)控制测试时的计算:想让模型停就强制结束思考;想让它多想,就在它要停的时候追加一个”Wait”。结果:s1-32B 在竞赛数学(MATH、AIME24)上超过 o1-preview 最多 27%;预算强制让 AIME24 从 50% 提到 57%。

1000 条就够——这和第 8 讲 LIMA 的”少而精”是同一个故事:推理能力的”种子”在预训练里,精选的少量轨迹负责把它激发出来、规定格式。

3.3 OpenThoughts:推理数据的配方

OpenThoughts(Guha 等,2025)的目标是建立开放的推理数据集,并系统地研究数据配方的每一个选择——1000 多次受控实验,每次只改变管线的一个部分:

  • (A) 问题来源:哪些现成的数据集最好?合成的还是真实的问题?
  • (B) 问题过滤:哪些过滤方法有用?领域怎样混合?
  • (C) 回答生成:用哪个老师?每道题生成几个答案?
  • (D) 答案过滤:要不要验证?过滤到什么程度?

主要发现(slides 的总结):

  1. 老师是第一重要的因素——而且更好的模型不一定是更好的老师:QwQ-32B 在基准上不如 DeepSeek-R1,在数学和科学上却是更好的老师(代码上 R1 更好)。
  2. 问题来源是第二重要的:真实的竞赛题、StackExchange 上的题好于随机合成的题(slides 的表格:数学里合成随机题 28.3、MATH 训练集 33.5、AMC/AIME 36.2、OpenMath-2 38.1)。问题过滤上,按 GPT-4.1-mini 回答的长度挑问题(长回答 ≈ 难题)对数学最有效。
  3. 轻度过滤:不要过度过滤——答案过滤(包括 GPT 验证、多数投票、按长度)往往不如不过滤(slides 的表格:不过滤 41.9、GPT 验证 38.0、多数投票 39.2、按长度 40.1)。可能的原因:验证器会错;过滤降低多样性;一些”错”的轨迹也能帮助学习。
  4. 每题多个答案:slides 的表格显示 4 个答案之后收益明显变小;论文把”每题采样多个答案”当作扩大数据的主要手段之一。
  5. 领域混合:平衡代码、数学、科学,泛化更稳。

规模上,数据集越大越好、曲线还没有到顶:最终的 OpenThoughts3 扩展到 120 万条,用 QwQ-32B 当老师;训练出的 OpenThoughts3-7B 在 AIME 2025 上 53%、LiveCodeBench 51%、GPQA Diamond 54%,比 DeepSeek-R1-Distill-Qwen-7B 分别高 15.3、17.2、20.5 个百分点。更早的 OpenThoughts2-1M 训练出的 OpenThinker2-32B 是第一个用公开推理数据追平 R1-Distill-32B 的模型。

3.4 在推理世界里

代码 02 演示 1:老师的选择(1000 道 4–12 步的题,每题一条轨迹):

老师老师自己的准确率学生的准确率学生视野
(学生,蒸馏之前)0.2224.00
A:最强,但推理写得简略(只写 40% 的步骤)0.8250.4685.17
A:最强,推理写得完整0.8250.7188.45
B:稍弱,推理写得完整0.6070.5588.45
C:更弱,推理写得完整0.4080.3828.45

最强的老师写得简略时,教出的学生不如稍弱、但每一步都写出来的老师。学生只能从写出来的步骤里学;被跳过的步骤、被压短的推理链,什么也教不了。这是”更好的模型不一定是更好的老师”的一种可能的机制(真实的原因还不完全清楚)。

代码 02 演示 2:每题几个答案;要不要验证:

每题几个答案(250 道题)124816
学生准确率0.3890.5010.5490.5620.563
答案过滤(1000 道 × 4 个答案)留下的轨迹学生准确率留下的题的平均步数
不过滤40000.5407.92
用标准答案:只留答对的20450.8277.43
LLM 评委(85% 认出对的,30% 放过错的)22790.6597.64
多数投票:留和多数一致的17950.8137.24

每题多几个答案有用,4 个之后收益递减——和 slides 一致。但答案过滤的结论和 OpenThoughts 相反:在这个世界里,用标准答案过滤大幅提升了学生。原因值得想清楚:我们的验证是完美的,而且”答案对”和”每一步都对”高度相关,所以过滤留下的轨迹每一步都是对的。OpenThoughts 的设定里,很多问题没有可靠的标准答案,验证器会错;过滤会删掉难题(看最后一列:留下的题变短了)、降低多样性;而答错的轨迹里大部分推理仍然有用。过滤是否有用,取决于验证器有多可靠、过滤会偏向哪些题。

代码 02 演示 3:问题从哪里来;s1 式的精选:

问题来源(各 1000 道)简单(1–3 步)中等(3–6 步)难(6–12 步)混合
学生准确率0.3360.4640.6560.626
从 2 万道题里怎样挑轨迹条数学生准确率
随机挑 1000 道10000.626
挑 1000 道难题10000.665
s1 式:难 + 老师答对 + 运算多样10000.866
全部 2 万道200000.647
全部 2 万道里老师答对的144820.840

难题教得更多(简单题的推理链短,学生的视野拉不长);s1 式精选的 1000 道好于全部 2 万道,甚至略好于 1.4 万多条”老师答对的”。在这个世界里,学习很快就饱和了,所以”挑得好”比”挑得多”重要;OpenThoughts 在真实规模上的结论是”数据越多越好、曲线还没到顶”。两者不矛盾:每一条都值得精挑,精挑的数据还可以继续扩大。


4. 开放的推理模型配方

4.1 Llama-Nemotron(NVIDIA)

一组开放的推理模型:Nano(8B)、Super(49B)、Ultra(253B)。训练流程:在 Llama 3 模型上做神经架构搜索(为了推理速度)、知识蒸馏、继续预训练,然后是以推理为重点的后训练:监督微调加大规模强化学习。它是第一批支持动态推理开关的开源模型——用户可以在推理时切换”普通聊天”和”推理”两种模式(这要求训练数据里两种模式都有、并且有明确的切换信号)。公开了完整的后训练数据集(Llama-Nemotron-Post-Training-Dataset)和训练代码。

4.2 OLMo 3(Allen AI)

7B 和 32B 两个尺寸,公开了”完整的模型流程”:每一个阶段、每一个检查点、每一条数据、每一个依赖。旗舰的 Olmo 3 Think 32B 被作者描述为”迄今最强的完全开放的思考模型”。Schmidt 第 7 讲的综述提到了它在数据上的几个特点:中期训练里约 7% 是推理轨迹(来自 QwQ、Gemini、Llama);CraneMath 合成数学改写(MATH +18.5);用 100 亿 token 的”微退火”实验在正式训练前快速评估数据。推理能力的培养从预训练的后期就开始了。

4.3 Tulu 3 的 RLVR(回顾)

第 8 讲:Tulu 3 在 GSM8K、MATH、IFEval 的约束上做 RLVR,答对给奖励——同样的思路,在更简单的任务上。


5. 智能体:环境即数据

5.1 为什么需要智能体

推理模型能解题,但不能行动(Guha 的 slides):不能用工具、不能和环境交互、不能调试和测试代码;真实的软件任务需要很多步。智能体 = 推理 + 行动 + 环境。 要解决的挑战:

  • 数据稀缺:现成的智能体轨迹很少;
  • 计算成本:在环境里做强化学习很贵;
  • 验证:怎样知道智能体成功了?

5.2 基准:SWE-Bench 与 Terminal Bench

SWE-Bench(Jimenez et al. 2023):在真实仓库里解决真实的 GitHub issue。2,294 个任务,来自 12 个流行的 Python 仓库;每个任务是”一个 issue → 一个代码补丁”,用仓库的测试验证。SWE-Bench Verified 是人工验证过的 500 个任务的子集。进展非常快:slides 的时间线显示,Verified 上的最好成绩从 2024 年春的个位数百分比,到 2025 年初超过 50%(“9 个月从 4.5% 到 52%“——这些具体的数字是 slides 给的,我没有逐一核对)。

Terminal Bench:终端里的智能体任务——调试和修代码、操作文件、系统管理、构建和测试流程。很难。

5.3 训练环境:SWE-Gym

SWE-Gym(Pan et al. 2024):2,438 个真实的 Python 任务,每个任务有一个可执行的运行环境(Docker 沙箱)、单元测试和自然语言的任务描述;平均轨迹 12 轮。用它的轨迹微调智能体,在 SWE-Bench Verified 和 Lite 上绝对提高最多 19 个百分点;再用在 SWE-Gym 轨迹上训练的验证器做推理时扩展(生成多个候选、让验证器挑),达到 32.0% 和 26.0%,当时开源权重 SWE 智能体中最好。SWE-smith、R2E-Gym 是类似的数据集。

5.4 SWE-smith:自动合成任务

SWE-smith 的报告从一个问题开始:现有的努力要么依赖 SWE-bench 式的收集(费力),要么不包含交互和执行(不扎根)。SWE-bench 的收集方式麻烦在哪?

  • 每个仓库、每个时间点都要配好安装和测试——要人力;
  • 每个任务一个环境——要大量存储(摘要:几 TB);
  • 只能来自真实的 PR——数量有限。

SWE-smith(Yang et al. 2025)是一个工具包,支持三个工作流:(1) 把一个 GitHub 仓库变成执行环境;(2) 在执行环境里合成几百到几千个任务实例——修改代码,让已有的测试失败;(3) 用这些环境和任务训练软件工程智能体。合成 bug 的方法包括让 LLM 改写函数、程序性的修改(基于语法树)、把几个 bug 组合起来、把真实的 PR 反向应用。结果:来自 128 个仓库的 5 万个任务,比之前的工作大一个数量级。

训练:拒绝采样微调——让强模型(Claude 3.5 / 3.7、GPT-4o)当”专家”在合成任务上运行 SWE-agent,只保留解决了的轨迹,用来微调 Qwen 2.5 Coder Instruct。SWE-agent-LM-32B 在 SWE-bench Verified 上 Pass@1 40.2%,开源模型中最好。报告最后提到了后续工作:6 万个任务、9 种编程语言、新的 bug 和 issue 生成方法、强化学习。

5.5 迷你 SWE-smith(代码 03)

演示 1:在 8 个函数上用语法树做所有单点修改(< ↔ <=、+ ↔ -、/ ↔ //、常数加减 1、and ↔ or、.lower() ↔ .upper()、去掉 sorted(...) ……),让至少一个测试失败的修改才算一个有效的任务:

候选修改强测试下有效弱测试下有效强测试也发现不了
合计(8 个函数)5953276
  • 一个小仓库就造出了几十个任务;
  • 弱测试下约一半的 bug”看不见”——例如把 median 里的 / 换成 //,弱测试(只测奇数长度的列表)全部通过,强测试在偶数长度的列表上失败;
  • 6 个修改连强测试也发现不了:有的是等价修改(clamp 里 < 换成 <=:xx 恰好等于边界时,返回边界和返回 xx 是同一个值),有的是测试没覆盖到的行为。SWE-smith 只保留让测试失败的修改,这类自动被丢掉。

演示 2:一个最简单的”修 bug 智能体”——知道哪个函数出错,随机尝试单点修改,每改一次跑一遍验证测试,通过了就宣布修好:

验证器宣布修好了真的修好了平均尝试次数“成功轨迹”里其实没修好的
弱测试(8 个用例)0.9810.3401.60.654
强测试(36 个用例)0.7740.7745.70.000

用弱测试当验证器,宣布的成功里 65% 是假的:很多任务在弱测试下一开始就”通过”,智能体什么都不改就交差;还有些”补丁”恰好让弱测试通过,却破坏了别的行为。拒绝采样微调用验证器挑选”成功”的轨迹——测试弱,训练数据里就混进了”假装修好”的轨迹,模型学到的是让测试通过,而不是修好 bug。 这和 §2.4 的验证器漏洞是同一个问题,换了一个场景。

5.6 OpenThoughts-Agent

Guha 的 slides 最后介绍了 OpenThoughts-Agent,两种训练方式:

  • SFT:数据来源 NL2Bash(3,200 个 shell 任务)和 InferredBugs(2,000 个 GitHub issue);让 GLM-4.6 在 Terminus-2 沙箱里解这些任务,收集成功的轨迹(共 5,200 条),微调基础模型——8B 模型在 TerminalBench2 上从 0% 到 4%。
  • 强化学习,用合成的验证器:2,500 个 NL2Bash 任务(自然语言描述),让 GPT-5-nano 写验证器的代码,过滤后保留 1,800 个可解的任务,用 GRPO(每个任务 8 次 rollout)训练。“合成的验证器是有效的——强化学习不需要人工标签。”

slides 的结果表:OpenThinker-Agent-V1 在 SWE-Bench Verified 上 15.7、TerminalBench-2 上 4.9,而同尺寸的 Qwen3-8B 是 0.7 和 0.0。以及 Endless Terminals:可扩展的强化学习环境。

注意”保留 1,800 个可解的任务”——这正是 §2.3 的”题目要落在能力边界上”;而”让模型写验证器”带来的,正是 §2.4 和 §5.5 的风险:验证器本身也需要被验证。

5.7 Guha 的总结

  1. 数据的整理和过滤极其重要;
  2. 测试时计算:扩展能力的新维度;
  3. 关于数据的好的科学研究真的能改进模型;
  4. 还有巨大的改进空间。

6. 一个统一的视角(补充)

推理和智能体的后训练数据,和聊天时代相比,形式变了:

聊天(第 8 讲)推理 / 智能体(本讲)
数据是什么(提示, 回答)、(提示, 好回答, 差回答)(问题, 验证器)、(仓库, 任务, 测试, 执行环境)
信号从哪来人或 AI 的判断可执行的检查(答案比对、单元测试)
主要风险评委的偏差、奖励模型被钻空子验证器的漏洞、测试太弱
数据的”质量”回答好不好题目难度是否合适、验证器是否可靠、环境是否可复现
怎样扩展更多的人工 / AI 标注合成问题、合成任务(SWE-smith)、合成验证器(OpenThoughts-Agent)

环境即数据:在 RLVR 和智能体训练里,“一条数据”不再是一段文字,而是一个可以反复交互、自动打分的环境。它的质量由三件事决定:难度(在不在模型的能力边界上)、验证(检查的是不是我们真正关心的东西)、多样性(覆盖多少种问题和技能)。前两件是这一讲的代码演示的主题;第三件和第 7–8 讲的结论一致。


7. 延伸与前沿 · Beyond the original lecture

本节是我补充的。

  • 课程式学习和自适应题库。代码 01 的过滤只做了一次;模型变强之后,题目会变得太简单。按当前模型的通过率不断更新题库(甚至让模型自己出题)是一个活跃的方向。
  • 过程奖励 vs 结果奖励。RLVR 只看最后的答案;过程奖励模型给每一步打分。R1 的经验是结果奖励就够了、过程奖励容易被钻空子;但在答案难以验证的任务上,如何给奖励仍是开放问题。
  • 验证器的质量。SWE-smith 依赖已有的测试;测试的覆盖率决定了任务和奖励的质量。“变异测试”(代码 03 演示 1 的反面:用注入的 bug 衡量测试有多强)可以用来评估和改进验证器。
  • 推理数据的污染。推理基准(AIME、GPQA)的题目量小,很容易泄漏到蒸馏数据和强化学习题库里;第 14 讲会讨论。

8. 小结 · Summary

  1. 推理模型:聊天机器人在竞赛数学、编程、博士水平科学题上碰到天花板;o1 显示训练时和测试时的计算都能扩展推理能力,代价是 10–100 倍的 token。
  2. R1:R1-Zero 只用可验证奖励的强化学习(GRPO)就激发出了长推理;R1 加上冷启动、拒绝采样(约 80 万条 SFT 数据)、多阶段强化学习;蒸馏到小模型比在小模型上做强化学习更有效。
  3. RLVR 的数据:题目要落在模型的能力边界上(全对或全错的组没有信号,难度均匀的题库约一半的采样白费);验证器的漏洞会被钻空子(奖励涨、真准确率跌)。
  4. 蒸馏推理轨迹:s1 的 1000 条精选(难度、多样性、质量);OpenThoughts 的上千次消融——老师第一、问题来源第二、轻度过滤、每题多个答案、领域平衡;更好的模型不一定是更好的老师;OpenThoughts3 扩展到 120 万条。
  5. 开放的推理模型:Llama-Nemotron(推理开关、公开的后训练数据)、OLMo 3(完整的模型流程)。
  6. 智能体:环境即数据。SWE-Bench / SWE-Gym 的真实任务;SWE-smith 从 128 个仓库合成 5 万个任务,拒绝采样微调出 40.2% 的开源模型;测试的强弱决定了能造出什么任务、“成功”是否真的成功。

9. 常见误区 · Common pitfalls

  1. “题库越大、越难越好。” 太难的题采样再多也没有信号(代码 01 演示 1);要按模型的能力挑题。
  2. “可验证的奖励不会被钻空子。” 验证器有漏洞时一样会(代码 01 演示 3、代码 03 演示 2)。
  3. “最强的模型就是最好的老师。” 老师写出了什么、写得多完整,也很重要(代码 02 演示 1;OpenThoughts 的 QwQ vs R1)。
  4. “只保留答对的轨迹总是更好。” 取决于验证器的可靠性和过滤带来的偏向;OpenThoughts 发现轻度过滤往往更好(代码 02 演示 2 的讨论)。
  5. “推理数据要很多。” s1 用 1000 条就有很大效果;但 OpenThoughts 也显示数据越多越好——质量和数量都重要。
  6. “测试通过 = bug 修好了。” 弱测试下,宣布的成功大多是假的(代码 03 演示 2)。
  7. “合成任务不如真实任务。” SWE-smith 的合成任务让开源模型达到当时最好的成绩;关键是合成过程要用真实的仓库和真实的测试来约束。
  8. “测试时计算可以替代训练数据。” 模型要先通过训练学会”有效地思考更久”,测试时的计算才有用(s1 的预算强制建立在 1000 条推理轨迹的微调之上)。

10. 练习 · Exercises

练习 1(GRPO 的有效题目) 一道题的通过率是 aa,每组采样 GG 个回答。(a) 写出这组”没有信号”(全对或全错)的概率。(b) G=8G = 8 时,a=0.05a = 0.05、0.50.5、0.950.95 的题各有多大概率没有信号?(c) 要让 a=0.05a = 0.05 的难题至少一半的时候有信号,GG 至少要多大?这说明了什么?

参考答案

(a) aG+(1−a)Ga^G + (1-a)^G。

(b) a=0.05a = 0.05:0.058+0.958≈0.6630.05^8 + 0.95^8 \approx 0.663;a=0.5a = 0.5:2×0.58≈0.0082 \times 0.5^8 \approx 0.008;a=0.95a = 0.95:同样约 0.663。

(c) 需要 1−0.95G≥0.51 - 0.95^G \ge 0.5(全对的概率可以忽略),G≥ln⁡0.5/ln⁡0.95≈13.5G \ge \ln 0.5 / \ln 0.95 \approx 13.5,即至少 14 个。难题要更大的组(更多的采样)才能偶尔碰到一次成功——成本高。所以要么过滤掉太难的题,要么先用别的方法(例如蒸馏)把模型的能力边界推过去,再在这些题上做强化学习。

练习 2(老师要写多完整) 代码 02 演示 1 里,最强的老师 A 只写 40% 的步骤时(0.468)不如完整的老师 B(0.558)。A 至少要写出多少比例的步骤,才能教得比 B 好?先估计,再看在代码副本里运行的结果。

参考答案(实际运行结果)

A 写出的步骤比例 → 学生准确率:40% → 0.468,50% → 0.523,60% → 0.571,70% → 0.613,80% → 0.647,100% → 0.715(这里所有比例用同一个随机种子,所以 100% 时和演示 1 的 0.718 略有不同)。大约写出 55% 以上的步骤,A 就教得比 B 好。在这个世界里,“写得完整”影响两件事:学生能看到多少步运算(学运算的能力),以及看到的推理链有多长(学视野)——后者影响更大:A 写 40% 时,学生的视野只到 5.17,B 能把它拉到 8.45。

练习 3(数学验证器的漏洞) 一个数学题的验证器把模型输出的最后一个数和标准答案做字符串比较。(a) 举出至少三种”答案对、却被判错”或”答案错、却被判对”的情况。(b) 这些漏洞在 RLVR 里会让模型学到什么?(c) 怎样改进?

参考答案

(a) 判错:等价的写法(1/2 vs 0.5、√2/2 vs 1/√2、“x = 3” vs “3”);单位或格式(“30%” vs “0.3”);最后一个数不是答案(模型在答案之后又写了一句”检查:2 + 2 = 4”)。判对:模型输出一串候选数字、最后一个碰巧对;标准答案本身错了。

(b) 模型会学到验证器认的格式(而不是正确的数学);会学到”把所有可能的答案都写一遍”;会回避等价但格式不同的表达;在标准答案错误的题上被惩罚正确的推理。

(c) 用符号计算(例如把表达式化简后比较)或数值比较;要求固定的答案格式(例如 \boxed{})并检查格式;对验证器做”对抗测试”(把等价写法、常见错误都喂进去看它怎么判);用多个验证器交叉检查;定期人工抽查高奖励的回答。

练习 4(测试有多强) 代码 03 演示 1 里,59 个候选修改中强测试发现了 53 个、弱测试只发现了 27 个。(a) 这个”被发现的修改的比例”叫作测试的变异分数(mutation score)。两套测试的变异分数各是多少?(b) 如果你只能用弱测试做 SWE-smith 式的数据,你会怎样减少”假装修好”的轨迹?(c) 为什么说”验证器本身也要被验证”?

参考答案

(a) 强测试 53/59 ≈ 0.90;弱测试 27/59 ≈ 0.46。(等价的修改无论多强的测试都发现不了,所以 1.0 通常达不到。)

(b) 例如:只用弱测试能发现的 bug 造任务(演示 1 里的 27 个),这样至少”一开始就通过”的假任务没有了;生成额外的测试(让 LLM 根据函数的文档写测试,再用原始代码检查这些测试是对的);保留一部分”隐藏的”测试只用来最终判断、不给智能体看;检查补丁是否真的改动了 bug 所在的位置、是否和注入的 bug 互为逆操作。

(c) 在 RLVR 和拒绝采样里,验证器就是”标签”:它的漏洞会被优化放大(代码 01 演示 3、代码 03 演示 2)。OpenThoughts-Agent 让 GPT-5-nano 写验证器,也必须过滤掉”不可解”或有问题的任务。变异测试是衡量验证器强弱的一种直接方法。

练习 5(讨论:s1 vs OpenThoughts) s1 说”1000 条精选就够了”,OpenThoughts 说”数据越多越好,到 120 万条还没到顶”。这两个结论矛盾吗?如果你有 10 万美元的预算来做一个数学推理模型的数据,你会怎样分配?

参考答案(要点)

不矛盾:s1 衡量的是”用很少的数据能走多远”(以及预算强制这类测试时方法),基础模型是很强的 Qwen2.5-32B-Instruct;OpenThoughts 衡量的是”在同一个配方下,规模扩大时会怎样”,目标是 7B 这样的较小模型、要追上更强的蒸馏模型。小数据的上限受基础模型的能力限制;大数据能把更多的能力”教”进去。代码 02 演示 3 的世界里学习很快饱和,所以只看到了 s1 的一面。

预算分配的思路:先用小规模实验(几千条)比较老师和问题来源(OpenThoughts 的发现:这两个因素最重要);选定配方后,把大部分预算花在扩大”好问题 × 每题多个答案”上;轻度过滤(去掉明显坏的、格式错的);留一部分预算做强化学习(在模型能力边界上的题)和评测(独立的、没被污染的题)。


11. 延伸阅读 · Further reading

原课阅读

  • DeepSeek-AI, DeepSeek-R1: Incentivizing Reasoning Capability in LLMs via Reinforcement Learning(2025):arXiv:2501.12948。
  • Muennighoff et al., s1: Simple test-time scaling(2025):arXiv:2501.19393。
  • Guha et al., OpenThoughts: Data Recipes for Reasoning Models(2025):arXiv:2506.04178。
  • Pan et al., Training Software Engineering Agents and Verifiers with SWE-Gym(2024):arXiv:2412.21139。
  • Bercovich et al., Llama-Nemotron: Efficient Reasoning Models(2025):arXiv:2505.00949。
  • OLMo 3(2025):arXiv:2512.13961。
  • Yang et al., SWE-smith: Scaling Data for Software Engineering Agents(2025):arXiv:2504.21798;swesmith.com。

本讲补充

  • Jimenez et al., SWE-bench: Can Language Models Resolve Real-World GitHub Issues?(2023)。
  • Shao et al., DeepSeekMath(2024)——GRPO 的提出。
  • Yu et al., DAPO: An Open-Source LLM Reinforcement Learning System at Scale(2025)——动态采样等。

和本目录其他课程的联系


12. 下一讲预告 · Next lecture

第 6–9 讲讨论了”每一种数据怎样做好”:网页、代码、指令、偏好、推理轨迹、智能体环境。但最终训练一个模型时,这些数据要混在一起——网页占多少、代码占多少、数学占多少?Llama 3 的”通用 50%、数学 25%、代码 17%、多语言 8%“是怎么定出来的?

第 10 讲:数据混合。 客座讲者 Mayee Chen:数据配比为什么重要、怎样在小规模上搜索配比再推到大规模(DoReMi、RegMix、数据混合的扩展律)、OLMix 这样的框架怎样在模型开发的全过程里管理配比。代码会在一个多来源的合成世界里搜索最优配比,看看小规模上找到的配比能不能推到大规模。

← 返回课程目录