SWE-Smith 是如何工作的?
引言
收集数据一直是训练语言模型解决软件工程问题的一大难题。在此前的SWE-Bench的工作中,从10个左右的 GitHub 仓库里人工手动构造出了最多 1000 条高质量的实例用于进行测试和研究,但人工操作显然限制了扩展性和可用性。现有的方法存在如下几个问题:
- 数据集的规模有限
- 创建成本较高(人力成本、存储成本等)
- 开源模型发展较为受限
![[Pasted image 20250714154807.png]]
基于这个痛点,SWE-Smith 框架被提出,这个框架可以被用来大规模自动化生产软件工程训练数据。和传统方法(手动寻找PRs相反),SWE-Smith 先为整个代码仓库构造一个统一且可执行的开发环境、然后在此环节中批量认为制造出 Task Instance (即 Bug)。使用这个框架,一个 50K 实例大小、跨越 128 个仓库的数据集被提出。基于这个数据集,通过基于 Claude 3,7 Sonnet产生的对话轨迹和对 Qwen 2,5 的微调,一个新的模型(SWE-agent-LM-32B)被提出,在没有推理时间缩放的情况下于 SWE-Bench-Verfied 验证器中得到了 40.2% 的求解分数。
SWE-Smith 的工作流程
SWE-smith的核心工作在于对于给定仓库,定义一个可执行环境,然后在这个环境中制造测试实例。(这种方法与 SWE-Bench 相反的)。
对于具有通过测试(Passing Test)的仓库创造执行环境
首先,为选定的Python代码仓库创建一个稳定的、超过80%的测试都能通过的Docker执行环境。以PyPI中下载次数最多的5000个软件包作为目标仓库,并按 GitHub 星号对 PyPI 软件包进行排序,然后从考虑范围中移除所有星号少于 1,000 的 PyPI 软件包,以及所有 12 个 SWE-bench 测试仓库。
![[Pasted image 20250714154754.png]]
创建 Task Instance 候选
在已构建的仓库环境中,四种不同的策略被采用来自动生成 Task Instance:
![[Pasted image 20250714155913.png]]
LM Generation
对于给定仓库,识别所有的程序实体(Entity),两种不同的基于语言模型的修改被引入:
- LM Modify: 向 LM 提供函数,并提示引入错误的修改
- LM Rewrite: 仅向 LM 提供函数头和文档字符串,要求 LM 对其重写
Procedural Modification
对于每一个函数,引入其抽象语法树(Abstract Syntax Tree),然后随机地进行一个或多个修改(例如移除某些条件/循环,或改变运算符等)
Combine Bugs
LM Generation 和 Procedural Modification 都仅通过编辑少量实体来制造实例。对于更复杂的要求,可以累积地对同一个文件进行多次变造,从而引入更大的运行实例。
Invert PRs (or "PR Mirror")
通过撤销(Undo)仓库的PRs更改(基于每次变更的 .diff)文件来重写受影响的文件,从而还原 PR 的编辑。
Task Instance 过滤
通过基于执行的候选补丁验证:将每个候选补丁应用到相应的代码库,运行测试套件,并仅保留那些破坏了一个或多个现有已通过测试(称为“Fail-to-Pass”测试)的补丁。测试运行时间限制为两分钟以提高效率;导致测试运行时间超过此时间限制的候选错误将被丢弃。
这确保了生成的实例是真实且可验证的,而非只是语法上的改变或无效的改动,排除了那些并没产出实际影响的补丁。从而保证评估标注的一致性和科学性。
生成 Problem Statement
Problem Statement的描述会直接影响到测试实例的困难度(Difficulty)和可行性(Feasibility),从而影响代理解决问题的能力。SWE-smith 使用一种简单的策略:对于每个任务实例,LM都会被提供.diff补丁、随机 Fail-to-Pass 的源码以及应用错误补丁后运行存储库测试套件的执行输出。LM被要求输出GitHub问题风格的文本,其中包含基于 Fail-to-Pass 的复现代码。
核心方法
利用 SWE-agent 和 LM 的推理能力:
SWE-agent 的角色:SWE-smith 不直接编写安装脚本,而是让 SWE-agent 扮演一个自动化的“程序员”角色。它运行 SWE-agent(一个基于语言模型 Agent-Computer Interface, ACI 的系统),并指示其完成代码库的安装和测试。
![[Pasted image 20250714155842.png]]
语言模型 (LM) 的自主操作:在 SWE-agent 框架下,作为核心的语言模型(如 Claude 3.5 Sonnet)会:
- 阅读文档,获取安装和依赖信息
- 执行 $\text{bash}$ 命令,执行推理出的安装命令
- 运行测试(如 $\text{pytest}$ 或者 $\text{unittest}$ ,验证安装是否成功,即现有测试是否都通过)
- 迭代修正,LM 对于安装失败的仓库会分析原因,并迭代调整操作,直到所有测试通过。
哪些事情是在构建 SWE-Smith 仓库时候依然需要人工介入的?
即使 SWE-smith 可以自动化地执行许多步骤(生成 bug patch,构建 Docker 镜像,运行 patch 和评估 F2P 等),仍有部分步骤是在引入新仓库时需要人工完成的:
为仓库准备安装脚本(install_repo.sh)
- SWE-smith 中用语言模型(agent)来探索安装步骤(例如:安装依赖、构建项目)
- 但 agent 给出的“安装轨迹”可能不总是标准或结构化的
配置测试输出解析(为测试实现 parser)
- SWE-smith 用测试结果判断 patch 是否有效
- 不同项目的测试输出格式不同
SWE-Smith 的生成成本
通过对 128 个 Python 仓库进行 SWE-smith 生成,得到了总共 50K 的测试实例。平均来说,每个仓库得到了 381 个测试实例,总成本为 $\$1360$. 实例生成的成本与策略直接相关。Invert PRs 由于更加依赖大语言模型,需要改写整个仓库,相比之下成本是最高的。
![[Pasted image 20250714153419.png]]
SWE-Smith 的执行成本
相较于 SWE-Bench,SWE-Smith 的磁盘空间要求更低,这是因为 SWE-Smith 扩展了执行环境,来自同一仓库的任务将共享相同的环境(相比之下,SWE-Bench 要求为每个任务实例创建单独的 Docker 镜像)。
![[Pasted image 20250714153821.png]]
基于 SWE-Smith 的实验微调
SWE-Smith 数据集的实验核心是依据拒绝采样微调(Rejection Sampling Fine-Tuning)的思想, 基本流程是使用一个非常强大的专家模型(Expert Model,Claude 3,7 Sonnet, based on SWE-agent)在 SWE-Smith 数据集上执行任务。通过收集记录所有 Expert Model 成功解决任务的完整操作步骤(被称为轨迹,Trajectories),对学生模型(Student Model,Qwen 2,5)进行微调。最后在标准的 SWE-Bench 测试集上评估经过微调的学生模型的性能。
难度评级的结论显示,SWE-Smith 生成的任务实例并不简单,专家模型在选定的 8686 个任务实例中的 17906 次尝试里,最终的池化样本为 6457 个,解决率为 36%。观察报告还显示更简单的轨迹(指多次运行中重复求解的实例)会降低模型性能。