研究提案 已修订

把子步奖励从策略前缀上摘下来:面向多步科学代码 RLVR 的前缀标准化信用分配

SciWalker 的子步执行奖励跑在策略自己生成的前缀上,等于前缀可用性与局部正确性的乘积;本提案用参考实现前缀做嫁接重放,制造出 BEACON 所需但代码场景不存在的里程碑判据,并据此重建分组与奖励

科学代码生成 强化学习 训练数据工程 信用分配 合成数据 AI for Science RLVR

背景与动机

多步科学编程的训练数据荒正在被数据侧解决。SciWalker(arXiv:2609.30054)把科学计算库的 API 与操作模式组合成算子,按输入输出兼容性连成图(每条子域 560 个算子,合计 17,920 个算子、772,178 条边),再随机游走采样长度 3–15 的算子链作为工作流线索,由大模型生成问题、参考实现与测试,用执行反馈逐轮修复。从 66,889 条候选链出发,经潜力评估(留存 32.2%)、上下文选择与复核(21,527)、生成与执行验证(25.7%)、润色与质量分级(12.2%),最终留下 8,178 题、37,820 个子步,每题 3–6 步、均值 4.62、中位数 5。用这批数据对 Qwen3.5-9B 跑 GSPO,SciCode 子问题准确率从 29.3% 提到 39.2%。

数据侧做完了,信用侧还停在最粗的一层。SciWalker 的子步奖励写作 ri,t=1[子步 t 的全部测试通过]r_{i,t}=\mathbf{1}[\text{子步 }t\text{ 的全部测试通过}],而测试的判定对象不是第 tt 步的代码,是「前 t−1t-1 步策略自己写出来的前缀 + 第 tt 步的代码」拼成的程序。把这两项拆开看,奖励实际是两个因子的乘积 ri,t=bi,t⋅ci,tr_{i,t}=b_{i,t}\cdot c_{i,t}:bi,tb_{i,t} 表示前缀在 tt 处可用,ci,tc_{i,t} 表示第 tt 步的局部实现在给定前缀下正确。第 tt 步的动作只能改变 ci,tc_{i,t},改不了 bi,tb_{i,t}。SciWalker 自己也写明这种结构——同一主问题同一子步的响应构成一组,尽管它们的前序代码可以不同;后续步骤的奖励不向前累积。组相对基线 Ai,t=(ri,t−μt)/(σt+δ)A_{i,t}=(r_{i,t}-\mu_t)/(\sigma_t+\delta) 于是建立在一组条件上下文互不相同的样本上:μt\mu_t 不是任何固定 xx 下的期望,σt\sigma_t 混进了前缀分叉带来的方差。

两个后果沿着子步序号 tt 单调恶化。第一条在分子:bi,tb_{i,t} 随 tt 几何衰减,第 tt 步真正可控的样本只剩 8⋅p^t8\cdot\hat p_t 个(p^t\hat p_t 为前缀到第 tt 步仍可用的比例),梯度幅度被 p^t\hat p_t 缩放。第二条在分母:前缀分叉随 tt 累积,σt\sigma_t 被抬高,除以 σt\sigma_t 又压一次。SciWalker 的训练预算是 150 步 × 32 题 × 8 条轨迹,8 条轨迹只在子步 1 同分布,从第 2 步起它们构成一棵前缀树而不是 8 个独立样本;tt 增大,这棵树的有效分叉数往下掉。

真正麻烦的是这个衰减现在看不见。SciCode 的评测口径是 288 个带科学背景的测试子问题(SciCode 原文:65 道主问题 / 288 个子问题构成测试集,另留 15 道主问题 / 50 个子问题作开发集),SciWalker 报的是子步准确率这一个池化标量。池化把所有子步序号压成一个数,前缀污染造成的增益分布偏斜被抹平。一篇把数据拆到子步级别的论文,训练信号却没有按子步记账,是当前配置里最容易被忽略的不对称。

这里还有一个构造性的边界值得写清楚:t=1t=1 时前缀为空,bi,1≡1b_{i,1}\equiv1 恒成立,p^1\hat p_1 不是估计量而是常量 1。也就是说第 1 步的 8 条轨迹确实共享同一个 xx,污染从第 2 步才开始进入。下面 P1 的判据等价于一个无条件阈值 p^5<0.5\hat p_5<0.5,代价是 p^1\hat p_1 不能拿来做任何跨 tt 的校准基线。

