开发者狂喜!Meta最新发布的LLM Compiler,77%的自动调优效率-人工智能

首页 2024-07-01 22:11:37

Meta做了一个非常好的LLMM Compiler,帮助程序员更有效地编写代码。

昨天,三大 AI 巨头 OpenAI、Google、Meta 发布自己大模型的最新研究成果 ——

OpenAI 推出基于 GPT-4 专门寻找训练 bug 的新模型 CriticGPT,谷歌开源 9B、27B 版 Gemma2,而且 Meta 人工智能的最新突破 ——LLM Compiler。

这是一个强大的开源模型,旨在优化代码,彻底改变编译设计。这一创新可能会改变开发者处理代码优化的方式,使其更快、更高效、更经济。
据悉,该 LLM Compiler 实现自动调优搜索的优化潜力 77%的结果可以显著减少编译时间,提高各种应用程序的代码效率。在反汇编方面,往返反汇编的成功率为 45%。

有网友表示,这就像是代码优化和反汇编的游戏规则变化者。
这对开发者来说是个不可思议的好消息。
概述

大语言模型在许多软件工程和编程任务中表现出了出色的能力,但它们在代码优化和编译器领域的应用尚未得到充分挖掘。训练这些 LLMs 包括昂贵的计算资源在内的大量计算资源需要消耗 GPU 时间和巨大的数据集往往使许多研究和项目不可持续。

为弥补这一空白,Meta 介绍了一个研究团队 LLM Compiler,专门优化代码,彻底改变编译设计。通过包含 5460 亿个标记的 LLVM-IR 以及汇编代码的庞大语料库上的训练模型,使模型能够理解编译器中间的表达、汇编语言和优化技术。
论文链接:https://ai.meta.com/research/publications/meta-large-language-model-compiler-foundation-models-of-compiler-optimization/

研究人员在他们的论文中解释说:「LLM Compiler 增强了对编译器中间的表达(IR)、了解汇编语言和优化技术。」这种增强的理解使模型能够执行以前仅限于人类专家或专业工具的任务。

LLM Compiler 训练过程如图所示 1 所示。
LLM Compiler 在代码大小优化方面取得了显著成果。在测试中,模型的优化潜力实现了自动调优搜索 77%的结果可以显著减少编译时间,提高各种应用程序的代码效率。

该模型具有更好的反汇编能力。LLM Compiler 在将 x86_64 和 ARM 汇编代码转换回 LLVM-IR 往返反汇编的成功率为 45%(其中 14% 完全匹配)。这种能力可能对逆向工程任务和旧代码维护具有不可估量的价值。

项目的核心贡献者之一 Chris Cummins 强调该技术的潜在影响:「通过提供两种大小的预训练模型(7 亿和 13 1亿参数)并通过微调版本显示其有效性,」他说,「LLM Compiler 为探索 LLM 在代码和编译器优化领域未开发的潜力铺平了道路。」

用于编译器优化 Code Llama

汇编代码和编译器 IR 在上面进行预训练

训练编程 LLMs 数据通常主要由图像组成 Python 汇编代码在这些数据集中的比例很小,由这种高级源语言组成的编译器 IR 比例较小。

为了建立一个很好的理解这些语言的人 LLM,研究团队用 Code Llama 权重初始化 LLM Compiler 模型,然后在以编译器为中心的数据集上进行训练 4010 亿个 token,该数据集主要由汇编代码和编译器组成 IR 组成,如表 1 所示。
数据集 LLM Compiler 主要在由 LLVM(版本 17.0.6)生成的编译器在中间表示和汇编代码上进行训练,这些数据来源于训练 Code Llama 同一数据集已在表中 2 对数据集进行了总结。和 Code Llama 同样,我们还可以从自然语言数据中获得少量的训练批次。
微调编译器模拟指令
?
为了理解代码优化的机制,研究团队对 LLM Compiler 通过模拟编译器优化模型进行微调指令,如图所示 2 所示。
它的想法是通过随机生成的编译器优化序列,从有限的未优化种子程序集合中生成大量的例子。然后他们训练模型预测优化生成的代码,并在应用程序优化后预测代码大小。

任务规范。给定未经优化的 LLVM-IR(由 clang 前端输出),一个优化过程列表,一个起始代码大小,生成这些优化后的结果代码和代码大小。

