算子融合

什么是算子融合

算子融合是一种通过合并计算图中多个算子到一个算子,达到减少计算量和内存访问的优化方法。

  • Conv + BatchNormalization + ReLu融合

从融合后的最终公式可以看出,可以在初始阶段就通过BN的均值和方差(推理阶段BN的均值和方差是常量)更新Conv层的weights和bias参数,这样融合后的算子相当少了一个BN层的操作,既减少了内存访问,也减少了计算量

如何做算子融合

算子分类

当存在多个输入,同时存在多种输入-输出映射关系时,最终的Mapping type由最复杂的那一个决定。Mapping type复杂度递增顺序:One-to-One,Reorganize,Shuffle,One-to-Many,Many-to-Many
注:Many-to-Many包含Many-to-One的类型

算子可融合性

绿色:可以融合,且有收益
黄色:要做profile才能确定是否有收益
红色:没有收益,不融合

计算图基于融合性分块

分块过程:

  1. 随机挑选一个One-to-One 算子节点做为种子节点
  2. 从种子节点往后进行融合,直到没有可以融合的节点,并更新块的Mapping Type
  3. 从种子节点往前进行融合,直到没有可以融合的节点,并更新块的Mapping Type
  4. 重复执行1、2、3,直到没有可用的种子节点

融合代码生成

基于编译生成融合代码(DNNFusion、TVM)

参考

  1. DNNFusion: accelerating deep neural networks execution with advanced operator fusion