AI智能总结
郭大雅 *1, 朱启浩∗1,2、杨德建1, 谢振达1、启东1, 张文涛1陈官厅1、小碧1, Y. Wu 1, Y.K. Li 1、罗富力1, 熊英飞2, 梁文峰1 1DeepSeek - AI2HCST (PKU) 教育部重点实验室 ; 北京大学 SCS{zhuqh, guodaya} @ deepseek. com https: / / github. com / deepseek - ai / DeepSeek - Coder Abstract 大型语言模型的快速发展已彻底革新了软件开发中的代码智能。然而,主要依赖闭源模型限制了广泛的研究与开发。为解决这一问题,我们推出了DeepSeek-Coder系列开源代码模型,其规模从13亿到330亿不等,并从2万亿个标记中从头开始训练。这些模型预先在高质量的项目级代码语料库上进行训练,并采用16K窗口的填空任务来增强代码生成和填补。我们的广泛评估表明,DeepSeek-Coder不仅在多个基准测试中实现了开源代码模型的最佳性能,还超越了现有的闭源模型如Codex和GPT-3.5。此外,DeepSeek-Coder模型处于宽松的许可之下,允许同时进行研究和无限制的商业使用。 1. Introduction 软件开发领域因大型语言模型的迅速进步(OpenAI, 2023;Touvron et al., 2023)而得到了显著转型,这些模型带来了代码智能的新时代。这些模型有可能自动化和简化许多编码方面的工作,从错误检测到代码生成,从而提高生产力并减少人为错误的可能性。然而,该领域的重大挑战之一是在开源模型(Li et al., 2023;Nijkamp et al., 2022;Rozier et al., 2023;Wang etal., 2021)与闭源模型(Gemini Team, 2023;OpenAI, 2023)之间的性能差距。尽管巨型闭源模型非常强大,但由于其专有性质,许多研究人员和开发者仍然难以访问这些模型。 为了应对这一挑战,我们推出了DeepSeek-Coder系列。该系列包括一系列开源代码模型,规模从13亿到33亿不等,涵盖每个规模的基版本和指令版本。每个系列中的模型均从87种编程语言中提取的2万亿个标记重新训练,确保对编程语言和语法有全面的理解。此外,我们尝试在仓库级别组织预训练数据,以增强模型在仓库内部跨文件上下文中的理解能力。除了在预训练过程中使用下一个标记预测损失外,我们还引入了Fill-In-Middle(FIM)方法(Bavarian etal., 2022;Li et al., 2023)。这种方法旨在进一步提升模型的代码完成能力。为满足处理更长代码输入的要求,我们将上下文长度扩展到16K。这一调整使我们的模型能够处理更加复杂和广泛的编码任务,从而增强了其在各种编码场景中的适用性和灵活性。 我们使用多种公开的代码相关基准进行了全面的实验。研究发现,在开源模型中,DeepSeek-Coder-Base 33B 在所有基准测试中均表现出优越的性能。此外,OpenAI GPT - 3.5 TurboCoder - Instruct 33B 超越在大多数评估基准中 ,OpenAI GPT - 4显著缩小两者之间的性能差距并且采用了开源模型。令人惊讶的是,尽管参数量较少,DeepSeek-Coder-Base 7B 在与参数量大五倍的模型(如 CodeLlama-33B)相比时仍能展现出竞争力的表现(Roziere et al., 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 数据抓取和过滤 我们在GitHub上收集了截至2023年2月之前创建的公共仓库,并仅保留了87种编程语言(如表1所示)。为了减少处理的数据量,我们应用了与StarCoder项目(Li等,2023)中使用的规则类似的过滤规则,初步筛选掉质量较低的代码。通过应用这些过滤规则,我们将数据总量减少了至原始大小的32.8%。为了使论文更加自包含,我们简要描述了StarCoder Data项目中使用的过滤规则: 首先,我们过滤掉平均行长度超过100字符或最大行长度超过1000字符的文件。此外,我们去除包含少于25%字母字符的文件。除了XSLT编程语言外,我们进一步过滤掉其他类型的文件。 "<? xml 版本 =" 其中字符串出现在前100个字符中。对于HTML文件,我们考虑可见文本与HTML代码的比例。我们保留那些可见文本至少占代码20%且不少于100个字符的文件。对于通常包含更多数据的JSON和YAML文件,我们仅保留字符计数在50到5000之间的文件。这有效地移除了大多数数据密集型文件。 2.2. Dependency Parsing 在之前的研究中(Chen et al., 2021;Li et al., 2023;Nijkamp et al., 2022;Rozier et al., 2023),大型语言模型主要在文件级别源代码上进行预训练,忽略了项目中不同文件之间的依赖关系。然而,在实际应用中,这类模型难以有效地扩展以处理整个项目级别的代码场景。因此,我们 我们将考虑如何在同一仓库内利用文件之间的依赖关系。具体来说,我们首先解析文件间的依赖关系,然后按照确保每个文件所依赖的上下文出现在该文件之前的顺序排列这些文件。通过根据依赖关系对文件进行对齐,我们的数据集更准确地反映了实际的编码实践和结构。这种增强的对齐不仅使数据集更具相关性,还可能提高模型在处理项目级代码场景时的实用性和适用性。值得注意的是,我们仅考虑文件之间的调用关系,并使用正则表达式提取这些关系,例如"导入"在 Python 中 ,"使用"在 C # 中 , 和"包括"in C. 该算法1描述了在一个项目内的文件列表中进行依赖分析的拓扑排序。初始步骤是设置两个数据结构:一个名为空邻接表。"图形"表示文件和空字典之间的依赖关系"学位"用于存储每个文件的 in - degrees 。然后 , 算法迭代每个文件对 , 以识别 驻留, 更新"图形"and"学位"相应地,接下来识别整体依赖图中的任何孤立子图。对于每个子图,算法采用修改后的拓扑排序。与标准方法选择入度为零的节点不同,该算法选择入度最小的节点,这使其能够处理图中的循环。选定的节点被添加到"结果"列表中的节点及其连接节点的入度减少。这一过程将持续进行,直到为每个子图生成一个拓扑排序序列。算法最终返回这些排序序列的列表,并将每个序列中的文件连接起来形成单个训练样本。为了包含文件路径信息,在每个文件开头添加一条注释以指示文件的路径。这种方法确保了路径信息保留在训练数据中。 2.3. Repo 级重复数据删除 最近的研究表明,通过去重训练数据集可以显著提高大型语言模型(LLMs)的性能。李等人(2022)发现语言模型训练语料库中往往包含大量的近似重复内容,并且通过移除长篇重复子字符串可以提升LLM的性能。科切托夫等人(2022)应用了近似去重方法到训练数据上,取得了显著的改进,并强调近似去重是实现竞争性性能的关键预处理步骤。在我们的数据集中,我们也采用了近似去重的方法。然而,与以往的工作相比,我们采取了不同的方法。我们是在代码仓库级别进行去重,而不是在文件级别进行,因为后者可能会过滤掉仓库内的某些文件,从而可能破坏仓库结构。具体而言,我们将仓库级别的所有代码拼接成一个样本,并应用相同的近似去重算法以确保仓库结构的完整性。 2.4. 质量筛选和去污 除了应用第2.1节中提到的过滤规则外,我们还使用了一个编译器和一个质量模型,并结合启发式规则进一步过滤掉低质量的数据。这包括包含语法错误、可读性差和低模块化的代码。我们在表1中提供了源代码的统计摘要,其中包括87种语言的总览,详细列出了每种语言的磁盘大小、文件数量以及所占百分比。总数据量为798 GB,共有6亿个文件。为了确保我们的代码训练数据不会受到来自测试集的信息污染,这些信息可能存在于GitHub上,我们实施了n-克gram过滤过程。该过程涉及移除符合特定标准的任何代码片段。具体而言,我们排除了包含来自HumanEval(Chen等,2021)、MBPP(Austin等,2021)、GSM8K(Cobbe等,2021)和MATH(Hendrycks等,2021)等来源的文档字符串、问题和解决方案文件。对于过滤标准,我们应用了以下规则:如果一段代码包含与测试数据中任何一个10-克gram字符串完全相同的字符串,则将其从训练数据中排除。当测试数据由短于10-克gram但不少于3-克gram的字符串组成时,我们采用精确匹配的方法进行过滤。 3. 培训政策 3.1. 培训策略 3.1. 1. Next Token 预测 下一个令牌预测我们模型的第一个训练目标被称为在这一过程中,各种文件被连接以形成固定长度的条目。然后,使用这些条目训练模型,使其能够根据提供的上下文预测后续的标记。 3.1. 2. Fill - in - the - middle 填充中间。我们模型的第二个训练目标被称为在代码预训练场景中,通常需要根据给定的上下文和后续 文本生成相应的插入内容。由于编程语言中的特定依赖关系,仅依靠下一个标记预测不足以学习这种中间填充能力。因此,一些方法(如Bavarian等,2022;Li等,2023)提出了Fill-in-the-Middle(FIM)的预训练方法。该方法涉及随机将文本分为三部分,然后打乱这三部分的顺序并用特殊字符连接它们。这种方法旨在在训练过程中融入一种填空预训练任务。在FIM方法中,使用了两种不同的模式:Prefix-Suffix-Middle(PSM)和Suffix-Prefix-Middle(SPM)。在PSM模式下,训练语料库按以下顺序组织:,,你:相反,SPM模式将段落排列方式设置为由前缀和后缀 flank 中间的部分。,,呈现了不同的结构性挑战。这些模式对于增强模型处理代码中各种结构排列的能力至关重要,并为高级代码预测任务提供了稳健的训练框架。 为了确定FIM方法中各种超参数的有效性,我们进行了系列消融实验。 实验设置:在本次实验中,我