← 返回 PaperDaily
视觉与图像
让代码AI出题考自己!南洋理工TCS两阶段强化学习方案全解析
考过程序设计竞赛的读者应该都有同感:决定命运的不是“你觉得自己写对了”,而是评测数据有没有精准戳中你代码里藏得最深的bug。
龙哥读论文
发布于 2026-09-05 00:31:07
阅读 5
查看原文
原论文信息如下:
代码大模型的新瓶颈:测试用例质量决定验证上限
考过程序设计竞赛的读者应该都有同感:决定命运的不是“你觉得自己写对了”,而是评测数据有没有精准戳中你代码里藏得最深的bug。如今代码大模型也撞上了同一面墙——随着模型能力越来越强,常规样例已经很难把不同候选解法区分开,问题正从“生成一段能跑的代码”变成“在一堆都能跑的代码里找出真正符合题意的那一个”。
于是“自我验证”成了一个极具吸引力的方案:让模型针对候选程序自己生成测试用例,再去执行、数通过数,谁通过得多谁就胜出。这种方案不依赖外部奖励模型,靠的是可执行证据,听起来非常优雅。但问题在于,自生成测试必须同时满足两个苛刻条件:一是可靠性 ,也就是测试用例的输入输出标注必须正确,不能在标准解身上“误伤”;二是区分度 ,也就是测试要能暴露错误程序的漏洞,否则错误解法全部蒙混过关,验证等于白做。前者不够会冤枉好人,后者不够会放过坏人。
论文实验里有一个非常值得玩味的现象:直接让基础模型“边写边考”,自生成测试带来的提升其实很有限;而只用人工整理的公开测试集去筛选候选,效果反而更好。这说明瓶颈从来不是“测试生成得不够多”,而是生成得不够好 ——测试用例的质量,直接决定了验证机制的天花板。
来自南洋理工大学和Skywork AI的研究团队,把这个问题建模成一个对抗式强化学习问题,并提出了一套名为TCS (Test Cases Scaling,测试用例扩展)的两阶段训练框架。它的核心思想并不复杂:让代码大模型既当“考生”又当“出题老师”,先用标准答案把模型教成一名合格的出题者,再让它学会针对当前错误解法“量身定制”反例。
TCS两阶段框架:从可靠测试到对抗反例的课程学习
先看TCS的任务设定:每个训练样本包含一道题目的自然语言描述P、一份标准解C*(ground-truth solution)和一套数据集测试集τ。TCS让同一个模型同时扮演两个角色——求解器 (Solver)根据P生成代码,目标是跑通τ里的全部测试;验证器 (Verifier)则拿到P和一个候选程序,生成新的测试用例,要求“标准解能通过、错误的候选程序过不了”。
为什么要一个人分饰两角?因为在执行可验证的设定下,标准解C*提供了一个干净的“可靠性锚点”,而候选程序C则定义了“对抗目标”。生成可靠测试和生成针对具体bug的反例,是两种容易混在一起的能力;先分开训练再统一,反而能取得更好的协同效果。整个训练流程如图2所示,求解器与验证器共享一套策略参数,使用GRPO(Group Relative Policy Optimization,组相对策略优化)进行联合优化。
GRPO是DeepSeek等工作中常用的强化学习算法,它用一个提示词下多个采样回答的平均奖励作为基线,省去了独立价值网络。每个候选的“优势”用组内标准化得到:
TCS之所以必须分成两个阶段,是因为“生成反例”的奖励极其稀疏。一个能揭露bug的测试用例,要求模型同时做到两件事:生成与标准解一致的正确输入输出,并且恰好命中当前错误候选的某个非平凡漏洞。让基础模型直接去优化这个目标,就好比让刚学编程的新手直接去出国际竞赛题,模型在长周期内拿不到任何正反馈,强化学习根本转不动。
但只学阶段1还不够。只要求“正确”会诱导模型走捷径,生成空数组、最小样例这类人畜无害的平凡用例——它们虽然不会误伤标准解,但也无法鉴别错误程序。因此当测试生成器在训练批次上的准确率超过0.75左右(1.5B模型大约需要200步,7B大约需要40步),训练就切换到阶段2。此时缓冲区B被清空,只收入“可执行但会挂掉至少一个数据集测试用例”的错误程序,并施加一个更苛刻的奖励:
R₂ᵗ(I_g, O_g, C*, C_wrong) = 1,当且仅当 Exec(C*, I_g) = O_g、Exec(C_wrong, I_g) ≠ O_g,且 (I_g, O_g) ∉ T_example;否则为0。
这个奖励函数处处体现“定向打击”的意图:同一组输入输出,标准解C*必须通过,错误候选C_wrong则必须失败。直接把奖励定义在“候选程序当前会怎么错”上,迫使模型去理解bug模式,而不是泛泛地找几个边界值。
策略对齐缓冲区:让验证器追踪求解器的失败演化
如果只看两个阶段奖励函数,可能会觉得TCS就是把离线数据拿来做两轮强化学习。真正让框架“活”起来的,是它的策略对齐缓冲区 (policy-aligned buffer,简称B)。
缓冲区里的候选程序不是从外部静态数据集里找来的,而是求解器在训练过程中实时生成的输出。每当模型写出新代码,只要满足当前阶段的筛选条件,就会被放进缓冲区;同时只保留最近T_b个训练步的样本,旧样本不断被丢弃。这样缓冲区内容始终跟随策略当前的能力分布滚动更新。
这个设计背后的逻辑值得细品。强化学习训练中,求解器策略每时每刻都在变化,早期模型犯的低级错误,到后期可能根本不会出现;反之,随着求解能力增强,新的、更隐蔽的失败模式会不断冒出来。如果验证器训练数据是固定离线的,它学到的是“如何打败过去的模型”,而不是“如何打败现在的模型”。在线缓冲区相当于一个永不掉线的陪练,逼着验证器永远面对求解器当下最真实的软肋。
值得注意的是,两个阶段对缓冲区样本的准入标准并不相同。阶段1只要求候选程序可执行,不要求它出错——此时验证器先学习面对各种代码风格生成可靠测试;一旦切换到阶段2,缓冲区立刻清空并转向只收“可执行但错误”的程序。这样的课程设计让模型先学会走,再学会跑。
理论保证与实验验证:指数级可靠性界与全面性能提升
光有漂亮的训练框架还不够,TCS还为“为什么自生成测试可以用来做推理时选择”提供了理论支撑。推理时,对同一道题采样N个候选代码,每个候选C_i生成M个测试用例,汇总成K = N × M个测试,然后选出通过数最多的候选:
当δ > α,也就是“测试对错误候选的命中能力”强于“测试本身出错的比例”时,随着测试数量K增大,选错候选的概率会指数级下降:
实验部分,论文在TACO和LiveCodeBench两个代码生成基准上验证了TCS的效果。TACO的25,433道题被过滤成6,318道拥有充分测试覆盖的实例用于训练,评估集是1,000道验证题;LiveCodeBench则作为跨分布测试集。模型选择DeepSeek-R1-Distill-Qwen家族,包含1.5B和7B两个尺寸。基线设置也相当用心:除了基础模型和联合SFT(joint SFT,使用R1-Distill-Qwen-32B生成的、已经人工筛选的对抗性数据)之外,还拆出了仅训练求解器的Code-RL和仅训练验证器的Test-RL,用于隔离联合训练的价值。
表格中有一个系统性规律:TCS训练后的模型,其自生成测试在做Best-of-N选择时的表现,从“明显弱于奖励模型排序”逆转为“持平甚至反超奖励模型排序”。这恰恰说明两阶段训练提升的不只是代码正确率,更包括“判断什么代码是对的”的验证能力。论文还报告了一个让人印象深刻的数字:在LiveCodeBench上,7B基础模型本来pass@1只有28.56,加入自生成测试加Best-of-N选择后冲到43.01,涨幅超过14个百分点。这个提升不是靠外部奖励模型,也不是靠人工测试用例,而是模型自己出题考自己考出来的。
解耦实验的价值在于排除“只是RL把求解器变强了”的替代解释。只做Code-RL虽然也能提升pass@1,但它生成测试的筛选能力并没有同步跟上;只做Test-RL虽然训出了一把好测试标尺,但求解器本身的进步有限。只有联合训练形成了一个正向循环:更聪明的求解器制造更难的失败模式,更强的验证器反过来帮助筛选出更好的解。
TCS生成的测试还具备不错的泛化筛选能力:用TCS-7B训练出的测试去筛选其他强外部模型的输出,也能带来一致的Best-of-N提升。这再次印证了论文的核心观点——“会出题”并不只是“会写代码”的副产品,而是一种可以迁移的代码理解能力。
局限与展望:从单测试生成到多测试协同
TCS的设定有一个前提:需要同时拿到问题描述、标准解和可执行测试环境。这个条件在竞赛编程类任务里成立,但在真实软件工程场景中并不总能满足——很多业务代码根本没有一份“标准答案”可以用来校验测试的可靠性。因此,把TCS推广到更开放的程序合成与单元测试自动生成场景,还需解决“标准解缺失”时的可靠性锚定问题。
另一个值得注意的方向是“多测试协同”。论文推理时默认每个候选只生成1个测试(M=1),而理论分析已经表明,每个候选生成多个独立测试、扩大K值,可以将选错概率进一步指数级压低。当生成测试的成本足够低时,让多个测试用例共同投票,可能会比单纯增加候选代码数量更划算。这也呼应了近年来大模型推理时扩展的研究主线:给模型更多“自我检查”的机会,往往比盲目多采样更高效。
从成本角度看,TCS需要额外的两阶段强化学习训练,对算力有一定要求。论文在NVIDIA H100 80GB上的训练与单次评估用时对比如下表所示,实际落地时还需要把执行测试用例的环境开销计入总成本。
龙迷三问
这篇论文到底在解决什么问题? 南洋理工大学与Skywork AI提出两阶段强化学习框架TCS,让代码大模型学会生成既可靠又具针对性的测试用例,推理时用自生成测试筛选正确代码。
这篇工作最值得看的点是什么? TCS在两个基准上均提升pass@1和推理时选择性能;TCS-7B在LiveCodeBench上pass@1从28.56提升至43.01(自生成测试选择BoN-32);TCS微调的1.5B模型可超越14B基础模型;自生成测试在无公开测试时优于奖励模型排序。
这篇工作的边界或风险在哪里? 优点:(1) 两阶段课程设计有效解决稀疏奖励问题;(2) 策略对齐缓冲区使验证器跟踪求解器演化失败模式;(3) 理论分析(指数可靠性界)为推理时扩展提供保证;(4) 联合训练产生协同效应。缺点:(1) 需要真实解C*进行训练验证,限制无验证解场景;(2) 每次推理仅生成单个测试用例,效率受限;(3) 硬切换两阶段可能非最优;(4) 训练计算资源需求高。
如果你还有哪些想要了解的,欢迎在评论区留言或者讨论~
龙哥点评
论文创新性分数: ★★★★☆。把测试生成拆成“可靠性”和“对抗性”两个阶段并用在线缓冲区衔接,角度在国内代码RL工作里不多见;还给推理时测试选择补了一个指数级可靠性界,形成了“现象→方法→理论”的完整叙事。
实验合理度: ★★★★☆。对照组设计得很扎实:既有外部奖励模型排序,又有CodeRM-8B测试生成器对比,还拆了Code-RL和Test-RL来隔离联合训练的作用;这类消融在代码生成RL论文里属于高配。扣一星是因为表格排版较乱,部分数字在正文与表中对读时要花不少力气。
学术研究价值: ★★★★☆。“让模型学会生成测试来验证自己”这个方向,对推理时扩展和代码智能体自我纠错都有借鉴意义;把测试生成的可靠性问题用两个可量化指标α和δ刻画,也给后续工作留下清晰的优化坐标。
稳定性: ★★★☆☆。在竞赛类代码生成任务上表现稳定,反复实验都指向同一个结论;但对“标准解缺失”的现实代码场景,TCS没有验证锚点,稳定性会明显下降,所以分值保留三星。
适应性以及泛化能力: ★★★☆☆。已经在TACO和LiveCodeBench两个分布上验证,而且强外部模型也能受益于TCS训练出的测试;但整体仍限定在Python算法题这类可执行验证的环境,真实软件工程场景的泛化能力尚未被证明。
硬件需求及成本: ★★★☆☆。两阶段RL训练需要H100级别显卡,推理时又要批量执行自生成测试,整体算力开销不低;但好处是不需要额外奖励模型参与排序,省掉了一个推理时的大模型调用成本。
复现难度: ★★★☆☆。论文公开了训练数据过滤标准、阶段切换阈值和推理时配置,技术上具备复现条件;但TACO数据筛选、32B教师数据生成和两阶段调参的工程量不小,实际跑通仍需投入可观时间。
产品化成熟度: ★★☆☆☆。目前最合适的产品落点是“算法题的自动验证与代码评测辅助”,比如给在线评测系统生成补充测试数据;距离通用的软件开发测试助手还有一段路,主要瓶颈是要么有标准解、要么有可靠的人工测试锚点。
可能的问题: 生成反例依赖“错误候选必须真的错误”,如果缓冲区里收集的代码只是边界用例失败而不是逻辑性错误,验证器学到的主要是边界条件排查,对深层逻辑缺陷的打击力还有待检验。
主要参考文献
Xu J, Zhang W, Lyu Z, et al. Two-Stage Reinforcement Learning for Sound and Adversarial Test Generation in Code LLMs. arXiv:2609.03955, 2025.
Shao Z, Wang P, Zhu Q, et al. DeepSeekMath: Pushing the Limits of Mathematical Reasoning in Open Language Models. arXiv:2402.03300, 2024. (GRPO)
Li R, Allal L B, Zi Y, et al. StarCoder: May the Source Be with You? TACO数据集相关,2023.
Jain N, Han K, Gu A, et al. LiveCodeBench: Holistic and Contamination Free Evaluation of Large Language Models for Code. ICLR 2025.
Chen B, Zhang F, Nguyen A, et al. CodeT: Code Generation with Generated Tests. ICLR 2023.
Ma Y, Xie Y, Gou J, et al. CodeRM: A Versatile and Efficient Reward Model for Code Generation. 2025.
代码生成再卷出新高度:光会写代码还不够,AI还得学会给自己出题、当自己的“AI考官”!对代码大模型、RL训练、测试生成与推理时扩展感兴趣的小伙伴,欢迎加入龙哥读论文粉丝群,扫描下方二维码或者添加龙哥助手微信号加群 :kangjinlonghelper。一定要备注:研究方向+地点+学校/公司+昵称(如 代码智能+上海+南洋理工+小龙) ,根据格式备注,可更快被通过且邀请进群。
『龙哥读论文』微信群目前包含:图像处理、大模型及智能体、自动驾驶及机器人、AI医疗及AI金融5个群~
*本文仅代表个人理解及观点,不构成任何论文审核或者项目落地推荐意见,具体以相关组织评审结果为准。欢迎就论文内容交流探讨,理性发言哦~ 想了解更多原文细节的小伙伴,可以点击 "阅读原文", 查看更多原论文细节哦!