diff --git a/chapter_frontend_and_ir/intermediate_representation.md b/chapter_frontend_and_ir/intermediate_representation.md index 995e21b..63d0d93 100644 --- a/chapter_frontend_and_ir/intermediate_representation.md +++ b/chapter_frontend_and_ir/intermediate_representation.md @@ -112,21 +112,7 @@ IR。 TorchScript是PyTorch的JIT实现,支持使用Python训练模型,然后通过JIT转换为语言无关的模块,从而提升模型部署能力,提高编译性能。同时,TorchScript IR显著改善了Pytorch框架的模型可视化效果。 -2、TensorFlow - -与PyTorch框架的动态图机制不同,TensorFlow机器学习框架因为其静态图机制而被人熟知。关于静态图和动态图的介绍,请参考第3.3章节。 - -TensorFlow框架同时支持静态图和动态图,是一个基于数据流编程的机器学习框架,使用数据流图作为数据结构进行各种数值计算。为了适配不同的硬件平台,基于静态计算图,TensorFlow采用了多种IR设计,其编译生态系统如图 :numref:`MLIR`所示。蓝色部分是基于图的中间表示,绿色部分是基于SSA的中间表示,各层级在结构和抽象层级上存在较大的差距,转换开销大,而且同一层级的中间表示优化是相互独立的,不利于协同优化。 - -![TensorFlow MLIR](../img/ch04/中间表示-MLIR.svg) -:width:`600px` -:label:`MLIR` - -针对这个问题,TensorFlow团队提出了MLIR(Multi-Level Intermediate -Represent,多级中间表示) -([@2020MLIR]),允许使用TensorFlow和其它机器学习库的项目编译更有效的代码,从而最大程度地利用基础硬件。MLIR是用于现代优化编译器的灵活基础架构,旨在定义一个通用的中间表示,在统一的基础架构中支持多种不同的需求。MLIR采用混合中间表示,允许在同一编译单元中结合多个层级的抽象来表示、分析和转换计算图,利用其模块化、可扩展的特点,解决了各种中间表示之间转换效率和可迁移性不高的问题,从而适配多种硬件平台。 - -3、Jax +2、Jax Jax机器学习框架同时支持静态图和动态图,其中间表示采用Jaxpr(JAX Program Representation) IR。Jaxpr @@ -142,10 +128,43 @@ Form)函数式表达形式,如图 :numref:`Jaxpr`所示。ANF形式将表达 Jax框架结合了Autograd 和 JIT,基于Jaxpr IR,支持循环、分支、递归、闭包函数求导以及三阶求导,并且支持自动微分的反向传播和前向传播。 -4、MindSpore +3、TensorFlow -与PyTorch、TensorFlow、Jax框架相同,MindSpore机器学习框架同时支持静态图和动态图。MindSpore框架采用的是一种基于图表示的函数式中间表示,即MindIR,全称MindSpore -IR。MindIR通过统一的中间表示,定义了网络的逻辑结构和算子的属性,能够消除不同后端的模型差异,连接不同的目标机器。 +TensorFlow框架同时支持静态图和动态图,是一个基于数据流编程的机器学习框架,使用数据流图作为数据结构进行各种数值计算。TensorFlow机器学习框架的静态图机制更为人所熟知。在静态图机制中,运行TensorFlow的程序会经历一系列的抽象以及分析,程序会逐步从高层的中间表示向底层的中间表示进行转换,我们把这种变换成为lowering。 + +为了适配不同的硬件平台,基于静态计算图,TensorFlow采用了多种IR设计,其编译生态系统如图:numref:`TFIR`所示。蓝色部分是基于图的中间表示,绿色部分是基于SSA的中间表示。在中间表示的转换过程中,各个层级的中间表示各自为政,无法互相有效地沟通信息,也不清楚其他层级的中间表示做了哪些优化,因此每个中间表示只能尽力将当前的优化做到最好,造成了很多优化在每个层级的中间表示中重复进行, 从而导致优化效率的低下。尤其是从图中间表示到SSA中间表示的变化过大,转换开销极大。此外,各个层级的相同优化的代码无法复用,也降低了开发效率。 + +![TensorFlow](../img/ch04/中间表示-MLIR.svg) +:width:`600px` +:label:`TFIR` + +针对这个问题,TensorFlow团队提出了MLIR(Multi-Level Intermediate +Represent,多级中间表示) +([@2020MLIR]),允许使用TensorFlow和其它机器学习库的项目编译更有效的代码,从而最大程度地利用基础硬件。MLIR是用于现代优化编译器的灵活基础架构,旨在定义一个通用的中间表示,在统一的基础架构中支持多种不同的需求。MLIR采用混合中间表示,允许在同一编译单元中结合多个层级的抽象来表示、分析和转换计算图,利用其模块化、可扩展的特点,解决了各种中间表示之间转换效率和可迁移性不高的问题,从而适配多种硬件平台。 + +4、MLIR + +针对这个问题,TensorFlow团队提出了MLIR(Multi-Level Intermediate +Represent,多级中间表示) +([@2020MLIR])。MLIR不是一种具体的中间表示定义,而是为中间表示提供一个统一的抽象表达和概念。 开发者可以使用MLIR开发的一系列基础设施,来定义符合自己需求的中间表示, 因此我们可以把MLIR理解为“编译器的编译器”。MLIR不局限于TensorFlow框架, 还可以用于构建连接其他语言与后端(如LLVM)的中间表示。 +MLIR深受LLVM设计理念的影响,但与LLVM不同的是, MLIR是一个更开放的生态系统。 在MLIR中, 没有预设的操作与抽象类型, 这使得开发者可以更自由地定义中间表示,并更有针对性地解决其领域的问题。MLIR通过Dialect的概念来支持这种可拓展性, Dialect在特定的命名空间下为抽象提供了分组机制,分别为每种中间表示定义对应的产生式并绑定相应的Operation, 从而生成一个MLIR类型的中间表示。Operation是MLIR中抽象和计算的核心单元,其具有特定的语意,可以用于表示LLVM中所有核心的IR结构, 例如指令, 函数以及模块等。 如下就是一个MLIR定义下的Operation: + +``` +%tensor = "toy.transpose"(%tensor) {inplace = true} : (tensor<2x3xf64>) -> tensor<3x2xf64> loc("example/file/path":12:1) +``` +- \% tensor: Operation定义的结果的名字, $\%$是为了避免冲突统一加入的。一个Operation可以定义0或者多个结果,它们是SSA值。 +- "toy.transpose": Operation的名字。它是一个唯一的字符串,其中Dialect为Toy。因此它可以理解为Toy Dialect 中的transpose Operation。 +- (\%tensor):输入操作数(或参数)的列表,它们是由其它操作定义或引用块参数的 SSA 值。 +- {inplace = true}:零个或多个属性的字典,这些属性是始终为常量的特殊操作数。在这里,我们定义了一个名为“inplace”的布尔属性,它的常量值为 true。 +- (tensor<2x3xf64>)->tensor<3x2xf64>:函数形式表示的操作类型,前者是输入,后者是输出。尖括号内代表输入与输出的数据类型以及形状, 例如$<2x3xf64>$代表一个形状位2X3, 数据类型为float64的张量。 +- loc("example/file/path":12:1):此操作的源代码中的位置。 + +由于各层中间表示都遵循如上的样式进行定义,所以各个层级的中间表示之间可以更加方便的进行转换, 提高了中间表示转换的效率。各个不同层级的中间表示还可以协同进行优化。 此外,由于中间表示之间不再相互独立, 各层级的优化不必做到极致,而是可以将优化放到最适合的层级。 其他的中间表示只需要先转换为该层级的中间表示,就可以进行相关的优化,提高了优化的效率与开发效率。TensorFlow从图中间表示到SSA中间表示的转换也可以通过使用MLIR来进行多层转换, 使转换更加平滑, 降低了转化的难度。 针对MLIR的更多内容将会在第六章进行介绍。 + +5、MindSpore + +与PyTorch、Jax、TensorFlow框架相同,MindSpore机器学习框架同时支持静态图和动态图。MindSpore框架采用的是一种基于图表示的函数式中间表示,即MindIR,全称MindSpore +IR。MindIR没有采用多层中间表示的结构,而是通过统一的中间表示,定义了网络的逻辑结构和算子的属性,能够消除不同后端的模型差异,连接不同的目标机器。 MindIR最核心的目的是服务于自动微分变换,而自动微分采用的是基于函数式编程框架的变换方法,因此MindIR采用了接近于ANF函数式的语义。MindIR具有以下特点: