文章目录

  • 前言
  • 一、AI编译器
    • 传统编译器与AI编译器
    • 部署深度模型
  • 二、TPU-MLIP
    • TPU-MLIP整体架构
    • 以YOLOV5s的转换为例
  • 三、MLIR上
    • 什么是MLIR
    • IR中间表达
    • Dialect
      • 什么是Dialect?
      • dialect是怎么工作的?
      • Dialect的内容
      • Opeartion
      • 创建新的dialect(添加新的operation)
        • (1)定义Toy Dialect
        • (2)加载到MLIRContext中
        • (3)定义operation
        • (4)创建流程总结
  • 四、TPU-MLIR前端转换
  • 总结

前言

b站学习视频


一、AI编译器

传统编译器与AI编译器

传统编译器的作用是降低编程难度;
AI编译器的作用主要是为了提高网络的性能;

部署深度模型





二、TPU-MLIP

TPU-MLIP整体架构


在模型转换的过程中会进行推理保证模型转换的正确性。

以YOLOV5s的转换为例



三、MLIR上

什么是MLIR

IR中间表达




Tensorflow 团队较早时采用了多种IR的部署,但是这样导致软件碎片化较为严重,因此Tensorflow 就提出了MLIR,用于统一各类的IR格式,协调各类IR的转换,带来更高的转换效率

Dialect

什么是Dialect?

从源程序到目标程序,要经过一系列的抽象以及分析,通过Lowering Pass来实现从一个IR到另一个IR的转换,但是IR之间的转换需要统一格式,统一IR的第一步就是要统一“语言”,因此MLIR提出了Dialect,各种IR可以转换为对应的mlir Diaect,不仅方便了转换,而且还能随意扩展。

dialect是怎么工作的?

dialect将所有的IR放在了同一个命名空间中,分别对每个IR定义对应的产生式绑定相应的操作,从而生成一个MLIR模型。每种语言的dialect(如TensorFlow dialect、HLO dialect、LLVM IR dialect)都是继承自mlir::dialect,并注册了属性、操作和数据类型,也可以使用虚函数来改变一些通用性行为
整个的编译过程:从源语言生成AST(Abstract Syntax Tree)抽象语法树,借助dialect遍历AST,产生MLIR表达式(此处可为多层IR通过Lowering Pass依次进行分析),最后经过MLIR分析器,生成目标硬件程序。

Dialect的内容

Dialect主要包括以下几个方面:
dialect主要是自定义的Type、Attribute、Interface以及operation构成。operation细分为attribute、type、constraint、interface、trait(属性、类型、限制、接口、特征)。同时存在ODS和DRR两个重要的模块,这两个模块都是基于tableGen模块,ODS模块用于定义operation,DRR模块用于实现两个dailect之间的conversion。

Opeartion

Opeartion是Dialect的重要组成部分,是抽象和计算的核心单元,可以看成是方言语义的基本元素。

%t_tensor = "toy.transpose"(%tensor) {inplace = true} : (tensor<2x3xf64>) -> tensor<3x2xf64> loc("example/file/path":12:1)

下面的代码可以理解为:生成的结果是 %t_tensor,toy dialect,执行的是 transpose 操作,输入数据是 %tensor,能够将 tensor<2x3xf64> 的数据转换成tensor<3x2xf64> 的数据,该 transpose 的位置在 “example/file/path”,第12行,第1个字符。
结构分析如下:
(1)%t_tensor:定义结果名称,SSA值,由%和<t_tensor>构成,一般<t_tensor>是一个整数型数字。
(2)toy.transpose:操作的名称,指明为Toy Dialect的transpose操作。
(3)(%tensor):输入的操作数的列表,多个操作数之间用逗号隔开。
(4){inplace = true}:属性字典,定义一个名为inplace的布尔类型,其常量值为true。
(5)(tensor<2x3xf64>) -> tensor<3x2xf64>:函数形式表示的操作类型,前者是输入,后者是输出。<2x3xf64>号中间的内容描述了张量的尺寸2x3和张量中存储的数据类型f64,中间使用x连接。
(6)loc(“example/file/path”:12:1):此操作的源代码中的位置。
格式图如下所示:

创建新的dialect(添加新的operation)

MLIR中创建新的dialect有两种方式,分别是直接在C++中定义以及在ODS(Operation Definition Specification)中定义,直接在C++中定义需要我们继承Op基类并重写部分构造函数,每个Op都要编写相应的C++代码,缺点是冗余且可读性比较差,所以我们一般使用ODS定义,操作者只需要根据operation框架定义的规范,在一个.td文件中填写相应的内容,使用MLIR的TableGen工具就可以自动生成上面的C++代码。

下面将以Toy语言为例,学习构造Toy Dialect并添加相应的Operation的流程。

