AI编译器与TVM

由于AI芯片的特殊性和高度定制化,为了兼容硬件的多样性,AI模型必须能被高效地映射到各种AI芯片上。AI编译器将深度学习框架描述的AI模型作为输入,将为各种AI芯片生成的优化代码作为输出。AI编译器的目标是通过编译优化的方法将深度学习框架产生的AI模型转化为与特定架构的AI芯片适配的可执行机器码。
主流的AI硬件厂商都提供了高度优化的算子库或者推理引擎来实现高效计算,但是依赖算子库的缺点是算子库覆盖的硬件范围有限,而且库函数的更新落后于模型的发展速度,无法充分发挥AI芯片算力。算子与硬件算子库高度耦合会导致算子不可分解,从而影响算子进一步优化,使其难以在硬件平台上高效执行。为了解决这些缺点,业界设计了AI编译器。AI编译器可以在代码生成期间生成对库函数的调用,这样工作量就可以从编译器转移到算子开发上了。相反,如果编译器有强大的代码生成能力,则对内核函数的优化的依赖也会减小。

AI编译器结构

在这里插入图片描述

常规的编译器包含三个部分:前端、优化器和后端。前端主要负责将输入的源代码解析为抽象语法树,做语法分析、语义分析等;优化器在前端的基础上进行优化;后端会尽可能利用目标机器上的特殊指令优化中间代码,并将其转化为指定硬件平台的机器码。该三部分的数据传输是通过IR(Intermediate Representation)传输的,IR可以保证编译器的跨平台。
AI编译器一般采用分层的设计,通过多级IR设计,实现针对AI模型的特定优化设计。高阶IR服务于前端,执行硬件无关的优化,低阶IR服务于后端,执行硬件相关的编译、优化和代码生成操作。高阶IR也叫图IR,旨在抽象计算和控制流,其目的是建立控制流及算子与数据之间的依赖关系,并为图优化提供接口。高阶IR还需要对数据张量和算子进行支持。低阶IR主要设计用于各种硬件相关的优化和代码生成。低阶IR会更加细粒度的反应硬件特性。低阶IR还需要兼容第三方工具链,利用已有编译工具完成通用优化和代码生成。
AI编译器的输入是深度学习框架的模型,然后AI编译器将输入转化为高阶IR。AI编译器前端会结合通用编译器优化和AI特定的图优化方法对计算图优化生成优化后的计算图,该部分的优化是硬件平台无关的优化。AI编译器的后端优化是在高阶IR转化为低阶IR后,利用硬件的先验信息,通过定制化优化pass将优化后的代码实现映射为AI芯片的执行指令。

TVM架构

TVM是一个端到端的全栈编译器,提供端到端的编译优化。TVM以AI模型作为输入,首先将其转化为计算图,然后执行高级数据流重写,为计算图生成优化图。算子级优化模块为优化图中每个融合算子生成高效代码,并以声明式张量表达式指定算子。TVM会给指定硬件目标算子建立可能的优化集合,然后使用基于机器学习的代价模型搜索优化算子。最后将生成的代码打包到可部署模块中。
代码生成是将TIR表示编译成目标硬件平台的机器码。TVM支持多种后端,包括但不限于:
LLVM:可以针对任意微处理器架构生成代码,包括标准x86和ARM处理器,AMDGPU和NVPTX代码生成,以及LLVM支持的任何其他平台;专门的编译器,如NVCC(NVIDIA的编译器);嵌入式和专用目标,通过TVM的Bring Your Own Codegen(BYOC)框架实现。因此,最终的输出是针对特定硬件平台优化的机器码,它可以是一个可执行文件、动态链接库(DLL)、静态链接库(LIB)或其他硬件平台支持的格式。这种格式的代码可以直接在目标硬件上运行,以实现高效的模型推理。
在这里插入图片描述

TVM图级优化

