编码大模型系列:Meta创新的“代码编译优化”的LLM

鲁班号导读正式上线。移步“鲁班秘笈”,查阅更多内容。

大型语言模型 (LLM) 已在各种软件工程和编码任务中展现出卓越的能力。然而,它们在代码和编译器优化领域的应用仍未得到充分探索。训练LLM需要大量资源,需要大量的 GPU时间和大量的数据收集。Meta语言模型编译器 (LLM Compiler),这是一套专为代码优化任务设计的强大、公开可用的预训练模型。

LLM Compiler建立在Code Llama的基础上,增强了对编译器中间表示 (IR)、汇编语言和优化技术的理解。该模型已在546B的LVM-IR和汇编代码的庞大语料库上进行了训练,并经过了指令微调。

LLM Compiler是根据定制的商业许可发布的,允许广泛重用。除了7B和 13B的规模,还有该模型的微调版本,展示了其在优化代码大小和从 x86_64和ARM汇编反编译回LLVM-IR的增强功能。

Code Llama

2024年1月29日发布代码Llama 70B是一个可以使用文本提示生成代码的大型语言模型。Code Llama是最先进的代码任务公开可用LLMs,可以使得当前开发人员的工作流程更快、更高效,并降低学习编码的门槛。Code Llama可以被用来作业以及教学。

Code Llama是Llama 2的代码专用版本,它是通过在特定的代码数据集进一步训练Llama 2而得到。它可以从代码和自然语言提示生成代码和关于代码的自然语言,例如,“写一个斐波那契数列的函数”。它还可用于代码的补全和调试,支持当今使用的许多最流行的语言,包括Python、C++、Java、PHP、Typescript (Javascript)、C#和Bash。

Code Llama提供多达100,000 个上下文Token。所有的模型都基于16,000个Token序列进行训练,在多达100,000个Token输入中显示出明显的改进。

Meta还微调Code Llama的另外两个变体:Code Llama-Python和Code Llama-Instruct。Code Llama-Python是Code Llama的专用语言变体,在 Python代码的100B的Token上进一步微调。Meta选择Python的原因是Python和PyTorch在AI社区中发挥着重要作用。

上图为Code Llama的家族谱系

LLM Compiler

刚刚,Meta在编译器优化方面又迈出了一大步,它推出了一套突破性的工具,基于LLM的编译器能够处理编译和反编译任务,在编译器技术领域树立了新的标杆。

编译器的中间表示(Intermediate Representation,IR)是编译过程中的一种抽象表示形式,位于源代码和目标代码之间。它的存在主要是为了帮助编译器在多个阶段进行优化和转换,从而生成高效的目标代码。

上图为LLM Compiler的训练过程,分两个阶段对546B的数据集进行训练,这些数据集以编译器为中心。在第一阶段,模型主要在未标记的编译器IR和汇编代码上进行训练。第二阶段对模型进行指令微调,以预测优化的输出和效果。进而生成7B和13B的LLM Compiler。

不同阶段使用的训练数据集,可以看出在编译优化方面还是加入不少的训练数据。尤其是第三阶段和第四阶段中,和代码相关的自然语言成为主力。

之后在164B个下游标记和反汇编任务数据集上进一步微调形成新的LLM Compiler FTD。在四个训练阶段中,每阶段都会保留先前15%的任务数据。

核心要点:如何学习编译优化

既然要优化编译,那么就需要想解锁下LLVM。LLVM是一套编译器基础设施项目,以C++写成,包含一系列模块化的编译器组件和工具链,用来开发编译器前端和后端。它是为了任意一种编程语言而写成的程序,利用虚拟技术完成编译时期、链接时期、执行时期以及“闲置时期”的优化任务。

它最早以C/C++为实现对象,而目前它已支持包括ActionScript、Ada、D语言、Fortran、GLSL、Haskell、Java字节码、Objective-C、Swift、Python、Ruby、Crystal、Rust、Scala以及C#等语言。

LLVM pass框架是LLVM系统的一个很重要的部分。LLVM的优化和转换工作就是由多个pass来一起完成的。类似流水线操作一样,每个pass完成特定的优化工作。