现有工作补不上这个缺口。BEACON(arXiv:2605.06078)把长程 RL 的两处病根讲得很清楚——信用误分配(早期正确动作被终局失败连坐)与样本低效(整组失败时方差为零、优势归零),给出的疗法是阶段切分 + 段内时序整形 + 双尺度优势,ALFWorld 长程任务上 92.9% 对 GRPO 的 53.5%,有效样本利用率从 23.7% 提到 82.0%。这套疗法有一个硬前提:里程碑指示器 Φ\Phi 由环境定义、不依赖被评估的策略——论文原话是 Φ\Phi “does not require learned models or manual annotation—it detects observable state changes from environment feedback”。三个环境里 Φ\Phi 分别是 ALFWorld 的物体状态变化(拾取成功、加热完成等,靠对环境响应做模式匹配)、WebShop 的页面转移、ScienceWorld 的环境显式子目标信号,都不由 agent 自己的历史决定。

BEACON 自己在附录 D 就把这件事列为首要局限:检测器需要领域知识手工设计,且对缺乏清晰子目标结构或可验证状态转移的环境可能不泛化;论文把「自动化里程碑发现」明确留作开放问题。这条自陈比任何外部评论都更直接——BEACON 的成功建立在「环境恰好给了 Φ\Phi」这个前提上,而这个前提在代码 RL 里恰恰不成立。代码 RL 里唯一可验证的逐步信号就是子步测试,而它跑在策略自己生成的前缀上,Φ\Phi 在这里无处落地。GRAFT 做的事就不只是「补一个缺失的组件」,而是正面回应 BEACON 自己点名的开放问题。

GiGPO(arXiv:2505.10978)的组内组按步序号对齐做第二层分组,在 agent 场景里步 tt 的状态同样由策略历史决定,跨前缀的问题照旧。SciWalker 沿用的 GSPO(arXiv:2507.18071)把组定义为同一查询的多次采样,前提同样是组内共享 xx。

核心思路

提出 GRAFT(Grafted Reference-prefix Attribution for Trajectory steps),核心动作只有一个:把第 tt 步的代码从它自己的前缀上摘下来,嫁接到参考实现的前缀上再判分。

SciWalker 每题都产出两份实现——基于基础数值函数的参考实现,与调用高层科学 API 的 oracle 实现——二者做过差分测试,测试覆盖数值正确性、参数变体、边界情形与科学不变量。这份参考实现此前只被当作生成期的验收标准和差分测试的一方,从未进入训练期的信用计算。把它按子步切开得到前缀 p<t∗p^*_{<t},把第 ii 条轨迹第 tt 步生成的代码按接口签名注入 p<t∗p^*_{<t} 的命名空间,重放该子步的测试,得到 r~i,t=1[嫁接到参考前缀后,子步 t 的测试通过]\tilde r_{i,t}=\mathbf{1}[\text{嫁接到参考前缀后,子步 }t\text{ 的测试通过}]。所有轨迹在同一子步上共享同一个前缀,r~i,t\tilde r_{i,t} 测的只剩下 ci,tc_{i,t}。原先那个被前缀污染的量于是可以完整地拆成三份,全部落到账本上:

原前缀在 tt 处是否可用,由 bi,tb_{i,t} 记录,取值为前 t−1t-1 步的子步测试是否全通过。第 tt 步唯一可控的量是前缀标准化后的局部正确性 r~i,t\tilde r_{i,t}。剩下那份交互残差 ϵi,t=ri,t−bi,tr~i,t\epsilon_{i,t}=r_{i,t}-b_{i,t}\tilde r_{i,t} 归前缀与局部的耦合。ϵ≠0\epsilon\neq0 意味着同一份第 tt 步代码在自己的前缀下与在参考前缀下判定不同,指向接口命名、量纲单位、返回结构的不一致。

训练侧对应两处改动。分组改成前缀条件分组:第 tt 步只在 bi,t=1b_{i,t}=1 的轨迹内部算 μt\mu_t 与 σt\sigma_t。这一步正是 BEACON 段级优势「只在到达同一里程碑的轨迹之间比较」的写法,差别在于这个判据不是环境给的,是嫁接造出来的。奖励改成 ri,t′=ri,t+λr~i,tr'_{i,t}=r_{i,t}+\lambda\tilde r_{i,t},λ=0\lambda=0 时严格退化为 SciWalker 原配置,可作为复现性自检。

与现有工作的分界线很清楚:BEACON 假定 Φ\Phi 存在,GRAFT 制造 Φ\Phi。制造所需的原料——参考实现、oracle 实现、差分测试、120 秒执行超时的沙箱——SciWalker 全部已经具备,只是从未朝信用分配的方向用过。

技术路线

