张朔铭,博士研究生,正在中国科学院计算技术研究所崔慧敏研究员指导下攻读计算机系统结构博士学位,目前主要的研究方向是AI编译。
zhangshuoming17@mails.ucas.ac.cn
本文分为两个部分,第一部分为综述(领域编译器发展的前世今生 • 综述);这部分重点讨论面向AI领域的编译技术。
随着人工智能时代的来临,AI领域应用的大量出现也促进着领域编译的发展,最突出的表现就是多种AI编译器的普及和应用。AI领域有几个重要的特征使得AI编译器面临很多新的机遇和挑战:一是AI领域中编程框架对计算图与算子分离的设计机制为编译优化提供了更多的机会和更广阔的空间;二是AI领域中对张量的抽象为编译优化提供了具有鲜明领域特征的语义信息;三是以Python为主的动态解释器语言前端为其与AI编译器的衔接带了挑战;四是面向AI的领域专用架构为应用的可移植性带来了挑战。在这些因素的驱动下,近年来学术界和工业界在AI编译方面提出了一系列创新性的方法,也为编译这一基础学科的发展注入了新的活力。
为了让开发者使用方便,框架前端(图层)会尽量对Tensor计算进行抽象封装,开发者只要关注逻辑意义上的模型和算子;而在后端算子层的性能优化时,又可以打破算子的边界,从更细粒度的循环调度等维度,结合不同的硬件特点完成优化。这种图算分离的解耦设计大大简化了AI复杂系统的设计,因此,多层IR设计无疑是较好的选择,目前的主流IR设计也是分为图(TVM Relay,XLA HLO,MindSpore MindIR等)和算子(TVM tir,XLA LLO,MindSpore AKG等)两层。以主流AI编译器TVM[13]和TensorFlow XLA[14]为例。TVM 和 XLA 上层都采用了数据流图的中间表示,用图结点来表示计算,边表示数据流的依赖。在下层TVM 和 XLA 都针对编译器自动生成不同平台的高效代码进行了设计。其中TVM底层针对深度学习核心的张量处理设计的中间表示tir,它借鉴了Halide的中间表示来描述结点内的计算,可以针对不同目标平台定制调度策略,从而实现平台相关的深度优化。TensorFlow XLA 则提出了一种基于代数表示的中间表示(XLA HLO),高层的数据流图被转换为XLA HLO 的中间表示,在此中间表示上可以实施支持jit的算子融合、内存操作消除等优化,优化后的XLA HLO 可以被翻译为LLVM 中间表示或直接映射到TPU 平台。TVM和TensorFlow XLA 的图与张量(或代数)中间表示相结合的方法,一方面能够适配人工智能领域用数据流图来描述应用的需求,另一方面又能够兼顾应用在不同硬件平台之间的移植和优化。
但图层和算子层独立优化无法充分发挥芯片性能。近来面向图算融合的优化也日益成为学术界重要的研究方向。EasyView[15]提出了针对在网络实现中高频出现的tensor view类算子的端到端在线编译自动融合方法,包含view lowering,内存活动追踪,读写关系一致的算子拓扑序列获取,以及计算内存优化策略等内容。Apollo[16]设计了一个开放式多层规约式融合架构以实现不同算子融合方式的协同组合。将不同的融合方式实现为不同的Layer,在各级layer分别做基于polyhedral优化的循环融合,通过计算图算子级别依赖和元素级别依赖的分析对访存密集型算子尽可能融合,识别无计算依赖的算子并行化等优化,然后通过对不同Layer进行逐层规约合并,从而得到最终的融合算子子图,并获得最佳的融合性能收益。
Apollo架构:子图切分,融合,优化[16]
AI编译器的优化目标主要是为了提升AI模型的端到端性能,这个性能会受到包括计算访存比,并行性,资源占用率等多方面因素影响,因而很难通过一个通用的策略涵盖大量不同的后端而都能达到非常优秀的性能。AI编译器通常通过搜索调度空间的方式,来寻找适配后端的极致张量优化策略。这里以TVM为例。TVM将计算和调度分离,计算通过张量表达式表示,张量表达式在设计上借鉴了 Halide、Darkroom 和 TACO。调度则是针对计算的一系列变换,为了在许多后端实现高性能,必须要支持足够多的调度原语来涵盖不同硬件后端的各种优化而包括tile/fuse/reorder/bind/compute_at等等,通过调度可以挖掘张量计算在特定硬件后端下的极致性能。TVM陆续发展了从基于模版的AutoTVM到基于搜索的Ansor,再到通过DSL tensorIR结合二者优点的Meta Schedule逐渐发展起来的自动调度搜索策略,可以针对不同的目标硬件平台来自动搜索的更优卸载方式,从而实现平台相关的深度优化。
MLIR是由Google 提出的一个能够快速构建领域编译器的基础设施,提出了一种构建可重用、可扩展编译器基础结构的新方法。其核心思想是利用多层次中间表示来解决软件的碎片化问题,减少构建Domain Specific Compiler的开销。MLIR虽然目前主要用于机器学习领域,但在设计上是通用的编译器框架,比如也有FLANG(llvm中的FORTRAN编译器)[22],CIRCT(用于硬件设计)[23]等与ML无关的项目。MLIR 提供一系列可复用的易扩展的基础组件,从而使得不同领域的编译开发人员能够快速的搭建领域专用编译器,而且不同领域的编译分析及优化可以被复用。
与 LLVM IR 唯一的中间表示不同,MLIR能通过多层方言(dialect)的设计,表示更高层次的结构和操作,比如神经网络的图结构,张量的计算等。MLIR将一些领域的特性抽象为方言并允许用户自定义新的方言,与此同时,MLIR 提供了不同方言间的转换机制来实现不同方言上编译分析和优化的复用。MLIR执行过程和LLVM一样,IR会通过由Pass组成的优化Pipeline,不断地方言内,方言间变换直到生成最终的IR,然后被lower到底层的通用IR上进行代码生成。MLIR不仅仅是一个中间表示,而是一个新的编译器基础设施。近年来,学术界和工业界也在MLIR 上开展了很多领域编译优化的工作。如下图所示的将TensorFlow XLA 接入到了MLIR 的例子。上层的模型输入为TF Graph,在MLIR架构下逐层变换到HLO,LHLO,Affine,Vector等更低层次的方言上,在每级方言上都有对应层次和粒度的优化和调度,如在最高层的HLO适合做融合等。最终生成LLVM IR或SPIR-V等通用中间表示,再调用后端通用编译器完成最终代码生成。这部分更详细的讨论可以参考“编译器与IR的思考: LLVM IR,SPIR-V到MLIR”
MLIR在Tensorflow XLA上的实现[25]
一方面,国内学术界在AI编译系统和AI加速器体系结构等方面有很多研究突破,包括但不限于语言,编译,软硬件系统设计等方面。例如:针对目前的张量优化只考虑了完全等价变换,为张量程序优化引入了部分等价变换的优化和对应的纠正机制的PET[26];通过语言层面引入对tensor的细粒度控制,包括tensor的不规则索引等,避免了大量冗余计算的FreeTensor[27];通过特定于GNN网络的图运算符抽象做优化的uGrapher[28];将硬件抽象设计为IR以支持更多intrinsic 原语的AMOS[29];通过基于残差的精度细化技术,控制量化误差,在性能和精度之间进行权衡的QUANTENSOR[30];根据优化目标配置实现云-移动部署的性能功耗综合优化的DNNTune[31];面向任意精度计算(Arbitrary Precision Computing:APC)的Cambricon-P[32]体系结构,等等。
另一方面,工业界结合各厂家自身业务的需求,在AI基础设施和系统技术上不断优化和探索,在不同的维度持续发力,也贡献了很多开源项目。在AI编译基础设施方面,华为的MindSpore社区[33]提供了一个主要面向华为的昇腾处理器后端的云边端全场景开放AI推理和训练框架。其在包括图算联合优化,大规模分布式自动并行,自动算子生成等多项技术上做出了探索和贡献。阿里巴巴的PAI团队也专注于编译优化,探索了XLA,TVM,MLIR等多条技术路线,目前在大颗粒算子融合技术,以及GPU上访存密集型算子的融合优化上也取得不错的效果,并在MLIR这条技术路线上扩充了框架应对动态输入shape上的能力[34]。此外,国内的大型互联网公司,AI技术和芯片公司等都在面向AI的编译技术上有越来越多的投入,极大推进了相关技术的发展。
内容中包含的图片若涉及版权问题,请及时与我们联系删除
评论
沙发等你来抢