有两种类型的任务:在第一种中,模型预期输出编译器 IR;在第二种中,模型预期输出汇编代码。输入两种类型 IR、优化过程与代码大小相同,提示决定了所需的输出格式。

代码大小。它们用两个指标来衡量代码的大小:IR 指令数和二进制大小。二进制大小将通过 IR 或者汇编降级为目标文件后,.TEXT 和 .DATA 计算段大小的总和。我们排除了 .BSS 段落,因为它不会影响磁盘的大小。

优化 pass。在这项工作中,研究团队针对 LLVM 17.0.6.使用新的过程管理器 (PM, 2021),它将 pass 模块、函数、循环等不同级别的分类,以及转换和分析 pass 。转换 pass 改变给定的输入 IR,而分析 pass 产生影响后续转换的信息。
?
在 opt 的 346 个可能的 pass 他们选择了参数 167 每次使用。这包括每条默认优化流水线。 (例如 module (default)),单独优化转换 pass (例如 module (constmerge)),但排除了非优化实用程序 pass (例如 module (dot-callgraph)) 以及不保留语义的转换 pass (例如 module (internalize))。

他们排除了分析 pass,由于它们没有副作用,我们依赖它们 pass 管理器根据需要注入依赖性分析 pass。接受参数 pass,我们使用默认值 (例如 module (licm))。表 9 包含所有使用 pass 列表。我们使用 LLVM 的 opt 工具应用 pass 并使用列表 clang 将结果 IR 降级为目标文件。清单 1 使用命令显示。
数据集。通过对表,研究团队 2 总结的未优化程序应用 1 到 50 个随机优化 pass 列表生成编译器模拟数据集。 pass 列表长度均匀随机选择。pass 从上述情况来看,列表是通过的 167 个 pass 集合均匀采样生成。导致编译器崩溃或在 120 秒后超时的 pass 排除列表。

LLM Compiler FTD :扩展下游编译任务?

微调优化标志调优指令

操作编译标志对操作性能和代码大小都有显著影响。研究团队训练 LLM Compiler FTD 模型执行下游任务,即为 LLVM 的 IR 优化工具 opt 选择生成最小代码大小的标志。

标志调整的机器学习方法以前表现出良好的效果,但在不同程序之间的泛化方面存在困难。以前的工作通常需要编译几十或几百个新程序来尝试不同的配置,并找到最好的性能选项。研究小组通过预测标志来最小化未见程序的代码大小,并在任务的零样本版本上进行培训和评估 LLM Compiler FTD 模型。

他们的方法不依赖于所选择的编译器和优化指标,他们计划在未来运行。目前,优化代码的大小简化了培训数据的收集。

任务规范。研究团队向前发展。 LLM Compiler FTD 模型呈现未优化的模型 LLVM-IR (由 clang 前端生成),并要求其生成应用程序 opt 如果不能改进输入代码,标志列表,这些优化应用前后的二进制大小和输出代码,将生成一个简短的输出信息,只包括未优化二进制大小。

他们使用和编译相同的受限优化器模拟任务 pass 二进制大小采用相同的方式计算。

图 3 解释了生成训练数据的过程以及如何在推理中使用模型。
只需要在评估过程中生成 pass 从模型输出中提取列表。 pass 列表,并使用给定的参数运行 opt。然后,研究人员可以评估模型预测的二进制尺寸和优化输出代码的准确性,但这些都是辅助学习任务,不需要使用。

正确性。LLVM 优化器并非无懈可击,以意外或未经测试的顺序运行优化 pass 它可能会暴露出微妙的正确性错误,从而降低模型的实用性。研究团队开发了这一风险,以缓解这一风险 PassListEval,这是帮助自动识别破坏程序语义或导致编译器崩溃的工具 pass 列表。图 4 显示工具的概览。
PassListEval 接受候选 pass 列表作为输入,并在一个中包含 164 个自测试 C 这些程序从程序的套件中进行评估 HumanEval-X。每个程序都包含一个编程挑战的参考解决方案,例如「检查两个数字之间的距离是否小于给定阈值」,单元测试套件验证了正确性。他们将候选 pass 列表应用于参考解决方案,然后将其与测试套件链接,以生成二进制文件。在执行过程中,如果任何测试失败,二进制文件将崩溃。如果任何二进制崩溃或任何编译器调用失败,我们将拒绝候选人 pass 列表。