TVM可以对计算图做各种图优化,按照优化范围可以分为局部优化和全局优化。局部优化包括算子融合、代数简化、常量折叠,是图级优化的重点。全局优化是在整个计算图中搜索特定特征,并对这些特征执行优化操作,例如死代码消除、公共子表达式消除。
高阶图优化的最好结果只能达到与算子库优化相同的性能。随着引入的算子越来越多,可融合的内核数量急剧膨胀,并且随着硬件后端种类不断增加,开发者将无法依赖算子库提供融合能力。考虑到每种硬件后端上算子手工实现优化内核会因工作量太大而不切实际。因此,TVM提供了代码生成方法为指定的AI模型算子生成可能的实现。在代码生成期间生成对库函数的调用,这样工作量就可以从编译器转移到算子开发上了。

计算与调度

TVM提供了张量表达式语言,为自动代码生成提供支持。张量表达式语言的每个计算操作分为两个部分:第一个部分指定输出张量形状,第二部分描述张量中每个元素的计算规则。张量表达式并没有指定执行细节,这为不同硬件中的优化实现提供可能性,开发者可以通过lambda表达式快速定义计算,而无需实现新函数。不同实现方法性能存在巨大差异,因此,TVM要求开发者指定如何执行计算,如访问数据的顺序、多线程并行的方式。TVM中将这种计算的实现称为调度(严格意义上来说是执行计算的实现的规划),由tvm.te.schedule.Schedule对象表示,其中包含若干阶段,每个阶段对应一个描述调度方式的操作。
TVM将计算和调度分离,同一种计算可以通过不同的调度实现。计算只定义了结果的计算方式,计算结果与运行平台无关。计算的实现由调度决定,调度取决于硬件,但不可影响结果的正确性。调度可以表示(为)张量表达式到底层代码的特定映射。TVM提供了许多调度原语为各种后端实现高性能代码。

自动调优框架

开发者需要对调度进行优化才能更好发挥硬件性能。这种优化可以是基于经验的手动优化,但是需要为每种硬件提供调度优化策略和调度相关参数,这样就会形成一个巨大的算子实现搜索空间。TVM提供了自动调度优化框架,可以为算子提供高性能底层代码实现。自动调优过程分两步:第一步定义搜索空间,第二部运行搜索算法。定义搜索空间可以看作是对调度的参数化,可将固定的调度改为定义调度策略的可调调度模板,通过该可调调度模板,从候选参数中选择在不同目标硬件上最优的参数组合。
TVM提供了四种调优器在搜索空间中找到最优调度,

  • RandomTuner:随机顺序遍历配置空间;
  • GridSearchTuner:以网络搜索顺序遍历配置空间;
  • GATuner:用遗传算法搜索配置空间,该方法无代价模型,只能在真实机器上测试;
  • XGBTuner:该优化器的代价模型基于模拟退火算法,使用XGBoost算法训练模型,然后在配置空间中测试最优配置。

在TVM中,搜索的主要是以下几个方面:

  • 调度参数:这些参数定义了如何在目标硬件上执行计算。它们包括循环的重排、并行化、向量化、展开、融合等循环变换。
  • 内存访问模式:不同的内存访问模式对性能有显著影响。搜索空间可能包括不同的内存访问模式,例如全局内存访问、共享内存访问、寄存器访问等。
  • 算子实现:对于某些操作,可能有多种实现方式。搜索空间可能包含不同的算子实现,以找到最适合特定硬件的版本。
  • 资源分配:这涉及到如何在硬件上分配计算资源,例如线程数、块数等。
  • 精度配置:在某些情况下,可以通过降低操作的数值精度来提高性能,搜索空间可能包括不同的精度配置。
  • 混合精度:在搜索空间中,还可以探索使用不同精度(如FP32和FP16)的组合来平衡性能和精度。
  • 自动调度算法:TVM提供了AutoTVM和AutoScheduler两种自动调优模块。AutoTVM是基于模板的调优模块,而AutoScheduler(Ansor)是无模板的调优模块,它们都通过搜索算法来探索搜索空间。

TVM两级IR