Toy语言是为了验证及演示MLIR系统的整个流程而开发的一种基于Tensor的语言。
Toy 语言具有以下特性:

  • Mix of scalar and array computations, as well as I/O
  • Array shape Inference
  • Generic functions
  • Very limiter set of operators and features

(1)定义Toy Dialect

①使用C++语言手动编写

class ToyDialect : public mlir::Dialect {public:explicit ToyDialect(mlir::MLIRContext *ctx);static llvm::StringRef getDialectNamespace() { return "toy"; }void initialize();
};

②使用ODS框架自动生成

在使用ODS定义操作的这些代码,都在Ops.td中,默认位置为
…/mlir/examples/toy/Ch2/include/toy/Ops.td

下面的代码块定义一个名字为Toy的Dialect在ODS框架中,使用let <…> = “…”/[{…}];方式依次明确 name、summary、description 和 cppNamespace各个字段的定义。

def Toy_Dialect : Dialect {let name = "toy";let summary = "A high-level dialect for analyzing and optimizing the ""Toy language";let description = [{The Toy language is a tensor-based language that allows you to definefunctions, perform some math computation, and print results. This dialectprovides a representation of the language that is amenable to analysis andoptimization.}];let cppNamespace = "toy";
}

然后在编译阶段,由框架自动生成相应的C ++代码,也可以使用下面的命令得到生成的C++代码。

${build_root}/bin/mlir-tblgen -gen-dialect-decls ${mlir_src_root}/examples/toy/Ch2/include/toy/Ops.td -I ${mlir_src_root}/include/

下图中右侧是 ODS 中的定义,左侧是自动生成的 C++ 代码。

(2)加载到MLIRContext中

定义好Dialect之后,需要将其加载到MLIRContext中,默认情况下,MLIRContext只加载内置的Dialect,若要添加自定义的Dialect,需要加载到MLIRContext。

// 此处的代码与官方文档中的稍有不同,但实际意义相同。
// 在代码文件 toyc.cpp 中,默认位置为 ../mlir/examples/toy/Ch2/toyc.cpp。
int dumpMLIR() {...// Load our Dialect in this MLIR Context.context.getOrLoadDialect<mlir::toy::ToyDialect>();
...
}

(3)定义operation

有了上面的Toy Dialect,便可以定义操作(Operation)。

# 此操作没有输入,返回一个常量。
%4 = "toy.constant"() {value = dense<1.0> : tensor<2x3xf64>} : () -> tensor<2x3xf64>

①使用C++语言手动编写
operation类是继承于CRTP类,有一些可选的traits来定义行为,下面是ConatntOp的官方定义:

class ConstantOp : public mlir::Op<ConstantOp, // The ConstantOp mlir::OpTrait::ZeroOperands, // takes zero input operandsmlir::OpTrait::OneResult, // returns a single result.mlir::OpTraits::OneTypedResult<TensorType>::Impl> {public:// Op inherit the constructors from the base Op class.using Op::Op; // Return a unique name of the operationstatic llvm::StringRef getOperationName() { return "toy.constant"; }// Return a value by fetching it from the attributemlir::DenseElementsAttr getValue(); // Operations may provide additional verification beyond what the attached traits provide.LogicalResult verifyInvariants(); // Provide an interface to build this operation from a set of input values.// mlir::OpBuilder::create<ConstantOp>(...)// Build a constant with the given return type and `value` attribute.static void build(mlir::OpBuilder &builder, mlir::OperationState &state,mlir::Type result, mlir::DenseElementsAttr value);// Build a constant and reuse the type from the given 'value'.static void build(mlir::OpBuilder &builder, mlir::OperationState &state,mlir::DenseElementsAttr value);// Build a constant by broadcasting the given 'value'.static void build(mlir::OpBuilder &builder, mlir::OperationState &state,double value);
};

定义好 operation 的行为后,我们可以在 Toy Dialect 的 initialize 函数中注册(register),之后才可以正常在 Toy Dialect 中使用 ConstantOp。

// 位于../mlir/examples/toy/Ch2/mlir/Dialect.cpp
void ToyDialect::initialize() {addOperations<ConstantOp>();
}

②使用ODS框架自动生成
首先在ODS中定义一个继承自Op类的基类Toy_Op。
关于Operation与Op的区别:
Operation:对于所有操作的建模,并提供通用接口给操作的实例。
Op:每种特定的操作都是由Op类继承来的,同时它还是Operation *的wrapper,这就意味着,当我们定义一个Dialect的Operation的时候,我们实际上是在提供一个Operation类的接口。

(4)创建流程总结

MLIR在OpBase.td文件中提供了一些公共结构帮助我们定义特定的Op:


TableGen语法简单学习:

Traits在MLIR中用于指定对象的特殊property及约束:

四、TPU-MLIR前端转换


TPU-MLIR前端转换的工作流程为:

其中在初始化Converter部分和生成MLIR文本部分,

前端转换示例:


总结

