Tiramisu:一种基于Polyheral的深度学习模型编译器

Tiramisu是一款深度学习模型编译器,采用基于Polyhedral的调度技术,提供领域特定语言DSL进行手动调度。它通过多级IR实现优化,包括抽象算法层、计算管理层、内存布局和分布式计算。在深度学习和图像处理基准测试中,Tiramisu展现出优于Intel MKL、Halide和PENCIL的性能。

1. 推理引擎编译模型的一般过程

业界主流的深度学习推理引擎,如TensorRT、Tensorflow Lite、TVM等,均由两个主要组件构成:模型编译器和推理运行时,前者负责将模型编译为可运行于目标设备的IR/代码,后者则负责在目标设备上导入编译后的IR/代码并执行推理过程。很明显,模型编译器是否能生成合理运用设备资源的代码,是保证模型推理性能的关键。模型编译器编译模型的一般过程,就是将模型由高级表示,转换为一系列中间表示(IR)的过程。如下图,以TVM为例,这个过程是:原始模型->Relay IR(图级别IR)-> Tensor IR(算子级别IR)-> Runtime IR(运行时IR)。


TVM框架模型编译过程

其中,由Relay IR转化为Tensor IR的步骤称为“调度生成”,对于TVM以外的推理引擎,该步骤的名称可能有差异,但都是必须的。调度的关键在于从时间、空间两个维度上彻底挖掘计算资源的极限潜能:

  • 时间维度上,任意时刻应尽可能地并行化数据无依赖关系的计算(CPU多物理核、GPU流处理器、CPU/GPU高级指令集),以避免不必要的串行计算

  • 空间维度上,尽可能将计算所需的数据放置于存取速度最快的区域(CPU L1 Cache、GPU L1 Cache、GPU C-Cache、GPU共享内存等),减少数据读写时间

综上可知,推理引擎的核心在于模型编译器,模型编译器的核心在于调度过程的生成技术。

2. 调度生成技术的分类

调度过程是否合理直接决定了CodeGen生成的运行时代码的执行效率,目前业界的调度编译技术可以归纳到下表的四个象限中:

调度生成技术分类


调度自动生成 调度非自动生成
依赖分析 PolyMage, Tensor, Comprehensions AlphaZ,CHiLL,URUK,Tiramisu
区间分析 AutoScheduler(TVM) Halide,AutoTVM

如上表,编译技术根据循环嵌套分析算法的不同可以分为基于依赖分析和基于区间分析的两大类:依赖分析也即传统编译器的应用仿射变换优化循环嵌套代码的多面体分析技术,由于深度学习模型的算子在推理阶段的循环控制流是静态可判定的,因此非常适合应用该技术优化计算过程;相比依赖分析,区间分析针对图像处理领域的常用计算(针对图像矩阵的卷积、池化操作)简化了循环计算过程为循环轴对齐,即简化依赖分析的多面体抽象为长方体抽象,以牺牲一定的资源利用为代价简化常用算子的编译过程。

两者相比,基于依赖分析的Polyhedral模型的调度描述更加细化、表达力更强,理论上可以将优化做到极致,但缺点是算法原理相对复杂且优化分析的复杂度更高;而基于区间分析的调度模型的优势在于,其在图像处理领域的优化效果和前者相差无几,但优化分析的复杂度低很多,缺点则是对于图像处理领域外的代码调度表达力不足,难以优化运行代码到极致性能。


另一种分类方式是调度生成的自动化程度,非自动化生成调度的编译器通常会向用户提供一种领域特定语言(DSL),如TVM的Tensor Expression、Tiramisu的Tiramisu Language,用户使用DSL语言描述由算子的计算到具体调度的转化过程;而自动化生成调度的编译器则会内置一套或多套编译准则,这套准则根据用户定义的计算过程描述以及设备性能描述自动生成最优的调度过程。

两类方法相比,非自动化的方法需要用户对目标设备的体系结构有足够理解并提供调度生成模板(AutoTVM)或具体调度过程(Tiramisu),用户在自定义的模板/过程上可以调整调度参数以优化调度过程;而自动化的方法则是对编译准则的设计者在计算机体系结构、代码编译原理方面提出了很高的要求,以确保设计的编译准则可以根据给定算子以及运行设备信息生成高效的调度过程。

