ARTICLE DETAIL

资讯详情

深耕网站建设、视觉设计与SEO优化的一线实战洞察。

GE图引擎AutoFuse融合策略

GE图引擎AutoFuse融合策略 融合策略【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge简介融合策略需要综合考虑后端能力、性能收益、内存峰值影响对融合行为做出决策和融合处理得到一个相对较优的融合结果。融合策略当前实现的功能如下支持统一的融合规则判断。支持动静态shape依赖符号化。支持融合规模控制。支持融合优先级处理。融合策略模块由CanFuse框架和Backend两部分组成CanFuse框架支持融合判断成环检测内存峰值等融合策略求解功能。Backend支持融合规则融合处理循环合并AscGraph融合、AscBackend融合功能。两部分交互主流程如下图 1CanFuse与Backend交互流程图 ![图1](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/canfuse_backend_interaction_flow.png CanFuse与Backend交互流程图?utm_sourcegitcode_repo_files)由Lowering模块做的融合为一次融合由CanFuse框架做的融合为二次融合二次融合简要流程如下首先进行一轮融合默认做10轮。获取可能融合的所有节点对。从上步得到的可融合节点对中获取融合优先级。根据优先级融合策略的分值进行排序。调用CanFuse框架进行融合规则判断确定是否能进行垂直融合。垂直融合两个融合节点之间有输入输出关系一个节点的输出为另一个节点的输入。进行内存峰值影响分析。确定是否能进行水平融合。水平融合两个节点间没有输入输出关系但是有来自同一个根节点的输入。对两个节点进行融合。融合条件判断判断两个节点是否能融合需要综合CanFuse框架和Backend的判断结果两个结果都必须能融合才能融合本章节分别给出两者的判断条件。CanFuse框架判断融合条件能够减少内存读写可融合的节点间必须有共用的内存比如下图所示Node1的输出1是Node3的输入可以融合Node3和Node4输入都来自Node1的输出1可以融合融合后都可以节省内存搬运。Node2和Node3虽然输入都来自Node1但不是Node1的同一个输出融合后还是要搬入两次不能减少内存搬运因此不能融合。图 1CanFuse判断融合条件1 ![图1](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/canfuse_fusion_condition_1.png CanFuse判断融合条件1?utm_sourcegitcode_repo_files)不会导致成环如下图所示Node1和Node3融合后会导致成环因此不能融合。图 2CanFuse判断融合条件2 ![图2](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/canfuse_fusion_condition_2.png CanFuse判断融合条件2?utm_sourcegitcode_repo_files)不超过最大融合个数限制默认最大融合个数为64融合规模控制主要是防止后端资源超限节点数按照Lowering生成的AscGraph里的节点数进行控制比如下图中的Node1和Node2融合后认为节点总数是9可以融合如果两个节点融合后总数超出阈值就不能融合。图 3CanFuse判断融合条件3 ![图3](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/canfuse_fusion_condition_3.png CanFuse判断融合条件3?utm_sourcegitcode_repo_files)不会导致内存峰值增加过度的融合可能会导致内存峰值的增加需要在执行性能和内存之间进行平衡完备的内存峰值评估是一个比较复杂的过程先按照简单策略进行评估对于节点跨度拓扑排序的ID差值超过设定阈值的不再进行融合当节点可以水平融合的时候会先计算融合后节点的输出内存是否超过13G如果超过13G则不融合。比如下图所示Node2-NodeN之间在融合前是有机会进行内存复用的融合后会导致内存峰值增加因此不能融合。图 4CanFuse判断融合条件4 ![图4](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/canfuse_fusion_condition_4.png CanFuse判断融合条件4?utm_sourcegitcode_repo_files)Backend判断融合条件两个AscGraph的loop轴要能映射能够融合的第一个条件是两个AscBackend的loop轴是否可以映射如果不是一套loop轴则判断融合是没有意义的。由于每个AscBackend是独立进行Lowering的各自的循环轴ID也是独立编号因此可能会存在轴ID不一致的问题典型场景如下图所示AscBackend1做了reduce后少了一个循环轴AscBackend2中z1等同AscBackend1中的z2AscBackend2中z2等同AscBackend1中的z3如果要融合则需要把AscBackend2中的loop轴调整为跟AscBackend1相同。图 5Backend判断融合条件 ![图5](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/backend_fusion_condition.png Backend判断融合条件?utm_sourcegitcode_repo_files)两个AscGraph要能满足Schedule的group merge规则假设对轴做一个抽象分组分为三个groupxgroup、ygroup、rgroup其中xgroup:为Concat类算子引入的一个单独groupConcat轴之前的轴是xgroup之后的是ygroup。**ygroup**Elementwise、Broadcast类型的算子循环轴。**rgroup**Reduce轴的集合。每个AscGraph都会有一个基于循环轴的(xgroup, ygroup, rgroup)根据算子融合规则推导可以判断两个AscGraph是否能融合成一个新的group然后CanFuse依据此规则判断后端Schedule是否支持融合。详细group merge规则请参见生成TilingCase。融合策略求解经过融合条件判断后若发现两个节点可以融合可能会产生多种融合结果的组合例如下图中的融合策略1和融合策略2当存在多种融合策略时需要确定哪种策略为最优。图 1多种融合策略场景 ![图1](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/multi_fusion_strategy_scenario.png 多种融合策略场景?utm_sourcegitcode_repo_files)计算整图的融合策略最优解是较为困难的主要原因有以下两点算法复杂度可能较高一种可行的思路是动态规划求解保证在nlog(n)有难度。性能估算模型不准确没有上板实际测试前难以准确确定融合后的真实性能。基于上述原因追求严格的全局最优解必然涉及大量的整图融合尝试和上板实测从而导致时间复杂度显著增加。因此现阶段采用score贪心的简单融合策略求解算法将图上可融合节点两两配对逐个进行CanFuse判断在可融合的情况下再根据打分进行排序以决定融合的先后顺序最后依次进行融合处理。第一轮融合后的节点将再次重复该处理尝试进行多轮融合最多融合10轮。融合打分规则节省的内存大小计算利用符号实现大小比较越大优先级越高。节点间的临近性计算使用topo序ID的差值越小优先级越高。排序优先级首先比较内存大小当内存大小相同时再比较临近性若临近性也相同则按topo序从小到大排列并进行去重处理最终得到可融合的节点对后续将按此顺序依次进行融合处理。以图2、图3为例简单说明贪心算法的使用如图2所示A、B、C、D组成AB、BC、CD融合节点对排序后确定融合顺序假设融合顺序CD优先AB次之融合后变成CD、AB当处理BC融合时B已经变成ABC已经变成CD最后变成ABCD的融合处理。图 2融合例子1 ![图2](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/fusion_example_1.png 融合例子1?utm_sourcegitcode_repo_files)如图3所示如果排序是AB优先BC次之融合过程会发生变化AB先融合在处理BC融合时由于B已经变成了AB会进行ABC的融合融合成ABC同理CD融合会进行ABCD的融合。图 3融合例子2 ![图2](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/fusion_example_2.png 融合例子2?utm_sourcegitcode_repo_files)两个场景的最终融合结果相同都是ABCD。然而假设A和D不能融合实际结果会有所不同图2的结果是AB、CD而图3的结果是ABC、D。由此可见融合的顺序变化会导致融合过程和结果的不同。当前算法也存在局限性当前的贪心算法仅考虑局部最优可能会导致全局并非最优。例如当A和D不能融合时如果优先融合CD可能会导致ABC无法融合从全局角度来看可能并非是最优策略。融合节点处理AscBackend和AscBackend之间才可以进行融合融合后可以循环轴合并生成的仍然是AscBackend类型无法循环轴合并的则生成FusedAscBackend类型。节点融合需要融合原图中的AscBackend并同时对AscBackend下的AscGraph进行子图融合子图融合过程中需要消除AscGraph上的load和store节点。融合节点处理原则如下示意图如图1所示。根据循环轴是否相同判断两个AscBackend是否能循环轴合并如果能循环轴合并合并AscBackend下的两个AscGraph。具体合并流程可参考图2。如果不能循环轴合并则将AscBackend放入一个新FusedAscBackend的子图中由后端决定生成多个kernel还是一个kernel包含多个循环。不能循环合并的FusedAscBackend与原图中的AscBackend直接融合成一个新FusedAscBackend。FusedAscBackend的子图中可能还存在可以循环合并的AscBackend框架应尽可能地进行循环轴合并。图 1融合节点处理 ![图1](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/fusion_node_processing.png 融合节点处理?utm_sourcegitcode_repo_files)图 2循环轴合并示意图 ![图2](https://raw.gitcode.com/cann/ge/raw/243ea8d2d8f7623dd210c0867dde5782ec5594a9/docs/zh/user_guides/graph_dev/figures/loop_axis_merge_diagram.png 循环轴合并示意图?utm_sourcegitcode_repo_files)【免费下载链接】geGEGraph Engine是面向昇腾的图编译器和执行器提供了计算图优化、多流并行、内存复用和模型下沉等技术手段加速模型执行效率减少模型内存占用。 GE 提供对 PyTorch、TensorFlow 前端的友好接入能力并同时支持 onnx、pb 等主流模型格式的解析与编译。项目地址: https://gitcode.com/cann/ge创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表