上面就是所有的pass(优化算子),各自身怀绝技!

总的来说,所有的pass大致可以分为两类:

  • 分析(analysis)和转换分析类的pass主要以提供信息为主

  • 转换类(transform)的pass主要优化中间代码

常用的代码优化方法(不同的pass):

  • 删除公共子表达式:如果表达式x op y先前已被计算过,并且从先前的计算到现在,x op y中的变量值没有改变,则x op y的这次出现就称为公共子表达式(common subexpression)

  • 删除无用代码无用代码(Dead-code):其计算结果永远不会被使用的语句

  • 常量合并:如果在编译时刻推导出一个表达式的值是常量,就可以使用该常量来替代这个表达式。

  • 代码移动:这个转换的结果是那些不管循环多少次都得到相同结果的表达式(即循环不变计算,loop-invariant computation),在进入循环之前就对它们进行求值。

  • 强度削弱:用较快的操作代替较慢的操作,如用加代替乘 。(例:2*x ⇒ x+x)

  • 删除归纳变量:对于一个变量x ,如果存在一个正的或负的常数c使得每次x被赋值时它的值总增加c ,那么x就称为归纳变量(Induction Variable)。在循环中,若有一组归纳变量的值的变化不变,可以将这组变量保留一个

聪明的读者一定反应过来了,感情这模型是在学习如何针对代码选择最优的pass list(优化算子组合)然后进行优化。对了!

Meta为了让LLM Compiler了解编译器优化的工作原理,它使用编译器模拟办法。这个办法将未优化的代码和随机选择的pass lists(优化算子组合,黄色部分)一起丢给opt,进而生成优化代码(IR 或汇编,绿色部分)。最后黄色部分和绿色部分一起作为训练集喂给LLM。

上图中的opt是LLVM工具链中的一个工具,用于分析和转换LLVM源文件中的中间表示(IR)。这个工具通常用于应用各种优化和转换操作,例如执行优化传递、插入优化插件等。

>opt input .bc -o output .bc -p ’module ( default <Oz >) ,module ( iroutliner )’

>clang output .bc -o output .o

>size output .o

上图展示了训练1和推理2期间的模型输入(提示)和输出(标签)的过程。为了生成训练提示的标签,未优化的代码和多个随机pass组合进行编译,然后针对输出二进制最小的pass组合进行最小化,之后再使用 PassListEval检查其正确性。最终被选择的pass list以及其相应的优化IR在训练期间用作标签。期间最经常被选择的100个pass组合将会在所有的应用中广播。

对于部署,Meta选择优化过的传递列表,以确保优化的代码是正确的。为了保证正确性,PassListEval很是关键,下图展示了这个过程:

那么如何进行反编译的微调呢,其实也很简单,通过训练模型将给定的代码样本反汇编为相应的IR来训练模型,以了解汇编(ASM,机器指令,黄色)和IR(优化过后的绿色部分)之间的关系。用于标记此训练任务的IR是利用优化过的IR。如下图所示:

这样LLM编译器经过微调,可在特定任务中表现出色,例如将编译后的代码反汇编回其中间表示 (LLVM-IR)。这对于理解遗留代码或反向优化特别有益,使LLM编译器成为维护和升级现有软件系统的宝贵工具。

效果如何

若要比较效果的话,肯定和优化命令-Oz作为基准来比较,从图中可以看出,效果还是挺不错的。虽然LLM Compiler在编译器优化任务上表现良好,并且相比先前的工作,对编译器表示和汇编代码的理解有所改进,但仍存在一些局限性。主要限制是输入的有限序列长度(上下文窗口)。

LLM 编译器支持 16k tokens的上下文窗口,但程序代码往往超过这个长度。例如,67%的MiBench基准中显示超过了这个上下文窗口。为了缓解这个问题,研究人员拆分了内容,然而仍有18%还是过长,无法作为输入。这样也是是后续的一个研究热点。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/38143.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

一个合理的前端应用文件结构

