CoSPlay:测试时通过自生成代码与单元测试的协作自博弈框架 CoSPlay: Cooperative Self-Play at Test-Time with Self-Generated Code and Unit Test
无真值单元测试、无训练的测试时代码生成:代码与单元测试双向协作自博弈共同进化。
前置知识
测试时计算扩展(Test-Time Scaling, TTS)
在推理阶段(不更新模型权重)通过增加采样、搜索或验证等手段来提升大语言模型表现的方法,例如 Best-of-N、自一致性、逐步推理等。其核心思想是把更多算力花在"怎么答题"上而不是"重新训练"上,通常需要某种可验证的奖励信号来引导采样方向,否则就只是堆采样。
本文是 TTS 框架的一种新设计,所有改进都发生在推理阶段,不依赖任何 ground-truth 单元测试,也不需要权重更新,因此必须依赖自生成的单元测试作为内部验证信号,这是 CoSPlay 全部方法能否成立的根本前提;不熟悉 TTS 就无法理解论文为什么要把推理成本从数百 token 推到 $10^5\sim10^6$ token。
可验证奖励强化学习(RLVR)
利用可在执行环境中验证的奖励(例如代码是否通过测试用例、数学答案是否正确)来训练大语言模型的方法。它绕过了人工偏好标注的噪声,但要求存在可靠的真值(ground-truth)信号。代表方法如 CURE、AceCoder、Absolute-Zero 都用预定义的真值单元测试做训练奖励,需要预先生成覆盖题目的输入输出对。
本文明确以 RLVR 为对比基线(用了 CURE-7B/14B、AceCoder 等),并指出 RLVR 需要大量 ground-truth UT 才能有效;而本文方法完全不需要这些真值,因此是 RLVR 的"测试时替代方案"。理解 RLVR 才能体会到 CoSPlay 论文最大卖点——它把 GT 数据需求从训练阶段彻底移到运行时。
执行矩阵与通过计数(Execution Matrix & Pass Count)
把 $N_c$ 个代码候选和 $N_t$ 个单元测试两两执行,得到一个 $M \in \{0,1\}^{N_c \times N_t}$ 的二值矩阵,$M_{ij}=1$ 表示代码 $c_i$ 通过了测试 $t_j$。由此可以定义代码通过计数 $p^{\text{code}}_i = \sum_j M_{ij}$(代码通过了多少测试)和测试通过计数 $p^{\text{UT}}_j = \sum_i M_{ij}$(测试被多少代码通过),并归一化为通过率 $\alpha$。
执行矩阵和通过计数是本文最核心的内部信号——在没有 ground-truth 的情况下,作者利用它来同时评判代码候选质量(高通过计数→更可能正确)和单元测试可靠性(高通过计数→更可能是有效测试),是协作自博弈得以进行的基础;理解它才能看懂 Section 2.3 四个 self-play 步骤为什么这样设计。
执行一致性与聚类选择(Execution Consensus / Output Clustering)
一种不依赖真值的代码选择方法:在多个候选代码上运行相同的随机输入,观察它们的输出签名 $\sigma(c_i) = (o_i(z_1),...,o_i(z_R))$,把输出兼容(即所有随机输入上输出一致)的代码聚成簇。直觉是:正确代码对相同输入有相同输出,错误代码则倾向于以不同方式出错,因此最大簇更可能是正确答案。本文还用 Proposition A.3 给出了形式化收敛保证。
这是本文阶段 3(最终选择)的关键机制,用来打破 BoN 平局,也是论文中"无 ground-truth 也能选出正确代码"的最后一道保险;如果不理解执行一致性,就无法明白为什么最大簇就能当答案,更看不到它与 CodeT 等"输出一致性过滤"的区别。
协作自博弈(Cooperative Self-Play)
博弈论术语,指多方参与者通过合作而非对抗来实现共同改进。在本文中,"代码池"与"单元测试池"就是博弈的两方,它们通过彼此的执行信号互相提升而非相互制约——代码用"通过多少测试"度量,UT 用"被多少代码通过"度量,两者形成正反馈循环。
区别于对抗式自博弈(如 self-play GAN),CoSPlay 的协作性体现在:代码通过单元测试来确认正确性,单元测试通过代码被通过的比例来确认可靠性,二者形成正反馈循环而非对立关系;这一博弈视角贯穿整个方法,理解它是把握论文 Section 2 灵魂的关键。
研究动机
近年来 LLM 代码生成能力的提升主要依赖两类方法:可验证奖励强化学习(RLVR)和测试时计算扩展(TTS),二者都需要 ground-truth unit test(GT UT)作为可靠信号。例如 SOTA RLVR 模型 CURE-7B/14B 用 4.5k 真值 UT 训练,AceCoder-RM 用了 329k 真值数据,AceCoder-Rule 也用了 22k。然而这类人工/官方编写的真值单元测试既贵又难规模化——每道题需要专家写覆盖边界情况的输入输出对。在没有 GT UT 的纯测试时场景下,现有方法(如 S*、SFS、MPSC、CodeTree、ThinkCoder、PowerSampling、CodeT)只能直接用模型自生成的 UT 来过滤/排序代码,但自生成 UT 经常出现两种问题:(1)期望输出写错;(2)与错误代码 spurious 耦合(错误地只通过了少数错误代码),导致既评不准代码也验证不了 UT 本身。
本文的目标是本文提出 CoSPlay,目标是建立一套完全不需要任何真值单元测试、不需要任何权重更新的测试时框架,仅用模型自身的代码生成与执行能力,就把代码生成 BoN 准确率抬升到能与 RLVR 训练过的模型(CURE-7B/14B)抗衡的水平,并在 RLVR 模型上进一步追加提升。具体而言,把 Qwen2.5-7B-Instruct 的平均 BoN 从基线的 22.1% 抬到 33.2%(+11.1 绝对提升),UT 准确率从 14.6% 抬到 78.3%;在 CURE-7B 上再加 +5.7%、CURE-14B 上加 +4.4%。
与已有工作不同的是,以往 GT-free TTS 工作只把生成的 UT 当成静态过滤器(采样完代码和 UT 后做一次性排序),缺乏"通过率反映可靠性/正确性"的反馈闭环。本文独到地把代码池和 UT 池放在执行矩阵里做双向 pass-count 信号,让两边相互打分、共同进化,再在 BoN 打平时用输出一致聚类做最终选择。这一"共进化"视角是已有 GT-free TTS 工作所忽视的。具体地:第一,让代码池按"非平凡最好 UT"自我 refactor;第二,让 UT 池按"被多数代码通过"的 feedback 自动剔除可疑样本;第三,给 BoN 平局提供最长输出兼容簇作为兜底。这三件事单独都有人做过,但组合在一个统一的执行矩阵自博弈里是本文的新意。
核心方法
CoSPlay 是一个三阶段的 pipeline,全程冻结 LLM 权重,仅靠提示工程和执行反馈。直觉上,"好的代码应该比坏代码通过更多有效的测试","好的测试应该被更多正确代码通过",所以把 $N_c$ 个代码候选和 $N_t$ 个 UT 放在一起两两执行,得到的 $N_c \times N_t$ 通过矩阵就可以同时给两侧打分,并据此迭代剔除低质量样本、修正可疑样本。技术路线分三步:第一阶段(Exp-Atk 引导的代码/UT 想法生成)先让 LLM 自己 brainstorm 多种解题思路,再针对每种思路去想可能的失败模式,从而生成针对性强、可区分的 UT 想法,避免直接 prompt 出"通用而无用"的测试。第二阶段(执行矩阵驱动的迭代自博弈)把代码池与 UT 池放在一起跑出执行矩阵,用 pass-count 信号做四步循环:①清洗全部失败的代码;②重生成与错误代码虚假耦合的"非平凡最差"UT;③用"非平凡最好"UT(即通过率高但非全过的)做代码 refine;④替换对当前代码池完全无区分力的 UT。第三阶段(输出一致聚类选择)当 BoN 出现并列冠军时,对这些候选在 $R$ 个随机合法输入上跑输出签名 $\sigma(c_i)=(o_i(z_1),...,o_i(z_R))$,用执行一致关系做兼容聚类,把选最大的簇作为最终输出。
核心创新是"执行矩阵驱动的代码-UT 协作共进化"。已有 GT-free TTS 方法在自生成代码和 UT 后只做一次性过滤或排序(思路见 CodeT 的输出一致性、CodeTree 的树搜索等);而 CoSPlay 把执行矩阵当成双向裁判,pass-count 既能评判代码可信度也能评判 UT 可信度,两侧可以互相"督促修复",并通过 exp-atk 引导确保初始 UT 与具体解法的失败模式对齐。这一视角下,原来彼此独立的"生成代码"、"生成 UT"、"选 Best-of-N"三个环节被融合成一条迭代的"协作自博弈"闭环。此外在最终选择阶段,加入了"正确代码在随机输入上输出相互一致"的输出一致聚类作为 BoN 平局的破局方法,这是一种不依赖任何真值的"功能性聚类"思路,比 CodeT 单层输出一致更具鲁棒性。
方法步骤详情
完整流程分为三个阶段、六个可操作步骤。阶段 1(Exp-Atk 引导的想法生成):(a) 对问题描述 $P$ 让 LLM 生成高级算法提示集合 $H=\{h_i\}$;(b) 在子集空间 $\Omega=\{\omega\subseteq H | |\omega|\in\{1,2\}\}$ 上扩展为详细解题方案池 $S$;(c) 对每个方案 $s\in S$ 让 LLM 分析潜在失败模式,得到"UT 攻击想法"池 $A$。阶段 2(池初始化与执行矩阵自博弈):(d) 代码池 $C=\{c_i\}_{i=1}^{N_c}$ 通过从 $S$ 随机抽题生成;测试池 $T=\{t_j\}_{j=1}^{N_t}$ 一半来自随机合法输入、一半来自 $A$ 中的攻击输入,期望输出通过"采样 4 次至少 3 次一致"来保证先验正确;(e) 在 $M\in\{0,1\}^{N_c\times N_t}$ 上执行四步循环:step①清掉全部失败的代码(按 $\alpha^{\text{code}}_i=0$)重新采样补齐;step②挑通过率最小但非平凡的 $t_{j_{\text{worst}}}$,将原 UT 与它通过的少数代码一起喂给 LLM 生成新 UT 打破虚假耦合;step③挑通过率最大但非平凡的 $t_{j_{\text{best}}}$,用其执行反馈 refine 失败的代码;step④替换通过率为 0 或 1 的 trivial UT。每步后重算 $M$,循环直到 $M$ 全 1 或达到 $T_{\max}=5$ 轮。阶段 3(输出一致聚类):(f) 对 BoN 并列最高的 $\mathcal{C}_{\text{high}}$ 代码,在 $R$ 个随机合法输入 $Z=\{z_r\}$ 上跑出输出,按"对所有 $z_r$ 输出一致且无 ERR"判定观察兼容 $c_i \sim_{\text{obs}} c_j$,按固定确定性顺序构造保守兼容簇 $\{G_m\}$;按 $S^{\text{cls}}(G_m)=\sum_{c_i\in G_m}\sum_{c_j\in G_m\setminus\{c_i\}}\sum_{k=1}^R \mathbb{1}\{o_i(z_k)=o_j(z_k)\neq\text{ERR}\}$ 取最大簇与簇内最高分代码作为最终答案。
技术新颖性
技术新颖性体现在三个层面。第一是"探索-攻击"双层想法生成:与 PlanSearch 的纯探索不同,CoSPlay 显式地把每种解题方案对应的失败模式作为 UT 设计的种子(exp-atk),让初始 UT 既可信又可区分,实测把初始 UT 准确率从 12.5% 提到 37.2%、Signal 从 26.5% 提到 33.7%(附录 Table 7),pass-count 平均提升了 $\delta=2.39$。第二是"双向 pass-count 信号引导的迭代自博弈":每步操作都有明确的可解释触发条件(all-fail / non-trivial worst / non-trivial best / zero-discrimination),并在每步后重算矩阵,这与 CodeT 等一次性评分不同。第三是"带 ERR 容错的输出一致聚类":使用 ordered pairwise valid agreement 分数 $S^{\text{cls}}$ 而不是简单簇大小,对运行时报错情况鲁棒,并被 Proposition A.3 形式化为:当候选独立采样时最大簇在后验上收敛到真签名。Theorem A.1 还形式化了 pass-count 与真实正确性的后验单调关系:$\Pr(\text{correct}\mid p^{\text{code}}_i)$ 随 $p^{\text{code}}_i$ 单调上升(需要满足 Eq.10 的优势阈值)。整体而言,它把 GT-free TTS 从"采样+静态过滤"升级到"动态协作博弈"。
实验结果
Table 1 是核心实验表,覆盖 LiveBench、LiveCodeBench v2、CodeContests、CodeForces 四个 SOTA 编码基准(分别 128/511/239/467 题)。在 7B 规模,Qwen2.5-7B-Instruct + CoSPlay w/Cluster 把平均 Signal 从 22.1% 提升到 31.9%、UT 准确率从 14.6% 提升到 78.3%、代码准确率从 19.0% 提升到 23.3%、BoN 从 22.1% 提升到 33.2%(+11.1 绝对),且 BoN 略微胜过用 4.5k 真值训练过的 CURE-7B(33.2% vs 32.9%),而 UT 准确率大幅领先(78.3% vs 54.9%)。在 14B 规模,Qwen2.5-14B-Instruct + CoSPlay 把 BoN 从 33.2% 拉到 42.0%(+8.8),UT 准确率从 32.4% 拉到 77.6%。把 CoSPlay 套在已经 RLVR 训练过的 CURE-7B/14B 上还能继续叠加:CURE-7B BoN 从 32.9% → 38.6%(+5.7),CURE-14B BoN 从 41.8% → 46.2%(+4.4),说明 CoSPlay 与 RLVR 互补、可叠加。在最强模型上,DeepSeek-V3.2-685B(685B 参数)平均 BoN 从 65.7% 提升到 68.2%,最难基准 CodeForces 上从 39.3% 提升到 50.0%(+10.7 绝对),证明对超大模型仍有显著价值。
查看结构化数据
| 任务 | 指标 | 本文 | 基线 | 提升 |
|---|---|---|---|---|
| LiveBench | BoN (Best-of-N) Acc. | 50.3% (Qwen2.5-7B-Ins. + CoSPlay w/ Cluster) | 36.2% (Qwen2.5-7B-Ins. baseline) | +14.1 绝对(+38.9% 相对) |
| LiveCodeBench v2 | BoN Acc. | 43.4% (7B + CoSPlay w/ Cluster) | 31.2% (7B baseline) | +12.2 绝对(+39.1% 相对) |
| CodeContests | BoN Acc. | 34.6% (7B + CoSPlay w/ Cluster) | 31.2% (7B baseline) | +3.4 绝对(+10.9% 相对);UT 准确率从 24.1% 跃升到 74.4%(+50.3) |
| CodeForces | BoN Acc. | 16.8% (7B + CoSPlay w/ Cluster) | 7.1% (7B baseline) | +9.7 绝对(+136.6% 相对),UT 准确率 12.9% → 85.0% |
| LiveBench(14B 规模) | BoN Acc. | 57.6% (Qwen2.5-14B-Ins. + CoSPlay w/ Cluster) | 51.0% (14B baseline) | +6.6 绝对;UT 准确率从 26.4% 跃升到 70.1% |
| CodeContests(14B 规模) | BoN Acc. | 40.0% (14B + CoSPlay w/ Cluster) | 34.6% (14B baseline) | +5.4 绝对;UT 准确率 43.2% → 71.7% |
| CURE-7B 增强(叠加 RLVR) | BoN Acc. | 38.6% (CURE-7B + CoSPlay w/ Cluster) | 32.9% (CURE-7B) | +5.7 绝对,证明对已 RLVR 的模型仍可叠加 |
| CURE-14B 增强(叠加 RLVR) | BoN Acc. | 46.2% (CURE-14B + CoSPlay w/ Cluster) | 41.8% (CURE-14B) | +4.4 绝对 |
| CodeForces on DeepSeek-V3.2-685B(前沿模型) | BoN Acc. | 50.0% (CoSPlay w/ Cluster) | 39.3% (Direct) | +10.7 绝对,说明在超大模型/难题上仍有显著价值 |
局限与改进
作者本人明确指出两点限制:(1)CoSPlay 依赖可执行环境来拿到 Code-UT 反馈,因此无法直接迁移到非可执行的推理任务(如开放式问答);(2)完整 CoSPlay 因为要迭代生成、运行、refine 代码和 UT,会消耗更多 token。但 Figure 11 也表明:即便在可比 token 预算下 CoSPlay 仍是 SOTA,且其改进斜率比 SFS、MPSC、S*、CodeTree、PowerSampling、ThinkCoder 都要陡,因此并非"花得多就赢"。另外 Section 4.1 给出了一个重要的"自博弈有效性三区段"分析:(a)当下层 backbone 太弱,初始 UT 正确先验低于阈值 $\rho_T^\star$ 时,pass-count 信号噪声大、虚假耦合占优、无法稳定改进;(b)当 backbone 极强时池子接近饱和,refresh 与 repair 的期望改善有限,反而引入采样方差导致震荡;(c)只有处于中间区域(pass-count 与正确性对齐且低支持样本仍有改进空间)时自博弈才能稳定提升。这从理论上解释了为什么 Qwen-7B-Coder(纯 code 预训练、非 instruct)这种"普通 backbone"甚至平均 BoN 比 baseline 还低(12.0%),因为它本身产生 code 的多样性不够,初始 UT 池质量就受限。我们观察到 Figure 8 在极端困难基准(CodeForces 信号密度提升主要靠 7B 模型从基线 7.1% 拉到 16.8%)上的提升幅度比简单基准更显著,表明该方法对难题更有效。
独立分析的弱点
独立分析可以看到几个值得改进的弱点:(1)**前期投入大、ROI 滞后**:Figure 11 显示 Qwen2.5-7B-Instruct 上 Direct 模式(仅 628.3 token)已经达到 Pass@1 22.7%,而完整 CoSPlay 需要 $10^5$ ~ $10^6$ token 才能追上并超过,扩大百倍推理成本才换来 +10% 左右的 Pass@1 提升;对于延迟敏感的应用很难直接套用。改进方向:可以把阶段 1 的 exp-atk 想法预生成做缓存复用、或者把阶段 3 的输出一致聚类仅在 BoN 平局 ≥2 时才启用,能省掉一半 token。(2)**单一模型表达能力的天花板**:论文 Section 4.1 提到 backbone 太弱或太强时 CoSPlay 失效,Qwen2.5-7B-Coder 这种 base 模型直接 +CoSPlay 反而退化到 12.0%(Table 1)。改进方向:可以引入预训练/instruct 差分、或者与 few-shot 示例结合启动 exp-atk;针对强模型则可减小 $N_c/N_t$ 与 $T_{\max}$ 来抵消"饱和震荡"。(3)**对运行时报错的脆弱性**:阶段 3 用 observed-compatibility 来回避 ERR,但实际中如果某道题大多数候选都炸出 ERR,聚类退化为随机。改进方向:用 LLM 自身的 self-debug 修复或加入 type-check 预筛来降低 ERR 比例。(4)**缺乏对 prompt 注入/对抗性输入的鲁棒性**:测试输入来自 LLM 自身 brainstorm,理论上可能被 prompt 操纵。改进方向:引入 sanity-check 与人类风格 hard-coded 边界用例作为锚点。(5)**执行矩阵 $N_c\times N_t$ 太小时统计噪声大**:64 个执行点不足以稳健区分高质量与低质量样本,论文也承认 $k=64$ 时仍未饱和。改进方向:把 pass-count 和双向 KL 散度等更复杂的统计量结合、做分层 bootstrap 评估。
未来方向
作者在 Section 5 明确提出两个方向:(1)将 CoSPlay 推广到非可执行推理任务,例如数学证明或形式化推理,把"单元测试"换成可验证的形式规约或公理检查;(2)提升 token 效率,降低迭代共进化的开销。基于成果可延伸的方向包括:(a)**与 RLVR 的深度融合**:当前只在推理时叠加 CURE,可考虑把 CoSPlay 的 pass-count 信号作为 RLVR 的在线奖励,做"test-time co-evolution + RLVR 微调"的两阶段训练;(b)**多模态扩展**:把 UT 池换成可执行的图像/视频断言,把代码扩展为多模态推理;(c)**Pipeline 与 UT 的解耦**:把 UT 设计做成独立子任务,预训练一个"attack idea 生成器",降低主模型 token 消耗;(d)**理论保证加强**:作者已经给出 Theorem A.1(pass-count 单调性)和 Proposition A.3(最大簇收敛性)的形式化基础,未来可以把"三区段效应"(weak/medium/strong backbone)的临界条件用更紧的理论界刻画;(e)**类集成扩展**:把多个不同家族模型的执行矩阵拼接(类似 ensemble 思想),进一步降低对单一 backbone 强弱的依赖;(f)**与 NeurIPS-style Best-of-N with verifier** 结合:如 Self-Rewarding LM、Quark-RL,用 reward model 标注 pass-count 替代输出聚类。
复现评估
论文在 GitHub Page 上公开了完整代码、数据集与日志(Dataset & Log 链接已在首页给出,作者团队 2026-5-13 上传);代码、prompt 模板、随机种子都可追溯。**算力成本**:所有实验跑在两块 NVIDIA H100 80GB GPU,使用 vLLM 推理框架,temperature=0.8、top-p=0.95、top-k=40。**重要超参**:代码池 $N_c=16$、UT 池 $N_t=16$、自博弈轮数 $T_{\max}=5$、每个 UT 输入采样 4 个期望输出且至少 3 个一致、Stage 1 中 UT 一半随机一半来自 exp-atk。**复现难度**:中等偏下——所有超参都给了默认,prompt 模板要按附录 H 复用。但由于完整跑一遍 Table 1 需要对 5+ 个 backbone × 4 个基准 × 多个种子组合实验,单卡复现 7B 主实验预计需要几天,14B 需要更长时间;想要作者 Figure 10(a) 那种 $k=64$ 的 scaling 实验,则需要把 token 预算拉到接近 $10^6$。**数据**:四个 benchmark 都来自公开比赛题(LiveBench、LiveCodeBench v2、CodeContests、CodeForces),评估脚本与 CURE 论文共享,避免了私有数据泄漏问题。
论文图表
2x2 分类矩阵,把现有方法按'TTS/RLVR × w/GT/w/o GT'四象限:TTS w/GT 用 GT 做执行+ Refine/Rerank,TTS w/o GT 通常只做静态 Refine,RLVR w/GT 用 GT 算 reward,RLVR w/o GT 用 GT-free reward(仍需训练)。右下角标出本文的 Cooperative Self-Play:Code-UT 双池(包含 Trivial/Fix/ReGen/Update/Replace 等动作)通过多轮协作共进化。
Figure 2 在 Section 1 开头把'为什么需要 GT-free & training-free 的共进化'画得非常直观——它把已有方法的全空间画出来,明确指出空白象限并说明本文如何填补,对理解论文 motivation 至关重要;如果跳过这张图直接读 Section 1 文字会错过作者精心设计的定位。
两张双对数坐标图(左 7B / 右 14B),横轴是平均 token cost,纵轴 Pass@1,绘制 Direct、BoN、SFS、S*、ThinkCoder、MPSC、CodeTree、PowerSampling 等 TTS baseline 与 CoSPlay、CoSPlay w/o self-cons.、CoSPlay w/o self-cons. & UT-iteration 等版本;越暗的标记表示越大的推理预算,CoSPlay 沿 round 0 → 5 给出轨迹,标注了 Direct 22.7% @ 628.3 token、26.5% @ 568.0 token 作为锚点。
这张图直接对比'花同样多 token 谁更划算',是评估 CoSPlay 工程可行性的最关键图表——它量化了 CoSPlay 比 SFS、S*、MPSC、CodeTree 等要更陡的提升斜率,直接决定一个工程师是否愿意把这套 pipeline 部署到生产环境。