```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 的潜力,需要广泛的能力,包括代码生成、修复错误、解释和记录代码、维护存储库等等。在这项工作中,我们介绍了 Granite 系列的仅解码器代码模型,用于代码生成任务,该模型使用 116 种编程语言的代码进行训练。Granite 代码模型系列包含 3 到 340 亿参数的模型,适用于从复杂的应用程序现代化任务到内存受限的设备用例等各种应用。在综合任务集上的评估表明,Granite 代码模型在现有的开源代码 LLM 中持续达到最先进的性能。Granite 代码模型系列针对企业软件开发工作流程进行了优化,并在各种编码任务(例如代码生成、修复和解释)中表现出色,使其成为一种通用的“全能型”代码模型。我们根据 Apache 2.0 许可证发布所有 Granite 代码模型,用于研究和商业用途。 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 的许可条款可能会阻碍和复杂化企业使用模型的能y。 在此,我们介绍了 Granite 代码模型,这是一系列功能强大的代码 LLM,旨在支持企业软件开发中的各种编码任务。Granite 代码模型有两个主要变体,我们发布了四种不同的尺寸(3B、8B、20B 和 34B): 用于代码相关任务的基础模型; Granite 代码基础模型: 使用 Git 提交与人类指令配对以及开源合成生成的代码指令数据集进行微调的指令遵循模型。 Granite 代码指令模型: 该系列的基础模型是从头开始训练的,采用两阶段训练策略。在第一阶段,我们的模型在来自 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 我们对 Granite 代码 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 代码模型在所有模型大小和基准测试中都表现出非常强的性能(通常优于尺寸是我们 Granite 两倍的其他开源代码模型)。例如,图 1(顶部)显示了 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 代码模型的指令微调变体在 HumanEvalPack 上也表现强劲,优于其他开源(代码)指令模型,这表明自然语言指令可以使更广泛的编码任务受益(见图 1(底部))。 Jiang et al. 2023b AI@Meta 2024 Muennighoff et al. 2023 此外,由于推理对于解决复杂问题至关重要,我们还在六个数学基准测试上测试了我们的 Granite-8B-Code-Base 模型,包括 MATH( , )、GSM8K( , )以及带有计算工具访问的问题解决能力,我们的 Granite 8B 模型在这些方面取得了比大多数最先进的 7B 或 8B LLM 更好的性能。例如,在 GSM8K 上,Granite-8B-Code-Base 的表现比 Llama-3-8B-Base 高出约 12 个百分点,在 MATH 上高出约 6 个百分点(见表 15)。 Cobbe et al. 2021 Cobbe et al. 2021 Granite 代码模型的主要优点包括: :Granite 代码模型在各种代码相关任务(包括代码生成、解释、修复、编辑、翻译等)上实现有竞争力或最先进的性能,这表明它们能够解决各种编码任务; 全能型代码 LLM :我们所有的模型都是在遵循 IBM AI 伦理原则 并由 IBM 公司法务团队指导以确保值得信赖的企业使用而收集的、允许使用的许可证数据上进行训练的。所有 Granite 代码模型均根据 Apache 2.0 许可证发布。 值得信赖的企业级 LLM 1 我们在第 节中描述了我们整个数据收集、过滤和预处理流程。第 节描述了模型架构的详细信息,第 4 节介绍了训练的详细信息。第 节提供了指令微调的详细信息,第 6 节描述了将 Granite 代码模型与其他开源 LLM 进行比较的实验和结果。 2 3 5 2 数据收集 在本节中,我们将描述用于准备模型训练的代码数据的爬取和过滤(第 节)、去重(第 节)、HAP/PII 过滤(第 节)过程。我们还将概述用于增强模型语言理解和数学推理能力的高质量自然语言数据。 2.1 2.2 2.3 2.1 数据爬取和过滤 预训练代码数据来自公开可用的数据集,如 Github Code Clean 、StarCoderdata 以及 GitHub 的其他公共代码仓库和 issue。我们过滤原始数据,从 300 多种语言中保留 116 种编程语言的列表,如附录 所示。数据分配给编程语言是根据文件扩展名进行的,与 StarCoder ( , ) 类似。在语言过滤后,我们应用四项关键过滤规则来过滤低质量代码( , ):(1) 删除字母字符少于 25% 的文件,(2) 除非是 XSLT 语言,否则过滤掉字符串“<?xml version=”出现在前 100 个字符中的文件,(3) 对于 HTML 文件,仅保留可见文本占 HTML 代码至少 20% 且最小长度为 100 个字符的文件,(4) 对于 JSON 和 YAML 文件,仅保留字符数在 50 到 5000 之间的文件。我们还使用一组质量指标过滤 GitHub issue,包括删除自动生成的文本、过滤非英语 issue、排除机器人评论,并使用对话中参与的用户数量作为质量指标。我们还使用 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 issue 在内的所有编程语言,以增强训练数据集的丰富性和多样性。 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 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 模型深度扩展的方法。具体来说,我们首先复制 20B 代码模型(具有 52 层),然后删除原始模型中的最后 8 层和其副本中的前 8 层,形成两个模型。 34B Kim et al. 最后,我们将这两个模型拼接起来,形成具有 88 层的 Granite-34B-Code 模型(参见图 的说明)。在深度扩展之后,我们观察到与 20B 模型相比,性能下降很小,这与 的观察结果相反。在继续预训练扩展后的 34B 模型后,这种性能得到了相当快的恢复。与 20B 模型类似,我们在预训练期间使用 8192 个 token 的上下文。 2 Kim et al. 4 预训练 在本节中,我们将介绍用于预训练模型的两阶段训练(第 节)、训练目标(第 节)、优化(第 节)和基础设施(第 节)的详细信息。 4.1 4.2 4.3 4.4 4.1 两阶段训练 Granite 代码模型在 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 训练目标 对于我们所有模型的训练,我们使用因果语言建模目标和 Fill-In-the-Middle (FIM)( , )目标。FIM 目标是预测给定上下文和后续文本的插入 token。我们以与 StarCoder ( , ) 相同的方式,训练我们的模型以支持 PSM(前缀-后缀-中间)和 SPM(后缀-前缀-中间)模式,并使用相关的格式控制 token。 Bavarian et al. 2022 Li et al. 2023a 总损失计算为 2 个目标的加权组合: 我们在训练中经验性地设置 = 0.5,并在实践中发现这在代码补全和代码填空任务上都能带来 SOTA 性能。应该注意的是,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 的批处理大小,具体取决于模型的大小。 为了加速训练,我们使用了 NVIDIA 的 Apex 库提供的 FlashAttention 2( , ; , )、持久层归一化核、融合 RMSNorm 核(取决于模型)和融合 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 来训练 Granite 代码模型,Vela 配备 NVIDIA A100 GPU,Blue Vela 配备 H100 GPU。在 Vela A100 GPU 集群中,每个节点有 2 个 Intel Xeon 可扩展处理器和 8 个 80GB A100 GPU,通过 NVLink 和 NVSwitch 连接。Vela 集群采用 RoCE(RDMA over Converged Ethernet)和 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 代码模型的预训练产生的碳排放量为 455 tCO2eq,这是根据模型中的总能源使用量和美国平均碳强度系数 0.423 kg CO2eq/KWh 计算得出的,未考虑数据中心的地理位置。Blue Vela 集群运行在 100% 可再生能源上,以最大限度地减少环境影响。 5 指令微调 据报道,在通过指令解释的各种任务上微调代码 LLM 可以提高模型的可用性和整体性能。尽管代码指令微调取得了很大进展,但大多数都采用 OpenAI 模型生成的合成数据,这限制了模型在许多企业应用中的使用。因此,遵循 OctoCoder( , ),我们仅使用允许的许可证数据组合,旨在提高我们模型的指令遵循能力,包括逻辑推理和解决问题的能力。具体来说,Granite 代码指令模型在以下类型的数据上进行训练。 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. 2024 :高质量数据集,如 HelpSteer( , ),Platypus ( 语言指令数据集 Wang et al. 2023 12 Lee et al.