1、01AI编译器后端优化介绍
1、AI编译器架构
准备好用Caffe、Tensorflow等训练好的神经网络模型。
神经网络模型转换成Graph IR,然后经过Graph Optimizer的一系列Pass优化, 列如:图算融合、数据排布转换、内存优化、死代码消除等
接着由Graph IR转成Tensor IR,然后经过Ops Optimizer的一系列Pass优化,列如:循环优化、算子融合、存储tiling、张量话等
接着由Tensor IR转成后端可以识别的。
2、后端优化与前端优化的区别
前端优化:输入计算图,关注计算图整体拓扑结构,而不关心算子的具体实现。在AI编译器的前端优化,对算子节点进行融合、消除、化简等操作,使计算图的计算和存储开销最小。
后端优化:关注算子节点的内部具体实现,针对具体实现使得性能达到最优。重点关心节点的输入、输出,内存循环方式和计算逻辑。
3、AI编译器后端部分
1)生成低级IR;
不同AI编译器内部低级IR形式和定义不同,但是对于同一算子,算法的原理实质相同。对于每个具体的算子,需要用AI编译器底层的接口来定义算法,再由编译器来生成内部的低级IR。
2)后端优化;
针对不同的硬件架构/微架构,不同的算法实现的方式有不同的性能,目的是找到算子的最优实现方式,达到最优性能。同一算子不同形态如Conv1x1,Conv3x3,Conv7x7都会有不同的循环优化方式。
3)代码生成;
对优化后的低级IR转化为机器指令执行,现阶段最广泛的借助成熟的编译工具来是实现,非AI编译器的核心内容。如把低级IR转化成为LLVM、NVCC等成功编译工具的输入形式,然后调用其生成机器指令。
为什么后端优化不直接使用传统的通用编译器,如GCC、LLVM呢?
- 深度学习中主要数据为张量(Tensor),传统编译器不擅长对张量计算优化
- 通用编译器主要针对通用编程语言,缺少领域特定语言DSL支持,以及相关的特殊优化。
4、算子分裂
访存密集型
计算密集型
这里不清楚
5、算子优化的挑战
优化手段多样:要在不同情况下权衡优化及其对应参数,对于优化专家来说也是相当耗费精力
通用性与移植性:不同类型的硬件架构差异,使得优化方法要考虑的因素也有很大的不同
优化间相互影响:各种优化之间可能会相互制约,相互影响。这意味着找到最优的优化方法组合和序列就是一个困难的组合优化问题,甚至是NP问题。
6、算子库
目的:针对访存密集型和计算密集型的算子优化。对于一个算子,要实现正确的的逻辑计算或许不难,但要结合硬件能力达到高性能就比较难了,要达到极致的性能更是难上加难。
业界一个最常用的方式是将预置的算子实现封装成计算库。如cudnn,cublas等这样优秀的计算库。
7、自动化生成
如果应对AI领域算子迭代更新快?
如何解决同一算子在多平台移植后一致性问题?
如何面对算子组合爆照问题?如参数多样,融合大算子等
自动kernel生成的方式,它的目标是对于给定算法自动生成目标平台上的高性能的实现
现在自动生成的方法分为:auto tuning、polyhedral
参考:https://www.bilibili.com/video/BV17D4y177bP/