用途
open-r1-reprod 是 open-r1 的复现项目,目标是对 0.5B、1.5B、3B、7B 的 Qwen 模型进行 GRPO 训练,在 MATH-lighteval 数学数据集上观察和分析不同尺寸模型的推理能力、规则奖励的各种 hack、多语言混合推理等现象。项目并不算成功,但也有一些有趣的发现,欢迎交流讨论。
主要能力
项目使用 open-r1 项目的代码,修改配置文件 config_grpo.yaml 进行训练。训练细节可查看 config_grpo.yaml。
在模型评估阶段,设置 2 种模式的 system,用来测试不同 system 的区别,默认使用 system2。设置 system_prompt,使模型能够遵守 <think>\n...\n</think>\n<answer>\n...\n</answer> 的格式。
基于规则的奖励函数包括准确率奖励(accuracy_reward)和格式奖励(format_reward、tag_count_reward),总奖励是三者之和。其中 tag_count_reward 是因为完整格式太难,模型可能很难遵守,因此对于出现部分格式的回答,通过 tag_count_reward 给予部分奖励。
学习率使用 cosine,最大值为 3.0e-06。
观察到的现象
观察奖励曲线,0.5B 的模型在 accuracy_reward 和 format_reward 中几乎没有变化,只有在 tag_count_reward 中有一定提升,达到 50%。这说明太小的模型无法通过 GRPO 提升回答的准确率,也无法很好地遵守格式。
1.5B 的模型在 accuracy_reward 中有一定的提升,达到 40%,在 format_reward 和 tag_count_reward 中达到接近 100%。对于 3B 和 7B 的模型,也有类似的曲线,区别在于 accuracy_reward 提升幅度不同,说明 GRPO 在 1.5B 的模型开始发挥作用,越大的模型效果越好。
不同参数的模型的推理长度总体平稳,并未出现随着训练的增加,推理长度增长的现象。
由于 7B 模型的 loss&kl&grad 曲线有非常剧烈的波动,如在 loss 曲线中可以达到 75.132,0.5B、1.5B 和 3B 模型的 loss 无法观察,因此将 0.5B、1.5B 和 3B 模型的 loss&kl&grad 曲线单独绘制(右侧图)。7B 模型在 35step 左右出现剧烈波动,loss 值达到 75.132,在 95step 时 loss 值达到 4.1998。1.5B 模型也出现了较大的波动,loss 值最高达到 0.4545。kl&grad 也表现出了与 loss 相同的变化趋势。
loss&kl&grad 曲线剧烈的波动可能将影响模型的性能,但是在奖励函数曲线上并未表现出来。测试 1.5B 模型(包括 1epoch、2epoch 和 3epoch)时,模型老是输出一堆乱码。7B 模型在 1epoch(58step)时表现良好,但是在 2epoch(116step)和 3epoch(174step)时,也是出现一堆乱码。这些现象可能与剧烈的 loss&kl&grad 曲线波动有关。
模型输出问题
观察到以下输出问题:没有完整的 <think>\n...\n</think>\n<answer>\n...\n</answer> 格式;回答不以 <think> 开头;凭空捏造 </journalism>;多种语言杂糅在一起回答,包括 think 和 answer。
Qwen2.5-7B-Instruct 得出错误答案,而经过 1epoch 训练之后,模型成功解决了该问题。2epoch 和 3epoch 模型输出乱码,这里不进行展示,但是对于训练数据,即使翻译成中文,3epoch 模型依然可以正确回答。
修改 system 不影响推理答案,但影响 <think>\n...\n</think>\n<answer>\n...\n</answer> 格式。
建议与发现
0.5B 小模型很难通过 GRPO 学习到推理能力,使用 1.5B 以上的模型进行训练比较合适。
对于格式奖励,模型总能以意想不到的方式绕过正确方式获得奖励,可以考虑以下方式:
- 将 <think>\n...\n</think>\n<answer>\n...\n</answer> 简化为 <think>\n...\n</think>\n,降低模型匹配格式的难度。
- 将问题与 <think>\n 拼接在一起,杜绝模型将思考过程放在 <think>\n 之前的可能性。
- 对于出现多次如 <think>\n 的情况,给予惩罚。
- 冷启动,先拿一部分格式正确的数据让模型学习匹配正确的格式。
对于答案奖励,需要设计合理的提取答案的方式,当然这很难。尝试过 OpenR1-Math-220k、s1K-1.1、Bespoke-Stratos-17k 和 MATH-lighteval 数据集,但是要么数据集太大、要么很难提取答案,最终才选择了 MATH-lighteval 数据集。挑选数据集时遇到的不同答案类型:
- 数值类型:例如整数 2、020,浮点数 3.14。
- 布尔类型:例如 True、true。
- 选择题:例如单选题 A、a,多选题 BCD、bC。
- 问题重复描述:例如 1+1=2,1+2.14=3.14。
- 具体推导过程的上述答案:例如...... so the answer is XXX、The answer is XXX、Answer is XXX、x=XXX。
- 带有 latex 格式的上述答案:例如...... so the answer is \boxed{XXX}、x=\boxed{XXX}、\fbox{XXX}。
- 证明题:不同的证明思路都是正确的,这种题无解。
对于多语言混合和乱码,可以考虑增加奖励函数,对于多语言混合和乱码的回答给予惩罚。
超参数很重要,不同参数量的模型的超参数可能存在差异。使用相同的超参数训练 0.5B、1.5B、3B、7B 的 qwen 模型,但结果千差万别:
- 0.5B 模型没有学到推理能力,格式也是蒙混过关。
- 1.5B 模型训崩了或者过拟合太严重,回答老是乱码。
- 3B 模型出现了多语言混合的现象。
- 7B 模型也是训崩了或者过拟合太严重,回答老是乱码,1epoch 时还好,后面越来越严重。
在 aime-2024 和 math-500 上测试,所有模型都有随着训练的增加,分数越来越低,可能出现了过拟合或者模型的回答格式错误。
训练过程中的 loss 突变可能会对模型造成较大的影响,例如 1.5B 和 7B 模型均出现突变,最终训练的效果也不好。但是令人疑惑的是,当突变发生在 1epoch 以内时,7B 1epoch 模型的效果居然还不错,反而是 2epoch 和 3epoch 模型效果不好。
参考项目与数据
本项目主要参考以下项目和资料:
- https://github.com/huggingface/open-r1 (代码流程)
- https://huggingface.co/datasets/DigitalLearningGmbH/MATH-lighteval (数据来源)