```html 作者: Mayank Mishra⋆, IBM Matt Stallone⋆, IBM Gaoyuan Zhang⋆, IBM Yikang Shen, IBM Aditya Prasad, IBM Adriana Meza Soria, IBM Michele Merler, IBM Parameswaran Selvam, IBM Saptha Surendran, IBM Shivdeep Singh, IBM Manish Sethi, IBM Xuan-Hong Dang, IBM Pengyuan Li, IBM Kun-Lung Wu, IBM Syed Zawad, IBM Andrew Coleman, IBM Matthew White, IBM Mark Lewis, IBM Raju Pavuluri, IBM Yan Koyfman, IBM Boris Lublinsky, IBM Maximilien de Bayser, IBM Ibrahim Abdelaziz, IBM Kinjal Basu, IBM Mayank Agarwal, IBM Yi Zhou, IBM Chris Johnson, IBM Aanchal Goyal, IBM Hima Patel, IBM Yousaf Shah, IBM Petros Zerfos, IBM Heiko Ludwig, IBM Asim Munawar, IBM Maxwell Crouse, IBM Pavan Kapanipathi, IBM Shweta Salaria, IBM Bob Calio, IBM Sophia Wen, IBM Seetharami Seelam, IBM Brian Belgodere, IBM Carlos Fonseca, IBM Amith Singhee, IBM Nirmit Desai, IBM David D. Cox, IBM Ruchir Puri†, IBM Rameswar Panda†, IBM 摘要 经过代码训练的大型语言模型(LLM)正在彻底改变软件开发过程。代码 LLM 越来越多地集成到软件开发环境中,以提高人类程序员的生产力,而基于 LLM 的代理也开始在自主处理复杂任务方面显示出潜力。要充分发挥代码 LLM 的潜力,需要广泛的能力,包括代码生成、修复 bug、解释和记录代码、维护存储库等等。在这项工作中,我们介绍了 Granite 系列的仅解码器代码模型,用于代码生成任务,并使用 116 种编程语言编写的代码进行训练。Granite Code 模型家族由 30 亿到 340 亿个参数的模型组成,适用于从复杂的应用程序现代化任务到设备上内存受限的用例等各种应用程序。在一系列全面的任务上的评估表明,Granite Code 模型在现有的开源代码 LLM 中始终达到最先进的性能。Granite Code 模型家族针对企业软件开发工作流程进行了优化,并且在各种编码任务(例如代码生成、修复和解释)中表现出色,使其成为一款通用的“全能型”代码模型。我们根据 Apache 2.0 许可证发布所有 Granite Code 模型,用于研究和商业用途。 https://github.com/ibm-granite/granite-code-models 1 引言 在过去的几十年里,软件已经渗透到我们社会生活的方方面面。随着软件开发需求的激增,提高软件开发生产力比以往任何时候都更加重要,而 LLM 为增强人类程序员提供了有前途的途径。LLM 在软件开发生产力方面的突出企业用例包括代码生成、代码解释、代码修复、单元测试和文档生成、应用程序现代化、漏洞检测、代码翻译等等。 近年来,LLM 在生成和操作代码方面的能力取得了快速进展,如今已有多种模型具备令人印象深刻的编码能力。模型规模从数十亿参数(例如 Llama-7B (Touvron et al., 2023)、Gemma-7B (Gemma-Team et al., 2024) 等)到数百亿不等:DBRX (Databricks)、Arctic (Snowflake)、Grok、Mixtral 8x22B (MistralAI)、Command R+ (Cohere),其预期用途的通用性各不相同,一些模型旨在涵盖代码之外的各种用途,而另一些模型则主要专注于编码相关任务(例如 StarCoder (Li et al., 2023a; Lozhkov et al., 2024)、CodeGen (Nijkamp et al., 2023)、CodeLlama (Rozie`re et al., 2023)、CodeGemma (CodeGemma Team et al., 2024))。 然而,代码 LLM 领域仍然存在重要的差距,尤其是在企业软件开发方面。首先,虽然非常大、通用的 LLM 可以实现出色的编码性能,但其规模使得部署成本高昂。较小的、专注于代码的模型( , ; , ; , ; , ; , )可以在更小、更灵活的包中实现出色的代码生成性能,但在生成之外的编码任务(例如修复和解释)中的性能可能落后于代码生成性能。 Li et al. 2023a Lozhkov et al. 2024 Nijkamp et al. 2023 Rozie`re et al. 2023 CodeGemma Team et al. 2024 在许多企业环境中,代码 LLM 的采用可能会因模型性能以外的因素而进一步复杂化。例如,即使是开源模型,有时也缺乏关于模型所使用的数据源和数据处理方法的透明度,这可能会侵蚀在任务关键型和受监管环境中对模型的信任。此外,当今开放 LLM 中的许可条款可能会阻碍和复杂化企业使用模型的可能性。 在这里,我们展示了 Granite Code 模型,这是一系列功能强大的代码 LLM,旨在支持企业软件开发中的广泛编码任务。Granite Code 模型有两个主要变体,我们以四种不同的大小(30 亿、80 亿、200 亿和 340 亿)发布: 用于代码相关任务的基础模型; Granite Code Base: 指令遵循模型,使用 Git 提交与人工指令配对以及开源合成代码指令数据集进行微调。 Granite Code Instruct: 该系列的基础模型是从头开始训练的,采用两阶段训练策略。在第一阶段,我们的模型在来自 116 种编程语言的 3 到 4 万亿个 token 上进行训练,确保对编程语言和语法的全面理解。在第二阶段,我们的模型在 5000 亿个 token 上进行进一步训练,其中包含精心设计的来自代码和自然语言领域的优质数据混合,以提高模型推理能力。我们在训练的两个阶段都使用无监督语言建模目标来训练基础模型。指令模型是通过在过滤后的 CommitPack( , )、自然语言指令遵循数据集(OASST( , )、HelpSteer( , ))和开源数学数据集(MathInstruct( , )和 MetaMathQA( , ))的组合上进一步微调上述训练好的基础模型,包括用于提高指令遵循和推理能力的合成代码数据集。 Muennighoff et al. 2023 Ko¨ pf et al. 2023 Wang et al. 2023 Yue et al. 2023 Yu et al. 2023 我们在一系列全面的基准测试中对我们的代码 LLM 进行了广泛的评估,包括 HumanEvalPack( , )、MBPP(+)( , ; , )、RepoBench( , )、ReCode( , )等。这组基准测试涵盖了除 Python 中的代码综合之外的许多不同类型的编码任务,例如代码修复、代码解释、代码编辑、代码翻译等,涵盖了大多数主流编程语言(Python、JavaScript、Java、Go、C++、Rust 等)。 Muennighoff et al. 2023 Austin et al. 2021 Liu et al. 2023a Liu et al. 2023b Wang et al. 2022 我们的研究结果表明,在开源模型中,Granite Code 模型在所有模型大小和基准测试中总体上表现非常出色(通常优于大小是 Granite 两倍的其他开源代码模型)。例如,图 (顶部)显示了 Granite-8B-Code-Base 与其他开源基础代码 LLM 的比较,包括 Mistral( , )和 LLama-3( , )等近期高性能通用基础 LLM 在 HumanEvalPack( , )上的比较。虽然 CodeGemma 和 StarCoder2 在生成代码方面表现不错,但在 HumanEvalPack 的代码修复和解释变体上的表现明显较差。平均而言,Granite-8B-Code-Base 在 HumanEvalPack 上的表现比最具竞争力的 CodeGemma-8B 模型高出近 12 个百分点(33.2% 对 21.3%),尽管其训练的 token 数量明显少于后者(4.5T 对 7.5T token)。除了基础模型,我们 Granite Code 模型经过指令微调的变体在 HumanEvalPack 上也表现出色,优于其他开源(代码)指令模型,这表明通过自然语言指令可以使更广泛的编码任务受益(请参阅图 (底部))。 1 Jiang et al. 2023b AI@Meta 2024 Muennighoff et al. 2023 1 此外,由于推理对于解决复杂问题和任务至关重要,我们还在六个数学基准测试上测试了我们的 Granite-8B-Code-Base 模型,包括 MATH( , )、GSM8K( , )以及有计算工具支持的问题解决。我们的 Granite 8B 模型在这些方面取得了比大多数最先进的 7B 或 8B LLM 更好的性能。例如,在 GSM8K 上,Granite-8B-Code-Base 的表现比 Llama-3-8B-Base 高出约 12 个百分点,在 MATH 上高出约 6 个百分点(请参阅表 )。 Cobbe et al. 2021 Cobbe et al. 2021 15 Granite Code 模型的主要优势包括: :Granite Code 模型在不同类型的代码相关任务中均取得具有竞争力或最先进的性能,包括代码生成、解释、修复、编辑、翻译等,证明了其解决各种编码任务的能力; 全能型代码 LLM :我们所有的模型都是根据 IBM 的人工智能伦理原则 收集的、允许使用的许可数据进行训练的,并由 IBM 公司法务团队指导,以确保值得信赖的企业使用。所有 Granite Code 模型均根据 Apache 2.0 许可证发布。 值得信赖的企业级 LLM 1 我们在第 节中描述了我们完整的数据收集、过滤和预处理流程。第 节描述了模型架构的细节,第 4 节描述了训练的细节。第 节提供了指令微调的详细信息,第 节描述了实验和结果,将 Granite Code 模型与其他开源 LLM 进行比较。 2 3 5 6 2 数据收集 在本节中,我们将描述用于准备模型训练的代码数据的爬取和过滤(第 节)、去重(第 节)、HAP/PII 过滤(第 节)过程。我们还概述了用于增强模型语言理解和数学推理能力的高质量自然语言数据。 2.1 2.2 2.3 2.1 数据爬取和过滤 预训练代码数据来自公共数据集,如 Github Code Clean 、StarCoderdata 以及 GitHub 的其他公共代码库和问题。我们过滤原始数据,保留 116 种编程语言,而不是 300 多种语言,如附录 所列。数据到编程语言的分配仅基于文件扩展名,与 StarCoder ( , ) 类似。在语言过滤后,我们应用了四个关键过滤规则来过滤低质量代码( , ):(1) 删除字母字符比例低于 25% 的文件;(2) 除了 XSLT 语言外,过滤掉字符串“<?xml version=”出现在前 100 个字符中的文件;(3) 对于 HTML 文件,仅保留可见文本占 HTML 代码至少 20% 且最小长度为 100 个字符的文件;(4) 对于 JSON 和 YAML 文件,仅保留字符数在 50 到 5000 之间的文件。我们还使用一组质量指标过滤 GitHub 问题,这些指标包括删除自动生成的文本、过滤掉非英语问题、排除来自机器人的评论,并使用对话中参与的用户数量作为质量指标。我们还为每个代码文件添加了与相应存储库关联的许可证信息,通过 Github API 找到,并且只保留具有允许性许可证的文件进行模型训练。 2 3 A Li et al. 2023a Li et al. 2023a 2.2 精确和模糊去重 我们采用激进的去重策略,包括精确去重和模糊去重,以从训练集中删除具有(近似)相同代码内容的文档。对于精确去重,我们首先计算文档内容的 SHA256 哈希值并删除具有相同哈希值的记录。在精确去重之后,我们应用模糊去重,目的是删除可能存在细微差异的代码文件,从而进一步消除数据的偏差。我们为此采用了一个两步方法:(1) 计算所有文档的 MinHash,然后利用局部敏感哈希(LSH)根据其 MinHash 指纹对文档进行分组;(2) 测量同一存储桶中每对文档之间的 Jaccard 相似度,并根据 0.7 的相似度阈值将除一个文档外的所有文档标记为重复项。我们将此近乎去重过程应用于包括 GitHub 问题在内的所有编程语言,以增强训练数据集的丰富性和多样性。 2.3 HAP、PII、恶意软件过滤 为了降低模型生成仇恨、辱骂或亵渎(HAP)语言的可能性,我们尽了最大努力从训练集中过滤 HAP 内容。我们首先创建一个 HAP 关键字词典,然后根据关键字在内容(包括注释)中的出现次数为每个代码文档添加注释。我们过滤掉超出 HAP 阈值的文档,该阈值是根据分布分析和代码文件手动检查计算得出的。此外,为了保护隐私,我们遵循 StarCoder( , )的策略,并尽最大努力从训练集中删除个人身份信息(PII)。具体来说,我们利用 StarPII 模型来检测内容中找到的 IP 地址、密钥、电子邮件地址、姓名、用户名和密码。PII 删除步骤将 PII 文本替换为相应的 token NAME、EMAIL、KEY、PASSWORD,并将 IP 地址更改为合成生成的 IP 地址,如 Li et al. (2023a) 所述。我们还使用 扫描我们的数据集,以识别和删除源代码中的恶意软件实例。 Li et al. 2023a 4 codesecure 2.4 自然语言数据集 除了收集用于模型训练的代码数据外,我们还整理了多个公开的高质量自然语言数据集,以提高模型在语言理解和数学推理方面的熟练程度。此类别下的代表性数据集包括网页文档(Stackexchange、CommonCrawl)、数学网页文本(OpenWeb-Math; ( )、StackMathQA; ( ))、学术文本(Arxiv、Wikipedia)和指令微调数据集(FLAN; ( )、HelpSteer( , ))。我们不对这些已预处理的自然语言数据集进行去重。 Paster et al. 2023 Zhang 2024 Longpre et al. 2023 Wang et al. 2023 3 模型架构 我们基于 transformer 解码器架构 ( , ) 训练了一系列不同大小的代码模型。这些模型的超参数如表 所示。对于所有模型架构,我们都使用了预归一化( , ):归一化应用于注意力机制和 MLP 块的输入。 Vaswani et al. 2017 1 Xiong et al. 2020 :Granite-code 模型家族中最小的模型,使用 RoPE 嵌入( , )和多头注意力( , )进行训练。该模型使用 swish 激活函数( , )和 GLU( , )用于 MLP,通常也称为 swiglu。对于归一化,我们使用 RMSNorm( , ),因为它比 LayerNorm( , )在计算上更有效。3B 模型以 2048 个 token 的上下文长度进行训练。 3B Su et al. 2023 Vaswani et al. 2017 Ramachandran et al. 2017 Shazeer 2020 Zhang & Sennrich 2019 Ba et al. 2016 :8B 模型与 3B 模型具有相似的架构,除了使用分组查询注意力(GQA)( , )。使用 GQA 在此规模下提供了模型性能和推理效率之间更好的权衡。我们以 4096 个 token 的上下文长度训练 8B 模型。 8B Ainslie et al. 2023 :20B 代码模型使用学习的绝对位置嵌入进行训练。我们在训练期间使用多查询注意力( , )以实现高效的下游推理。对于 MLP 块,我们使用 GELU 激活函数( , )。为了对激活进行归一化,我们使用 LayerNorm( , )。该模型以 8192 个 token 的上下文长度进行训练。 20B Shazeer 2019 Hendrycks & Gimpel 2023 Ba et al. 2016 :为了训练 34B 模型,我们遵循 的方法进行 20B 模型的深度扩展。具体来说,我们首先将具有 52 个层的 20B 代码模型复制,然后删除原始模型的最后 8 层及其副本的前 8 层,形成两个模型。 34B Kim et al. 最后,我们将两个模型连接起来形成 Granite-34B-Code 模型,该模型具有 88 层(参见图 的说明)。深度扩展后,我们观察到与 20B 模型相比,性能下降非常小,这与 的观察结果相反。在继续预训练扩展后的 34B 模型后,这种性能恢复得相当快。与 20B 模型类似,我们在预训练期间使用了 8192 token 的上下文。 2 Kim et al. 4 预训练 在本节中,我们提供有关两阶段训练(第 节)、训练目标(第 节)、优化(第 节)和基础设施(第 节)的详细信息,这些细节用于预训练模型。 4.1 4.2 4.3 4.4 4.1 两阶段训练 Granite Code 模型在 3.5T 到 4.5T token 的代码数据和与代码相关的自然语言数据集上进行训练。数据通过字节对编码(BPE, ( , ))进行分词,使用与 StarCoder ( , ) 相同的分词器。遵循( , ; , ),我们通过以下方式使用高质量数据进行两阶段训练。 Sennrich et al. 2015 Li et al. 2023a Shen et al. 2024 Hu et al. 2024 • :在第一阶段,3B 和 8B 模型都在包含 116 种语言的代码数据上训练 4 万亿 token。20B 参数模型在 3 万亿 token 的代码上进行训练。34B 模型在深度扩展后,在 1.4T token 上进行训练,深度扩展是在 20B 模型的 1.6T 检查点上完成的。 第一阶段(仅代码训练) • :在第二阶段,我们纳入了来自技术、数学和网页文档等各种领域的其他高质量公共可用数据,以进一步提高模型在推理和解决问题方面的能力,这对于代码生成至关重要。我们在第二阶段训练中,对所有模型训练了 500B token(80% 代码和 20% 语言数据)。 第二阶段(代码 + 语言训练) 4.2 训练目标 对于我们所有模型的训练,我们使用因果语言建模目标和填充中间(FIM)( , )目标。FIM 目标是预测给定上下文和后续文本的插入 token。我们训练模型以支持 PSM(前缀-后缀-中间)和 SPM(后缀-前缀-中间)模式,并使用与 StarCoder ( , ) 相同的相关格式控制 token。 Bavarian et al. 2022 Li et al. 2023a 总损失计算为两个目标的加权组合: 我们在训练期间经验性地将 设置为 0.5,并发现这在实践中效果很好,在代码补全和代码填充任务上都能获得最先进的性能。应注意的是,FIM 目标仅在预训练期间使用,但在指令微调期间将其删除,即我们将 设置为 1。 α α 4.3 优化 我们使用 AdamW 优化器([Kingma & Ba](#_bookmark80), [2017](#_bookmark80)),其中 β1 = 0.9,β2 = 0.95,权重衰减为 0.1,用于训练我们所有的 Granite 代码模型。对于第一阶段的预训练,学习率遵循余弦调度,从 3 10−4 开始,衰减至 3 10−5,初始线性预热步长为 2k 次迭代。对于第二阶段的预训练,我们从 3 10−4 开始(20B 和 34B 模型为 1.5 10−4),并采用指数衰减调度将其衰减到初始学习率的 10%。在预训练的两个阶段中,我们根据模型大小使用 4M-5M token 的批量大小。 为了加速训练,我们使用了 FlashAttention 2( , ; , )、持久层归一化核、融合 RMSNorm 核(取决于模型)和 NVIDIA 的 Apex 库中提供的融合 Adam 核。我们使用了 NVIDIA 的 Megatron-LM( , ; , )的一个自定义分支,用于我们所有模型的分布式训练。我们使用 3D 并行(张量并行、流水线并行和数据并行)进行训练。我们还使用序列并行( , )来减少训练期间大上下文长度的激活内存消耗。我们使用 Megatron 的分布式优化器,并采用混合精度训练( , )在 BF16( , )下进行,并使用 FP32 进行梯度 all-reduce 和梯度累积以提高训练稳定性。 Dao et al. 2022 Dao 2023 Shoeybi et al. 2019 Narayanan et al. 2021 Korthikanti et al. 2023 Micikevicius et al. 2018 Kalamkar et al. 2019 4.4 基础设施 我们使用 IBM 的两个超级计算集群,即 Vela 和 Blue Vela,分别配备 NVIDIA A100 和 H100 GPU,来训练 Granite Code 模型。在 Vela A100 GPU 集群中,每个节点有 2 个 Intel Xeon 可扩展处理器和 8 个 80GB A100 GPU,通过 NVLink 和 NVSwitch 连接。Vela 集群采用 RoCE(Converged Ethernet 上的 RDMA)和 GDR(GPU-direct RDMA)进行高性能网络连接。同样,Blue Vela 集群中的每个节点由双 48 核 Intel 处理器和 8 个 80GB H100 GPU 组成。Blue Vela 采用 3.2Tbps InfiniBand 互连,以促进节点之间的无缝通信,其特点是高吞吐量和低延迟。此外,Blue Vela 采用独立的、专用的 InfiniBand 存储 fabric,为每个计算节点提供 800Gbps 带宽,并由多个 ESS6000 存储设备支持。这两个集群都为在数千个 GPU 上训练我们的模型提供了可扩展且高效的基础设施。我们估计预训练 Granite Code 模型产生的碳排放量为 455 tCO2eq,该排放量是根据模型总能耗和美国平均碳强度因子 0.423 kg CO2eq/KWh 计算得出的,未考虑数据中心的地理位置。Blue Vela 集群运行在 100% 可再生能源上,以最大限度地减少对环境的影响。 5 指令微调 在各种通过指令解释的任务上对代码 LLM 进行微调已被证明可以提高模型的可用性和整体性能。尽管代码指令微调取得了很大进展,但大多数方法都采用了 OpenAI 模型生成的合成数据,这限制了模型在许多企业应用中的使用。因此,遵循 OctoCoder( , ),我们仅使用许可允许的数据组合,旨在提高我们模型的指令遵循能力,包括逻辑推理和解决问题的技能。具体来说,Granite Code Instruct 模型在以下类型的数据上进行训练。 Muennighoff et al. 2023 • :CommitPackFT( , ),这是跨 92 种编程语言的完整 CommitPack 数据集的过滤版本 ; 代码提交数据集 Muennighoff et al. 2023 6 :MathInstruct ( , )和 MetaMathQA( , ); 数学数据集 7 Yue et al. 2023 Yu et al. 2023 :Glaive-Code-Assistant-v3 、Self-OSS-Instruct-SC2 、Glaive-Function-Calling-v2 、NL2SQL 和一些合成 API 调用数据集( , 代码指令数据集 8 9 10 11 Basu et al. 20