TVM有两级IR:Relay IR和张量级IR。Relay IR作为一种高阶图级IR,旨在最大限度利用函数式编程语言、类型系统和编译器技术的研究成果,改善模型部署开销。Relay IR的表达同时采用基于DAG的IR和基于let-binding的IR。DAG即有向无环图,可以明确表示算子之间的依赖关系,但是缺乏计算范围的定义,可能会出现二义性问题。let-binding通过在有限范围内为某些函数提供let表达式来消除语义二义性。高级IR有助于执行通用优化如内存重用、布局转化、自动分区等。
高阶IR实现包括数据表示和算子实现。TVM的数据表示包括张量数据表示、形状表示、数据布局和边界推断等。TVM中数据通常以张量形式组织,通过占位符表示,持有明确的形状信息。通过占位符,开发者可以在不考虑具体元素的情况下操作计算图,实现了计算的定义与执行的分离。
数据布局是作为算子的参数写入的,以便算子的实现和减少编译开销。数据布局包括维度顺序、分片、填充和跨距等。不同的硬件最优数据不同,执行性能也不同。Relay算子受数据布局影响程度各不相同,布局转换本身会消耗资源引入开销,TVM将Relay算子分为对布局无感、对布局轻度敏感和对布局重度敏感三类。TVM提供了ConvertLayout Pass,希望能以最少的数据布局转化次数改变整个图的数据布局。
在高阶IR的算子实现中,开发者需要描述计算和调度,声明输入输出的形状。TVM添加新算子各层IR都需要改动,图级IR需要为新算子设置计算规则,张量级IR需要为每个硬件平台实现对应内核。
低阶IR以更细粒度的表示形式描述计算,通过提供计算调优和内存访问接口实现目标相关的优化。经过Relay优化和降级之后,优化的算子通过TIR降级为C++/CUDA,或者降级为LLVM IR,然后通过NVCC或者LLVM等后端优化器和代码生成器产生机器码。

运行时定制

TVM运行时是部署和执行已编译模块的主要方式,其目标是提供可与前端语言交互的API集合。TVM运行时有两个基础模块:PackedFunc和ModuleNode。TVM代码生成将已编译对象封装为Module对象,并以PackedFunc对象形式返回其中的已编译函数。自定义硬件平台后端应派生ModuleNode子类实现各自的运行时模块,并在其中添加目标相关的运行时API调用。

  • 使用TVM运行时:编译后的模型可以生成为一个可执行文件或者库文件,然后通过TVM运行时来加载和执行。TVM运行时是一个轻量级的模块,提供了C API以及Python和Rust等语言的绑定,用于动态加载和执行编译后的模型。
  • 集成到应用程序:编译后的模型可以被集成到应用程序中,例如集成到移动应用或嵌入式设备中。这种方式下,应用程序可以直接调用编译后的模型执行推理。
  • 使用Graph Executor:TVM提供了Graph Executor,它是一个执行引擎,用于执行编译后的模型。Graph Executor可以加载编译后的模型,并执行推理过程。
  • 使用RPC服务:TVM支持远程过程调用(RPC)服务,允许模型在一台服务器上编译,然后通过网络在另一台设备上执行。这种方式适用于模型部署在不同的硬件平台或分布式系统中。
  • 使用WebAssembly:TVM还支持将模型编译为WebAssembly格式,使得模型可以在Web浏览器中运行,无需后端服务器。
  • 使用TVM微控制器运行时:对于微控制器和嵌入式系统,TVM提供了专门的运行时系统,用于在资源受限的设备上执行编译后的模型。
  • 使用TensorRT:对于NVIDIA GPU,TVM可以与TensorRT集成,利用TensorRT的高性能推理优化来执行编译后的模型。
  • 使用OpenCL:在支持OpenCL的设备上,TVM可以编译模型并利用OpenCL运行时来执行模型。
  • 使用Metal:对于苹果设备,TVM可以编译模型并使用Metal API来执行模型。

TVM前后端优化

计算图到目标代码的过程中可以分解若干个独立的步骤,这些步骤成为pass。RelayIR和TIR都包含一系列pass,为了使这些pass正确顺序执行,需要一个管理器安排pass执行顺序,在TVM中称作TVM pass基础架构。通过pass基础架构可以管理不同层次IR的优化pass。

前端优化

前端优化时通过遍历Relay IR,并从中捕获特定计算特征,以此指导图重写和图转换。前端优化与硬件无关只适用于计算图。
优化pass可以分两种:函数级优化和模块级优化。函数级优化实现Relay或TIR模块中各函数内部优化,没有全局信息,不能添加或删除函数。如常量折叠、死代码消除。模块级优化用于实现过程间优化和分析,作用于IRModule对象上,可以对任何函数体做修改。如移除无用函数。

