最近,研究者们开始探索大型语言模型(LargeLanguageModels(LLMs))在代码方面的应用,CodeLLMs接受大量源代码集合的训练,并能够从自然语言描述和其他代码片段中合成程序。
研究CodeLLM面临的挑战之一是这些系统的开发缺乏开放性和透明度。虽然已经发表了一些论文,但它们并不总是对开发过程有全面的描述。一些研究小组通过付费API服务或商业产品提供了他们的CodeLLM(如CodeX)。其他小组公布了模型权重(如InCoder),但没有公布训练数据。因此,研究人员很难完全重现这些模型。LLMs的一个重要预处理步骤是训练数据的重复数据删除,因为据报道它可以提高模型性能。然而,模型的性能通常对这种预处理方法的超参数非常敏感,作者认为,与其让研究人员独立迭代预处理细节,不如从一开始就更广泛地共享由数据卡支持的高质量数据集,社区的进展会更快。
本文发布TheStack(一个许可源代码的大型数据集),向对CodeLLM进行开放和负责任的研究迈出了一步。本文描述了如何从GitHub收集和处理代码存储库,并展示了小规模CodeLLM的有前景的结果。具体而言,本文作出以下贡献:
最近的研究表明,训练集中的重复数据删除可以显著提高LLM的性能。Lee等人表明,语言模型的训练语料库包含许多接近重复的词,当去掉长重复的子字符串时,LLM性能会提高。Hernandez等人还发现,即使重复一小部分训练数据也会严重损害模型性能,这可能是由于数据记忆消耗了部分容量。数据复制在代码数据集中更为常见,因为重用和克隆其他代码存储库是常见的做法。事实上,Lopes等人观察到,GitHub数据中有很大一部分由克隆组成,导致精确和接近重复的比例很高。Allamanis研究了代码复制对机器学习模型的影响,并表明它会导致高度膨胀的性能指标。然而,许多现有的代码LLMs只应用精确的重复数据删除,这在训练数据中留下了大量接近重复的数据。
在精确重复数据删除的基础上,本文在预处理流程中实现了近乎重复的数据删除。我们首先根据非字母数字字符将文件拆分为单词/标记,并删除标记少于10个的文件。接下来,我们用所有文档的256种排列计算MinHash,并使用局部敏感哈希(LSH)来找到重复的集群。通过确保原始集群中的每个文件与减少的集群中的至少一个文件相似,我们进一步减少了这些集群。当两个文件的Jaccard相似度超过0.85时,我们认为它们相似。我们发现,在许可数据集中,38.6%的文件只是其他文件的近似副本并被删除,它们也代表了数据集体积的53.7%。每种编程语言的细目见表3。
为了更深入地了解收集的数据集,我们首先分析每种编程语言的数据量,然后与其他代码数据集进行比较,最后对python子集进行更广泛的分析。
表3中列出了30种编程语言的可用数据量。可以看到全许可证数据集包含超过29TB的数据。仅选择许可文件将数据集减少到3.1TB,即仅保留大约10%的数据集。对于某些编程语言(例如SQL,Batchfile,TypeScript),我们发现只有不到4%的数据具有许可许可。我们可以通过向许可许可列表中添加更多的许可来增加这一百分比(请参阅附录a)。如果进一步对许可许可数据集应用近似重复数据删除,最终将得到1.4TB,减少了50%以上。例如,当不擅长这些数据时,只保留了37%的HTML。从图1中可以看出,少数几种编程语言构成了数据集的大部分。对于许可数据集,四种最大的语言——html(746GB)、Javascript(486GB)、Java(271GB)和C(222GB)——占用了数据集大小的55%以上。
表1展示了TheStack和CodeParrot、AlphaCode、CodeGen、PolyCoder进行比较。注意,AlphaCode和CodeGen没有公布他们的数据,但提供了每种编程语言的数据量的统计数据。值得一提的是,CodeParrot包含具有copyleft许可证(例如GPL)的文件,而我们的许可许可证数据集则没有。PolyCoder不过滤许可信息,也可能包含copyleft许可的文件。Stack和CodeParrot提供了30种编程语言的源代码,而AlphaCode、PolyCoder和CodeGen分别只提供其中12种、12种和6种语言的数据。此外,我们观察到我们的数据集是CodeParrot(第二大公开可用的代码数据集)的3倍多。我们还看到,对于每种编程语言,我们的数据集比CodeParrot更大。
首先,作者研究许可数据集的Python子集中有多少配置文件和测试文件。这些配置文件在GitHub存储库中非常丰富,但没有捕获源代码的复杂功能。
接下来,对数据集中的10,000个样本使用py_compile模块来估计有效Python文件的数量。我们发现只有0.7%的文件由于语法错误而无法编译。具体来说,作者发现大约0.1%的Python文件存在标记化错误(例如,由于制表符和空格的不一致使用)。
最后,分析文件中的文档字符串和注释。这些数据对于文档生成和自然语言代码翻译等应用程序至关重要。我们分析10,000个文件中的一个子集。首先使用ast和tokenize模块来提取文档字符串和注释,作者发现它们占子集容量的18%,20%的文件只有很少(少于20个字符)或没有自然文本。
为了识别提取的文档字符串和注释的语言,作者使用fasttext库中的模型。作者发现94%的文件是英文的。在其他语言中,汉语和法语最受欢迎,有100多个样本。图2中展示了自然语言的完整分布。需要注意的是,这种语言检测并不完美,因为文档字符串通常包含带有英文关键字的代码示例。
为了更好地理解收集的数据集的质量,本文研究了在几个版本的python子集上从头训练的transformer模型的性能。作者评估了HumanEval和MBPP上的模型,并与类似规模的CodeGen、InCoder和Codex模型进行了比较。作者在研究过程的后期发现,一些预训练集受到了来自评估基准的示例的污染。由于运行实验成本高且耗时长,本文只重新运行几个实验来调查数据污染的影响。
作者实验了自己的python数据集的4个版本,以及CodeParrot的Python子集。对于自己的数据集,我们要么使用来自所有存储库(all-license)的python文件,要么使用来自具有许可许可(permissive-license)的存储库的python文件。对于这些数据,要么应用近重复数据删除(near-dedup),要么不进行进一步过滤(none)。值得强调的是,接近重复数据删除的过程是在我们在数据集收集期间应用的重复数据删除之上的。对于CodeParrot,我们只试验了接近重复数据删除的版本12。
对于所有数据集,遵循Codex的过滤方法,并使用以下方法删除文件:
在训练模型之后,作者发现一些训练集包含了来自评估基准的示例。本文通过搜索HumanEval和MBPP的自然语言提示符的精确字符串匹配来检测这种污染问题。表4显示了每个子集中发现的受污染文件的数量。所有子集都包含HumanEval示例,但只有python-all-license子集包含MBPP示例。为了调查数据污染的影响,我们在几乎重复数据删除的python-all-license和python-permission-license数据集上重新运行实验。为此,我们从这些数据集中删除了受污染的文件。请注意,我们只删除了提示符的精确副本,因此不检测转述。
表5和表6中报告HumanEval和MBPP结果。之后,作者给出了几点讨论。
对训练数据应用近似重复数据删除会在全许可证和许可许可证数据集上产生显著改善。在permission-license数据集上,近似重复数据删除将HumanEval性能从27.21%提高到37.00%pass@100,将MBPP性能从44.99%提高到54.69%pass@100。我们看到全许可证数据集的结果也有类似的提升,其中HumanEval性能从36.67%提高到44.00%pass@100,MBPP性能从53.59%提高到61.00%pass@100。
我们能够复现text2python的结果,以前的工作只允许许可的源代码。在HumanEval上,我们观察到,在没有几乎重复数据删除的情况下,许可许可数据集(27.21%pass@100)的性能明显低于Codex(36.27%pass@100)和CodeGen(35.19%pass@100)。但是,在应用近似重复数据删除后,Codex和CodeGen的性能达到了一致(37.00%pass@100)。在MBPP上,我们观察到类似的结果。如果没有近似重复数据删除,python允许数据集(44.99%pass@100)的性能明显低于CodeGen(51.80%pass@100)。但是,近似重复数据删除的版本(54.69%pass@100)超过了CodeGen的结果。
在Codeparrot(另一个发布的代码数据集)上的训练在HumanEval上达到30.37%pass@100,这明显低于我们发布的数据集的性能(37.00%pass@100)。在MBPP上,CodeParrot的表现也低于我们发布的数据集(45.44%vs54.69%pass@100)。CodeParrot由从BigQuery中提取的数据组成,不足以获得HumanEval和MBPP上的竞争模型。
令人惊讶的是,我们发现删除受污染的文件对text2python结果的影响很小。在HumanEval上,许可-许可证数据集有很小的下降(37.00%vs36.01%pass@100),而全许可证数据集有很小的增长(44.00%vs45.52%pass@100)。我们还看到MBPP上的全许可证数据集受到了较小的影响(61.00%vs58.28%pass@100)。我们推测数据污染的影响是最小的,因为(1)小模型不太可能记住训练数据,(2)污染文件很少。
本文介绍了TheStack,这是一个拥有超过3Tb许可源代码的大型数据集。本文描述了数据集收集的细节,给出了一个简单的数据集分析,并在HumanEval基准测试上展示了有希望的结果。实验结果表明,近似重复数据删除是在text2code基准测试中获得有竞争力结果的重要预处理步骤。本文发布了30种常见编程语言的所有许可文件,以及一个近乎重复数据删除的版本。在未来的工作中,我们希望进一步改进已发布的数据集。我们对发布其他编程语言的数据持开放态度,计划研究删除PII和恶意代码的方法,并开始尝试让开发人员有可能从数据集中删除他们的数据。我们希望Stack将成为开放和负责任的CodeLLM研究的有用资源。
TheStack是BigCode项目的一个输出。BigCode的目标是在设计和默认情况下负责任。该项目是在开放科学的精神下进行的,专注于负责任的CodeLLM开发。
随着TheStack的发布,我们的目标是在研究社区中增加CodeLLM的可访问性、可重复性和透明度。在各个BigCode工作组中开展了降低风险和改进CodeLLM道德最佳实践的工作。法律、道德和治理工作组探讨了诸如许可(包括copyleft和许可代码的预期使用)、生成的代码归属于原始代码、限制处理的权利、个人身份信息(PII)的包含以及恶意代码的风险等主题。这项工作正在进行中。
我们希望CodeLLM能够让来自不同背景的人编写更高质量的代码并开发低代码应用程序。当代码生成系统指导专业开发人员如何编写更健壮和有效的代码时,关键任务软件将变得更容易维护。虽然社会影响是积极的,但代码llm的可访问性的增加也带来了一定的风险,例如过度依赖生成的代码以及对软件开发就业市场的长期影响。
从GitHub收集的代码不包含人口统计信息或关于人口统计的代理信息。然而,这并不是没有风险,因为代码中的注释可能包含有害或冒犯性的语言,这可以从模型中学习到。
与Julia和Scala等小众编程语言相比,C和Javascript等被广泛采用的编程语言过多。我们发现一些编程语言,如SQL,Batchfile,TypeScript不太可能被许可(4%vs平均10%)。这可能导致对这些语言的描述有偏见。许可文件也往往较长。
我们还发现,英语语言在文档字符串和注释中被过度表示,因为它占Python文件数据的96%。
TheStack目前的一个限制是为网站抓取HTML可能不符合Web内容可访问性指南(WCAG)。这可能会对html生成的代码产生影响,可能会引入web可访问性问题。
我们注意到数据中包含姓名和电子邮件地址等个人身份信息(PersonallyIdentifiableInformation,PII)。这个PII已经在GitHub上向公众公开,但是,我们计划在未来的工作中删除PII。
少数存储库被删除了,因为它们在下载阶段触发了内部安全工具。但是,我们没有完全扫描数据集的恶意软件,因此,可能仍然存在着恶意代码。
我们在python数据集上展示了较小模型的text2code结果。有必要进行更多的研究,以确定是否可以为更大的模型和其他编程语言(而不是Python)获得强有力的结果。