在大型应用中&#xff0c;最关键且最具挑战性的方面之一就是拥有一个良好且合理的文件结构。在考虑通过微前端将代码库拆分成多个应用之前&#xff0c;可以遵循一些步骤来改善项目级别的架构&#xff0c;并在您考虑这一路径时使过渡更容易。 我们的目标是应用某种模块化方法&am…

MSPM0G3507——定时器例程讲解4——timx_timer_mode_periodic

以下示例以周期模式配置TimerG并切换LED。周期从500ms开始&#xff0c;每次切换减少50ms&#xff0c;直到周期为100ms&#xff0c;然后重复。设备在等待中断时保持待机模式 #include "ti_msp_dl_config.h"/* ((32KHz / (321)) * 0.5s) 45 - 1 495 due to N1 ticks …

Qt中用QLabel创建状态灯

首先ui设计中分别创建了4个大灯和4个小灯。 编辑.h文件 #ifndef LED_H #define LED_H#include <QWidget> #include <QLabel>QT_BEGIN_NAMESPACE namespace Ui { class Led; } QT_END_NAMESPACEclass Led : public QWidget {Q_OBJECTpublic:Led(QWidget *parent n…

服务器硬件以及RAID配置

目录 一、RAID磁盘阵列原理&#xff08;嘎嘎重要&#xff09; 1、RAID的概述 2、常用的RAID 2.1、RAID 0 2.2、RAID 1 2.3、RAID 5 2.5、RAID 10 3、阵列卡介绍 二、建立软件RAID磁盘阵列 1、添加硬盘 2、使用fdisk分区&#xff0c;类型为fd 3、mdata命令使用参数 …

安全与加密常识(3)什么是数字签名和数字证书

文章目录 数字签名工作原理关键特点应用实例 数字证书数字证书和数字签名趣味实例 数字签名 数字签名是一种通过密码运算生成的数据&#xff0c;用于验证信息的完整性和来源&#xff0c;确保数据在传输过程中未被篡改&#xff0c;同时提供发送者的身份认证和防止抵赖的功能。它…

Qt: QPushButton 按钮实现 上图标下文字

效果如下&#xff1a; 实现有如下几种方式&#xff1a; 1. 使用 QPushButton 设置 setStyleSheet 例&#xff1a; ui->recorder->setStyleSheet("QPushButton{"\"border: 1px solid #00d2ff; "\"min-height: 60px; "\"col…

python多继承的3C算法

python多继承的3C算法 有很多地方都说python多继承的继承顺序&#xff0c;是按照深度遍历的方式&#xff0c;其实python多继承顺序的算法&#xff0c;不是严格意义上的深度遍历&#xff0c;而是基于深度遍历基础上优化出一种叫3C算法 python多继承的深度遍历 class C:def ru…

MySQL高级-MVCC-原理分析(RR级别)

文章目录 1、RR隔离级别下&#xff0c;仅在事务中第一次执行快照读时生成ReadView&#xff0c;后续复用该ReadView2、总结 1、RR隔离级别下&#xff0c;仅在事务中第一次执行快照读时生成ReadView&#xff0c;后续复用该ReadView 而RR 是可重复读&#xff0c;在一个事务中&…

Django 配置静态文件

1&#xff0c;DebugTrue 调试模式 Test/Test/settings.py DEBUG True...STATICFILES_DIRS [os.path.join(BASE_DIR, static),] STATIC_URL /static/ 1.1 创建静态文件 Test/static/6/images/Sni1.png 1.2 添加视图函数 Test/app6/views.py from django.shortcuts impor…

uniapp,uni-fab组件拖动属性,替代方案

文章目录 1. 背景2. 替代方案2.1 方案一2.2 方案二 参考 1. 背景 最近基于uniapp开发一款设备参数调试的APP软件&#xff0c;其中有使用到悬浮按钮&#xff0c;快速开发阶段&#xff0c;为了能尽快上线&#xff0c;直接使用了uni-ui的扩展组件uni-fab&#xff0c;参考【1】&am…

Configure C/C++ debugging