后端优化

TVM后端优化不仅针对低阶IR做优化,更针对不同硬件目标,结合硬件特性和后端优化技术,实现高效代码生成。后端优化可通过不同方式实现。一种是针对自定义加速器硬件,利用AI模型特性设计定制化的后端优化方法。第二种是将低阶IR转化为LLVM IR,利用LLVM基础结构生成优化的硬件可执行机器码。第三种是将低阶IR转化为内核源代码如CUDA,在利用已有的编译器如NVCC生成可执行代码。

AI推理引擎与AI编译器的区别

在这里插入图片描述
简单来讲,推理引擎就是对前端模型进行解释执行,一般是JIT的编译方式,提供了优化的kernel实现和设计的IR,并且IR一般是一种。AI编译器同样完成了对前端模型的执行操作但是一般包含多级IR,每级IR有不同的优化称作Pass,可以前端模型转化为C代码或者其他可执行代码,也可以转化为某种IR然后交由Runtime来解释执行。

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

onlyoffice docker启用jwt并生成jwt

一、说明 本文是docker教程,linux/win的安装版本也类似,只需要修改配置文件中的secrt就可以了【Configuring JWT for ONLYOFFICE Docs - ONLYOFFICE】 二、正文开始 docker启动时候如果不想使用jwt,加上参数-e JWT_ENABLEDfalse就可以了&…

AI驱动的支持截图或线框图快速生成网页应用的开源项目

Napkins.dev是什么 Napkins.dev是一个创新的开源项目,基于AI技术将用户的截图或线框图快速转换成可运行的网页应用程序。项目背后依托于Meta的Llama 3.1 405B大型语言模型和Llama 3.2 Vision视觉模型,结合Together.ai的推理服务,实现从视觉设…

Centos7安装ZLMediaKit

https://github.com/ZLMediaKit/ZLMediaKit 一 获取代码 git clone https://gitee.com/xia-chu/ZLMediaKit cd ZLMediaKit git submodule update --init git submodule update --init 命令用于初始化和更新 Git 仓库中的子模块(submodules)。这个命令…

AI劳动力崛起:人将面临失业危机?

场景 第一眼看到这个网站的时候,AI员工官网(好像是部署在美国),我觉得很好奇,真的可以让AI替代人类完成工作吗?替代到什么程度呢?能以自然语言直接驱动吗? 正好手上在做爬虫项目&am…

X射线衍射(X-ray Diffraction,XRD)小白版

文章目录 实验过程原理晶体构成X射线波长diffraction 干涉效应 Braggs Law晶体间距d散射角度θ半波长λ/2公式 公式名称由来应用设备 实验过程 In the X-ray experiment , a sample is placed into the center of an instrument and illuminated with a beam of X-rays. 在X射…

Debug-029-el-table实现自动滚动分批请求数据

前情提要 最近做了一个小优化,还是关于展示大屏方面的。大屏中使用el-table展示列表数据,最初的方案是将数据全部返回,确实随着数据变多有性能问题,有时请求时间比较长。这里做的优化就是实现列表的滚动到距离底部一定高度时再次请…

Python语法结构(二)(Python Syntax Structure II)

💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。 推荐:Linux运维老纪的首页…

Shell编程-函数

作者介绍:简历上没有一个精通的运维工程师。希望大家多多关注作者,下面的思维导图也是预计更新的内容和当前进度(不定时更新)。 我们前面学习了那么多命令,以及涉及到部分逻辑判断的问题。从简单来说,他就是Shell编程,…

在Xshell中查看日志文件详情

学习总结 1、掌握 JAVA入门到进阶知识(持续写作中……) 2、学会Oracle数据库入门到入土用法(创作中……) 3、手把手教你开发炫酷的vbs脚本制作(完善中……) 4、牛逼哄哄的 IDEA编程利器技巧(编写中……) 5、面经吐血整理的 面试技…

排序06 粗排模型