第一步,诊断先行,零梯度更新。 用 SciWalker 原配置跑一遍 150 × 32 × 8 的采样,不更新参数,只输出三张按子步序号对齐的曲线:p^t\hat p_t(前缀可用率)、σ^t跨前缀\hat\sigma_t^{\text{跨前缀}} 与 σ^t前缀内\hat\sigma_t^{\text{前缀内}}、∣Ai,t∣|A_{i,t}| 的分位数。核心假说在这一步就能判生死。成本是 38,400 条轨迹的采样加一次重放,比跑完四臂便宜一个量级。

第二步,前缀库构建。 对 8,178 题的参考实现按子步边界切出 p<t∗p^*_{<t}。纯字符串与模块级操作,不调模型,每步的接口签名一并记录,供嫁接对齐。

第三步,嫁接执行器。 在现有执行器上开一个分支:把轨迹第 tt 步代码注入 p<t∗p^*_{<t} 的命名空间,固定随机种子、深拷贝全局状态,重放该子步测试,沿用 120 秒超时。

⚠️ 成本估算需在下预算前重算。 原文「相对 8 次 rollout 的生成开销可忽略」这一判断没有给出算式,按论文配置反推并不显然:单臂诊断即 150×32×8=38,400150\times32\times8=38{,}400 条轨迹,乘每题均值 4.62 个子步约 17.7 万次额外执行;四臂训练再乘 4 约 70.9 万次。以 120 秒超时为上限,最坏情况量级远超「可忽略」(即便实际平均单次执行只有 1 秒,单臂也约 49 小时 CPU 时间)。这笔开销是否可忽略,取决于三件原文没有说明的事:子步测试相对端到端测试是否短得多、执行能否与生成流水线并行、嫁接重放能否复用已有的沙箱池。第一步的诊断必须先把这三条测出来再决定四臂是否跑得起,否则会出现「诊断证实问题存在、 ablation 却做不完」的窘境。

第四步,双信号账本。 每个(问题, 子步)记录 (bi,t,r~i,t,ri,t,ϵi,t)(b_{i,t},\tilde r_{i,t},r_{i,t},\epsilon_{i,t}),外加首次失败步 τi\tau_i。τi\tau_i 直接给出前缀树的截断深度,p^t\hat p_t 就是 τi≥t\tau_i\ge t 的经验频率。

第五步,训练侧接入。 前缀条件分组 + 加权奖励,λ\lambda 从 0 起步做扫描。四臂对照:A 为 SciWalker 原配置(复现基线),B 只换奖励,C 只换分组,D 两者都换。

关键技术挑战集中在三处。 一是接口漂移:轨迹代码改了函数名或签名,嫁接会直接 ImportError,需要区分「接口不兼容」与「局部错误」——先做静态签名对齐,对齐失败记为不可嫁接(NA)而不是判 0,否则 NA 会被当成失败信号灌进梯度。二是状态污染:科学代码常带随机数发生器与模块级缓存,必须用固定 seed 加命名空间深拷贝重放,否则 r~\tilde r 自身不可复现。三是分布偏移:参考前缀是完美前缀,模型训练时永远见不到,r~\tilde r 测的是在最优上下文下能否做对,会高估局部能力;r~\tilde r 只作局部项进入加权,原始 rr 作为可达性项保留,不单独替换。

预期成果

诊断层面给出三条可直接检验的量:p^t\hat p_t 从第 1 步到第 5 步(SciWalker 子步数中位数)的衰减幅度;跨前缀 σ^t\hat\sigma_t 与前缀内 σ^t\hat\sigma_t 的比值;ϵi,t\epsilon_{i,t} 的非零率。这三条不需要任何训练就能算出,也就能在最便宜的时候否掉本提案。

训练层面的目标分两类。硬指标是 SciCode 288 个子问题的池化准确率在四臂之间的排序,以及按子步序号拆开的增益分布——后者是原配置从未报告的口径,也是本提案真正要改变的东西。软指标沿用 BEACON 的口径报非零方差组占比,代码场景的目标定在 60% 以上(BEACON 在 ALFWorld 上从 23.7% 提到 82.0%,代码子步的通过率结构与 embodied 环境不同,不直接套用同一数值)。

五条可证伪预测:P1——p^5<0.5p^1\hat p_5<0.5\hat p_1,若不成立则前缀污染不构成主要矛盾;P2——臂 A 在 t≥3t\ge3 的子步上增益不显著(95% 置信区间跨 0),增益集中在 t≤2t\le2;P3——D 不劣于 B 且 D 不劣于 C,即两处改动互补而非冗余;P4——臂 C 的组内标准差显著低于臂 A,若持平说明 σ\sigma 稀释不成立、只需改奖励;P5——ϵi,t\epsilon_{i,t} 非零率超过 5%,说明前缀与局部的耦合不是稀有事件,而是一类可批量标注的数据缺陷。