Configure C/C debugging launch.json 文件用于在 Visual Studio Code 中配置调试器。 Visual Studio Code 会生成一个 launch.json (位于项目的 .vscode 文件夹下),其中几乎包含了所有必需的信息。要开始调试,您需要填写 program 字段,指定要调试的可执行文件的路径。这必须…

【从零开始学架构 架构基础】四 架构设计的复杂度来源:可扩展性复杂度来源

架构设计的复杂度来源其实就是架构设计要解决的问题&#xff0c;主要有如下几个&#xff1a;高性能、高可用、可扩展、低成本、安全、规模。复杂度的关键&#xff0c;就是新旧技术之间不是完全的替代关系&#xff0c;有交叉&#xff0c;有各自的特点&#xff0c;所以才需要具体…

新书速览|Linux C与C++一线开发实践

《Linux C与C一线开发实践》 本书内容 Linux C/C编程在Linux应用程序开发中占有重要的地位&#xff0c;掌握这项技术将在就业竞争中立于不败之地。《Linux C与C一线开发实践》内容针对初中级读者&#xff0c;贴近软件公司一线开发实践。全书厚达620多页&#xff0c;知识点丰富…

51单片机第6步_stdlib.h库函数

本章重点学习stdlib.h库函数。 #include <REG51.h> //包含头文件REG51.h,使能51内部寄存器; #include <stdlib.h> //float atof (char *s1); //参数s1字符串可包含正负号,小数点或E(e)来表示指数部分,如123.456或123e-2; //若首字符是非数据字符,或为正负号…

[NSSCTF]-Reverse:[SWPUCTF 2021 新生赛]easyapp(安卓逆向,异或)

无壳 把后缀名改为zip&#xff0c;找到apk 查看jadx 这里调用了MainActivity的lambda$onCreate$0$MainActivity&#xff0c;然后又调用了Encoder进行异或。 exp&#xff1a; result棿棢棢棲棥棷棊棐棁棚棨棨棵棢棌 key987654321 flag for i in range(len(result)):flagchr(…

HarmonyOS开发:应用完整性校验

简介 为了确保应用的完整性和来源可靠&#xff0c;OpenHarmony需要对应用进行签名和验签。 应用开发阶段&#xff1a; 开发者完成开发并生成安装包后&#xff0c;需要开发者对安装包进行签名&#xff0c;以证明安装包发布到设备的过程中没有被篡改。OpenHarmony的应用完整性校…

关于响应式编程的理解与SpringCloudGateway的理解

关于响应式编程的理解与SpringCloudGateway的理解 一. 响应式编程与函数式编程的区别二. 响应式编程中常用的组件2.1 RxJava定义2.2 Rxjava基本概念2.3 RxJava 用法 三 SpringcloudGateway四 常见的四种限流规则 一. 响应式编程与函数式编程的区别 总的来说&#xff0c;响应式编…

GPIO和PIN

文章目录 1 GPIO和Pin1.1 GPIO和Pin基础概念1.2 GPIO输入模式1.3 GPIO输出模式1.4 GPIO的HAL库1.4.1 一些HAL库表示1.4.2 HAL库常用GPIO函数1.4.3 GPIO点亮led灯程序例子 1 GPIO和Pin 1.1 GPIO和Pin基础概念 ​ 单片机有很多的引脚&#xff0c;为了操控每一个引脚&#xff0c…

grpc学习golang版( 四、多服务示例 )

系列文章目录 第一章 grpc基本概念与安装 第二章 grpc入门示例 第三章 proto文件数据类型 第四章 多服务示例 第五章 多proto文件示例 第六章 服务器流式传输 第七章 客户端流式传输 第八章 双向流示例 文章目录 一、前言二、定义proto文件三、编写server服务端四、编写Client客…

MySQL之可扩展性(九)

可扩展性 直接连接 2.修改应用的配置 还有一个分发负载的办法是重新配置应用。例如&#xff0c;你可以配置多个机器来分担生成大报表操作的负载。每台机器可以配置成连接到不同的MySQL备库&#xff0c;并为第N个用户或网站生成报表。 这样的系统很容易实现&#xff0c;但如果…