前面讲的多目标模型主要是用于精排。 粗排:尽量减少推理的计算量,牺牲准确性确保线上推理的速度足够快。 精排模型和双塔模型 中间的神经网络被多个任务共享 因此,前期融合模型用于召回,后期融合可以作为精排。 小红书粗排的三…

Shell案例之一键部署mysql

1.问题 我认为啊学习就是一个思考的过程,思考问题的一个流程应该是:提出问题,分析问题,解决问题 在shell里部署mysql服务时,我出现一些问题: 1.安装mysql-server时,没有密钥,安装…

PCL 基于中值距离的点云对应关系

目录 一、概述 1.1原理 1.2实现步骤 1.3应用场景 二、代码实现 2.1关键函数 2.1.1 获取中值距离筛选后的对应点对 2.1.2获取初始点对 2.1.3可视化 2.2完整代码 三、实现效果 PCL点云算法汇总及实战案例汇总的目录地址链接: PCL点云算法与项目实战案例汇…

NetSuite Transfer Order Saved Search的关键字段取值

针对于Transfer Order的Saved Search,我们最经常遇到的问题就是如何取到From Location,To Location,Quantity Fulfilled,Quantity Received这几个值。 原生的TO Register无法取到对应的信息,系统中也没有相应的标准Se…

关于vue3中如何实现多个v-model的自定义组件

实现自定义组件<User v-model"userInfo" v-model:gender"gender"></User> User组件中更改数据可以同步更改父组件中的数据&#xff1a; 1 父组件&#xff1a; <User v-model"userInfo" v-model:gender"gender">&…

[Unity Demo]从零开始制作空洞骑士Hollow Knight第十七集:制作第一个BOSS苍蝇之母

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 前言一、战斗场景Battle Scene相关逻辑处理 1.防止玩家走出战斗场景的门2.制作一个简单的战斗场景二、制作游戏第一个BOSS苍蝇之母 1.导入素材和制作相关动画2.制作…

C#从零开始学习(GameObject实例)(unity Lab3)

这是书本中第三个unity Lab 在这次实验中,将学习如何使用C#编写代码用unity编写C#代码 GameObject实例 本次将完成的工作 将游戏资产配置在文件夹中创建材质把GameObject变成预制件脚本控制游戏防止球体重叠 将游戏资产配置在文件夹中 Script放代码 Prefabs放预制件 MAteria…

PostgreSQL的学习心得和知识总结(一百五十五)|[performance]优化期间将 WHERE 子句中的 IN VALUES 替换为 ANY

目录结构 注&#xff1a;提前言明 本文借鉴了以下博主、书籍或网站的内容&#xff0c;其列表如下&#xff1a; 1、参考书籍&#xff1a;《PostgreSQL数据库内核分析》 2、参考书籍&#xff1a;《数据库事务处理的艺术&#xff1a;事务管理与并发控制》 3、PostgreSQL数据库仓库…

RabbitMQ系列学习笔记(八)--发布订阅模式

文章目录 一、发布订阅模式原理二、发布订阅模式实战1、消费者代码2、生产者代码3、查看运行结果 本文参考&#xff1a; 尚硅谷RabbitMQ教程丨快速掌握MQ消息中间件rabbitmq RabbitMQ 详解 Centos7环境安装Erlang、RabbitMQ详细过程(配图) 一、发布订阅模式原理 在开发过程中&…

大数据治理的核心思想

目录 ​编辑1.1 大数据治理的定义与重要性 1.2 大数据治理的关键要素 1.2.1 数据质量管理 1.2.2 数据安全管理 1.2.3 合规性管理 1.2.4 数据共享与协作 1.2.5 数据驱动的决策 二、对未来趋势的看法 2.1 技术发展趋势 2.1.1 人工智能与机器学习 2.1.2 云计算与边缘计…

Python数据处理工具笔记 - matplotlib, Numpy, Pandas

matplotlib, Numpy, Pandas 由于有很多例子是需要运算后的图表看着更明白一些&#xff0c;很明显csdn不支持 所以用谷歌的Colab(可以理解为白嫖谷歌的云端来运行的jupyter notebook)来展示&#xff1a; Colab链接(需要梯子)&#xff1a;Python数据挖掘 当然如果实在没有梯子&…