Satori: Reinforcement Learning with Chain-of-Action-Thought Enhances LLM Reasoning via Autoregressive Search
Paper: arXiv:2502.02508 Code: satori-reasoning/Satori Code reference:
main@af1ef945(2025-06-03)
1. Motivation
现有 reasoning 训练主要有两条路:一是 SFT/蒸馏,把强模型的长推理轨迹灌给学生;二是 RLVR / verifier-guided search,依赖外部 verifier 在推理时或训练时提供反馈。但两者都没真正把“搜索能力”内化到单个 LLM 里,前者成本高且依赖教师轨迹,后者通常还需要多模型/外部打分器,部署成本和复杂度都不低。这篇论文要解决的具体问题是:能否让单个 7B LLM 学会带自反思、自探索的 autoregressive search,并且在只用少量格式示例的情况下,通过 RL 自己把这种搜索能力做出来。
这个问题值得研究,因为一旦搜索能力被内化,模型在数学推理上可以像 test-time search 一样分配更多计算,而且这种能力还能迁移到 out-of-domain reasoning。论文对现状的不满并不止于“分数还不够高”,而是认为现有 open reasoning pipeline 把真正昂贵、真正有价值的搜索能力都放在了系统外部。无论是 best-of-N、step-level verifier-guided search,还是双模型的 critique-and-revise,本质上都说明 LLM 在额外计算和额外反馈帮助下可以更强;但这些方法并没有回答:模型本身是否学会了搜索,还是只是在一个更复杂的 inference wrapper 里被调度着搜索。
作者把这个问题说得很尖锐:test-time scaling 的强大已经被反复证明,但典型实现往往需要 extensive sampling 和外部反馈,通常是奖励模型给最终答案打分,或者 verifier 给中间步骤打分。这样做的直接代价是两点:一是部署成本高,因为系统至少是 two-player framework;二是 search capability 没被 internalize 到单个 policy 中,所以很难说模型本体真正获得了更强 reasoning ability。
与之相对,纯 SFT 也不是令人满意的终点。论文在引言中明确指出,人类标注高质量长 CoT 的成本极高,而 stronger-model distillation 虽然可扩展,却 often limits the model’s reasoning capabilities to certain level。这里的潜台词是:学生可以学会“像教师那样写”,但不等于学会在新题目、尤其是没有现成教师轨迹的情况下,自己发现错误、回退路径、重构策略。所以 Satori 的 motivation 不是简单地“把 CoT 变长一点”,而是重写 post-training 的目标函数。
作者想要的不是单次 rollout 上更好看的推理文本,而是一个能在推理过程中执行自反思和自探索的单模型 policy。只要这个目标成立,它带来的收益就不该局限在数学域:任何需要长链 reasoning 的任务,都可能从“能回头看、能换路走”这种行为里受益。论文还特别把自己和 concurrent work 区分开。和 DeepSeek-R1 这种“小规模冷启动 SFT + 大规模 RL”的高层路线相比,Satori 更强调可开源、可复现、可研究的小模型配方:在 7B 规模验证 autoregressive search 能否被学进单模型。
这一点决定了整篇论文的评价标准不是“是否超过所有闭源大模型”,而是“是否在开放、较小规模底座上,证明了另一条 reasoning enhancement 路线成立”。
Figure 1 解读:左侧是 format tuning,模型先学会 COAT 的 meta-action 语法;右侧是 self-improvement,模型在 RL 中通过 restart 和 explore 重新展开推理并修正错误。核心不是“多想几步”,而是把“何时回头、何时换策略”显式编码进同一个 policy。
Figure 1 还体现了作者对问题拆解方式的判断:先把“模型会不会写这种轨迹”与“模型能不能靠这种轨迹提升任务表现”分成两个阶段。Stage 1 并不追求大量任务增益,而是给模型注入一套新的 reasoning syntax;Stage 2 才真正通过 RL 让这套 syntax 变成有效行为。这种拆分本身也是对动机的回应,因为作者认为 search ability 的瓶颈不只是缺数据,而是缺合适的 action space 和训练信号。
2. Idea
核心 insight 是:推理里的搜索行为不必由外部 verifier 只在推理末端控制,而可以通过 meta-action token 直接变成 LLM 的输出空间,再用 RL 把“回退”和“探索”本身变成可学习动作。Satori 的关键创新是 COAT + RAE:COAT 把 CoT 扩展成包含 restart / explore 的 autoregressive search 轨迹,RAE 则把训练状态从中间轨迹重启,让模型在长链条和稀疏奖励下仍能持续发现更优解。和传统 CoT SFT 不同,它不是教模型复述正确推理,而是教模型在出错后如何重新组织推理。更具体地说,Satori 的 idea 包含三个彼此咬合的判断。
第一,搜索行为必须先被“表示”出来,否则无法直接训练。传统 CoT 只有 continuation,模型只能接着往下写;COAT 则把 reflect、restart、explore 这类元动作显式放进输出空间,让模型在 token 级别上表达“我要检查前文”“我要从这里重来”“我要换一种策略”。这一步相当于给推理过程加上控制接口。第二,长链 reasoning 的训练困难不只是 reward sparse,还包括 state coverage 差。很多题目不是从第一步就全错,而是中途某一步偏了。若每次 rollout 都从题目开头开始,模型会一遍遍重复自己已经会的前缀,却很少集中练习那些真正导致失败的中间状态。
RAE 的核心想法就是把这些 partial trajectories 再利用起来,从中间状态启动新的 rollout,让模型专门学“如何从半错状态修回来”。第三,仅靠最终答案对错给奖励,早期 RL 太稀疏,所以必须用 ORM 做 preference shaping。也就是说,哪怕两条轨迹最后都没答对,系统仍要尽可能区分谁“更接近正确、值得继续强化”。因此,Satori 不是把 reward model 当成单纯的验收器,而是当成让 search policy 在冷启动早期也能收到可学习梯度的 dense hint。
这三点组合起来后,Satori 和普通 CoT SFT 的 fundamental difference 就非常清楚了。后者优化的是“单一路径文本 continuation”,前者优化的是“一个会管理自身推理过程的 policy”。这也是为什么论文反复强调,它不是在教模型背更多正确解,而是在教模型何时质疑已有解、何时从已有解中抽身、何时另辟新路。
3. Method
3.1 Overall framework
Satori 分两阶段训练:先做小规模 format tuning,让模型熟悉 COAT 轨迹和 meta-action token;再做大规模 RL self-improvement,用 PPO 类训练和 reward model / outcome reward model 驱动 autoregressive search。输入端统一用 Qwen-2.5-Math-7B 作为 base model,目标是把“推理格式”和“搜索能力”分开学,再合并到一个 policy 里。
如果把方法拆开看,Satori 实际上解决了四个不同问题:COAT representation 负责定义 action space;format tuning 负责冷启动;RAE + PPO 负责把训练重点放到关键中间状态;iterative self-improvement 负责避免 policy 卡在局部最优。论文的方法价值在于,这四个问题都被显式识别并分别设计了机制,而不是寄希望于“更强 base model + 更多 SFT”自然涌现。
Figure 2 解读:图里展示了三阶段数据量级差异。Satori 只用 10K FT 数据建立 COAT 格式,再用 300K RL 数据做 self-improvement;对比同 base model 的 2.5M SFT 方案,Satori 试图证明“少量格式对齐 + 大规模自改进”比纯监督更有效。
Figure 2 其实也在表达 supervision allocation 的立场。作者并不是否认监督信号的重要性,而是认为监督更适合用来注入“格式”和“动作语法”,而能力提升主要来自大规模 self-improvement。换句话说,FT 负责告诉模型“这种轨迹长什么样”,RL 才负责告诉模型“这样做为什么有用”。
3.2 COAT 形式
论文把 Chain-of-Thought 视为 COAT 的特例:CoT 每一步都只是 continuation,而 COAT 允许每个 reasoning step 以 meta-action 开头。论文定义了几类动作,其中最关键的是 restart(从当前轨迹回到更早状态重开)和 explore(识别当前推理缺陷并尝试新策略)。这使得模型不再只输出单一路径,而是能在同一次生成里显式表达“纠错”和“换路”。作者的关键观察是:CoT 只能表达“继续想”,而复杂推理实际还需要“停下来检查”“承认前面错了”“从这里回退”“换个思路重做”。如果这些行为不进入 action space,就只能依赖 prompt 工程或外部搜索器间接诱导;
一旦把它们变成可输出 token,模型就有机会在训练中直接学会这些行为。附录里的合成示例也说明 COAT 并非单一模板,而是包含多种 search pattern:有的轨迹只包含一次 reflect 做正确性验证,有的轨迹在发现错误后继续 explore 新路线,还有的轨迹会经历两轮 self-reflection/self-explore。也就是说,COAT 不是把 CoT 加两枚 special token 就结束,而是把“推理过程管理”整体纳入语言序列。从归纳偏置角度看,COAT 默认错误是可操作状态,而不是终局失败。普通 CoT 一旦中间某步错了,模型只能继续在错误前提上外推;COAT 则允许模型把错误显式暴露出来,再把后续 token 用在修复该错误上。
这恰好为后面的 RAE 提供了训练接口。
3.3 Format tuning
FT 阶段只用 10K 示范轨迹,目标不是学题,而是学轨迹格式。实现上,示范轨迹来自 multi-agent synthesis:generator 先采样大量初始解,critic 对候选解做反馈,随后 generator 基于反馈继续生成,最后用 reward model 选出 top-k 轨迹。这个阶段解决的是“模型一开始不知道 meta-action token 怎么用”的冷启动问题。 附录 D.1 给出了比正文更具体的数据处理细节。训练题源来自 OpenMathInstruct-2 和 NuminaMath-CoT,作者先删除 invalid questions 和错误标签,再使用受 rStar 启发的 mutual consistency filtering:让 QwQ 重新回答问题,并与源答案比对,只保留一致样本;随后再去重,最终得到约 550K 条高质量样本。这个清洗动作很重要,因为后续 RL 若建立在脏标签或重复问题上,restart 和 reflection 会学到很多无效模式。 multi-agent synthesis 框架由三类模型组成:
Generator:Qwen-2.5-Math-7B-InstructCritic:Llama-3.1-70B-InstructOutcome Reward Model:Skywork-Reward-Llama-3.1-8B-v0.2
附录中的实际流程是:generator 以 temperature=0.3、最大 2048 token,为每道题先采样 K=100 条初始解;把结果分为 correct / incorrect / invalid 三类,丢弃 invalid 后,随机挑 4 条正确和 4 条错误轨迹交给 critic。critic 以 temperature=0.2、最大 256 token 生成反馈,generator 根据反馈继续 conditional generation;整个过程最多迭代 m=2 轮,因此单题最多得到 8 × 2 = 16 条 demonstration trajectories。
作者进一步把合成轨迹分成五种类型:Type-I 无 critic 反馈;Type-II-I 有一次中间验证;Type-II-II 在验证后再纠错并 explore;Type-III-I 直接进行 reflection + explore;Type-III-II 则做两轮 self-reflection / self-explore。最终 ORM 会在每种类型里选 top-1 轨迹(若该类型存在),组成 FT 的示范集。这样做的好处是,模型不会只看到一类“最像标准答案”的轨迹,而是能接触到不同形态的 search behavior。
论文特别强调,10K 条 demonstration 已足以让 base model internalize COAT format。这里“足够”的含义不是靠 10K 题就学会数学,而是足以把元动作语法注入模型,使其知道何时可以发出 reflect/explore,以及这些 token 后面应接何种文本行为。
3.4 Self-improvement via RL
RL 阶段使用 RAE 思路:从原始题目起点和随机中间轨迹状态共同启动 rollout,扩大初始 state coverage。这样做的直觉是,长链推理的难点不只是最终答案稀疏,而是很多中间状态根本没被覆盖;重启可以让模型反复接触那些“半对半错”的轨迹分支。 论文在这里借鉴了 Go-Explore 的核心直觉:如果策略总是从少数相似初始状态出发,就很难覆盖那些真正决定成败的关键中间状态。数学推理尤其中如此,因为很多错误并非来自根本性 misunderstanding,而是局部计算错误、分支选择错误或验证缺失。让 policy 一直从题目开头重新走一遍,不如直接把这些“半成品状态”拿出来反复练。 论文里的 reward 主要来自 outcome reward model。对每个题目 ,先采样多条轨迹,构造正负样本对 ,再用 Bradley-Terry 目标训练 ORM:
\mathcal{L}_{rm}(\psi) = -\mathbb{E}_{(x,\\tilde y^+,\\tilde y^-)\sim D_r} \log \sigma\\big(r_\\psi(x,\\tilde y^+) - r_\\psi(x,\\tilde y^-) - \\tau\\big)
这里 是 margin。直觉上,ORM 不只是判断对错,还拉开优解和劣解的分数间隔,让 PPO 的奖励信号不至于过稀。论文同时强调:如果没有这种 preference shaping,初期正确轨迹太少,RL 很容易退化成稀疏奖励问题。 RAE 的算法流程可以概括为:先对每个问题采样多条轨迹,再随机选一条正确轨迹 和一条错误轨迹 ;从它们的尾部随机回退不超过 步,得到中间状态 与 ;随后在状态后拼接 <|reflect|>,把这些状态分别放入正负 restart buffers,再与原始问题一起构成新的初始状态集合 。这样,policy 训练时既会看到“本来对但可能被改坏”的状态,也会看到“本来错但有机会修对”的状态。 作者将总体 reward 写为:
r(z, \\tilde y) = r_{rule}(\\tilde y_L, y^*) + \\sigma(r_\\psi(z, \\tilde y)) + r_{bonus}(z, \\tilde y).
其中 rule-based reward 只看最终答案是否匹配标准答案,定义为 ;preference bonus 来自 ORM 输出;reflection bonus 则专门塑形 search 行为:
r_{bonus}(z, \\tilde y)=
\\begin{cases}
\\beta, & z \\in D_{restart}^{-} \\text{ and } \\tilde y_L = y^*, \\\\
-\\beta, & z \\in D_{restart}^{+} \\text{ and } \\tilde y_L \\neq y^*, \\\\
0, & \\text{otherwise.}
\\end{cases}
这一定义很有针对性。若模型从错误状态出发最终修正成功,会拿到正 bonus;若模型从正确状态出发反而把题做坏,会吃到负 bonus。也就是说,Satori 奖励的不是“多反思”本身,而是“有价值的反思”。这能解释为什么后面的分析会区分正向 self-correction (F→T) 与负向 self-correction (T→F)。
正文里还给了一个重要直觉解释:RAE 通过 partial trajectories 改变了 initial state distribution,使其比只从题目 prompt 出发时更均匀。作者把这和 Kakade & Langford 关于 state coverage 更充分时学习界更紧的论述联系起来,虽然没有给出完整理论证明,但至少说明这不是拍脑袋的 heuristic,而是有 RL 经验和理论背景支撑的设计。
3.4.1 Iterative self-improvement
除了单轮 RL,论文还引入 iterative self-improvement。做法是:每完成一轮 RL,就把当前优化后的 policy 通过 SFT/distillation 压回 base model;然后从这个新初始化继续下一轮 RL。作者把这个过程视为一种 parameter reset mechanism,有助于 policy 逃离 local sub-optimum,避免陷入“越来越擅长同一种错误搜索模式”的 vicious cycle。
3.5 论文公式与 released code 实现差异
论文描述的是 COAT/RAE + ORM 驱动的两阶段框架;released code 的训练入口 examples/satori/train.sh / train_multi.sh 直接调用 openrlhf.cli.train_ppo_ray,并把 prompt_data、reward_pretrain、pretrain 和批量大小、max_samples 等训练超参写进 launch script。也就是说,代码层面落地为 OpenRLHF 的 PPO Ray 训练管线,而不是论文正文里抽象描述的独立算法伪代码。
这个差异对复现理解很关键。论文里的 COAT、RAE、restart buffers 和 reflection bonuses 主要是概念层与数据层设计;released code 则更像“把这些设计压缩进一套 OpenRLHF 训练 recipe 中”。例如脚本里最直接暴露给用户的是:
pretrain=Satori-reasoning/Satori-SFT-7Breward_pretrain=Satori-reasoning/Satori-RM-7Bprompt_data=Satori-reasoning/Satori_RL_data_with_RAE
这说明相当一部分 Satori-specific 行为已经提前体现在数据构造和 prompt 分布里,而不是通过一个单独的 RAETrainer 类在训练脚本中显式实现。换句话说,论文方法的“特别之处”主要藏在数据与训练状态设计,而非完全体现在代码结构表面。
3.6 Code-to-paper mapping
Code reference:
main@af1ef945(2025-06-03) — pseudocode and mapping based on this commit
| Paper Concept | Source File | Key Class/Function |
|---|---|---|
| FT / RL 训练入口 | examples/satori/train.sh | ray job submit -> openrlhf.cli.train_ppo_ray |
| 多机 RL 训练入口 | examples/satori/train_multi.sh | ray job submit -> openrlhf.cli.train_ppo_ray |
| PPO/Ray 编排 | openrlhf/cli/train_ppo_ray.py | main, parser, PPORayActorGroup, PPOTrainer |
| Prompt 预处理 | openrlhf/datasets/prompts_dataset.py | preprocess_data, PromptDataset |
| PPO 训练循环 | openrlhf/trainer/ppo_trainer.py | BasePPOTrainer, fit, evaluate |
def train_ppo_ray(args):
strategy = init_deepspeed_strategy(args)
actor = build_actor_group(args)
ref = build_reference_group(args)
reward = build_reward_group(args)
critic = build_critic_group(args) if args.critic_pretrain else None
trainer = PPOTrainer(
pretrain=args.pretrain,
strategy=strategy,
actor_model=actor,
critic_model=critic,
reward_model=reward,
ref_model=ref,
vllm_engines=create_vllm_engines(args),
prompt_max_len=args.prompt_max_len,
max_new_tokens=args.generate_max_len,
temperature=args.temperature,
top_p=args.top_p,
)
actor.load_pretrained(args.pretrain)
reward.load_pretrained(args.reward_pretrain)
if critic is not None:
critic.load_pretrained(args.critic_pretrain)
trainer.fit()
actor.save_model()def preprocess_data(data, tokenizer, input_key="query"):
prompt = data[input_key]
if tokenizer.bos_token:
prompt = tokenizer.bos_token + prompt
return prompt, data["answer"], data.get("reflect_status", 0)def build_training_prompt(sample):
prompt = sample["query"]
answer = sample["answer"]
reflect_status = sample.get("reflect_status", 0)
return {
"prompt": prompt,
"target": answer,
"reflect_status": reflect_status,
}第二段伪代码表达的是一个关键映射:在 released code 里,paper-level 的“中间状态重启 + 触发反思”最后会被压成 prompt 数据中的字段结构,而不是单独暴露成复杂对象。reflect_status 这类字段说明 prompt 本身已经携带了“当前是否处于 reflection-conditioned state”的信息。
3.7 关键组件
restart 负责把生成过程从当前半成品轨迹切回更早状态,适合处理中间步骤出错但仍有修复空间的情形;explore 则显式提示模型识别关键缺陷并切换新解法。两者一起解决的是长 horizon 下“模型卡在一条错误路径里出不来”的问题。如果去掉它们,COAT 会退化成普通 CoT,模型很难在同一轨迹里表现出自修正和策略切换。
Figure 3 解读:随着 RL 训练推进,policy accuracy 上升、response length 增长,说明模型不是只学到“更高分”,还学会了给更难题分配更多 token 预算。这个现象是 autoregressive search 的外显证据。
正文对 Figure 3 的补充解释很值得记下:response length 并不是从一开始单调增长,而是在早期先下降、后期再上升。作者观察到,前 0-200 步左右模型尚未学会 self-reflection,RL 先把输出压向更短更直接的回答;等 reflection/search 行为逐渐成形后,模型才开始愿意为困难问题花更多 token,长度重新增长并伴随更高准确率。这说明“更长回答”不是目标本身,而是 search behavior 被训练出来后的副产品。
从整体依赖关系看,Satori 的组件是强耦合的:没有 COAT,RL 学不到可解释的 search actions;没有 FT,模型不会这些动作的基本语法;没有 RAE,关键中间状态几乎不会反复出现;没有 ORM 和 reflection bonus,early-stage RL 几乎学不到任何稳定信号;没有 iterative self-improvement,则第二轮性能抬升缺乏机制支撑。论文实验基本就是在逐项验证这个闭环确实成立。
4. Experimental Setup
- 数据集规模:FT 用 10K 示范轨迹;RL 用 300K 轨迹;训练数据源是 OpenMathInstruct-2、NuminaMath-CoT,且先过滤无效题、再做 mutual consistency filtering;ORM 训练还从 550K unique questions 中构造约 300K preference 数据。
- 模型:base model 是
Qwen-2.5-Math-7B;multi-agent 生成器是Qwen-2.5-Math-Instruct;critic 是Llama-3.1-70B-Instruct;ORM 用Skywork-Reward-Llama-3.1-8B-v0.2。 - 指标:
GSM8K、MATH500、OlympiadBench、AMC2023、AIME2024、FOLIO、BoardgameQA、CRUXEval、StrategyQA、TableBench、STEM,其中Avg.是同组基准的平均分;Policy Acc.表示 RL 训练中 policy 的通过率,Response Length表示平均生成 token 数。 - 训练配置:
examples/satori/train.sh里单机脚本使用 8 GPU Ray head,ref/reward/critic/actor各 1 节点 2 GPU;micro_train_batch_size=1,train_batch_size=128,micro_rollout_batch_size=32,rollout_batch_size=1024,max_samples=100000,max_epochs=1,bonus_scale=0.5,prompt_max_len=1024,generate_max_len=3072,actor_learning_rate=2e-7,critic_learning_rate=5e-6,zero_stage=3,bf16。
4.1 数据清洗与构造逻辑
附录 D.1 说明,作者并不是直接把公开数学数据原样投入训练,而是先做了较强的数据工程。两份源数据 OpenMathInstruct-2 与 NuminaMath-CoT 合并后,先去掉 invalid questions 与错误标签,再做两轮质量控制:
mutual consistency filtering:用QwQ重新回答原题,并与源答案对比;若答案不一致,则认为该样本不稳定而移除。deduplication:使用去重工具移除重复或高度相似问题。
这样得到约 550K 的高质量问题池。随后,Satori 的不同训练阶段从该问题池中再派生不同子集:
10KCOAT demonstration 用于 FT。300K轨迹用于 RL self-improvement。- 约
300Kpreference 数据用于 ORM 训练。
因此,论文的核心实验并不是“在海量原始题目上粗暴堆训练”,而是在清洗后题池上分别优化格式学习、自改进学习和奖励塑形。
4.2 评测任务覆盖面
数学域主评测包括 GSM8K、MATH500、OlympiadBench、AMC2023、AIME2024。作者特别强调,除 GSM8K 外,其余基本都属于 competition-level problems,因此更能考察长链 search 是否真正提升了难题求解能力。
out-of-domain 部分则覆盖多种 reasoning 类型:
FOLIO与BoardgameQA:逻辑 / 规则推理。CRUXEval:代码推理。StrategyQA:常识推理。TableBench:表格推理。STEM:MMLU-Pro 的 STEM 子集,涉及 physics、chemistry、computer science、engineering、biology、economics。
统一评测设置是 greedy decoding、无工具调用、zero-shot pass@1 accuracy。这一设置有两个好处:一是隔离出模型本体能力,不让外部工具或多次采样重新引入 search;二是使论文关于“单模型 internalized search”的主张更可信。
4.3 Baseline 选择
small-scale 主要 baseline 有:
Qwen-2.5-7B-InstructQwen-2.5-Math-7B-InstructNuminaMath-7B-CoT
其中最关键的对照是 Qwen-2.5-Math-7B-Instruct,因为它与 Satori 使用同一底座 Qwen-2.5-Math-7B。这使得实验能较干净地回答:性能差异究竟来自更好的 base model,还是来自 Satori 的 post-training recipe。
large-scale baseline 则包括 Llama-3.1-70B-Instruct、OpenMath2-Llama3.1-70B、QwQ-32B-Preview、o1-preview 等。论文把这些大模型更多作为性能上界和外部参照,而不是同规模公平对比对象。
4.4 Released code 对应的训练超参与硬件
根据 examples/satori/train.sh,公开单机 RL 脚本的核心配置如下:
- 预训练 actor 初始化:
Satori-reasoning/Satori-SFT-7B - 奖励模型:
Satori-reasoning/Satori-RM-7B - RL prompt 数据:
Satori-reasoning/Satori_RL_data_with_RAE - 采样温度:
0.6 micro_train_batch_size=1train_batch_size=128micro_rollout_batch_size=32rollout_batch_size=1024max_samples=100000max_epochs=1bonus_scale=0.5prompt_max_len=1024generate_max_len=3072actor_learning_rate=2e-7critic_learning_rate=5e-6init_kl_coef=0.0zero_stage=3bf16
硬件与系统编排方面,脚本先用 ray start --head --num-gpus 8 启动单机 8 GPU head;随后把 ref、reward、critic、actor 四个角色都设成 1 node × 2 GPU,并使用 vllm_num_engines=2、vllm_tensor_parallel_size=2。同时开启 colocate_critic_reward 与 colocate_actor_ref,以及 normalize_reward、packing_samples、adam_offload、flash_attn、gradient_checkpointing。
多机脚本 examples/satori/train_multi.sh 则把每类角色扩成 2 nodes × 8 GPU,vllm_num_engines=8,micro_train_batch_size=4,max_samples=1000000,并打开 save_hf_ckpt 与 max_ckpt_num=999。因此,如果后续有人按 released code 复现,应该优先以这些脚本中的具体覆盖值为准,而不是 OpenRLHF 默认参数。
5. Experimental Results
5.1 Main results
Table 1 结果:
| Model | GSM8K | MATH500 | OlympiadBench | AMC2023 | AIME2024 | Avg. |
|---|---|---|---|---|---|---|
| Qwen-2.5-Math-7B-Instruct | 95.2 | 83.6 | 41.6 | 62.5 | 16.7 | 59.9 |
| Satori-Qwen-7B-FT (300K) | 92.3 | 78.2 | 40.9 | 65.0 | 16.7 | - |
| Satori-Qwen-7B | 93.2 | 85.6 | 46.6 | 67.5 | 20.0 | 62.6 |
| Satori-Qwen-7B (Round 2) | 93.9 | 83.6 | 48.5 | 72.5 | 23.3 | 64.4 |
Satori 在 7B 规模上超过同底座的 Qwen-2.5-Math-7B-Instruct,尤其在 OlympiadBench 和 AIME2024 上提升更明显,说明 COAT + RL 更适合难题。 若只看和最关键 baseline Qwen-2.5-Math-7B-Instruct 的差值,Satori-Qwen-7B 在 MATH500 上是 85.6 - 83.6 = +2.0,在 OlympiadBench 上是 46.6 - 41.6 = +5.0,在 AMC2023 上是 67.5 - 62.5 = +5.0,在 AIME2024 上是 20.0 - 16.7 = +3.3。这说明增益主要集中在更难、更需要搜索的任务,而不是简单题上普涨。 Round 2 的结果也很关键。第二轮 iterative self-improvement 后,模型变成 93.9 / 83.6 / 48.5 / 72.5 / 23.3,平均分升到 64.4。其中 AMC2023 比首轮再提 +5.0,AIME2024 再提 +3.3,说明第二轮并非只带来噪声式波动,而是继续在 hardest tasks 上扩展收益。
Table 2 结果:
| Model | FOLIO | BGQA | CRUXEval | StrategyQA | TableBench | STEM | Avg. |
|---|---|---|---|---|---|---|---|
| Qwen-2.5-Math-7B-Instruct | 68.9 | 51.3 | 28.0 | 85.3 | 36.2 | 45.2 | 52.5 |
| Satori-Qwen-7B | 71.4 | 61.8 | 42.5 | 86.3 | 43.4 | 56.7 | 60.4 |
| Satori-Qwen-7B (Round 2) | 72.9 | 58.5 | 41.1 | 90.4 | 44.6 | 57.4 | 60.8 |
模型虽然只在数学数据上训练,但在 FOLIO、BGQA、CRUXEval、StrategyQA、TableBench、STEM 上也有明显迁移,说明 COAT 学到的是更通用的 reasoning 行为,而不只是数学模板。
如果和 Qwen-2.5-Math-7B-Instruct 逐项比较,Satori-Qwen-7B 在 FOLIO 上是 71.4 vs 68.9,在 BGQA 上是 61.8 vs 51.3,在 CRUXEval 上是 42.5 vs 28.0,在 StrategyQA 上是 86.3 vs 85.3,在 TableBench 上是 43.4 vs 36.2,在 STEM 上是 56.7 vs 45.2。其中 BGQA、CRUXEval、STEM 的增益尤其大,说明 RL 训练出的 search behavior 并不只在数学符号域里有效。
Round 2 的 out-of-domain 结果整体也维持住了第一轮收益:FOLIO=72.9、StrategyQA=90.4、TableBench=44.6、STEM=57.4,平均 60.8。虽然 BGQA 与 CRUXEval 相比第一轮略有回落,但整体仍显著高于同底座 math instruct baseline。这与作者对 iterative self-improvement 的表述一致:第二轮主要继续推高整体 reasoning ceiling,而不是保证所有 benchmark 单调上升。
5.2 Ablation and analysis
Table 3:COAT vs CoT
Table 3 显示 COAT 比 CoT 更强:Qwen-7B-CoT (SFT+RL) 在 AMC2023 和 AIME2024 上分别只有 60.0 / 10.0,而 Satori-Qwen-7B 达到 67.5 / 20.0,说明“显式 meta-action 搜索”比单纯 CoT 续写更有效。
完整看 Table 3,Qwen-7B-CoT (SFT+RL) 在 GSM8K / MATH500 / Olym. / AMC2023 / AIME2024 上分别为 93.1 / 84.4 / 42.7 / 60.0 / 10.0,而 Satori-Qwen-7B 对应为 93.2 / 85.6 / 46.6 / 67.5 / 20.0。除了 GSM8K 几乎持平外,其余尤其是 hard math benchmarks 都有明显优势。这个结果说明决定性因素不是“有没有 RL”本身,而是 RL 训练的对象究竟是普通 CoT continuation,还是带元动作的 COAT search trajectory。
Table 4:self-correction
Table 4 的 self-correction 分析表明,Satori 在 MATH500、OlympiadBench 和 MMLUPro 上都能把部分错误答案修正为正确答案,且 RL 后正向 self-correction 明显增强:Satori-Qwen-7B-FT 在三项任务上的 T→F / F→T 分别是 79.4% / 20.6%、65.6% / 34.4%、59.2% / 40.8%,而 Satori-Qwen-7B 变成 39.0% / 61.0%、42.1% / 57.9%、46.5% / 53.5%。这支持了论文对“RL 让模型学会自反思”的主张。
Table 5:FT data vs self-improvement
Table 5 说明,10K FT + 300K RL 组合优于仅用 300K FT 的同底座方案,证明 self-improvement 比单纯扩大监督数据更划算。Figure 3 进一步显示,训练越久,policy accuracy 越高、response length 越长,表明模型愿意为困难问题花更多推理 token。
Table 5 是对“是不是多收集点 FT 数据也能达到同样效果”的直接反驳。Satori-Qwen-7B-FT (300K) 在 in-domain 上只有 92.3 / 78.2 / 40.9 / 65.0 / 16.7,out-of-domain 上只有 50.5 / 29.5 / 74.0 / 35.0 / 47.8;而 Satori-Qwen-7B 达到 93.2 / 85.6 / 46.6 / 67.5 / 20.0 与 61.8 / 42.5 / 86.3 / 43.4 / 56.7。也就是说,即便给 FT-only 模型喂到 300K 监督数据,它仍明显不如“10K FT + 300K RL”的组合。论文借此证明,大规模自改进不是省成本替代品,而是 qualitatively different 的能力来源。
Figure 4:test-time compute allocation
Figure 4 解读:难度越高,RL 后模型分配的 token 越多,说明它不是均匀增大输出,而是对 hard cases 做更强的 test-time compute allocation。
Figure 4 的价值在于把“test-time scaling behavior”具体化了。作者按 difficulty levels 比较 Satori-Qwen 与 Satori-Qwen-FT,发现 level 越高,RL 后模型新增的 response length 越明显,同时 accuracy 增益也越大。换言之,Satori 不是粗暴地把所有题都回答得更长,而是更像学会了按难度动态分配推理预算。
5.3 Limitations
论文没有把 COAT 的理论收敛性讲完整,也没有证明 RAE 在所有 long-horizon reasoning 场景都成立。正文明确把“更均匀的 state coverage 有利于学习”的解释定位为受 RL 理论启发的直觉性论证,更严格的理论分析留给未来工作。 现实层面的限制同样明显。尽管 Satori 最终部署目标是单模型 autoregressive search,但训练期仍依赖较复杂的三模型 synthesis 流水线与 RL 基础设施:generator、critic、ORM、PPO trainer 缺一不可。相比普通 SFT,这条路线的工程复杂度和算力门槛都更高。 此外,released code 暴露出的更多是 OpenRLHF 训练 recipe,而不是所有 paper-level 机制的完整独立实现接口。这意味着复现者仍需要结合论文、README 与数据资产来理解 RAE/COAT 的具体落点。最后,论文虽然展示了 out-of-domain transfer,但还没有系统分析 failure cases,例如哪些场景下 reflect 容易过度修正、哪些问题上 explore 可能引入无效分支。
5.4 Overall conclusion
Satori 证明了一个 7B 模型可以通过“少量格式冷启动 + 大规模 RL 自改进”的组合,把一部分 autoregressive search 行为内化成单模型能力。它最重要的结论不是单个表格中的最高分,而是以下三点同时成立:
- search 行为可以通过 meta-action token 显式进入 LLM 的 action space;
- 从中间状态重启并配合偏好奖励,能显著改善长链推理训练中的 sparse reward 与 state coverage 问题;
- 训练出的 self-reflection / self-exploration 行为能迁移到数学之外的逻辑、代码、表格与 STEM 推理任务。
因此,这篇论文的真正价值更像是一条 open-source reasoning post-training 路线图:与其无限堆叠 CoT 监督数据,或把搜索永久留在推理时外部系统里,不如重新设计模型的动作空间、训练状态分布和奖励塑形方式,让“搜索”本身成为 policy 会做的事。