首先关于传统编译器与AI编译器的区别,我觉得很直接,传统编译器主要是将我们使用的c++、java、python语言编译成机器可以理解的二进制码,而AI编译器主要是用于对模型进行加速。

AI编译器与TPU-MLIP相关推荐

  1. AI编译器与传统编译器的联系与区别

    AI编译器与传统编译器的区别与联系 总结整理自知乎问题 针对神经网络的编译器和传统编译器的区别和联系是什么?. 文中提到的答主的知乎主页:@金雪锋.@杨军.@蓝色.@SunnyCase.@贝壳与知了. ...

  2. AI编译器XLA调研

    文章目录 一.XLA简介 二.XLA在TensorFlow中的应用 2.1 XLA是什么?(tensorflow\compiler\xla) 2.2 TensorFlow怎样转化为XLA (tenso ...

  3. AI编译器TVM部署示例解析

    AI编译器TVM部署示例解析 AI编译器TVM(一)--一个简单的例子 概述 什么是TVM? TVM可以称为许多工具集的集合,这些工具可以组合起来使用,实现一些神经网络的加速和部署功能.这也是为什么叫 ...

  4. 希姆计算:基于 TVM 的 DSA AI 编译器构建

    本文首发自 HyperAI超神经微信公众号~ 大家好我是来自希姆计算的淡孝强,今天我将和三位同事一起来给大家分享如何在 TVM 上支持 NPU. DSA 编译器解决的本质问题就是不同的模型需要部署到硬 ...

  5. Domain Specific Compiling: 领域编译器发展的前世今生 • 面向AI的编译技术

    from: 领域编译器发展的前世今生 • 面向AI的编译技术 作者简介: 张朔铭,博士研究生,正在中国科学院计算技术研究所崔慧敏研究员指导下攻读计算机系统结构博士学位,目前主要的研究方向是AI编译. ...

  6. AICompiler编译器介绍及访存密集算子优化

    简介:欢迎走进阿里云机器学习PAI AICompiler编译器系列.随着AI模型结构的快速演化,底层计算硬件的层出不穷,用户使用习惯的推陈出新,单纯基于手工优化来解决AI模型的性能和效率问题越来越容易 ...

  7. 【2018,中国智能+】新智元10万+热文排行,AI爆发没有看客

    2018年的第一天,大家新年好! 人工智能在去年着实火热了一把,无数新技术.新产品.新公司在这一年爆发,新智元也忠实地记录着这一年的历史. 2017年,人工智能领域发生的几次重要事件,不仅改变着整个行 ...

  8. 传统编译器和DL编译器的调研和理解

    文章目录 Part One : 传统编译器 1.1 前端 1.2 中端 常见的优化 1.3 后端 指令的选择 寄存器分配 指令重排 1.4 总结 Part Two:深度学习编译器 2.1 为什么需要 ...

  9. 论 做 AI 芯片的正确姿势

    https://xie.infoq.cn/article/d5ab8bea53fa8a08406fabf9d 论做 AI 芯片的正确姿势 作者:flow 2020-08-10 本文字数:14908 字 ...

最新文章

  1. P2870 [USACO07DEC]最佳牛线,黄金Best Cow Line, Gold(加强版)(贪心+hash哈希)
  2. 1CCTableView的使用,TableView响应和小格子tableView实现
  3. python删除字符串_Python3 - 删除字符串中不需要的字符
  4. 软件:推荐五款超级好用的电脑小众软件,值得收藏!
  5. 爬虫代码分析(1)--下载小说
  6. 电源层和地线层完整性规则_射频电路设计实例以及一些经常遇见的问题
  7. SeetaFace人脸识别系统
  8. 西门子200PLC指令详解——比较指令
  9. 计算机考研专业课——c语言
  10. 解决树莓派中文显示框框乱码
  11. 如何添加油猴脚本用以模拟点击网页按钮
  12. C语言 母牛生小牛问题 多组测试数据
  13. iphone8引发的AR大事件
  14. centos7解决hadoop2.6.4多次格式化导致的slave节点datanode无法启动的问题
  15. OTA全称为Over-The-Air technology(空中下载技术)
  16. 谈我所经历的区块链历程
  17. 探讨mos管串并联分裂问题
  18. 剪辑软件怎么加声音?
  19. 惠普软件技术总监赵大平:IT与业务的结合
  20. 第8天:布局翘楚 - Grid 布局概述

热门文章

  1. 数据挖掘期末复习01-02
  2. zuiqingchun4
  3. Android 高德地图 Polyline 实时绘制行动轨迹
  4. 安装gi的时候回退root.sh的执行
  5. 用ClickHouse在GitHub上数星星
  6. 英文文章单词自动查找脚本
  7. python编码格式 兼容中文_python中文编码(汉字乱码问题解决方案)
  8. c语言合并两个顺序表算法,顺序表的两种合并操作(C语言)
  9. php计算笛卡尔积批量生成电商sku列表
  10. Win10如何启用Administrator账户