怎样去学习mlir这套框架?
之前已经总结过一篇MLIR入门理解 ,这篇文章同样是对入门MLIR的总结,不同的是从MLIR的演进角度去理解如何学习MLIR。
这篇文章主要从两个角度去讨论MLIR:
- MLIR出现的背景:模型算法越来越复杂,计算量越来越大;
- Dialect的演进:Dialect解决什么问题,需要什么基本模块,基本模块需要哪些扩展。
算法模型的发展带来两个问题:
1. 算子越来越多,越来越复杂;
2. 计算量越来越大。
为了解决这两个问题,需要从两个方面去着手:
- 软件方面:各个框架需要增加更多的算子,方便模型研究人员去使用和验证算法;
- 硬件方面:需要算力更高的硬件去满足模型训练的需求,为使能硬件,需要软件开发人员去弥补框架和硬件之间的gap。
以上便是算法模型发展带来的问题,为解决这两个问题,我们有什么办法?
对第一点,框架适配,各大框架都有一套自己的opset标准,以至于出现了ONNX,想要统一这个标准。软件层面我们面临两大问题:a. 如何方便算法人员使用框架;b. 不同框架的模型如何转换。对a.,算法人员一般使用python,对应的框架也都有python接口,这里不讨论。对b.,不同框架之前,目前大部分情况是把ONNX作为中间接口,比如TensorFlow <-> ONNX <-> PyTorch.
有了ONNX,问题貌似就解决了,不需要MLIR。这里,我们假设所有框架都统一了,只有一种框架,那也就不需要ONNX了,我们是否还需要一套中间模块?
个人理解,我们同样需要一套中间模块,原因是随着计算量增加,除了NV GPU,也出现了一批创业公司去做AI芯片,每家芯片都有自己不同的intrinsic,为了使能硬件,可以像NV那样做一套库,提供一套API。个人理解,这种方式带来的问题是需要大量的人力投入,不适合创企。
综上,MLIR出现的核心背景即:提供一套中间模块(即IR,后面不再拿IR来描述,以模块来描述更容易理解),这个中间模块有两个作用:1. 对接不同的软件框架;2. 对接软件框架和硬件芯片。
进一步思考总结,对接软硬件,主要是为了对接opset。
MLIR提供的解决方案是Dialect和DialectConversion。Dialect用来抽象opset,DialectConversion用来做转换。

Dialect为了能达到对框架和硬件的抽象,提供了如下模块:Type, Attribute, Operation,这三者缺一不可,是MLIR最基本的模块。
DialectConversion为了能达到转换的目的,提供如下模块:ConversionTarget, ConversionPattern, TypeConverter。这里前两个模块是最基本的模块,一个用来表示进行转换的两个Dialect,一个用来匹配符合转换的operation。其实这三个模块也不一定是必需的,只要能完成conversion的功能即可。
以上Dialect和DialectConversion便是MLIR最基础的两个模块。
为了进一步丰富Dialect的表达功能,MLIR提供了transformation模块,用来提供Dialect内部operation的转换变形。同时MLIR给Dialect提供了canonicalization模块,也是做内部转换。Canonicalization 详细讲了为什么要做canonicalization。
目前为止,我们的MLIR模块如下所示:

接着为了增加对Dialect和Operation的标准化和功能扩展,MLIR增加了Constraint, Interface, Trait,方便对Operation进行限制和扩展。

目前为止,还缺少的一点是对Operation的描述,Operation作为Dialect的核心元素,提供对算子的抽象,引入两个模块:Region和Block。同时,为了对在哪里做transformation和DialectConversion进行管理,提供了Pass模块。
到此为止,MLIR的基本功能就已经完备了。
为了统一管理MLIR的Dialect这些模块,让各个Dialect能更好的进行Conversion,MLIR提供了两个tablegen模块,即:ODS和DRR。
ODS:统一Dialect,Operation等Dialect内部类的创建;
DRR:统一Canonicalization, Transformation和Conversion的创建,即PatternRewritter的管理(除此之外,也提供对Pass的管理)。
以上便是MLIR的第一大贡献,也是最基础的功能。但只提供Dialect和DialectConversion解决不了实际应用问题。好比C++语法和STL库,以上这些模块可以比作C++语法,描述如何采用MLIR来实现Dialect和DialectConversion,但所实现的Dialect提供哪些功能,以及如何去弥补软硬件之间的gap,设计一套合适的架构,则是MLIR的另一大贡献。MLIR提供了一些基础的Dialect,方便开发人员去使用,这些Dialect各有侧重。具体讲解,可参考这篇文章:hunterzju:MLIR中Dialects分类及关联
最后,总结MLIR的学习过程如下:
- 学习MLIR基本模块;
- 学习MLIR提供的Dialects,各个Dialects的定位,以及为弥补软硬件gap,提供的这些gap的分类和关联。
关于MLIR基本模块学习过程如下:
- Dialect, Attribute, Type, Operation;想象如果自己去实现,该怎么设计类;
- DialectConversion;想象在自己实现的前四个模块上,如何实现DialectConversion;
- Interface, Constraint, Trait;同样,想象自己会怎么增加这些功能;
- Transformation, Concalization;
- Region, Block:基于1. 设计的Operation,以及4. 增加的Transformation,想象如何对Operation进行抽象,提取出Region和Block的概念;
- Pass;
- 最后才是ODS和DRR。
以上便是个人目前阶段,对MLIR基本功能演进的思考,欢迎大家讨论。