在代码上训练的大型语言模型(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 等人,2023 年)、Gemma-7B(Gemma-Team 等人,2024 年)等)到数百亿参数不等:DBRX(Databricks)、Arctic(Snowflake)、Grok、Mixtral 8x22B(MistralAI)、Command R+(Cohere)等,在用途的普遍性方面也有所不同,一些模型旨在涵盖代码之外的一系列用途,而其他模型主要关注编码相关任务(例如 StarCoder(Li 等人,2023a;Lozhkov 等人,2024 年)、CodeGen(Nijkamp 等人,2023 年)、CodeLlama(Rozière 等人,2023 年)和 CodeGemma(CodeGemma Team 等人,2024 年))。
然而,当前用于代码的 LLM 领域仍然存在重要差距,尤其是在企业软件开发的背景下。首先,虽然非常大的通用 LLM 可以在编码方面取得出色的性能,但它们的规模使得部署成本很高。较小的专注于代码的模型(Li 等人,2023a;Lozhkov 等人,2024 年;Nijkamp 等人,2023 年;Rozière 等人,2023 年;CodeGemma Team 等人,2024 年)可以在更小和更灵活的格式中实现出色的代码生成性能,但在编码任务(例如修复和解释)中的性能可能落后于代码生成性能。
在许多企业环境中,除了模型的性能外,其他因素可能会进一步使代码 LLM 的采用变得复杂。例如,即使开放模型有时也缺乏透明度,即模型中使用的数据源和数据处理方法,这可能会侵蚀关键任务和受监管环境中对模型的信任。此外,当前开放源代码 LLM 中的许可条款可能会阻碍和复杂化企业使用模型的能力。
在这里,该研究介绍 Granite Code 模型,这是一系列高性能的代码 LLM,旨在支持企业软件开发广泛的编码任务。Granite Code 模型有两个主要变体,该研究以四种不同的规模发布(3B、8B、20B 和 34B):
• Granite Code Base:用于代码相关任务的基础模型;
• Granite Code Instruct:使用 Git 提交与人类指令的组合以及开源合成生成的代码指令数据集进行微调的指令遵循模型。
该系列的基础模型已经使用两阶段训练策略从头开始训练。在第一阶段,该研究的模型使用116 种编程语言的 3 到 4 万亿个令牌进行训练,确保对编程语言和语法的全面理解。在第二阶段,该研究的模型使用来自代码和自然语言领域的高质量数据的精心设计的 5000 亿个令牌进一步训练,以提高模型的推理能力。该研究使用无监督的语言建模目标来训练这两个阶段的基础模型。通过进一步微调上述训练过的基础模型,使用 CommitPack(Muennighoff 等人,2023 年)的过滤变体、自然语言指令遵循数据集(OASST(Köpf 等人,2023 年)、HelpSteer(Wang 等人,2023 年))和开源数学数据集(MathInstruct(Yue 等人,2023 年)和 MetaMathQA(Yu 等人,2023 年))以及用于提高指令遵循和推理能力的合成生成的代码数据集的组合来得出指令模型。
该研究在一套全面的基准上广泛评估代码 LLM,包括 HumanEvalPack(Muennighoff 等人,2023 年)、MBPP(+)(Austin 等人,2021 年;Liu 等人,2023a)、RepoBench(Liu 等人,2023b)、ReCode(Wang 等人,2022 年)等。这套基准涵盖了 Python 之外的许多不同类型的编码任务,例如,代码修复、代码解释、代码编辑、代码翻译等,涵盖大多数主要编程语言(Python、JavaScript、Java、Go、C++、Rust 等)。
该研究的发现揭示,在开源模型中,Granite Code 模型在所有模型规模和基准测试中整体表现出非常强大的性能(通常优于是 Granite 两倍大的其他开源代码模型)。作为说明,图 1(上)显示了 Granite-8B-Code-Base 与其他开源基础代码 LLM 在 HumanEvalPack(Muennighoff 等人,2023 年)上的比较,包括最近表现出色的通用基础 LLM,如 Mistral(Jiang 等人,2023b)和 Llama-3(AI@Meta,2024)。虽然 CodeGemma 和 StarCoder2 在生成代码方面表现还不错,但在HumanEvalPack 的代码修复和解释变体上表现明显较差。平均而言,Granite-8B-Code-Base在 HumanEvalPack 上的表现优于最具竞争力的 CodeGemma-8B 模型近 12 个百分点(33.2%对 21.3%),尽管训练的令牌数量明显更少(4.5T 对 7.5T 个令牌)。除了基础模型外,该研究的Granite Code 模型的指令微调变体在 HumanEvalPack 上也表现出色,优于其他开源(代码)指令模型,展示了对更广泛的编码任务的自然语言指令的好处(见图 1(下))。
此外,由于推理对于解决复杂的问题和任务至关重要,该研究还在六个数学基准上测试了Granite-8B-Code-Base 模型,包括 MATH(Cobbe 等人,2021 年)、GSM8K(Cobbe 等人,2021 年)和使用计算工具解决问题,其中该研究的 Granite 8B 模型相比大多数最先进的 7B 或8B LLM 取得更好的性能。例如,Granite-8B-Code-Base 在 GSM8K 上的表现优于 Llama-3-8B-Base 约 12 个点,在 MATH 上优于约 6 个点(见表 15)。
Granite Code 模型的主要优势包括:
• 全能型代码 LLM:Granite Code 模型在不同类型的代码相关任务上实现有竞争力的或最先进的性能,包括代码生成、解释、修复、编辑、翻译等,展示了解决不同编码任务的能力;
• 值得信赖的企业级 LLM:该研究所有的模型都是在遵循 IBM 人工智能道德原则 1并在 IBM公司法律团队的指导下收集许可数据进行训练的,以实现值得信赖的企业使用。所有Granite Code 模型都是在 Apache 2.0 许可下发布的。
该研究在第 2 节中描述了整个数据收集、过滤和预处理管道。第 3 节描述了模型架构的详细信息,第 4 节描述了训练详情。第 5 节提供了有关指令微调的详细信息,第 6 节描述了与其他开源 LLM 相比 Granite Code 模型的实验和结果。
2 数据收集
在本节中,该研究描述了用于准备模型训练代码数据的爬取和过滤(第 2.1 节)、重复数据消除(第 2.2 节)、HAP/PII 过滤(第 2.3 节)过程。该研究还概述了用于增强模型语言理解和数学推理技能的高质量自然语言数据。
2.1 数据爬取和过滤
预训练代码数据来自公开可用的数据集,如 Github Code Clean 2、StarCoderdata 3以及 GitHub的其他公共代码存储库和问题的组合。该研究从 300 多种语言中过滤原始数据,保留 116 种编程语言的列表,如附录 A 所列。与 StarCoder(Li 等人,2023a)类似,数据到编程语言的分配仅基于文件扩展名进行。语言过滤后,该研究应用四个关键过滤规则来过滤掉质量较低的代码(Li 等人,2023a):(1)删除字母字符少于 25% 的文件,(2)除 XSLT 语言外,过滤掉"<?xml version="出现在前 100 个字符内的文件,(3)对于 HTML 文件,只保留可见文本占 HTML 代码至少 20% 且最小长度为 100 个字符的文件,(4)对于 JSON 和 YAML 文件,只保留字符数在 50 到 5000 之间的文件。该研究还使用一组质量指标过滤 GitHub 问题,包括删除自动生成的文本、过滤掉非英语问题、排除机器人的评论以及使用参与对话的用户数量作为质量指标。该研究还使用 Github API 找到的相应存储库关联的许可信息注释每个代码文件,并且只保留具有许可许可的文件用于模型训练。
2.2 精确和模糊重复数据删除
该研究采用积极的重复数据删除策略,包括精确和模糊重复数据删除,以删除训练集中具有(几乎)相同代码内容的文档。对于精确重复数据删除,该研究首先计算文档内容的SHA256 哈希,并删除具有相同哈希的记录。在精确重复数据删除之后,该研究应用模糊重复数据删除,目的是删除可能有轻微变化的代码文件,从而进一步消除数据偏差。该研究为此应用两步方法:(1)计算所有文档的 MinHashes,然后利用局部敏感哈希(LSH)根据其 MinHash 指纹对文档进行分组,(2)测量同一桶中每对文档之间的 Jaccard 相似度,并根据 0.7 的相似度阈值将除一个文档之外的文档注释为重复项。该研究将这种近似重复数据删除过程应用于包括 GitHub 问题在内的所有编程语言,以增强训练数据集的丰富性和多样性。
2.3 HAP、PII、恶意软件过滤
为了减少模型生成仇恨、辱骂或亵渎(HAP)语言的可能性,该研究努力从训练集中过滤掉 HAP 内容。该研究首先创建一个 HAP 关键字字典,然后用内容中包括注释在内的此类关键字出现次数注释每个代码文档。该研究根据分布分析和代码文件的手动检查计算出 HAP 阈值,过滤掉超过该阈值的文档。此外,为了保护隐私,该研究遵循 StarCoder(Li 等人,2023a)的做法,努力从训练集中编辑个人身份信息(PII)。具体来说,该研究利用 StarPII 4模型来检测内容中发现的 IP 地址、密钥、电子邮件地址、姓名、用户名和密码。PII 编辑步骤将 PII 文本替换为相应的令牌 ⟨NAME⟩、⟨EMAIL⟩、⟨KEY⟩、⟨PASSWORD⟩,并将 IP 地址更改为合成生成的 IP 地址,如 Li 等人(2023a)所述。该研究还使用 ClamAV 5扫描数据集,以识别和删除源代码中的恶意软件实例。
2.4 自然语言数据集
除了收集模型训练的代码数据外,该研究还策划了几个公开可用的高质量自然语言数据集,以提高模型在语言理解和数学推理方面的能力。这一类别下的代表性数据集包括网络文档(Stackexchange、CommonCrawl)、数学网络文本(OpenWebMath;Paster 等人,2023 年,StackMathQA;Zhang,2024 年)、学术文本(Arxiv、Wikipedia)和指令调优数据集(FLAN;Longpre 等人,2023 年,HelpSteer(Wang 等人,2023 年))。该研究不对这些已经预处理过的自然语言数据集进行重复数据删除。
3 模型架构
该研究基于 transformer 解码器架构(Vaswani 等人,2017 年)训练了一系列不同大小的代码模型。这些模型的模型超参数在表 1 中给出。对于所有模型架构,该研究使用预归一化(Xiong 等人,2020 年):应用于注意力和 MLP 块输入的归一化。
表 1:Granite Code 模型的模型配置。
模型 | 3B | 8B | 20B | 34B |
---|---|---|---|---|
Batch size | 2048 | 1024 | 576 | 532 |
Context length | 2048 | 4096 | 8192 | 8192 |
Hidden size | 2560 | 4096 | 4096 | 6144 |
FFN hidden size | 10240 | 14336 | 24576 | 24576 |
Attention heads | 32 | 32 | 48 | 48 |
Key-Value heads | 32 (MHA) | 8 (GQA) | 1 (MQA) | 1 (MQA) |
Layers | 32 | 36 | 52 | 88 |
Normalization | RMSNorm | RMSNorm | LayerNorm | LayerNorm |
Activation | swiglu | swiglu | gelu | gelu |
Vocab size | 49152 | 49152 | 49152 | 49152 |
3B:Granite-code 模型家族中最小的模型使用 RoPE 嵌入(Su 等人,2023 年)和多头注意力(Vaswani 等人,2017 年)进行训练。该模型使用带有 GLU(Shazeer,2020)的 swish 激活函数(Ramachandran 等人,2017 年)作为 MLP,通常也称为 swiglu。对于归一化,该研究使用 RMSNorm(Zhang 和 Sennrich,2019 年),因为它在计算上比 LayerNorm(Ba 等人,2016 年)更有效。3B 模型的上下文长度为 2048 个令牌进行训练。
8B:8B 模型的架构与 3B 模型类似,但使用分组查询注意力(GQA)(Ainslie 等人,2023 年)。在这个规模下使用 GQA 可以在模型性能和推理效率之间提供更好的平衡。该研究使用 4096 个令牌的上下文长度训练 8B 模型。
20B:20B 代码模型使用学习到的绝对位置嵌入进行训练。该研究在训练期间使用多查询注意力(Shazeer,2019)进行高效的下游推理。对于 MLP 块,该研究使用 GELU 激活函数(Hendrycks 和 Gimpel,2023)。对于归一化,该研究使用 LayerNorm(Ba 等人,2016 年)。该模型使用 8192 个令牌的上下文长度进行训练。
34B:为了训练 34B 模型,该研究遵循 Kim 等人提出的 20B 模型深度放大方法。具体来说,该研究首先复制具有 52 层的 20B 代码模型,然后从原始模型中删除最后 8 层,并从其副本中删除初始 8 层,以形成两个模型。最后,该研究将两个模型连接起来,形成具有 88 层的 Granite-34B-Code 模型(见图 2 的说明)。深度放大后,该研究观察到与 20B 模型相比性能下降非常小,与 Kim 等人观察到的情况相反。在该研究继续预训练放大的34B模型后,这种性能很快就恢复了。与 20B 类似,该研究在预训练期间使用 8192 个令牌的上下文。
4 预训练
在本节中,该研究提供了有关两阶段训练(第 4.1 节)、训练目标(第 4.2 节)、优化(第 4.3 节)和基础设施(第 4.4 节)在模型预训练中使用的细节。
4.1 两阶段训练
Granite Code 模型在 3.5T 到 4.5T 个与代码相关的自然语言数据集中的代码数据令牌上训练。数据通过字节对编码(BPE,(Sennrich 等人,2015 年))进行标记化,采用与 StarCoder(Li 等人,2023a)相同的标记器。遵循(Shen 等人,2024 年;Hu 等人,2024 年),该研究利用两阶段训练的高质量数据,如下所示。
• 阶段 1(仅代码训练):在阶段 1 中,3B 和 8B 模型都在 4 万亿个代码数据令牌上训练,包括 116 种语言。20B 参数模型在 3 万亿个代码令牌上训练。在 20B 模型的 1.6T 检查点完成深度放大后,34B 模型在 1.4T 个令牌上训练。
•第 2 阶段(代码 + 语言训练):在第 2 阶段,该研究包括来自各个领域的额外的高质量公开可用数据,包括技术、数学和网络文档,以进一步提高模型在推理和解决问题方面的性能,这对代码生成至关重要。该研究在第 2 阶段训练中为所有模型训练 5000 亿个令牌(80% 的代码和 20% 的语言数据)。
4.2 训练目标
对于所有模型的训练,该研究使用因果语言建模目标和填充中间(FIM)(Bavarian 等人,2022 年)目标。FIM 目标的任务是在给定上下文和后续文本的情况下预测插入的标记。该研究训练模型以使用 PSM(前缀-后缀-中间)和 SPM(后缀-前缀-中间)模式,与 StarCoder(Li 等人,2023a)相同的相关格式控制标记。
总体损失计算为 2 个目标的加权组合:
L
=
α
L
C
L
M
+
(
1
−
α
)
L
F
I
M
L = αL_{CLM} + (1 − α)L_{FIM}
L=αLCLM+(1−α)LFIM
在训练过程中,该研究根据经验设置
α
=
0.5
α = 0.5
α=0.5,并发现这在实践中效果很好,在代码完成和代码填充任务上都达到了 SOTA 性能。需要注意的是,FIM 目标仅在预训练期间使用,但该研究在指令微调期间删除它,即设置
α
=
1
α = 1
α=1。
4.3 优化
该研究使用 AdamW 优化器(Kingma 和 Ba,2017 年), β 1 = 0.9 β_1 = 0.9 β1=0.9, β 2 = 0.95 β_2 = 0.95 β2=0.95,权重衰减为 0.1,用于训练所有的 Granite 代码模型。对于第一阶段预训练,学习率遵循余弦计划,从 3 × 1 0 − 4 3 × 10^{−4} 3×10−4 开始,在 2k 次迭代的初始线性预热步骤中衰减到 3 × 1 0 − 5 3 × 10^{−5} 3×10−5。对于第二阶段预训练,该研究从 3 × 1 0 − 4 3 × 10^{−4} 3×10−4(对于 20B 和 34B 模型为 1.5 × 1 0 − 4 1.5 × 10^{−4} 1.5×10−4)开始,并采用指数衰减计划将其退火到初始学习率的 10%。该研究在预训练的两个阶段中根据模型大小使用 4M-5M 个令牌的批大小。
为了加速训练,该研究使用 NVIDIA Apex 库中提供的 FlashAttention 2(Dao 等人,2022 年;Dao,2023 年)、持久层归一化内核、融合 RMSNorm 内核(取决于模型)和融合 Adam 内核。该研究使用 NVIDIA Megatron-LM(Shoeybi 等人,2019 年;Narayanan 等人,2021 年)的自定义分支进行所有模型的分布式训练。该研究使用 3D 并行的混合训练:张量并行、流水线并行和数据并行。该研究还使用序列并行(Korthikanti 等人,2023 年)来减少训练期间大上下文长度的激活内存消耗。该研究在 BF16 中使用具有混合精度训练的 Megatron 分布式优化器 (Micikevicius 等人,2018 年)(Kalamkar 等人,2019 年),在 FP32 中使用梯度全归约和梯度累积以提高训练稳定性。
4.4 基础设施
该研究使用 IBM 的两个超级计算集群 Vela 和 Blue Vela 训练 Granite Code 模型,分别配备了 NVIDIA A100 和 H100 GPU。在 Vela A100 GPU 集群中,每个节点有 2 个 Intel 至强可扩展处理器,带有 8 个 80GB A100 GPU,通过 NVLink 和 NVSwitch 相互连接。Vela 集群采用 RoCE(融合以太网上的 RDMA)和 GDR(GPU 直接 RDMA)进行高性能网络。同样,Blue Vela 集群中的每个节点由双 48 核 Intel 处理器和 8 个 80GB H100 GPU 组成。Blue Vela 采用 3.2Tbps InfiniBand 互连,以促进节点之间的无缝通信,以其高吞吐量和低延迟而闻名。此外,Blue Vela 采用独立的专用 InfiniBand 存储结构,为每个计算节点提供 800Gbps,并由多个 ESS6000 存储设备支持。两个集群都提供可扩展和高效的基础设施,用于在数千个 GPU 上训练模型。该研究估计预训练 Granite Code 模型的碳排放量约为 455 t C O 2 e q tCO_2eq tCO2eq,这是根据模型中的总能源使用量和 0.423 k g C O 2 e q / K W h kg CO_2eq/KWh kgCO2eq/KWh 的美国全国平均碳强度因子计算的,没有考虑数据中心的位置。Blue Vela 集群使用 100% 可再生能源运行,以最大限度地减少对环境的影响。
5 指令微调
在各种通过指令解释的任务上微调代码 LLM 已被证明可以提高模型的可用性和整体性能。虽然代码指令微调已经取得了很大进展,但大多数采用 OpenAI 模型生成的合成数据,这限制了模型在许多企业应用中的使用。因此,继 OctoCoder(Muennigh off 等人,2023 年)之后,该研究仅使用许可数据的组合,旨在增强模型的指令遵循能力,包括逻辑推理和解决问题的技能。具体来说,Granite Code Instruct 模型在以下类型的数据上进行训练。
• 代码提交数据集:CommitPackFT(Muennighoff 等人,2023 年),跨 92 种编程语言的完整 CommitPack 数据集的过滤版本; 该研究选择了原始 CommitPackFT 和预训练期间使用的 116 种语言列表中共同的 92 种编程语言。
•数学数据集:MathInstruct 7(Yue 等人,2023 年)和 MetaMathQA(Yu 等人,2023 年);
由于未知或 NC 许可证,该研究从 MathInstruct 中删除了 GSM8K-RFT 和 Camel-Math。
•代码指令数据集:Glaive-Code-Assistant-v3 8,Self-OSS-Instruct-SC2 9,Glaive-Function-Calling-v2 10,NL2SQL 11和一些合成生成的 API 调用数据集(Basu 等人,2024 年);
https://huggingface.co/datasets/glaiveai/glaive-code-assistant-v3
https://huggingface.co/datasets/bigcode/self-oss-instruct-sc2-exec-filter-50k
https://huggingface.co/datasets/glaiveai/glaive-function-calling-v2
https://huggingface.co/datasets/bugdaryan/sql-create-context-instruction
•语言指令数据集:高质量数据集,如 HelpSteer(Wang 等人,2023 年)、Open Platypus (Lee 等人,2023 年)的开放许可证过滤版本,包括一组硬编码的提示,以确保模型在给出有关其名称或开发人员的查询时生成正确的输出。
https://huggingface.co/datasets/garage-bAInd/Open-Platypus
对于训练,该研究使用具有 250 个预热步骤的余弦调度器,初始学习率为
1
0
−
5
10^{−5}
10−5,并训练三个 epoch。此外,该研究在嵌入向量中添加大小为
5
N
h
\frac{5}{\sqrt{Nh}}
Nh5 的随机均匀噪声,其中
N
N
N 是序列长度,
h
h
h 是嵌入维度,如 Jain 等人所提出的。额外的噪声提高了指令模型的整体答案质量。该研究使用 FlashAttention 2(Dao,2023 年;Dao 等人,2022 年)和无填充 Transformer 13实现来减少微调期间的 GPU 内存使用和冗余 FLOP。该研究还使用完全激活检查点(Korthikanti 等人,2023 年),这使该研究能够在几个小时内在单个节点的 8×A100 GPU 上微调 8K 上下文长度的 Granite-20B-Code 模型。
https://huggingface.co/blog/mayank-mishra/padding-free-transformer
6 评估
该研究在广泛的任务上评估 Granite Code 模型,包括代码生成、代码解释、代码修复、代码编辑、数学推理等,如表 2 所示。该研究将模型与几个开源代码 LLM 进行比较:StableCode(Pinnaparaju 等人,2024 年)、Code Llama(Roziere 等人,2023 年)、StarCoder(Li 等人,2023b)、StarCoder2(Lozhkov 等人,2024 年)和 CodeGemma 14,包括最近性能出色的通用开源 LLM,如 Mistral(Jiang 等人,2023a)和 LLama-3 15。对于所有的基准,该研究使用相同的脚本和环境评估基线模型(包括研究的模型)以进行公平比较。
https://storage.googleapis.com/deepmind-media/gemma/codegemma report.pdf
https://github.com/meta-llama/llama3
6.1 代码生成
6.1.1 HumanEvalSynthesize:6 种语言的多语言代码生成
虽然大多数先前的代码 LLM 仅使用 HumanEval(Chen 等人,2021 年)评估 Python 上的代码生成能力,但该研究在研究中采用了具有挑战性的 HumanEvalSynthesize(Muennighoff 等人,2023 年)基准,它将 Humaneval 基准的 Python 问题扩展到另外五种常用编程语言,即 JavaScript、Java、Go、C++、Rust。该研究以零样本方式评估所有模型,对于基础模型使用带完成格式的贪心解码,对于指令微调模型使用指令模板。在为指令微调模型构建提示时,该研究遵循它们官方示例中提供的格式。该研究在 HuggingFace 模型卡、GitHub 存储库以及正式出版物或技术报告中搜索合适的提示格式。
表 3 显示了基础和指令模型在 HumanEvalSynthesize 基准上的结果。Granite-3B-Code-Base 是性能最好的小型模型,比 CodeGemma-2B 提高了 +3%。总体而言,在基础模型中,Granite Code 模型在 7B-8B 规模上实现了最佳平均性能,在 13B-20B 规模模型中实现了第二好的平均性能,并且与最佳模型(StarCoder2-15B 落后 0.1%)非常接近。虽然 CodeLlama-34B 在 HumanEval Python 上取得了更好的分数,但 Granite-34B-Code-Base 在其他语言上取得了更好的性能,从而在 6 种语言的平均水平上提高了 4%。在指令模型中,Granite Code 模型始终优于等效大小的 CodeLlama;3B、8B 和 20B 模型甚至优于大两倍的 CodeLlama 模型。值得注意的是,即使是该研究较小的模型 Granite-3B-Code-Instruct 也超过了 CodeLlama-34B-Instruct 的性能。此外,该研究还可以看到,Granite Code 模型的性能优于更大的最先进的开源通用语言模型,包括 Gemma、Mixtral 和 Llama 3 系列模型。这表明特定领域的代码模型可以实现更好的性能和效率,从而使它们更适合对成本和性能敏感的企业环境。
6.1.2 MultiPL-E:18 种语言的多语言代码生成
MultiPL-E(Cassano 等人,2023 年)是一个规范的基准,用于评估代码模型在更多样化的 18 种不同编程语言集上的表现。在 MultiPL-E 上,该研究比较了所有基础模型在 Go 和 Swift 以外的 16 种语言上的表现,每个提示采样 50 个完成结果,温度为 0.2,top-p 为 0.95,如(Lozhkov 等人,2024 年)所示。
表 4 显示,在所有模型大小的每种语言中,没有一个模型在所有语言上都表现最佳。与类似大小的开源模型 CodeLlama-7B 相比,Granite-8B-Code-Base 在 16/18 种编程语言上表现最佳。在中等模型中,StarCoder2-15B 表现最佳。在大型模型中,Granite-34B-Code-Base 在大多数语言上都优于 CodeLlama-34B,证明了它在跨多种语言的代码生成方面的有效性。
6.1.3 MBPP 和 MBPP+:Python 中的代码生成
MBPP(Austin 等人,2021 年)和 MBPP+(Liu 等人,2023a)是评估代码模型最广泛研究的两个基准。虽然每个 MBPP 问题的提示包括自然语言描述,后面是几个测试,但 MBPP+ 包含的测试比原始基准多 35 倍。该研究使用贪心解码并报告所有模型的平均 pass@1。表 5 总结了不同基础模型的结果。如该研究所见,Granite-3B-Code-Base 显著优于 CodeGemma-2B,但在这两个基准上都落后于 StarCoder2-3B。在中等参数范围内,Granite Code 模型在平均水平上分别以 ∼5% 和 ∼15% 的优势击败了 CodeLlama-7B 和 CodeLLama-13B。此外,Granite-34B-Code-Base 与 CodeLlama-34B 非常接近,两个基准的平均差异仅为 0.9%。
6.1.4 DS1000:Python 中的数据科学任务
DS-1000(Lai 等人,2023 年)是一个广泛研究的基准,它提供了一个全面的 1,000 个数据科学工作流集合,涵盖从 Matplotlib 到 TensorFlow 的七个不同库。该研究使用温度 0.2 和 top-p 0.95 为每个库生成 40 个样本,并报告所有最高 8B 参数模型的平均 pass@1,并设置代码完成。
表 7 总结了 DS-1000 的结果。在小型模型中,StarCoder2-3B 表现最佳。Granite-3B-Code-Base 排名第二,在 7 个库的平均水平上超过 CodeGemma-2B 12 个百分点以上。Granite-8B-Code-Base 实现了 34.5% 的最佳平均性能,超过了所有其他类似参数大小的模型。
Granite Code 模型在所有规模上都达到了相对较高的准确率(例如,在 2B-3B 规模上优于 CodeGemma,在 7B-8B 规模上优于 StarCoder2,在相同规模下优于 CodeLlama 模型)。这表明该研究的 Granite Code 模型不仅能够生成良好的代码,而且能够在实际数据科学工作流中更准确地使用库。
6.1.5 RepoBench、CrossCodeEval:仓库级代码生成
实践中的代码生成通常发生在存储库的上下文中,而不是在孤立的文件中。因此,该研究使用 RepoBench(Liu 等人,2023b)和 CrossCodeEval(Ding 等人,2024 年)来评估不同模型的仓库级代码完成能力。
在 RepoBench 上,该研究使用 level 2k 跨三种设置进行评估:cross-file-first(12,000 个数据点)、cross-file-random(5,000 个数据点)和 in-file(7,000 个数据点)。该研究报告跨设置的平均编辑相似度和精确匹配。遵循 Liu 等人(2023b),该研究将所有模型的生成温度设置为 0.2,top-p 采样参数设置为 0.95。该研究将模型限制为每个提示最多生成 64 个新令牌,并选择输出的第一个非空和非注释行作为预测。
对于 CrossCodeEval,遵循 Ding 等人(2024 年),该研究使用 OpenAI 的 ada 嵌入,使用检索和生成(RG)方法,最大序列长度为 2k。该研究将所有模型的最大跨文件上下文设置为 512 个令牌,最大生成令牌设置为 50 个令牌。该研究对所有模型生成使用原始实现中的统一提示格式,温度为 0.2,top-p 为 0.95。除了 Granite-3B-Code-Base(2,048)和 Granite-8B-Code-Base(4,096)外,所有模型的最大序列长度均设置为 8,192,考虑到它们各自的上下文长度。
表 6 显示了不同模型在 RepoBench v1.1 上的性能。Granite-3B-Code-Base 在较小的模型中表现出色,StarCoderBase-3B 实现了领先的性能指标。在中等模型中,Granite-8B-Code-Base 在 Java 上表现非常强大,而在 Python 中排名第二,CodeGemma-7B 在两个指标上都表现最好。在较大的模型中,Granite-20B-Code 在两种编程语言的所有 4 个指标上不仅优于 StarCoder2-15B,而且优于 CodeLlama-34B。这证明了 Granite Code 模型强大的仓库级代码生成能力,尽管没有像(Lozhkov 等人,2024 年;CodeGemma Team 等人,2024 年)那样使用仓库级文件打包进行训练;该研究将此作为一个有趣的未来工作,以进一步提高模型的性能。
表 8 显示了 CrossCodeEval 的结果。从表中可以看出,在类似大小的模型中,CodeGemma-7B 在 Python 和 TypeScript 上表现最佳,而 StarCoder2-7B 在 Java 和 C# 上表现最佳。同样地,Granite-20B-Code-Base 在3 种编程语言(Python、Java、C#)上优于 CodeLlama-13B,而在 TypeScript 方面落后。在所有模型大小和编程语言中,没有一个模型在所有指标上都表现最佳,这与 MultiPL-E 中的发现类似。这表明在所有编程语言上实现一致高性能仍然具有挑战性。
6.1.6 FIM:填充评估
Granite Code 模型使用 FIM 目标进行代码完成目的的训练,如第 4.2 节所述。该研究使用 SantaCoder-FIM 基准(Allal 等人,2023 年)进行填充评估,该基准测试模型在 Python、JavaScript 和 Java 解决 HumanEval 中填充一行代码的能力。该研究使用贪心解码并报告所有模型的平均精确匹配。表 9 显示,Granite Code 模型在所有模型大小上显著优于 StarCoder 和 StarCoder2,证明它是代码完成用例的出色全面模型。此外,该研究观察到将模型大小从 8B 扩展到 34B 没有性能提升,表明较小的模型通常更适合 FIM 代码完成任务。
6.2 代码解释和修复
虽然大多数先前的代码 LLM 主要关注使用代码生成基准评估性能,但用户可能希望在合成之外的其他具有挑战性的场景中使用这些模型,例如解释和修复代码。因此,继(Muennighoff 等人,2023 年)之后,该研究在 HumanEvalPack 基准的代码解释和修复变体上测试了不同代码模型的性能,涵盖 6 种不同的编程语言。
对于 HumanEvalExplain 和 HumanEvalFix,该研究以零样本方式评估所有模型,对于基础模型使用带完成格式的贪心解码,对于指令微调模型使用指令模板。
HumanEvalExplain 基准的结果如表 10 所示。Granite Code 基础模型以很大优势显著优于其他 SOTA 基础代码 LLM,包括 StarCoder2 和 CodeGemma。有趣的是,Granite-8B-Code-Base 在平均水平上以 9.3% 的优势击败了 CodeLlama-34B,同时接近 CodeLlama-70B。该研究将这一性能归因于数据混合和基础模型训练决策。指令微调后,所有基础模型的跨语言性能显著提高。在代码指令模型中,Granite-34B-Code-Instruct 表现最佳,达到 41.9% 的平均分数,非常接近 CodeLlama-70B-Instruct 的 41.1% 分数。值得注意的是,CodeGemma-7B-IT 从指令微调中获得了最大的改进,但仍落后于 Granite-8b-Code-Instruct 2.5% 的平均水平。Mixtral-8x22B-Instruct-v0.1 在所有基准模型中表现最佳,表明更大模型的潜在优势以及在一般自然语言数据上训练可能有助于此任务。
表 11 报告了 HumanEvalFix 的结果。与 HumanEvalExplain 类似,Granite Code 基础模型显著优于其他基础模型。值得注意的是,Granite-8B-Code-Base 再次表现出令人印象深刻的性能,使其接近 CodeLlama-70B 和 Llama-3-70B。指令微调后,该研究在几乎所有模型上都观察到性能提升。值得注意的是,该研究的 8B 和 20B 指令模型在小于 34B 参数的模型中实现了最佳性能。然而,该研究看到在转移到超过 34B 参数的更大模型时,性能显著提高(约 10 个百分点)。在大型指令模型中,Granite-34B-Code-Instruct 的性能与至少两倍参数的其他模型相似,因此具有更好的成本和性能平衡。
图 3 比较了 Granite-8B-Code-Instruct 与最先进的开源指令微调通用 LLM 的性能。Granite-8B-Code-Instruct 始终优于比较模型,强调了特定领域代码模型的必要性。总之,这些结果表明,该研究的基础模型和指令模型不仅能够生成良好的代码,而且在代码修复和解释方面也表现出色,展示了它们解决企业软件开发中各种编码任务的能力。
6.3 代码编辑和翻译
CanItEdit 是最近设计用于评估代码 LLM 指令代码编辑任务的基准。该基准包含 105 个手工编写的 Python 程序,其中每个问题包含一段代码,并附有两种类型的指令:描述性或惰性。目标是根据指令修改代码;惰性和描述性指令都应该导致相同的编辑。继 Cassano 等人(2024)之后,该研究使用相应的指令格式比较不同的指令微调模型,随机采样温度为 0.2,top-p 为 0.95,每个问题 20 个完成结果。
表 12 显示了不同模型在 CanItEdit 基准上的性能。它表明,与 CodeGemma 和 CodeLlama 相比,Granite Code 模型具有更高的通过率,以及较少的不必要的代码更改。这一结果表明,Granite Code 模型能够更好地理解用户的意图,并在实际情况下对现有代码进行准确的更改。
CodeLingua(Pan 等人,2024 年)是一个数据集,旨在测试模型在代码翻译方面的能力。它包含两组程序:一组包含从 Avatar(Ahmad 等人,2021 年)采样的 251 个 Java 程序和 251 个 Python 程序,另一组来自 CodeNet(Puri 等人,2021 年),包含五种语言的 250 个程序:C、C++、Go、Java 和 Python。对于每个程序,提供了一组以输入和预期输出形式的单元测试。任务包括将每个程序从源语言翻译成五种目标语言(从 CodeNet 采样的语言)。Pass@1 用作评估翻译准确性的指标。对于每个生成,该研究使用贪心解码和每个指令微调模型建议的提示格式。对于基础模型,或者在未指定指令格式的情况下,该研究使用数据集中的默认提示。对每个生成应用基本的后处理,以删除生成工件,例如重复输入指令、源语言代码、目标语言名称和格式化令牌(例如 ```)。
表 13 显示了 CodeLingua 基准的结果。对于源语言 C、C++ 和 Go,表中报告的结果直接取自 Codenet 上的运行,而对于 Java 和 Python,报告的结果是 Avatar 和 CodeNet 上运行的平均值。该研究从 CodeLingua 排行榜 16中报告了 Octocoder 和 CodeLlama 的数字。Granite Code 模型的性能与 CodeGemma 相当。值得注意的是,翻译的正确性不仅取决于模型生成的代码,还取决于作为答案的一部分提供的额外元数据和解释。该研究测试了指令微调模型,因为该研究观察到基础模型经常难以理解翻译代码的请求本身。另一方面,指令模型倾向于在生成的翻译代码之外添加额外的信息。CodeLLama 系列似乎特别受此问题的影响,因为对生成结果进行后处理以仅提取相关代码构成了一项非平凡的任务。另一方面,CodeGemma 和 Granite 模型产生格式良好的输出,易于解析。有趣的是,对于 Granite 模型来说,Go 似乎是最难翻译的目标语言,而 C 是翻译成功率最高的源语言。
https://codetlingua.github.io/leaderboard.html
6.4 代码推理、理解和执行
表 14:CRUXEval 基准的性能。该研究对 pass@1 使用温度 0.2,对 pass@5 使用温度 0.8,均使用 10 个样本,如(Gu 等人,2024 年)所示。
模型 | CRUXEval-I | CRUXEval-O |
---|---|---|
Pass1 | Pass5 | |
StarCoderBase-3B | 27.5 | 44.9 |
StableCode-3B | 33.5 | 54.2 |
StarCoder2-3B | 32.1 | 50.3 |
CodeGemma-2B | 29.6 | 45.5 |
Granite-3B-Code-Base | 30.6 | 50.9 |
StarCoderBase-7B | 29.8 | 47.5 |
CodeLlama-7B | 36.2 | 53.7 |
StarCoder2-7B | 34.2 | 53.8 |
CodeGemma-7B | 42.6 | 60.9 |
Granite-8B-Code-Base | 36.0 | 55.8 |
StarCoderBase-15B | 31.0 | 49.2 |
CodeLlama-13B | 42.2 | 61.8 |
StarCoder2-15B | 47.4 | 68.3 |
Granite-20B-Code-Base | 39.1 | 59.0 |
CodeLlama-34B | 47.8 | 65.6 |
Granite-34B-Code-Base | 43.3 | 61.3 |
CRUXEval(Gu 等人,2024)是由 800 个 Python 函数和输入-输出对组成的基准,包括两个任务:CRUXEval-I(输入预测)和 CRUXEval-O(输出预测)。该研究使用温度 0.2 报告 pass@1,使用温度 0.8 报告 pass@5,均使用 10 个样本,如 Lozhkov 等人(2024 年);Gu 等人(2024 年)所示。表 14 显示,Granite Code 模型与其他模型的性能具有竞争力。Granite-3B-Code-Base 在 CRUXEval-I 上优于 CodeGemma-2B,但在 CRUXEval-O 上落后。有趣的是,在 3B 参数下没有一个模型在所有任务上都始终表现最佳。然而,在 7B-8B 参数下,CodeGemma-7B 在这两项任务上都优于所有模型。对于大型模型,Granite-34B-Code-Base 在 CRUXEval-I 上落后于 CodeLlama-34B,但在 CRUXEval-O 上表现更好。随着该研究将 Granite Code 模型的大小从 3B 扩展到 34B 参数,CRUXEval-I 和 CRUXEval-O 的性能都有所提高,证明了更大模型在代码推理和执行任务方面的优势。
6.5 数学推理
该研究使用以下四个广泛使用的基准来评估 Granite-8B-Code-Base 和各种 7B-8B 基线模型的数学推理能力:
- MATH(Hendrycks 等人,2021 年):来自高中数学竞赛的数据集;该研究使用 Gao 等人(2023 年)的 4-shot实验设置;
- GSM8K(Cobbe 等人,2021 年):中学水平数学应用题的数据集;该研究使用 Gao 等人(2023 年)的5-shot 实验设置; •SAT(Azerbayev 等人,2023 年):由 2023 年 5 月 College Board SAT考试中没有图表的 32 道数学题组成的数据集;该研究使用 Azerbayev 等人(2023 年)的相同实验设置
- OCW(Lewkowycz 等人,2022 年):从麻省理工学院的 OpenCourseWare 收集的本科水平 STEM问题;该研究使用 Azerbayev 等人(2023 年)的 4-shot 实验设置。
继 Azerbayev 等人(2023年)之后,该研究还评估了在使用计算工具解决问题方面的模型:
- MATH+Py 通过编写使用内置数值运算、math 模块和 SymPy 的 Python 程序来解决 MATH 任务;该研究使用
Azerbayev 等人(2023 年)的 5-shot 提示和实验设置; - GSM8K+Py 通过编写执行以生成整数答案的 Python
程序来解决 GSM8K 任务;该研究使用 Azerbayev 等人(2023 年)的 8-shot 提示和实验设置。
表 15 总结了结果。尽管没有针对数学推理进行特定调优,但 Granite-8B-Code-Base 展示了令人印象深刻的推理能力,优于大多数现有的 7B 到 8B 模型。虽然其他模型在某些任务上可能特别强大,但该研究的模型在所有任务上始终达到前 1 或前 2 的性能。
6.6 调用函数和工具
该研究采用伯克利函数调用排行榜(BFCL)(Yan 等人,2024 年)来评估 LLM 调用函数和工具的能力。BFCL 是一个跨 4 个类别的 1700 个函数的函数调用数据集:简单、多个、并行和并行多个函数调用 - 每个类别在模型可以访问的潜在函数数量和模型必须生成的输出函数数量方面有所不同。该研究使用两种流行的方法来评估模型生成答案的准确性:基于抽象语法树(AST)的度量进行输出的模糊评估,以及可执行评估来匹配模型生成函数和真实函数的输出。
图 4 显示了不同 Granite Code 模型在 BFCL 基准上的结果。从图中可以看出,总体准确性从 Granite-3B-Code-Base 的 25.65% 提高到 Granite-34B-Code-Base 的 57.12%,表明模型缩放在函数(工具)调用能力方面的有效性。该研究还在图 5 中比较了 Granite-8B-Code 与 CodeLlama-7B,发现 Granite-8B-Code-Instruct 在 AST 摘要、执行摘要和总体准确性方面分别以 22%、14% 和 12% 击败了 CodeLlama-7B-Instruct。此外,图 5 显示,指令微调始终提高两个基础模型的性能,Granite Code 模型的改进更为明显。例如,从 Granite-8B-Code-Base 到 Granite-8B-Code-Instruct,总体准确性提高了 +17.88%,表明该研究精心策划的数据混合在微调基础模型方面的有效性。
6.7 模型鲁棒性
虽然规范代码生成任务的性能至关重要,但该研究认为,实际鲁棒性评估也是系统地表征不同模型所必需的。因此,该研究考虑对代码合成的鲁棒性进行基准测试,代码合成是源代码最具代表性的下游任务之一。ReCode(Wang 等人,2022 年)提供了 30 种不同的一般扰动,包括文档字符串、函数名称和代码,以评估代码生成模型的鲁棒性。该研究使用 HumanEval 基准的扰动版本,使用 5 个种子的贪心生成,如(Wang 等人,2022 年)中所推荐的。
表 16 显示了不同模型对每个扰动类别的最坏情况 RP@1。虽然 Granite-3B-Code-Base 始终优于 CodeGemma-2B,但 Granite-8B-Code-Base 在所有类别上都落后于 CodeGemma-7B。与 CodeLlama 模型相比,Granite Code 模型获得了更好的性能,显示出它在每个大小上以鲁棒的方式进行泛化。该研究最大的模型 Granite-34B-Code-Base 在所有四个类别上始终优于 CodeLlama-34B。这表明 Granite-34B-Code-Base 具有更强的处理未见实例和扰动的能力。总的来说,该研究还观察到 Granite Code 系列中更大模型的 RP@1 更高(例如,从 Granite-3B-Code-Base 的 40.1% 提高到 Granite-34B-Code-Base 在所有扰动上平均 52.0%),表明更大的模型有助于提高最坏情况下的鲁棒性。
7 结论
该研究提出了一系列解码器式 Granite Code 模型,大小从 30 亿到 340 亿参数不等,在完成从代码生成到修复错误、解释和记录代码、维护存储库等广泛任务方面具有很强的多功能性。这些模型已被证明适用于从复杂的应用程序现代化任务(IBM,2023 年)到设备内存受限用例的应用。广泛的评估表明,Granite Code 模型在可用的开源代码 LLM 中始终达到最先进的性能,在代码生成、解释和错误修复等各种代码相关任务的平均性能上,与最近发布的 CodeGemma、StarCoder2 和 Llama3 模型相匹配或超过,涵盖多种流行的编程语言。该研究的经验和结果表明,Granite Code 模型在处理企业软件开发工作流中的不同任务方面具有更强的能力。该研究根据 Apache 2.0 许可证发布了所有 Granite Code 模型,用于研究和商业使用。该研究计划持续发布这些模型的更新,以提高其性能,例如利用 CodeNet 指令数据集(Puri 等人,2021 年),并且在不久的将来,该研究计划发布长上下文以及专门针对 Python 和 Java 的模型变体。
参考文献
(略)
综合以上内容,我对 Granite Code 模型有以下几点看法:
-
Granite Code 模型是一个全面且高性能的代码模型系列,不仅在代码生成方面表现出色,在代码修复、解释等其他任务上也达到了业界领先水平。这对企业级软件开发非常有价值,可以大幅提高开发效率。
-
Granite Code 模型覆盖了多个参数规模,从 3B 到 34B 不等,可以灵活应对从资源受限的边缘设备到大规模云应用的各种场景需求。
-
Granite Code 模型采用高质量的数据和独特的两阶段训练方式,有效融合了代码领域和自然语言领域的知识,大幅提升了模型的语言理解和推理能力。这是其性能优势的关键所在。
-
Granite Code 强调模型的可信与合规,所有训练数据都经过了严格的许可审查与过滤,并且以 Apache 2.0 许可开源,更适合企业级应用。
-
虽然 Granite Code 在多语言代码生成、代码编辑、代码翻译等方面已经展现了很强的性能,但进一步增强对话式交互、多模态感知、长程推理等能力,将使其在更广泛的应用场景中发挥更大价值。
-
Granite Code 的成功验证了领域专用模型的重要性。结合特定领域知识,采用先进的预训练和微调技术,在特定垂直领域构建高质量的语言模型,将是大模型技术发展的重要方向之一。
-
大规模语言模型已经展现了令人瞩目的能力,代码理解与生成只是其中一个重要方向。随着模型规模不断扩大,训练数据与算法持续优化,人工智能将在更多领域取得突破,成为数字时代的关键生产力。
-
我们应该客观地看待大模型带来的机遇与挑战。合理发挥其在提高生产效率、拓展创新空间等方面的巨大潜力,同时重视数据隐私安全、伦理监管、节能优化等问题。只有在技术创新和社会进步之间找到平衡,人工智能的发展才能持续健康。