StarCoder2-Instruct: 面向代码生成的完全透明和宽松的自对齐

指令微调 (Instruction tuning) 是一种赋予大型语言模型 (LLM) 理解并遵循人类自然语言指令能力的微调方法。然而,对于编程任务,大多数模型要么是基于人工编写的指令(成本非常高)进行微调,要么是基于由庞大且专有的 LLM 生成的指令(可能不被许可使用)进行微调。我们推出了 StarCoder2-15B-Instruct-v0.1,这是首个通过完全宽松和透明的流程进行训练的、完全自对齐的代码 LLM。我们的开源流程使用 StarCoder2-15B 生成数千个指令-响应对,然后用这些数据来微调 StarCoder-15B 自身,无需任何人工标注或从庞大且专有的 LLM 中蒸馏的数据。
StarCoder2-15B-Instruct 在 HumanEval 上的得分为 72.6,甚至超过了 CodeLlama-70B-Instruct 的 72.0 分! 在 LiveCodeBench 上的进一步评估表明,自对齐模型甚至优于使用从 GPT-4 蒸馏的数据训练的同一模型,这意味着 LLM 从其自身分布内的数据中学习可能比从教师 LLM 的偏移分布中学习更有效。
方法

我们的数据生成流程主要包括三个步骤
- 从 The Stack v1(一个包含大量宽松许可源代码的语料库)中提取高质量且多样化的种子函数。
- 创建多样化且贴近真实场景的代码指令,这些指令涵盖种子函数中存在的不同代码概念(例如,数据反序列化、列表拼接和递归)。
- 对每条指令,通过执行引导的自验证生成高质量的响应。
在接下来的部分中,我们将详细探讨这些方面。
收集种子代码片段
为了充分解锁代码模型的指令遵循能力,模型应当接触到涵盖广泛编程原则和实践的多样化指令。受 OSS-Instruct 的启发,我们通过从开源代码片段中挖掘代码概念来进一步促进这种多样性,这些代码片段特别是来自 The Stack V1 中结构良好的种子 Python 函数。
对于我们的种子数据集,我们从 The Stack V1 中仔细提取了所有带有文档字符串的 Python 函数,使用 autoimport 推断所需的依赖项,并对所有函数应用以下过滤规则
- 类型检查: 我们使用 Pyright 启发式类型检查器来移除所有产生静态错误的函数,这些错误可能表示代码项不正确。
- 去污染:我们检测并移除了所有我们用于评估的基准测试项。我们在解决方案和提示上都使用了精确字符串匹配。
- 文档字符串质量过滤:我们利用 StarCoder2-15B 作为评判员,移除文档质量差的函数。我们向基础模型提供 7 个小样本 (few-shot) 示例,要求它对是否保留该项回答“是”或“否”。
- 近似去重:我们利用 MinHash 和局部敏感哈希,以 0.5 的 Jaccard 相似度阈值来过滤数据集中的重复种子函数。这与应用于 StarCoder 训练数据的流程相同。
这个过滤流程最终从 500 万个带有文档字符串的函数中筛选出 25 万个 Python 函数的数据集。这个过程很大程度上受到了 MultiPL-T 中数据收集流程的启发。
Self-OSS-Instruct
收集完种子函数后,我们使用 Self-OSS-Instruct 来生成多样化的指令。具体来说,我们采用上下文学习 (in-context learning) 的方式,让基础的 StarCoder2-15B 从给定的种子代码片段中自我生成指令。这个过程利用了 16 个精心设计的小样本 (few-shot) 示例,每个示例的格式为 (代码片段,概念,指令)。指令生成过程分为两个步骤
- 概念提取: 对于每个种子函数,提示 StarCoder2-15B 生成一个该函数中存在的代码概念列表。代码概念指的是编程中使用的基础原则和技术,例如 模式匹配 和 数据类型转换,这些对于开发者来说是必须掌握的关键知识。
- 指令生成: 然后提示 StarCoder2-15B 自我生成一个包含已识别代码概念的编程任务。
最终,这个过程生成了 23.8 万条指令。
响应自验证
有了从 Self-OSS-Instruct 生成的指令,我们的下一步是为每条指令匹配一个高质量的响应。以前的做法通常依赖于从更强的教师模型(如 GPT-4)中蒸馏响应,期望这些响应质量更高。然而,蒸馏专有模型会导致许可证不宽松,而且更强的教师模型也并非总是可用。更重要的是,教师模型也可能出错,并且教师和学生模型之间的分布差异可能是有害的。
我们提出通过明确指示 StarCoder2-15B 在生成包含自然语言的响应后,再生成用于自验证的测试来进行自对齐。这个过程类似于开发者测试他们代码实现的方式。具体来说,对于每条指令,StarCoder2-15B 生成 10 个格式为 (自然语言响应,测试) 的样本,我们在沙箱环境中过滤掉那些未能通过测试执行的样本。然后,我们为每条指令随机选择一个通过测试的响应,加入最终的监督微调 (SFT) 数据集。我们总共为 23.8 万条指令生成了 240 万个(10 x 23.8 万)响应(温度设为 0.7),其中 50 万个通过了执行测试。去重后,我们剩下 5 万条指令,每条指令配对一个随机的通过测试的响应,这最终构成了我们的 SFT 数据集。
评估
在流行且严谨的 EvalPlus 基准测试中,StarCoder2-15B-Instruct 脱颖而出,成为其规模级别中表现最佳的宽松许可 LLM,超过了规模更大的 Grok-1 Command-R+、DBRX,同时与 Snowflake Arctic 480B 和 Mixtral-8x22B-Instruct 的表现相当。据我们所知,StarCoder2-15B-Instruct 是首个通过完全透明和宽松流程达到 70+ HumanEval 分数的代码 LLM。它显著优于 OctoCoder,后者是之前采用透明流程的最先进的宽松许可代码 LLM。
即使与具有限制性许可证的强大 LLM 相比,StarCoder2-15B-Instruct 仍然具有竞争力,超过了 Gemini Pro 和 Mistral Large,并与 CodeLlama-70B-Instruct 相当。此外,完全基于自生成数据训练的 StarCoder2-15B-Instruct,其性能与在 GPT-3.5/4 蒸馏数据上微调 StarCoder2-15B 的 OpenCodeInterpreter-SC2-15B 不相上下。