数据集。这个团队来自一个 450 万个未优化 IR 训练了标志调优示例数据集 LLM Compiler FTD 模型,这些 IR 用于预训练。最好生成每个程序 pass 例如,他们进行了广泛的迭代编译过程,如图所示 3 所示。

1. 研究团队使用大规模随机搜索生成最佳程序候选人 pass 列表。他们最多独立生成每个程序 50 个 pass 从之前描述的随机列表开始 167 个可搜索 pass 采样均匀集中。每次他们评估一个程序时,他们都会评估一个程序 pass 在列表中,记录生成的二进制大小,然后选择生成最小二进制大小的每个程序 pass 列表。他们运行了 220 独立编译1亿次,平均每个程序 4,877 次。

2. 生成的随机搜索 pass 列表可能包含冗余 pass,这些 pass 对最终结果没有影响。另外,有些 pass 顺序是可交换的,重新排序不会影响最终结果。他们开发了一个最小化的过程,并将其应用于每个过程中,因为这些噪声将在训练数据中引入 pass 列表。

最小化包括三个步骤:冗余 pass 消除、冒泡排序和插入搜索。在冗余 pass 在消除过程中,他们通过迭代删除单个 pass 最好是最小化 pass 列表,看它们是否对二进制有贡献,如果没有,就丢弃它们。重复这个过程,直到你不能再放弃它 pass。然后试着对冒泡进行排序 pass 根据关键字对子序列提供统一的排序 pass 进行排序。最后,通过遍历插入排序 pass 列表中的每一个 pass 并尝试在它之前插入 167 个搜索 pass 每个人都来执行局部搜索。如果这样做改善了二进制的大小,就保留这个新的 pass 列表。在达到固定点之前,将整个管道循环最小化。最小化后的 pass 列表长度分布如图所示 9 所示。平均 pass 列表长度为 3.84。

3. 他们以前描述过 PassListEval 最适合候选人使用 pass 列表。这样,他们就确定了 1,704,443 个独立 pass 列表中的 167,971 个 (9.85%) 编译或操作时会出现错误

4. 他们将 100 最常见的最优 pass 列表广播到所有程序,如果发现改进,每个程序的最佳更新 pass 列表。之后,唯一最好的 pass 列表总数从 1,536,472 减少到 581,076。

与上述自动调优管道相比 -Oz 产生了 7.1% 减少了几何平均二进制大小。图 10 显示了单个 pass 的频率。对他们来说,这种自动调优是每个程序优化的黄金标准。虽然发现的二进制节省了显著的规模,但这需要 280 超过1亿次额外编译的计算成本 21,000 个 CPU 天。对 LLM Compiler FTD 指令微调执行标志调优任务的目的是在不运行编译器数千次的情况下,实现自动调优器性能的一部分。

?微调反汇编指令

将代码从汇编语言提升到更高层次的结构,可以进行额外的优化,如直接集成到应用程序代码中的库代码,或将剩余代码移植到新架构。将机器学习技术应用于二进制可执行文件生成可读、准确的代码,在反编译领域取得了进展。在本研究中,研究团队展示了它 LLM Compiler FTD 如何通过微调反汇编,学习汇编代码和编译 IR 之间的关系。任务是学习 clang -xir - -o - -S 逆向翻译如图所示 5 所示。
往返测试。使用 LLM 反汇编会导致正确性问题。升级代码必须通过等价检查器验证,这并不总是可行的,或者需要手动验证正确性,或者通过充分的测试用例获得信心。然而,正确性的下限可以通过往返测试找到。也就是说,通过提升 IR 重新编译成汇编代码。如果汇编代码相同,则 IR 是正确的。这为使用 LLM 结果提供了一种简单的方法,并且是衡量反汇编模型效用的一种简单方法。

任务规范。研究团队向模型提供汇编代码,并训练它发出相应的反汇编 IR。本任务的上下文长度设置为输入汇编码 8k 个 token 和输出 IR8k 个 token。

数据集。他们从以前任务中使用的数据集中衍生汇编代码和 IR 是的。他们的微调数据集包括 470 输入一万个样本 IR 在降低到 x86 汇编以前已经使用过 - Oz 优化。

