在近期的神经信息处理系统大会(NIPS 2024)上,一篇由伊利诺伊大学厄巴纳-香槟分校(UIUC)、加州大学伯克利分校(UC Berkeley)和东北大学等多所知名高校联合发表的论文引起了广泛关注。该论文提出了一种名为SelfCodeAlign的创新方法,旨在通过自我对齐(self-alignment)的方式,使代码生成的大型语言模型(LLMs)在无需大量人工注释或蒸馏的情况下,实现性能的显著提升。
近年来,大型语言模型在代码相关任务中展现出了卓越的性能,包括程序合成、程序修复、代码优化、代码补全、代码翻译、软件测试和软件代理等。这些模型通常在数万亿的代码标记上进行预训练,并采用各种训练目标(如下一个标记预测),使其能够自然地理解和生成代码片段。
为了充分发挥LLMs的潜力,通常需要在高质量的指令遵循数据上对基础模型进行进一步的微调,这一步骤被称为指令微调。然而,获取高质量的指令微调数据既关键又具有挑战性。一种常见的方法是使用人工注释,但这种方法成本高昂。另一种方法是使用知识蒸馏,通过让更强的LLMs生成输出来训练较弱的LLMs,但这种方法可能违反专有LLMs的服务条款,并且依赖于更强的LLMs限制了其通用性。
为了解决上述问题,研究团队提出了SelfCodeAlign,这是一种完全透明且无需大量人工注释或蒸馏的代码LLM自我对齐管道。SelfCodeAlign的核心思想是利用基础模型自身生成多样化的编码概念,并使用这些概念生成新的编码任务。然后,模型为每个任务生成多个响应,并使用测试用例对这些响应进行配对和验证。最后,只有通过测试的示例才会被选择用于指令微调。
SelfCodeAlign的具体实现包括以下几个步骤:
种子代码片段收集:从一个名为The Stack V1的大型、许可友好的代码语料库中收集高质量的种子代码片段。这些片段将作为生成指令和响应的起点。
多样化指令生成:使用一种名为Self-OSS-Instruct的自对齐改编方法,通过上下文学习让基础模型从给定的种子代码片段中生成多样化的指令。这包括概念提取和指令生成两个子步骤。
响应生成与自我验证:对于每个生成的指令,基础模型生成多个格式为(响应,测试)的输出。然后,在沙箱环境中执行测试,过滤掉失败的响应。最后,为每个指令随机选择一个通过测试的响应,将其添加到最终的指令微调数据集中。
为了评估SelfCodeAlign的有效性,研究团队在多个编码任务上进行了广泛的实验,包括函数生成、类生成、数据科学编程和文件级代码编辑。实验结果表明,使用SelfCodeAlign微调的CodeQwen1.5-7B模型在所有任务上都显著优于原始模型和使用OctoPack(一种先前的无人工注释或蒸馏的指令微调方法)微调的模型。
具体而言,在HumanEval+基准测试中,SelfCodeAlign微调的模型实现了67.1的pass@1分数,比CodeQwen1.5-7B提高了21.4分,比CodeQwen1.5-7B-OctoPack提高了16.5分。这一结果表明,SelfCodeAlign的合成数据生成方法在增强代码LLM的能力方面比自然数据更有效。
此外,研究团队还对SelfCodeAlign的各个组件进行了分析,证明了种子选择、概念生成和执行过滤等组件对管道的积极贡献。他们还展示了SelfCodeAlign在各种规模的LLMs(从3B到33B)上的有效性,并指出基础模型可能从与其自身数据分布相似的数据中学习得更有效。
SelfCodeAlign的提出为代码LLM的自我对齐提供了一种全新的思路,有望推动该领域的发展。通过避免对人工注释和蒸馏的依赖,SelfCodeAlign为构建更强大的代码助手铺平了道路。
然而,SelfCodeAlign也存在一些局限性,例如其数据生成限制在约3000个标记的窗口内,这可能导致其分布偏向于中等大小的样本。此外,生成的单元测试可能存在错误,需要进一步研究以改进测试用例的生成。
展望未来,研究团队计划将SelfCodeAlign应用于更复杂的领域,如复杂程序生成和代理软件工程。他们还希望探索使用长上下文指令响应对进行生成和训练的方法,以及将负样本纳入强化学习循环以引导模型远离错误响应的方法。