算子融合
什么是算子融合
算子融合是一种通过合并计算图中多个算子到一个算子,达到减少计算量和内存访问的优化方法。
- 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才能确定是否有收益
红色:没有收益,不融合
计算图基于融合性分块
分块过程:
- 随机挑选一个One-to-One 算子节点做为种子节点
- 从种子节点往后进行融合,直到没有可以融合的节点,并更新块的Mapping Type
- 从种子节点往前进行融合,直到没有可以融合的节点,并更新块的Mapping Type
- 重复执行1、2、3,直到没有可用的种子节点
融合代码生成
基于编译生成融合代码(DNNFusion、TVM)
参考