训练参数?

编码通过字节标记数据,使用和使用 Code Llama、Llama 和 Llama 2 相同的标记器。他们在所有四个训练阶段使用相同的训练参数。他们使用的大部分训练参数和 Code Llama 使用相同的基础模型 AdamW 优化器,β1 和 β2 的值为 0.9 和 0.95。他们使用余弦调度,预热步骤是 1000 步骤,将最终学习率设定为峰值学习率 1/30。

与 Code Llama 与基本模型相比,团队将单个序列的上下文长度从 4096 增加到 16384,但批量尺寸保持恒定 400 万个 token。为了适应更长的上下文,他们将学习率设置为 2e-5,并进行了修改?RoPE 嵌入位置的参数将频率重置为基本值 θ=10^6。这些设置与 Code Llama 基本模型的长上下文训练是一致的。

?评估
?
对研究团队进行评估 LLM Compiler 模型在标志调优和反汇编任务中,编译器模拟 token 软件工程任务的预测和性能。
?
标志调优任务
?
方法。他们评估 LLM Compiler FTD 在未见程序的优化标志调优任务中的表现与 GPT-4 Turbo 和 Code Llama - Instruct 进行比较。从模型输出中提取和优化每个模型的运行推理 pass 然后他们使用这个列表 pass 列表优化特定程序,记录二进制大小,使用基线 -Oz 优化程序的二进制大小。
?
对于 GPT-4 Turbo 和 Code Llama - Instruct,他们在提示后添加一个后缀,提供额外的上下文来进一步描述问题和预期的输出格式。
?
生成的所有模型 pass 列表都使用 PassListEval 验证失败的,使用验证 -Oz 作为替代品。进一步验证模型生成 pass 列表的正确性,他们链接最终程序二进制文件,并保守地输出和使用它们 -O2 差分测试优化管道优化的基准输出。
?
数据集。研究团队使用从 MiBench 提取基准套件 2,398 评估测试提示。为了生成这些提示,它们被构成 24 个 MiBench 基准的所有 713 每个翻译单元,从每个单元生成未优化的翻译单元 IR,然后将它们格式化为提示。如果生成的提示超过 15k tokens,他们使用 llvm-extract 将代表翻译单元 LLVM 模块分成较小的模块,每个函数一个,导致模块分成较小的模块 1,985 个提示适合 15k token 上下文窗口,剩下的 443 不适合翻译单元。在计算性能分数时,它们是对的 443 使用排除的翻译单元使用被排除的翻译单元 -Oz。表 10 总结基准。
结果。表 3 显示了标志调优任务中所有模型的零样本性能。只有 LLM Compiler FTD 模型比 -Oz 改进,13B 参数模型略优于较小模型,在 61% 在生成比的情况下 -Oz 目标文件较小。
在某些情况下,模型生成 pass 列表导致比 -Oz 目标文件大小较大。例如,LLM Compiler FTD 13B 在 12% 在退化的情况下。这些退化可以通过简单的编译程序避免两次:一次使用模型生成 pass 列表,一次使用 -Oz,然后选择产生最佳结果 pass 列表。相对于消除 -Oz 退化,这些 -Oz 备份分数将 LLM Compiler FTD 13B 相对于 -Oz 总体改进提高到 5.26%,并使 Code Llama - Instruct 和 GPT-4 Turbo 相对于 -Oz 适度改进。图片 6 在每个基准上显示每个模型的性能细分。
?二进制尺寸的准确性。虽然模型生成的二进制尺寸预测对实际编译没有影响,但研究团队可以在预测优化前后评估模型二进制尺寸的性能,以了解每个模型对优化的理解。图 7 显示结果。
LLM Compiler FTD 二进制大小预测与实际情况密切相关,7B 对于未经优化和优化的二进制模型,参数模型的大小分别达到 0.083 和 0.225 的 MAPE 值。13B 参数模型的 MAPE 值相似,分别为 0.082 和 0.225。Code Llama - Instruct 和 GPT-4 Turbo 二进制大小预测与实际情况几乎无关。研究人员注意到,LLM Compiler FTD 优化代码的错误略高于未优化代码。特别是 LLM Compiler FTD 偶尔会出现高估优化效果的趋势,导致预测二进制低于实际情况。