作者: 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 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 的许可条款可能会阻碍和复杂化企业使用模型的能v力。 在这里,我们介绍了 Granite Code 模型,这是一系列功能强大的代码 LLM,旨在支持企业软件开发中的广泛编码任务。Granite Code 模型有两个主要变体,我们以四种不同的大小(3B、8B、20B 和 34B)发布: 用于代码相关任务的基础模型; 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 的两倍的其他开源代码模型)。如图 (顶部)所示,在 HumanEvalPack( , )上,Granite-8B-Code-Base 与其他开源基础代码 LLM 进行了比较,包括 Mistral( , )和 LLama-3( , )等近期表现出色的通用基础 LLM。虽然 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 Muennighoff et al. 2023 Jiang et al. 2023b AI@Meta 2024 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 的 AI 道德原则 ,并由 IBM 公司法律团队指导,使用符合许可要求的数据进行训练,以实现值得信赖的企业使用。所有 Granite Code 模型均根据 Apache 2.0 许可证发布。 值得信赖的企业级 LLM 1 我们在第 节中描述了我们完整的数据收集、过滤和预处理流程。第 节描述了模型架构的详细信息,第 4 节是训练细节。第 5 节描述了指令微调的细节,第 6 节描述了比较 Granite Code 模型与其他开源 LLM 的实验和结果。 2 3 2 数据收集 在本节中,我们描述了用于准备模型训练代码数据的爬取和过滤(第 2.1 节)、去重(第 2.2 节)、HAP/PII 过滤(第 2.3 节)。我们还概述了用于增强模型语言理解和数学推理能力的高质量自然语言数据。 2.1 数据爬取和过滤 预训练代码数据来自公开可用的数据集,如 Github Code Clean 、StarCoderdata 以及 GitHub 上的其他公共代码存储库和问题。我们过滤原始数据,从 300 多种语言中保留 116 种编程语言的列表,如附录 所示。数据到编程语言的分配仅基于文件扩展名进行,与 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 Amass 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 嵌入( , )和多头注意力( , )进行训练。该模型在 MLP 中使用 swish 激活函数( , )和 GLU( , ),也常被称为 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. 最后,我们将这两个模型连接起来形成具有 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 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 训练目标 对于我们所有模型的训练,我们使用因果语言建模目标和 Fill-In-the-Middle (FIM)( , )目标。FIM 目标负责预测给定上下文和后续文本的插入 token。我们训练我们的模型以使用 PSM(前缀-后缀-中间)和 SPM(后缀-前缀-中间)模式,并使用与 StarCoder ( , ) 相同的相关格式控制 token。 Bavarian et al. 2022 Li et al. 2023a 总损失计算为两个目标的加权组合: 我们在训练期间经验性地将 α = 0.5,并在实践中发现它效果很好,从而在代码补全和代码填充任务上都取得了 SOTA 性能。需要注意的是,FIM 目标仅在预训练期间使用,但在指令微调期间我们将其删除,即设置 α = 1。 4.3 优化 我们使用 AdamW 优化器([Kingma & Ba](#_bookmark80),(#_bookmark80)),对于所有 Granite 代码模型的训练,β1 = 0.9,β2 = 0.95,权重衰减为 0.1。对于第一阶段预训练,学习率遵循余弦调度,从 3 × 10 开始,衰减到 3 × 10 ,初始线性预热步骤为 2k 次迭代。对于第二阶段预训练,我们从 3 × 10 (20B 和 34B 模型为 1.5 × 10 )开始,并采用指数衰减调度将其衰减到初始学习率的 10%。在两个预训练阶段,我们都使用 4M-5M token 的批量大小,具体取决于模型大小。 −4 −5 −4 −4 为了加速训练,我们使用了 NVIDIA 的 Apex 库中的 FlashAttention 2( , ; , )、持久层归一化核、融合 RMSNorm 核(取决于模型)和融合 Adam 核。我们使用 NVIDIA 的 Megatron-LM( , ; , )的自定义分支进行所有模型的分布式训练。我们使用 3D 并行:张量并行、流水线并行和数据并行。我们还使用序列并行( , )来减少训练期间大上下文长度的激活内存消耗。我们使用 Megatron 的分布式优化器进行混合精度训练( , ),在 BF16( , )下进行梯度 all-reduce,并使用 FP32 进行梯度累积以提高训练稳定性。 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 Code 模型,分别配备 NVIDIA A100 和 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 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. 2024 :高质量数据集,如 HelpSteer( , ),Platypus ( , 语言指令数据集 Wang et al. 2023 12 Lee et al.