用极小模型复现R1思维链失败后的感悟

 Datawhale分享 
作者:林正,来源:知乎
知乎:https://zhuanlan.zhihu.com/p/27699656438 

前言

投完 ICML 之后火急火燎的入门 RL,花了一些时间把 RLHF 学了。后来在知乎上看到了很多优秀的开源 R1 复现项目,于是手痒痒啃了下比较火的两个开源项目准备自己实践一下,一个是 Huggingface 的 Open-R1,一个是 Logic-RL。由于 Logic-RL 基于 Verl,模型推理和训练过程都是shard到不同显卡上的,Huggingface 的GRPOTrainer是单独用一张显卡做vllm推理,所以我在浅尝 Open-R1 做数学题的训练之后转移到了 Logic-RL 上面。

因为是民科,手上只有四张降了功率的 3090,我就拿 0.5B 的千问做的实验,中间遇到了不少问题。

探索 0.5B 模型在 KK 数据集上的强化学习训练

我使用了 qwen-0.5B 的 instruct 模型实验,我看 logic-rl 论文中 instruct 模型也可以复现出思维链增长。但这里选用 instruct 模型主要还是因为base模型很难训练。

1. 多余的 reward 会让模型变懒

我首先是使用了 Logic-RL 中原来配置的 reward 规则,在原版规则中,模型学会格式后会得到一定奖励,但很快模型的输出就变得很短

<think>The reasoning process here involves understanding the characteristics of knights and knaves, analyzing the statements made by each person, and determining who is a knight and who is a knave.</think>  
<answer>Ethan is a knight, David is a knave, Samuel is a knight.</answer><\|im_end|>

然后模型几乎不 care 回答是否正确,输出长度急剧下降到只有几十个的长度。于是我尝试更改规则,仅当模型格式正确且回答正确的时候才有 reward,其余情况都是最低分。

但令人没想到的模型依然只是水一下思考内容,然后在 answer tag 里输出答案,似乎只要遵循 <think></think> 的格式就会让模型放弃思考过程。我后来将格式 reward 中有关 <think></think> 的要求去掉了,在训练过程中就能顺利保留下来模型的思考过程。

2. 模型很难直接学习 3ppl 以上的问题

0.5B 模型可能是太小了,直接混合 3ppl-7ppl 的数据集训练会导致 reward 一直在最低分附近震荡,然后一会就开始输出胡言乱语。训练开始没多久我就看到输出长度爆炸增长,我以为是长思维链的出现,但其实是模型错误预测 token 导致输出大段胡言乱语。

于是,我转换了 2ppl 的数据集,让模型在2ppl数据集上先进行 10 个 step 的学习,然后在 3ppl 数据集上进行 20 个 step 的学习,再换到 4ppl 上进行 10 个 step,5ppl 上训练 10step,最后换到 6ppl 上进行长的 RL 训练。这类似于课程学习,但在训练结束后我是保存了模型之后在新的训练中加载保存的模型,所以相当于 reference model 被更新了。

这个过程中确实观察到了一些有意思的现象,例如

错误检查

2. ****Avery's statement****: If Jacob is a knight, then Avery must be a knave, regrettably (vice versa). 
Since Jacob is not a knight, there'
s a contradiction here, indicating a **mistake** in our reasoning. 
Alternatively, if Jacob is a knight, Avery must be a knave, meaning Jacob cannot be the perfect knight according to her statements.

Recheck

So, the contradiction here comes from Scarlett being a knight. 
This means the first term is misleading. Let's **recheck the clues**.

虽然感觉推理过程好像不是很对。。。

还有一些输出我没有保存,例如语言混杂,使用数学来解逻辑问题,以及使用什么蕴含树?来解决问题的过程也是有的。

3. 模型总是会收敛到一个极短的推理过程

这也是为什么说复现是失败的,虽然通过前面的修改模型能顺利学到 6ppl 的问题上,但是模型的推理过程总是会变得极为简单,我分别多次尝试了在预热训练(前面提到的课程学习)后在 5ppl 和 6ppl 的数据集,或者混合的数据集上训练,都会出现思维链随着准确度越来越高下降的过程

5ppl上长训练,思维链长度下降
6ppl上长训练,思维链长度下降

观察模型的输出,它最后都会收敛到一个固定的,甚至是错误的推理模式

