[斯坦福CS336]作业五:对齐与推理强化学习
1 作业概述
本次作业中,你将获得训练语言模型解决数学问题时进行推理的实践经验。
需实现的内容
- 针对 Hendrycks 等人 [2021] 提出的竞赛数学问题数据集 MATH,实现零样本提示基线模型。
- 利用更强推理模型(DeepSeek R1,DeepSeekAI 等人,2025)的推理轨迹进行有监督微调(SFT)。
- 采用专家迭代(Expert Iteration)方法,通过验证奖励提升推理性能。
- 采用组相对策略优化(GRPO)方法,通过验证奖励提升推理性能。
对于感兴趣的同学,我们将在未来几天发布可选作业部分:使语言模型与人类偏好对齐。
需运行的内容
- 评估 Qwen 2.5 Math 1.5B 模型的零样本提示性能(作为基线)。
- 利用 R1 的推理轨迹对 Qwen 2.5 Math 1.5B 进行有监督微调(SFT)。
- 利用验证奖励对 Qwen 2.5 Math 1.5B 进行专家迭代训练。
- 利用验证奖励对 Qwen 2.5 Math 1.5B 进行 GRPO 训练。
作业地址: Assignment5-alignment GitHub仓库
接下来我将分享完成作业的一部分细节和心得。
2 语言模型的推理能力
2.1 动机
语言模型的显著应用场景之一是构建能处理多种自然语言处理任务的通用系统。本次作业将聚焦语言模型的一个新兴应用场景:数学推理。我们将以此为测试平台,搭建评估体系、执行有监督微调,并探索利用强化学习(RL)训练语言模型进行推理的方法。
本次作业与以往作业有两处不同:
- 不再使用之前作业中的语言模型代码库和模型。理想情况下,我们希望使用之前作业中训练的基础语言模型,但微调这些模型无法获得令人满意的结果 —— 它们的能力太弱,无法展现复杂的数学推理能力。因此,我们将切换到一个可访问的现代高性能语言模型(Qwen 2.5 Math 1.5B Base),并在此基础上开展大部分工作。
- 引入新的基准数据集评估语言模型。此前,我们认为交叉熵可作为许多下游任务的良好替代指标。但本次作业的核心是缩小基础模型与下游任务之间的差距,因此必须使用独立于交叉熵的评估方法。我们将采用 Hendrycks 等人 [2021] 提出的 MATH 12K 数据集,该数据集包含具有挑战性的高中竞赛数学问题。我们将通过对比模型输出与参考答案来评估语言模型的性能。
2.2 思维链推理与推理强化学习
语言模型领域近期的一个热门趋势是利用思维链(Chain-of-Thought)推理提升各类任务的性能。思维链指的是逐步推理问题的过程,在得出最终答案前生成中间推理步骤。
语言模型的思维链推理
早期的思维链方法通过 “草稿本”(scratchpad)将问题分解为中间步骤,微调语言模型解决算术等简单数学任务 [Nye 等人,2021]。其他研究则通过提示强模型在回答前 “逐步思考”,发现这能显著提升其在小学算术题等数学推理任务上的性能 [Wei 等人,2023]。
基于专家迭代的推理学习
自训练推理器(STaR)[Zelikman 等人,2022] 将推理构建为一个自举循环:预训练模型首先生成多样化的思维链(CoT),仅保留能得出正确答案的思维链,然后利用这些 “专家” 轨迹进行微调。重复该循环可提升语言模型的推理能力和解题率。STaR 证明,这种基于专家迭代 [Anthony 等人,2017] 的方法,通过对生成答案进行自动字符串匹配验证,无需人工编写推理轨迹即可自举推理能力。
基于验证奖励的推理强化学习(o1、R1)
近期研究探索了使用更强大的强化学习算法结合验证奖励来提升推理性能。OpenAI 的 o1(及后续的 o3/o4)[OpenAI 等人,2024]、DeepSeek 的 R1 [DeepSeek-AI 等人,2025] 以及 Moonshot 的 kimi k1.5 [Team 等人,2025] 均采用策略梯度方法 [Sutton 等人,1999] 在数学和代码任务上进行训练,通过字符串匹配或单元测试验证答案正确性,在竞赛数学和编程任务上取得了显著性能提升。后续研究如 Open-R1 [Face,2025]、SimpleRL-Zoo [Zeng 等人,2025] 和 TinyZero [Pan 等人,2025] 证实,即使在参数规模仅为 1.5B 的模型上,基于验证奖励的纯强化学习也能提升推理性能。
实验设置:模型与数据集
在后续章节中,我们将逐步采用更复杂的方法训练基础语言模型,使其能通过逐步推理解决数学问题。本次作业将使用 Qwen 2.5 Math 1.5B Base 模型,该模型基于 Qwen 2.5 1.5B 模型,在高质量合成数学预训练数据上进行了持续预训练 [Yang 等人,2024]。MATH 数据集可在 Together 集群的 /data/a5-alignment/MATH 路径下获取。
开源替代数据集(面向开源审计者)
由于版权限制,MATH 数据集未公开。若你在本地完成作业,可使用以下开源数学推理数据集:
- Countdown [Pan 等人,2025]:基于英国电视节目《Countdown》的简单合成任务,是小规模推理强化学习的常用测试平台,获取链接:[此处]。
- GSM8K [Cobbe 等人,2021a]:小学算术题数据集,难度低于 MATH,适合调试代码正确性并熟悉推理强化学习流程,获取链接:[此处]。
- Tulu 3 SFT Math [Lambert 等人,2025]:使用 GPT-4o 和 Claude 3.5 Sonnet 生成的合成数学问题,由于是合成数据,部分答案(甚至问题)可能存在错误,获取链接:[此处]。
- 其他数学 SFT 数据集:[此处链接]。
若数据集中未直接提供简短真实标签(如 1/2),可使用 Math-Verify 等数学答案解析器处理真实标签列。
3 评估零样本 MATH 性能
我们首先评估基础语言模型在 MATH 数据集的 5K 测试集上的性能。建立该基线有助于理解后续每种方法对模型行为的影响。
作业题(数学基线性能):4 分
(a) 编写脚本评估 Qwen 2.5 Math 1.5B 模型在 MATH 数据集上的零样本性能
该脚本需要完成以下任务:
- 从
/data/a5-alignment/MATH/validation.jsonl加载 MATH 验证集样本; - 使用
r1_zero提示词将这些样本格式化为语言模型可接收的字符串提示词; - 为每个样本生成模型输出;
- 计算评估指标;
- 将样本、模型生成结果以及对应的评估分数序列化保存到磁盘,以便后续作业题进行分析。
在实现过程中,编写一个如下所示的 evaluate_vllm 方法会很有帮助,后续你可以复用该方法:
def evaluate_vllm(
vllm_model: LLM,
reward_fn: Callable[[str, str], dict[str, float]],
prompts: List[str],
eval_sampling_params: SamplingParams
) -> None:
"""
针对一组提示词评估语言模型性能,
计算评估指标,并将结果序列化保存到磁盘。
"""提交要求:一份用于评估零样本 MATH 数据集基线性能的脚本。
See at [eval.py][https://github.com/Kosthi/assignment5-alignment/blob/main/eval.py]
(b) 在 Qwen 2.5 Math 1.5B 模型上运行你的评估脚本
统计模型生成结果分别落入以下三类的数量:
- 格式奖励和答案奖励均为 1(完全正确);
- 格式奖励为 1、答案奖励为 0(格式正确,答案错误);
- 格式奖励和答案奖励均为 0(格式和答案均错误)。
观察至少 10 个格式奖励为 0 的案例,你认为问题出在基础模型的输出上,还是出在解析器上?为什么?再观察至少 10 个格式奖励为 1 但答案奖励为 0 的案例,你有什么看法?
提交要求:关于模型和奖励函数性能的分析说明,包含各类案例的示例。
1. 数量统计
根据日志开头的汇总信息(num_examples=5000)及各类计数,模型生成结果分布如下:
- 格式奖励和答案奖励均为 1(完全正确):
count(fmt=1,ans=1)=139例。 - 格式奖励为 1、答案奖励为 0(格式正确,答案错误):
count(fmt=1,ans=0)=693例。 - 格式奖励和答案奖励均为 0(格式和答案均错误):
count(fmt=0,ans=0)=4168例。
2. 对“格式奖励为 0”案例的观察
在日志提供的至少10个此类案例中(标记为 sample_fmt0_ans0_examples=10),问题主要出在基础模型的输出上,而非解析器。
主要原因:这些失败案例的共同点是模型没有遵循指定的输出格式。根据日志,正确的格式应包含清晰的 <think> 推理过程和用 <answer> 标签包裹的最终答案。然而,问题模型输出经常出现:
- 格式结构混乱:例如在回答 “What is the positive difference between $120%$ of 30 and $130%$ of 20?” 时,模型在
<think>标签内直接给出了答案,并且混入了<end think> <answer>等未定义的标签,导致解析失败。 - 输出无关内容与符号:例如在回答函数逆问题 “Let $f(x)=7x+5$…” 时,模型的
<think>内容包含大量无关代码片段、乱码字符(如 “</<br>下一格*/{ */”),甚至插入图片链接,完全偏离了数学推理。 - 推理与答案未分离:模型经常在思考部分就写下“答案是…”,或者最终答案没有用要求的标签包裹。
这些现象表明,基础模型在遵循严格的结构化输出指令上存在困难,未能生成可供解析器正确处理的文本。
3. 对“格式奖励为 1 但答案奖励为 0”案例的观察
在日志随后提供的至少10个此类案例中(标记为 sample_fmt1_ans0_examples=10),模型成功遵循了格式要求,但答案本身是错误的。
主要看法:这揭示了模型的核心能力局限。在格式正确的情况下,错误类型包括:
- 数学计算错误:例如计算
$i^5+i^{-25}+i^{45}$时,模型得出$2i$,但正确答案应为$i$。 - 逻辑推理错误:例如在求满足不等式
$|x|+1>7$和$|x+1|\le7$的整数和时,模型正确列出了计算步骤,但错误地将-6包含在内,得到和-21,正确答案应为-15。 - 最终答案表述不精确:例如问垂直线条数量,模型在
<answer>中正确给出了导致分母为零的值 “-3$ and $2$”,却没有将其转化为最终答案“2条”。
这表明,模型在一定程度上学会了“模仿”解题的格式和框架,但其数学推理、计算准确性和对问题最终要求的理解仍然不足。
(c) Qwen 2.5 Math 1.5B 模型在 MATH 数据集上的零样本基线性能表现如何?
提交要求:用 1-2 句话概括评估指标结果。
根据评估日志中的指标(mean_reward=0.0278,且完全正确的比例仅为139/5000≈2.78%),该模型在MATH数据集上的零样本基线性能非常弱,其生成结果在格式和答案上的整体正确率极低,尚不具备可靠解决复杂数学问题的能力。
4 用于MATH的有监督微调
问题(sft_experiment):在MATH数据集上运行SFT(2分)(2个H100小时)
1. 使用Qwen 2.5 Math 1.5B基础模型,在推理SFT示例(在/data/a5-alignment/MATH/sft.jsonl中提供)上运行SFT,改变SFT中唯一示例的数量,范围为{128, 256, 512, 1024},以及使用完整数据集。调整学习率和批次大小,以在使用完整数据集时至少达到15%的验证准确率。
提交内容: 与不同数据集大小相关的验证准确率曲线。
少量sft的样本反而比大量的更好, 熵也下降的更快更低, 样本多了模型反而 confuse。

2. 过滤推理SFT示例,仅包括产生正确答案的示例。在(完整)过滤数据集上运行SFT,并报告过滤数据集的大小和你达到的验证准确率。
提交内容: 报告数据集的大小和你达到的验证准确率曲线。将你的发现与之前的SFT实验进行比较。
实验暂定
5 用于MATH的专家迭代
问题(expert_iteration_experiment):在MATH数据集上运行专家迭代(2分)(6个H100小时)
在MATH数据集(在/data/a5-alignment/MATH/train.jsonl中提供)上使用Qwen 2.5 Math 1.5B Base模型运行专家迭代,改变每个问题的rollout数量G和SFT步骤中使用的轮数,并使用n_ei_steps = 5。改变每个专家迭代步骤的批次大小(即Db的大小)在{512, 1024, 2048}中。(你不需要尝试这些超参数的所有可能组合。只要足够得出关于每个的结论即可。)记录训练过程中模型响应的熵。确保vLLM在第二个答案标签处终止生成,如SFT部分所做的那样。
提交内容:
- 与不同rollout配置相关的验证准确率曲线。至少尝试2种不同的rollout计数和轮数计数。
- 一个在MATH上达到至少15%验证准确率的模型。
- 一个简短的2句讨论,将你的性能与SFT性能进行比较,以及在EI步骤之间的性能比较。
- 一个显示训练过程中模型响应熵的图表。
实验暂定