您的浏览器禁用了JavaScript(一种计算机语言,用以实现您与网页的交互),请解除该禁用,或者联系我们。[深度求索AI&北京大学]:当大型语言模型遇上编程:代码智能的崛起 - 发现报告

当大型语言模型遇上编程:代码智能的崛起

AI智能总结
查看更多
当大型语言模型遇上编程:代码智能的崛起

Daya Guo*1, Qihao Zhu∗1,2, 杨德建1, 谢振达1, 邓凯1, 张文涛1Guanting Chen1,Xiao Bi 1, Y. Wu 1, 李永凯1, 罗富立1, 邢莹飞2Wenfeng Liang1 1DeepSeek-AI2HCST (PKU) 国家重点实验室,教育部;北京大学,物理学院{zhuqh, guodaya}@deepseek.com https://github.com/deepseek-ai/DeepSeek-Coder 摘要 大型语言模型的快速发展革新了软件开发中的代码智能。然而,封闭源模型的主导地位限制了广泛的研究与开发。为此,我们推出了DeepSeek-Coder系列,这是一系列开源代码模型,规模从1.3B至33B不等,在2万亿个token上进行从头训练。这些模型在高质量项目级代码语料库上进行预训练,并采用带有16K窗口的填空任务来提升代码生成与填充能力。我们广泛的评估表明,DeepSeek-Coder不仅在多个基准测试中实现了开源代码模型的顶尖性能,还超越了现有的封闭源模型如Codex和GPT-3.5。此外,DeepSeek-Coder模型采用宽松许可证,允许进行研究和不受限制的商业使用。 1. 引言 软件开发领域因大型语言模型的迅速发展而发生了显著变革(OpenAI, 2023; Touvron 等人, 2023),这些模型带来了代码智能的新时代。这些模型有潜力自动化并简化编码的许多方面,从错误检测到代码生成,从而提高生产力并降低人为错误的可能性。然而,在该领域面临的主要挑战之一是开源模型(Li 等人, 2023; Nijkamp 等人, 2022; Roziere 等人, 2023; Wang 等人,2021)与闭源模型(Gemini 团队, 2023; OpenAI, 2023)之间的性能差距。强大的巨大型闭源模型因其专有性质,通常对许多研究人员和开发者难以获得。 为应对这一挑战,我们推出了DeepSeek-Coder系列。该系列涵盖了一系列开源代码模型,规模从1.3B到33B不等,包括每个规模的基准版本和指令版本。系列中的每个模型都基于来自87种编程语言的200万亿条令牌从头开始训练,确保了对编程语言和语法的全面理解。此外,我们尝试在代码库级别组织预训练数据,以增强预训练模型对代码库内跨文件上下文的理解能力。除了在预训练过程中采用下一令牌预测损失外,我们还引入了填充中间(Fill-In-Middle, FIM)方法(Bavarian等人,2022年;Li等人,2023年)。该方法旨在进一步增强模型的代码补全能力。为满足处理更长的代码输入的需求,我们将上下文长度扩展至16K。这一调整使我们的模型能够处理更复杂和广泛的编码任务,从而提高其在各种编码场景中的通用性和适用性。 我们使用各种与公共代码相关的基准测试进行了全面的实验。结果表明,在开源模型中,DeepSeek-Coder-Base 33B在所有基准测试中始终表现出卓越的性能。此外,DeepSeek-OpenAI GPT-3.5 TurboCoder-Instruct 33B 超过在大多数评估基准中,OpenAI GPT-4显著缩小了绩效差距之间和开源模型。值得注意的是,与参数量是DeepSeek-Coder-Base 7B五倍的大型模型(如CodeLlama-33B)相比,DeepSeek-Coder-Base 7B尽管参数量较少,却展现了具有竞争力的性能(Roziere等,2023)。总而言之,我们的主要贡献是: • 我们介绍了DeepSeek-Coder-Base和DeepSeek-Coder-Instruct,我们先进的以代码为重点的大型语言模型(LLMs)。这些模型通过在庞大的代码语料库上进行广泛训练而开发,展现出在87种编程语言上理解的专业能力。此外,它们以多种模型规模提供,以满足广泛的计算和应用需求。我们首次尝试在模型开发过程中整合仓库级数据构建。• 我们模型的预训练阶段。我们发现它可以显著提升跨文件代码生成的能力。 • 我们的分析 严格检验了FIM训练策略对代码模型预训练阶段的影响。这些综合研究的成果揭示了FIM配置的有趣方面,为代码预训练模型的改进和发展提供了宝贵的见解。 • 我们对我们的代码LLM在各种涵盖大量代码相关任务的基准上进行了广泛的评估。结果表明,DeepSeek-Coder-Base在这些基准上超越了所有现有的开源代码LLM。此外, 通过使用教学数据进行的细致微调,DeepSeek-Coder-Instruct实现了OpenAI GPT-3.5 Turbo与相比更好的表现在代码相关任务中的模型。 2. 数据收集 DeepSeek-Coder的训练数据集由87%的源代码、10%的英文代码相关自然语言语料库和3%的代码无关中文自然语言语料库组成。英文语料库包括来自GitHub的Markdown和StackExchange的材料。1,这些被用于增强模型对代码相关概念的理解,并提高其处理库使用和错误修复等任务的能力。与此同时,中文语料库由旨在提升模型汉语理解能力的优质文章组成。在本节中,我们将概述构建代码训练数据的过程。该过程涉及数据爬取、基于规则的过滤、依存句法分析、仓库级别去重和质量筛选,如图2所示。在下文中,我们将分步骤描述数据创建流程。 2.1. GitHub数据爬取与过滤 我们收集了2023年2月之前在GitHub上创建的公共仓库,并仅保留表1中列出的87种编程语言。为减少待处理的数据量,我们应用了与StarCoder项目(Li等人,2023)相似的过滤规则,初步筛选出质量较低的代码。通过应用这些过滤规则,数据总量减少至原始规模的32.8%。为使论文自包含,我们简要描述了StarCoder数据项目中使用的过滤规则: 首先,我们过滤掉平均行长度超过100个字符或最大行长度超过1000个字符的文件。此外,我们移除字母字符少于25%的文件。除了XSLT编程语言之外,我们进一步过滤掉文件<?xml version=\ where the string出现在前100个字符中。对于HTML文件,我们考虑可见文本与HTML代码的比率。我们保留那些可见文本至少占代码20%且不少于100个字符的文件。对于通常包含更多数据的JSON和YAML文件,我们只保留字符数在50到5000之间的文件。这有效地移除了大多数数据量大的文件。 2.2. 依存句法分析 在之前的研究工作(Chen等人,2021年;Li等人,2023年;Nijkamp等人,2022年;Roziere等人,2023年)中,用于代码的大型语言模型主要在文件级别的源代码上进行预训练,这忽略了项目中文件之间的依赖关系。然而,在实际应用中,这些模型难以有效地扩展以处理整个项目级别的代码场景。因此,我们 在本步骤中,将考虑如何利用同一代码仓库内文件之间的依赖关系。具体而言,我们首先解析文件间的依赖关系,然后按照确保每个文件所依赖的上下文置于输入序列中该文件之前的原则对文件进行排序。通过根据其依赖关系对文件进行对齐,我们的数据集更准确地反映了真实的编程实践和结构。这种增强的对齐不仅使数据集更具相关性,还可能提高模型在处理项目级代码场景中的实用性和适用性。值得注意的是,我们仅考虑文件间的调用关系,并使用正则表达式来提取这些关系,例如\"import\在Python中,使用在C#中,和includein C. 算法1描述了在同一项目中对文件列表进行依赖分析的拓扑排序。最初,它设置了两个数据结构:一个名为空邻接表\"图表\用来表示文件之间的依赖关系以及一个叫做空的字典。\"inDegree\用于存储每个文件入度。 然后,该算法遍历每对文件以识别依赖关系。 dencies, updating\"图表\and\"inDegree\据此。接下来,它识别整体依赖图中任何断开的子图。对于每个子图,该算法采用改进的拓扑排序。与标准方法选择入度为零的节点不同,此算法选择入度最小的节点,这使其能够处理图中的循环。选定的节点被添加到\"结果\列举,并且其相连节点的入度被降低。这个过程持续进行,直到为每个子图生成一个拓扑排序序列。算法最后通过返回这些排序序列列表结束,并且每个序列中的文件被连接起来形成一个单独的训练样本。为了包含文件路径信息,在每份文件的开头添加一个标明文件路径的注释。这种方法确保路径信息被保留在训练数据中。 2.3. 回收级别去重 近期研究表明,通过为大型语言模型(LLMs)进行训练数据去重可以显著提升模型性能。Lee等人(2022)指出,语言模型训练语料库中常包含大量近似重复内容,通过移除冗长的重复子串可以增强LLM的性能。Kocetkov等人(2022)将近似去重方法应用于训练数据,实现了显著性能提升,并强调近似去重是实现代码基准任务竞争性表现的关键预处理步骤。在我们的数据集中,我们也采用了近似去重方法。然而,与先前工作相比,我们的方法存在差异。我们在代码库级别而非文件级别进行去重,因为后者可能过滤掉库内的部分文件,从而破坏代码库结构。具体而言,我们将来自代码库级别的拼接代码视为单个样本,并应用相同的近似去重算法,以确保代码库结构的完整性。 2.4. 质量筛选与脱污 除应用第2.1节中提到的过滤规则外,我们还采用编译器和质量模型,结合启发式规则,进一步过滤低质量数据。这包括存在语法错误、可读性差和模块化程度低のコード。我们在表1中提供了源代码的统计摘要,涵盖了总共87种语言,详细列出了每种语言的磁盘大小、文件数量和百分比。总数据量为798 GB,包含603亿份文件。为确保我们的代码训练数据不被GitHub上可能存在的测试集信息污染,我们实施了n-gram过滤过程。该过程涉及移除符合特定标准的任何代码片段。具体而言,我们从HumanEval (Chen et al., 2021)、MBPP (Austin et al., 2021)、GSM8K (Cobbe et al., 2021)和MATH (Hendrycks et al., 2021)等来源中过滤掉包含docstrings、问题和解决方案的文件。针对过滤标准,我们应用以下规则:若某段代码包含与测试数据中任何10-gram字符串完全一致的字符串,则将其排除在训练数据之外。在测试数据包含长度短于10-gram但不少于3-gram的字符串的情况下,我们采用精确匹配方法进行过滤。 3. 培训政策 3.1. 训练策略 3.1.1. 下一个标记预测 下一个标记预测我们的模型的第一个训练目标是在这个过程中,各种文件被连接起来形成固定长度的条目。然后,这些条目被用来训练模型,使其能够根据提供的上下文预测后续的标记。 3.1.2. 填空题 fill-in-the-middle.我们的模型的第二个训练目标被称为在代码预训练场景下,通常需要根据给定上下文和后续 文本生成相应的插入内容。由于编程语言中存在特定依赖,仅依赖下一个词预测不足以学习这种填空能力。因此,几种方法(Bavarian等人,2022年;Li等人,2023年)提出了填空中间(FIM)的预训练方法。该方法涉及将文本随机分为三部分,然后打乱这些部分的顺序并用特殊字符连接。该方法旨在将填空预训练任务整合到训练过程中。在FIM方法论中,采用了两种不同的模式:PSM(前缀-后缀-中间)和SPM(后缀-前缀-中间)。在PSM模式下,训练语料库以푃푟푒 푓 푖푥,푆푢 푓 푓 푖푥,푀푖푑푝푙푒, 以使中间段落被前缀和后缀夹在中间排列。相反, SPM模式将段落排列为푆푢 푓 푓 푖푥,푃푟푒 푓 푖푥,푀푖푑푝푙푒,呈现出不同的结构挑战。这些模式在增强模型处理代码中各种结构安排的能力方面发挥着关键作用,为高级代码预测任务提供稳健的训练框架。 为了确定FIM方法中各种超参数的有效性,我们进行了一系列的消融实验。 实验设置:在本实验中,我们采用DeepSeek-Coder-Base 1.3