定性产出是一份可移植的前缀—局部分解账本。它不依赖 SciWalker 的算子图,任何具备「多步 + 逐步可执行验证」结构的合成代码语料都能挂上去:SWE 多轮轨迹、notebook 单元级数据、科学工作流管线。这类语料当前都只报池化的逐步通过率,前缀污染在每一处都存在且都未被测量。

局限性与失效模式

嫁接判据的外生性是有边界的。 r~i,t\tilde r_{i,t} 相对于「策略前缀」外生,却并不相对于「参考实现」外生。SciWalker 的两份实现走的是两条不同路线——参考实现基于基础数值函数,oracle 实现调用高层科学 API——同一子步在这两条路径下的「正确」未必只有一种写法。ϵi,t≠0\epsilon_{i,t}\neq0 至少有三类来源:接口不兼容、数值口径差异(容差、单位、返回结构)、真正的局部实现错误。P5 想用非零率断言「一类可批量标注的数据缺陷」,前提是先把这三类分开记账;否则 ϵ\epsilon 的高非零率完全可以是参考实现自身的风格差异造成的。诊断阶段应把 ϵ≠0\epsilon\neq0 的样本按失败类型分桶,只有第三类占比可观时 P5 才成立。

分组收缩会反过来放大方差。 前缀条件分组只在 bi,t=1b_{i,t}=1 的轨迹内部比较,代价是有效组规模随 tt 缩水。若 P1 成立(p^5<0.5\hat p_5<0.5),第 5 步的组内样本数不足 8 条的一半,σt\sigma_t 的估计本身就不稳;更极端时整组 r~\tilde r 取值相同,σt≈0\sigma_t\approx0,优势被 δ\delta 压平,这一步实际不产生梯度。也就是说改分组有可能把「方差被污染」换成「方差不可估」,这正是 P4 要防的反面。落地时需要两件原文没写的配套:一个最小组规模阈值(低于阈值不计算段级优势),以及一个「组退化率」监控量——退化组应当从优势计算中剔出,而不是当成零优势样本灌进去,后者会静默地降低有效学习率。

r~\tilde r 进入奖励后存在目标漂移。 λ>0\lambda>0 时,策略有一条捷径可走:写出不依赖前缀、自我包含也能通过测试的代码。这与多步科学工作流要求的「承接上游中间结果」直接冲突。子步通过率会上升,端到端通过率反而下降,而前者正是本提案要改造的奖励信号本身——护栏必须设在端到端通过率上,不能设在子步通过率上。这是四臂 ablation 之外需要单独盯的一件事,因为它不在任何一个原指标里。

r~\tilde r 不能外流成评测指标。 参考前缀是完美前缀,模型在训练时永远见不到、在推理时更拿不到。r~i,t\tilde r_{i,t} 测的是「在最优上下文下能否做对」,系统性高于策略的真实局部能力。它在训练期作加权局部项是有意义的,一旦有人把它当评测口径,就会得到一个不可复现到推理时的虚高分数。

P2 的置信区间必须按 tt 分别报告。 按子步序号拆开后,各 tt 的可用样本量并不相等(tt 越大、前缀仍可用的轨迹越少),把 t≥3t\ge3 合并成一个区间会掩盖样本量的差异,也会让「增益集中在 t≤2t\le2」这一结论变得不可判。正确做法是逐 tt 报区间,并把每档的实际样本数一并列出。

相关工作

  • SciWalker(arXiv:2609.30054):本提案的改造对象。算子图采样 + 执行反馈合成 8,178 道多步科学编程题,子步奖励定义为 ri,t=1[子步 t 测试全通过]r_{i,t}=\mathbf{1}[\text{子步 }t\text{ 测试全通过}],组内前缀可异。
  • BEACON(arXiv:2605.06078):里程碑引导的长程策略学习,双尺度优势 A^=Atraj+λAseg\hat A=A^{\text{traj}}+\lambda A^{\text{seg}},段级优势只在到达同一阶段的轨迹间比较。Φ\Phi 由环境定义,本提案正是为代码场景制造这个 Φ\Phi。
  • GSPO(arXiv:2507.18071):组序列策略优化,SciWalker 用的是其 GSPO-token 形式,组定义为同一查询的多次采样。
  • GiGPO(arXiv:2505.10978):组内组策略优化,在轨迹级组之上按步序号嵌套步级组,步级组仍跨策略自身前缀。
  • SciCode(arXiv:2407.13168):由科学家人工编制的多步科研编程基准,SciWalker 沿用其主问题/子问题格式,本提案的目标评测口径(288 个带背景的子问题)也来自它。