根据以上对比可知,“四象限表”列出的所有调度生成技术并不存在绝对的优劣之分,每一种技术都是根据自身需求在通用性/特定领域性能两个维度上做取舍。本文即将介绍的Tiramisu可以归类于“基于依赖分析的调度非自动化生成”中。

3. Tiramisu DSL

Tiramisu定义了一套领域专用语言(DSL),该语言以C++为基础,提供了一套API供用户调用。用户可基于Tiramisu DSL APIs定义循环优化、内存布局等转化规则以指导算子调度的生成过程,Tiramisu Compiler进而根据用户定义的规则将原始深度学习模型的所有算子转化为低级别IR,并最终生成运行于设备后端的优化代码。理解Tiramisu DSL的一个高效方法是了解其定义的数据结构和算法,下图展示了Tiramisu转化代码为设备代码的全过程。

3.1 Tiramisu DSL——算法篇

Tiramisu定义的算法更准确的称呼是调度命令,用于描述数据排布如何设置、多层循环如何做仿射变换、设备计算资源如何利用等信息。Tiramisu共定义了4种类型的调度命令:

  • 循环嵌套变换命令:这一类型的调度命令包括常见的仿射变换,如循环展开、分割、移位等。

  • 循环-硬件关联命令:该类型的调度命令包括循环并行、向量化以及绑定循环到指定计算资源的操作等。

  • 数据操作命令:数据操作命令可以分为4种类型:(1) 分配Tensor空间命令 (2) 设置Tensor属性命令,如设置数据存储位置(host/device/shared) (3)数据拷贝命令 (4) 设置数据存取属性命令。如表所示,数据操作命令也有高级和低级之分,通常用户使用高级命令即可完成一般的调度规划,更细致的规划则需要低级命令参与

  • 数据同步操作命令:Tiramisu相比其他Compiler比较有特色的命令,类似于MapReduce的思路。设计者考虑到一次计算的数据量非常大的情况下可能需要多节点共同计算,因此设计了send/recv的调度操作,籍此可以在多节点之间共享数据或数据片段。

以blur算法为例,原始的blur算法计算定义如下:


与之等价的计算过程为:


接下来可以应用Tiramisu定义的调度命令优化blur算法的计算过程,如下图(a)所示,tile()命令将by计算作了循环展开操作;同时compute_at()命令在j0循环开始的地方计算了bx,供后续by的计算过程调用;parallelize()命令在i0循环处并行计算i0对应的循环体(即i0循环对应的代码块)。

同样的blur算法,在GPU上优化的方式则大不相同,如上图(b):首先,tile_gpu()命令展开by循环的计算并映射展开后的循环到GPU block上;compute_at()命令和(a)的功能相当;cache_shared_at()表示将bx的计算结果保存于共享内存中;store_in()指定了bx和by的入口函数,本例中表示bx和by的计算结果以SOA格式存储;最后的device_to_host_copy明显是计算后的结果拷贝(GPU到内存)。上图(c)考虑blur算法运行在分布式系统上,假设数组in[][][]在分布式系统中的所有节点上都已初始化,每个节点n根据数组in的一个chunk执行各自的计算任务,再用send()和recv()命令在节点间同步计算结果。

3.2 Tiramisu DSL——数据结构篇

数据结构方面Tiramisu定义了4层中间表示,分层式设计的目的在于解耦循环嵌套、内存排布以及分布式计算通信三类优化操作,以简化调度命令的设计过程。第一层IR用producer-consumer关系描述原始算法的计算过程(不考虑内存分配);第二层IR指定算法涉及的所有子计算的执行顺序;第三层IR指定数据在被调用之前应当以何种布局被放置于哪里;第四层IR(可选)指定在分布式系统中各节点协同计算的方式。

理解基于多面体模型(Polyheral)优化过程以及后文的IR定义需要掌握两个基本概念:整数集合与映射。在Polyhedral模型中,整数集合代表的是迭代域,映射用于表示内存访问并转换迭代域和内存访问(应用循环嵌套和内存访问转换)。例如,以下的整数元组集合描述了一个两重循环:

