Program Synthesis via Test-Time Transduction¶
会议: NeurIPS 2025
arXiv: 2509.17393
代码: GitHub
领域: 程序合成 / LLM 推理
关键词: program synthesis, transductive inference, active learning, hypothesis elimination, LLM, edge cases
一句话总结¶
提出 SYNTRA 框架,将程序合成重新定义为转导式学习——在测试时利用可见的 test inputs 和 LLM 的判断来迭代消除不一致的候选程序假设,通过 greedy maximin 算法最小化 LLM 查询次数,在 4 个 benchmark 上准确率提升最高达 196%。
研究背景与动机¶
- 领域现状:基于 LLM 的程序合成通常采用归纳方式——从少量训练示例生成程序,期望其泛化到未见输入。常见策略是采样多个候选程序,用训练 examples 过滤。
- 现有痛点:训练例子通常很少(如电子表格场景中用户手填几行),合成的程序遇到 edge case(测试时的非典型输入)时容易出错。问题在于认知不确定性——模型不知道测试时会出现什么样的输入。
- 核心矛盾:归纳合成追求"从少量例子推出通用程序",但 Vapnik 的转导原则指出"不必为了解决特定问题而先解决更一般的问题"。如果测试输入可见,直接利用它们比追求一般化更高效。
- 本文要解决什么:当测试输入在合成时可见时,如何利用它们提升程序的鲁棒性?
- 切入角度:将问题建模为有限假设类上的主动学习——用 LLM 对选定的 test input 预测输出(伪标签),淘汰与伪标签不一致的候选程序,迭代直到只剩一个。关键是选哪个 test input 查询最高效。
- 核心 idea 一句话:用 LLM 的转导预测能力做"裁判",对 test inputs 逐个判别,从候选程序空间中二分搜索式地淘汰不一致假设。
方法详解¶
整体框架¶
输入是程序规约 \(S\)(含训练 I/O 对和可选的自然语言描述)+ \(N\) 个 test inputs。输出是一个程序。流程:(1) 用 LLM 采样生成多个候选程序 \(\mathcal{P}\);(2) 用训练 examples 过滤得到 \(\mathcal{P}'\);(3) 在 test inputs 上执行候选程序,按输出 tuple 去重得到假设类 \(\mathcal{H}\);(4) 迭代选择 test input → LLM 预测输出 → 淘汰不一致假设 → 直到只剩一个。
关键设计¶
- 有限假设类的构建:
- 做什么:将候选程序转化为 test inputs 上输出的 N-tuple 集合
- 核心思路:多个候选程序可能在 test inputs 上产生相同输出 tuple——去重后得到假设类 \(\mathcal{H}\),每个假设是一个 N-维输出向量。假设 realizable 条件成立(正确假设在 \(\mathcal{H}\) 中)
-
设计动机:在输出空间而非程序空间上操作,大幅减少假设数量
-
Greedy Maximin 查询选择:
- 做什么:选择"最有区分力"的 test input 来查询 LLM
- 核心思路:对每个 test input \(i\),计算其在当前版本空间 \(\mathcal{V}_t\) 上的最坏情况淘汰数 \(\min_y |\{h \in \mathcal{V}_t | h[i] \neq y\}|\),选择 maximin 最大的 \(i^*\)。平局时选输出总长度最短的(LLM 更容易判断短输出)
-
设计动机:类似二分搜索——每次查询都在最坏情况下淘汰最多假设,最小化总查询次数
-
LLM 转导预测(伪标签):
- 做什么:给定 test input 和候选输出集合,让 LLM 选择正确输出
- 核心思路:将规约 \(S\)、test input \(\tilde{x}_{i^*}\) 和该位置的候选输出集 \(\{h[i^*] | h \in \mathcal{V}_t\}\) 一起提供给 LLM,让其用推理能力和世界知识选择。这是一个多选题而非开放生成
- 设计动机:LLM 做多选比从头生成更准确;利用了 LLM 的常识推理能力而非仅代码生成能力
训练策略¶
不涉及额外训练。整个框架是纯推理时(test-time)方法,利用预训练 LLM 的代码生成和推理能力。
具体实现中,程序合成模型 \(\sigma\) 通过 LLM 采样多个候选程序,用训练示例过滤后在 test inputs 上执行得到假设类。转导模型 \(\tau\) 也用 LLM 实现,利用其推理能力和世界知识从候选输出中选择正确答案。两者可使用相同或不同的 LLM。整个过程不需要梯度更新或模型微调。
实验关键数据¶
主实验¶
| Benchmark | 任务 | SYNTRA 提升 |
|---|---|---|
| Playgol | 字符串变换归纳合成 | 最高 +196% |
| MBPP+ | 自然语言→代码 | 显著提升 |
| 1D-ARC | 视觉推理 | 显著提升 |
| MiniGrid | 程序化世界建模 | 显著提升 |
查询效率¶
| 策略 | LLM 额外调用数 |
|---|---|
| Random input selection | 较多 |
| Maximin selection | 减半(相对于随机选择的额外调用) |
关键发现¶
- 所需查询数随 test inputs 数量 \(N\) 亚线性增长——对大规模 test set 可扩展
- LLM 做"选择题"(从候选输出中选)比"生成题"(直接预测输出)的准确率显著更高
- Maximin 策略在 edge case 密集的场景下优势最明显——因为 edge case 正是不同假设分歧最大的地方
亮点与洞察¶
- Vapnik 转导原则的精准应用:将"不要解一般问题"的哲学转化为可操作的程序合成框架,简洁有力
- LLM 的角色转换:LLM 不仅是代码生成器,还是"裁判"(transduction model)——两种能力的组合比单独使用任一种都强
- 二分搜索式推理:maximin 算法本质上是在假设空间做对数级搜索,查询效率有理论保证
- 实用场景驱动:电子表格自动化、数据变换等场景天然满足"test inputs 可见"的条件,直接可用
局限性 / 可改进方向¶
- Realizability 假设:假设正确程序在候选集中,但如果 LLM 采样的程序不包含正确的,框架失败。可用更多采样或多模型缓解,但增加成本
- LLM 伪标签错误:如果 LLM 选错输出,会错误淘汰正确假设(级联错误)。单次错误可能不可恢复
- 仅验证了 Python 程序:DSL 或其他编程范式下的效果未验证,特别是领域特定语言可能有不同的假设空间结构
- 假设空间大小受限:当候选程序数量极大时,假设类 \(\mathcal{H}\) 的构建和消除效率可能成为瓶颈
- test inputs 需预先可见:纯归纳场景(如 API 设计、库开发)没有预定义的 test inputs,框架不直接适用
- 改进方向:(1) 引入 soft elimination(根据 LLM 置信度概率淘汰)减少级联错误;(2) 结合执行反馈——对剩余假设做更多 test case 执行验证;(3) 自动生成额外 test inputs 进一步分辨假设;(4) 探索与 self-repair 方法(如 reflexion)的结合
相关工作与启发¶
- vs 标准 LLM 程序合成(Codex/CodeLlama):标准方法生成后用训练 examples 过滤;SYNTRA 进一步用 test inputs 做第二轮过滤
- vs AlphaCode/CodeT:这些work 采样大量程序后用聚类/投票选最佳;SYNTRA 用结构化的假设消除替代投票
- vs 1D-ARC 直接推理:纯 LLM 推理无法保证输出一致性;合成程序后执行保证了所有 test inputs 的一致性
- 启发:转导+假设消除框架可推广到 LLM 做选择题的其他场景(如 tool selection、plan disambiguation)
评分¶
- 新颖性: ⭐⭐⭐⭐⭐ 转导式程序合成的问题定义新颖,框架优雅且理论动机清晰
- 实验充分度: ⭐⭐⭐⭐ 4 个 benchmark 覆盖字符串/代码/视觉/世界模型,查询效率分析完整
- 写作质量: ⭐⭐⭐⭐⭐ 问题定义严谨,算法描述清晰,Vapnik 的转导原则引用精准
- 价值: ⭐⭐⭐⭐⭐ 开辟了一个新的程序合成范式,+196% 的提升令人印象深刻