To determine the identities of each character, we will analyze each statement step by step.  
  
1. Avery's statement: "Zoey is a knight if and only if Aiden is a knave." Therefore, Zoey is a knave if Aiden is a knight.  
2. Zoey'
s statement: "Aria is not a knave." Hence, Aria is a knight.  
3. Lily's statement: "Zoey is a knight and Aiden is a knight." Therefore, Zoey is a knight.  
4. Evelyn'
s statement: "Aria is a knave or Lily is a knight." Since Aria is a knight, Evelyn must be a knight.  
5. Aria's statement: "Evelyn is a knight or Avery is a knave." Since Avery is a knight, Aria's statement is true, so Aryan is a knight.  
6. Aiden's statement: "Avery is a knave." Therefore, Aiden is a knave.  

So, the identities of the characters are:  
- Avery is a knave,  
- Zoey is a knight,  
- Lily is a knight,  
- Evelyn is a knight,  
- Aria is a knight,  
- Aiden is a knight.  
  
The final answer is:  
<answer> (1) Avery is a knave, (2) Zoey is a knight, (3) Lily is a knight, (4) Evelyn is a knight, (5) Aria is a knight, (6) Aiden is a knight. </answer><|im_end|>

模型的回答固定为(1)总起,一步一步推理。(2)先重复每个人的话,在后面紧接着做推理。(3)给出答案。(4)在<answer> tag 里给出答案。

但是,当我们仔细检查推理过程的时候,发现这个推理是错的,但答案是对的。例如第四条,Since Aria is a knight, Evelyn must be a knight,第五条 Aryan 名字都没出现过。当然最明显的,推理过程得到的结论,例如第六条 Aiden is a Knave 和答案 Aiden is a knight 根本也对不上。

虽然 Logic-RL 论文中 Instruct 模型也是经历了输出长度下降之后上升

图源Logic-RL: Unleashing LLM Reasoning with Rule-Based Reinforcement Learning

但是我这里并不能在下降后上升,因为在 32 次 rollout 中,模型的输出几乎都一模一样了,模型的最短回答和最长回答几乎都收敛了,即模型不再探索新的可能性,熵已经收敛了。

可能原因的讨论

我对于 rule based reward+RL 训练的理解是,这个过程类似于抽签+筛选。如果抽到了正确的回答,那模型就知道这一次它是做对了的,会继续往这个方向靠,如果回答错误就被惩罚,抛弃这个 action,被筛选掉。我们不断抽签过程中,模型的某些行为会被我们保留下来并强化,某些行为会被我们抛弃。

那么首先是筛选过程可能不准确,例如某次回答中模型不思考或胡乱思考,直接猜答案,但是答案猜对了,得到了 reward,另一次回答进行了详尽且前后 consistent 的推理,但不幸答案是错的,那么这个行为会被筛掉。

对于简单的问题,小模型可通过简短的推理,或者直接给出答案的方式做对题,那么这些行为都会被保留下来。但对于难的问题,小模型一开始会尝试使用长思维链解决这个问题,但因为能力不足,它总是答不对,那么长思考的行为就会被我们筛选掉。

总的来说,我感觉是我们抽不出来小模型使用长思维链做对题的签,所以导致思维链收敛到很短。而因为直接给答案做对题概率可能更大,模型对于思考过程几乎不完善,而直接去学从 prompt 到答案的映射。随着训练进行,模型在 val set 上的准确度是越来越高的,在我的训练步数内,5ppl 上能达到 33%,6ppl 上能达到  22%,且还没有饱和,所以它是有能力做对题,但肯定不是靠思维链做对题。

而大的模型本身应该就有抽出长思维链+正确答案的潜力,所以这个行为能被我们保留并强化,在训练后期,简单题(例如仅靠一次前向推理就能确定所有人的身份)被学完,而后,当 rollout 出模型依靠更长思维链解决难题的样本后模型自然就会往长思维链解决难题上靠。

总结

总的来说,这次做的几次实验都没成功,模型太小肯定是个问题。换个大一点的模型试试吧,不知道我的四张3090还能不能撑得住。

由于刚入坑RL,很多东西都是速成的,可能理解上有误,还请见谅。

一起“”三连

(文:Datawhale)

发表评论