除了 EvalPlus,我们还在 LiveCodeBench 上评估了类似或更小规模的最先进开源模型。LiveCodeBench 包含了 2023 年 9 月 1 日之后创建的新编程问题。我们还评估了针对数据科学程序的 DS-1000。在 LiveCodeBench 上,StarCoder2-15B-Instruct 在所有被评估的模型中取得了最佳成绩,并且持续优于蒸馏了 GPT-4 数据的 OpenCodeInterpreter-SC2-15B。在 DS-1000 上,尽管 StarCoder2-15B-Instruct 的训练数据中数据科学问题非常有限,但其表现仍然具有竞争力。

结论
StarCoder2-15B-Instruct-v0.1 首次证明,我们可以在不依赖于像 GPT-4 这样的更强教师模型的情况下,创建出功能强大的指令微调代码模型。这个模型表明,自对齐——即模型利用自身生成的内容进行学习——对于代码领域同样有效。它完全透明并允许蒸馏,这使其区别于其他规模更大但不够透明的宽松许可模型,如 Snowflake-Arctic、Grok-1、Mixtral-8x22B、DBRX 和 CommandR+。我们已将我们的数据集和包括数据整理和训练在内的整个流程完全开源。我们希望这项开创性的工作能够激励该领域未来更多的研究和发展。
资源
- StarCoder2-15B-Instruct-v0.1:指令微调模型
- starcoder2-self-align:自对齐流程
- StarCoder2-Self-OSS-Instruct:自生成的指令微调数据集
引用
@article{wei2024selfcodealign,
title={SelfCodeAlign: Self-Alignment for Code Generation},
author={Yuxiang Wei and Federico Cassano and Jiawei Liu and Yifeng Ding and Naman Jain and Zachary Mueller and Harm de Vries and Leandro von Werra and Arjun Guha and Lingming Zhang},
year={2024},
journal={arXiv preprint arXiv:2410.24198}
}