简介
概述
算子融合是整网性能提升的一种关键手段,包括图融合和UB融合。
系统内置了一些图融合和UB融合规则,均为默认开启且能关闭的(如有其他情况,会特殊说明)。当前文档仅对部分融合规则进行介绍。
图融合
客户在使用图方式描述网络时,采用跟硬件无关的融合优化,实现算子性能提升。
图融合是FE根据融合规则进行改图的过程。图融合用融合后算子替换图中融合前算子,提升计算效率。图融合的场景如下:
- 在某一些算子的数学计算量可以进行优化的情况下,可以进行图融合,融合后可以节省计算时间。例如:conv+biasAdd,可以融合成一个算子,直接在L0C中完成累加,从而省去add的计算过程。
- 在融合后的计算过程中可以通过硬件指令加速的情况下,可以进行图融合,融合后能够加速。例如:conv+biasAdd的累加过程,就是通过L0C中的累加功能进行加速的,可以通过图融合完成。
图融合包括:图融合、图拆分融合。
- 图融合:对图上算子进行数学相关的融合,将多个算子融合成一个或者几个算子,该融合跟硬件无关。
如图1所示,conv2D和Batchnorm算子做融合,经过数学公式的推导,将Batchnorm作用到conv2D上,融合成了conv2D算子。
- 拆分融合:将一个算子拆分成多个算子,并将拆分后的多个算子分别和其他算子进行融合。
如图2所示,算子X被拆分成X1和X2两个算子,X1和A进行融合,融合成A1,X2和B、C进行融合,融合成BC1。
UB融合
客户在使用图方式描述网络时,经过图编译对图进行UB融合优化,实现硬件相关的融合优化,提升算子执行性能。
UB即昇腾AI处理器上的Unified Buffer,UB融合是对图上算子进行硬件UB相关的融合。例如两个算子单独运行时,算子1的计算结果在UB上,需要搬移到DDR。算子2在执行时,需要将算子1的输出由DDR再搬移到UB,进行算子2的计算逻辑,计算完之后,又从UB搬移回DDR。
从这个过程会发现1的结果从UB->DDR->UB->DDR。这个经过DDR进行数据搬移的过程是浪费的,因此将1和2算子合并成一个算子,融合后算子1的数据直接保留在UB,算子2从UB直接获取数据进行算子2的计算,节省了一次输出DDR和一次输入DDR,省去了数据搬移的时间,提高运算效率,有效降低带宽。
如何关闭/开启融合规则
用户可以在模型编译时,提前识别是否需要关闭/开启某些融合规则,便于提升编译性能。方法如下:
- ATC模型转换时,通过--fusion_switch_file配置融合开关配置文件路径以及文件名。示例:
--fusion_switch_file=/home/fusion_switch.cfg
- IR模型构建时,通过FUSION_SWITCH_FILE配置融合开关配置文件路径以及文件名。示例:
std::map<AscendString, AscendString> global_options = { {ge::ir_option::FUSION_SWITCH_FILE, "/home/fusion_switch.cfg"}, }; auto status = aclgrphBuildInitialize(global_options);
- 模型训练和在线推理时,通过fusion_switch_file配置融合开关配置文件路径以及文件名。示例:
custom_op.parameter_map["fusion_switch_file"].s = tf.compat.as_bytes("/home/fusion_switch.cfg")
其中,传入的fusion_switch.cfg文件需要用户自己创建,文件名自定义,文件内容示例如下,on表示开启,off表示关闭。
{ "Switch":{ "GraphFusion":{ "ConvToFullyConnectionFusionPass":"on", "SoftmaxFusionPass":"on", "ConvConcatFusionPass":"on", "MatMulBiasAddFusionPass":"on", "PoolingFusionPass":"on", "ZConcatv2dFusionPass":"on", "ZConcatExt2FusionPass":"on", "TfMergeSubFusionPass":"on" }, "UBFusion":{ "FusionVirtualOpSetSwitch":"on" } } }
同时支持用户一键关闭/开启融合规则,如下以关闭为例。
{ "Switch":{ "GraphFusion":{ "ALL":"off" }, "UBFusion":{ "ALL":"off" } } }
需要注意的是:
- 以上一键式关闭融合规则仅是关闭系统部分融合规则,而不是全部融合规则,原因是关闭某些融合规则可能会导致功能问题。
- 一键式关闭融合规则的同时,可以开启部分融合规则:
{ "Switch":{ "GraphFusion":{ "ALL":"off", "SoftmaxFusionPass":"on" }, "UBFusion":{ "ALL":"off", "FusionVirtualOpSetSwitch":"on" } } }
- 一键式开启融合规则的同时,可以关闭部分融合规则:
{ "Switch":{ "GraphFusion":{ "ALL":"on", "SoftmaxFusionPass":"off" }, "UBFusion":{ "ALL":"on", "FusionVirtualOpSetSwitch":"off" } } }
如何查看融合规则执行顺序
模型运行完成后,用户可以通过日志查看融合规则执行顺序。步骤如下。
- 进入日志落盘路径。
默认设置为 $HOME/ascend/log/debug/plog/。该路径可以通过ASCEND_PROCESS_LOG_PATH指定,详细信息请参考《日志参考》。
cd $HOME/ascend/log/debug/plog/
- 查看已生效的融合规则。
执行以下命令可以查看已生效的融合规则,其中effected_times表示融合规则生效次数。
cat * | grep "GraphId" | grep -v "effected_times=0" | grep "effected_times="
输出信息示例如下:
[INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.288.365 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[TfTagNoConstFoldingFusionPass]: pattern=tfTagNoConstFoldingFusion1, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.409.757 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[TfMergeWeightQuantFusionPass]: pattern=tfMergeWeightQuantFusion0, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.909.250 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[Conv2DQuantProcessFusionPass]: pattern=Conv2DQuantProcessFusion, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.910.555 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[V200NotRequantFusionPass]: pattern=notRequantPassPattern1, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.910.644 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[V200NotRequantFusionPass]: pattern=notRequantPassPattern2, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.910.782 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[DeleteNoConstFolding]: pattern=deleteNoConstFoldingFusion0, matched_times=2, effected_times=2. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.940.829 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[ZConcatExt2FusionPass]: pattern=ConcatExt2FusionPass, matched_times=1, effected_times=1. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.943.310 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[ZSplitVDFusionPassV2]: pattern=SplitVDFusionPassV2, matched_times=1, effected_times=1. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.943.398 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[ZSplitVDFusionPass]: pattern=SplitVDFusionPass, matched_times=1, effected_times=1. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:58.946.086 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[SplitConvConcatFusionPass]: pattern=SplitConvConcatFusionPass, matched_times=1, effected_times=1. [INFO] GE(3675829,atc.bin):2025-04-10-20:10:59.079.485 [pattern_fusion_base_pass.cc:259]3675829 RunOnePattern:GraphId[0], GraphFusionPass[FixPipeAbilityProcessPass]: pattern=FixPipeAbilityProcessPass, matched_times=2, effected_times=2.
- 日志中打印的融合规则顺序即为它们的实际执行顺序。
- 也可以通过cat * | grep "GraphId" | grep "effected_times="查看所有匹配过的融合规则。