### SAP中受托批指令流程订单受托外包装流程订单的区别 在SAP系统中,受托批指令流程订单(Subcontracting Batch Instruction Process Order)和受托外包装流程订单(Subcontracting Packaging Process Order)虽然都涉及外部协作方的参,但在实际业务场景中的应用目的、处理逻辑以及数据流存在显著差异。 #### 1. **定义应用场景** - **受托批指令流程订单** 主要用于生产制造过程中某一特定工序由外部供应商完成的情况。在这种模式下,企业将半成品发送至外部供应商处进行加工,供应商仅负责指定工序的操作[^3]。完成后,加工后的物品返回企业内部继续后续工艺直至最终成品入库。此类型的订单强调的是对外部供应商执行的具体加工作业及其费用核算。 - **受托外包装流程订单** 则专注于产品的包装环节外包给第三方服务商的情形。它通常发生在商品已经完成主要生产和组装之后,但需要额外的专业化包装服务才能满足市场或客户需求时采用的方式之一[^1]。这里更侧重于如何利用外部资源提升物流效率和服务质量而非单纯的技术性加工活动本身。 #### 2. **物料流动方向** - 对于**受托批指令流程订单**, 物料通常是未完全制成的产品部件或者中间状态下的材料被送往合作厂商那里接受进一步改造后再送回来加入到整体生产线当中去形成最终产物的一部分. - 而在**受托外包装流程订单**的情况下, 成品可能已经被制造完毕并准备就绪待运往客户手中之前才交给专门从事此类工作的单位来进行最后一步即适当形式(如按箱装载)以便运输储存更加便捷安全高效地到达目的地. #### 3. **财务管理重点** - 在涉及到成本计算方面,**受托批指令流程订单**更多关注的是基于所消耗时间长度或者其他衡量指标来确定应付予承包者的报酬金额大小等问题;同时还要考虑到原先转移出去那些处于初级形态阶段的商品价值变化情况等因素影响整个供应链的成本构分析过程之中. - 相较之下,**受托外包装流程订单**则把焦点放在因实施这些特殊安排所产生的附加支出上面——比如租赁使用某些专用设备设施之类的开销项目上,并且由于这属于末端处理性质的工作所以一般不会直接影响到核心产品本身的定价策略制定等方面考虑范围之内. #### 4. **系统配置功能支持** - 配合上述两种不同类型的任务需求,SAP软件平台提供了相应定制化的解决方案选项可供选择运用其中: - 当面对类似于前者那样的复杂技术要求较高的作业环境时候就需要启用更为精细复杂的参数设定机制以确保能够准确追踪记录每一个细节步骤进展状况直到顺利完成为止. ```abap CALL TRANSACTION 'CO01' USING itab MODE 'E' EXPORTING SELECTION-TABLE = sel_tab VARIANTS = var_tab[] ``` 上述代码片段展示了调用事务码`CO01`(创建生产订单)的一个例子,在设置条件筛选表(`sel_tab`)及变量列表(`var_tab[]`)的基础上自动化生成目标文档实例. - 至于后者相对简单明了一些的情境条件下,则可以通过简化版界面快速输入必要信息要素从而加快工作效率减少人为错误发生几率的同时保持足够的灵活性适应各种可能出现的变化情形. ```sql SELECT * FROM vbak INTO TABLE @DATA(lt_vbak) WHERE vbeln IN (@lv_belnr_low TO @lv_belnr_high). ``` 此SQL查询语句是从销售凭证头表(VBAK)提取符合条件的数据集存入局部内表@DATA(lt_vbak),适用于批量检索关联记录场合。 --- ### 论 综上所述可以看出尽管两者同属ERP领域内的子模块范畴却各自承担着截然不同的使命角色发挥独特作用贡献自身力量共同构建起现代化企业管理信息化体系大厦基石部分不可或缺的重要组成单元组成部分构成因素等等诸多层面意义非凡值得深入研究
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Linux基金会AI&Data基金会

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值