[{"data":1,"prerenderedAt":354},["ShallowReactive",2],{"content-query-W5DzaAP2iy":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"date":10,"cover":11,"type":12,"category":13,"body":14,"_type":348,"_id":349,"_source":350,"_file":351,"_stem":352,"_extension":353},"/technology-blogs/zh/639","zh",false,"","大V博文系列：PLDI 2021论文分析(二)","DNNFusion一种深度学习框架算子层融合与加速工具","2021-07-06","https://obs-mindspore-file.obs.cn-north-4.myhuaweicloud.com/file/2021/07/06/9c07ec5b088d4d6db86b67c177aca309.png","technology-blogs","大V博文",{"type":15,"children":16,"toc":339},"root",[17,25,31,44,55,64,76,85,90,98,103,111,124,129,137,142,149,160,165,170,177,182,189,194,199,204,209,216,221,226,231,236,260,271,276,283,288,296,301,308,313,322,327,334],{"type":18,"tag":19,"props":20,"children":22},"element","h1",{"id":21},"大v博文系列pldi-2021论文分析二",[23],{"type":24,"value":8},"text",{"type":18,"tag":26,"props":27,"children":28},"p",{},[29],{"type":24,"value":30},"作者：金雪锋",{"type":18,"tag":26,"props":32,"children":33},{},[34,36],{"type":24,"value":35},"作者主页：",{"type":18,"tag":37,"props":38,"children":42},"a",{"href":39,"rel":40},"https://www.zhihu.com/people/jin-xue-feng",[41],"nofollow",[43],{"type":24,"value":39},{"type":18,"tag":26,"props":45,"children":46},{},[47,49],{"type":24,"value":48},"文章来源：",{"type":18,"tag":37,"props":50,"children":53},{"href":51,"rel":52},"https://zhuanlan.zhihu.com/p/386887676",[41],[54],{"type":24,"value":51},{"type":18,"tag":26,"props":56,"children":57},{},[58],{"type":18,"tag":59,"props":60,"children":61},"strong",{},[62],{"type":24,"value":63},"本次小伙伴们带来的是PLDI 2021的论文《DNNFusion-Accelerating Deep Neural Networks Execution with Advanced Operator Fusion》分析，里面对fusion做了一个分类，很有参考价值",{"type":18,"tag":26,"props":65,"children":66},{},[67,69],{"type":24,"value":68},"论文链接：",{"type":18,"tag":37,"props":70,"children":73},{"href":71,"rel":72},"https://link.zhihu.com/?target=https%3A//dl.acm.org/doi/10.1145/3453483.3454083",[41],[74],{"type":24,"value":75},"https://dl.acm.org/doi/10.1145/3453483.3454083dl.acm.org",{"type":18,"tag":77,"props":78,"children":80},"h2",{"id":79},"背景与动机",[81],{"type":18,"tag":59,"props":82,"children":83},{},[84],{"type":24,"value":79},{"type":18,"tag":26,"props":86,"children":87},{},[88],{"type":24,"value":89},"深度学习网络在编译阶段可以展开为算子图结构，典型的算子如Add, Softmax，Conv等等，由于深度学习网络层数深，结构复杂，生成的算子数量众多，带了巨大的计算资源在和时间的消耗。业界对于加速算子的计算展开了一定研究，比较经典的方法是将多个算子重新组合成一个新的算子，同时对生成的代码进行底层的性能优化，较知名的如TensorfLow XLA, TVM[1]等等。融合成新算子后计算相对于多个单算子分别计算的好处是可以实现内存复用，并提高GPU、CPU、寄存器等计算资源的利用率。之前的研究在进行算子融合变换时对算子的属性要求相对严格，而错过了一些可以融合的优化机会，并没有彻底的利用好硬件性能。我们需要更通用的融合策略，从而能全面覆盖所有可融合场景。",{"type":18,"tag":77,"props":91,"children":93},{"id":92},"本文概述",[94],{"type":18,"tag":59,"props":95,"children":96},{},[97],{"type":24,"value":92},{"type":18,"tag":26,"props":99,"children":100},{},[101],{"type":24,"value":102},"本文提出依据算子属性对算子合理的进行类别划分，按类型融合，具有更好覆盖性和融合识别能力，加速了计算。 模型命名为DNNFusion，主要包括三部分：1）代数化简部分，即将图层上的数学表达替换为更高效的模式 2）算子融合部分，依据自定义的类别划分和融合算法将1或多个算子融合成一个新算子 3）后续优化。",{"type":18,"tag":77,"props":104,"children":106},{"id":105},"方案介绍",[107],{"type":18,"tag":59,"props":108,"children":109},{},[110],{"type":24,"value":105},{"type":18,"tag":112,"props":113,"children":114},"ul",{},[115],{"type":18,"tag":116,"props":117,"children":118},"li",{},[119],{"type":18,"tag":59,"props":120,"children":121},{},[122],{"type":24,"value":123},"代数化简",{"type":18,"tag":26,"props":125,"children":126},{},[127],{"type":24,"value":128},"代数化简是一个在算子层加速中较通用的手段，即将某种特定的tensor计算转化为数学上等价的tensor计算，转化后的计算方式须较转化之前的计算方式计算量更小。下图为几个转化案例：",{"type":18,"tag":26,"props":130,"children":131},{},[132],{"type":18,"tag":133,"props":134,"children":136},"img",{"alt":7,"src":135},"https://pic4.zhimg.com/80/v2-1abb732d06d66e09bbcea76148c48d23_720w.jpg",[],{"type":18,"tag":26,"props":138,"children":139},{},[140],{"type":24,"value":141},"DNNFusion中也应用了代数化简，作者将代数化简分为结合律、分配律和交换律三类，共包含45条结合律化简，38条分配律化简和66条交换律化简。下图具体列举了一些实例。",{"type":18,"tag":26,"props":143,"children":144},{},[145],{"type":18,"tag":133,"props":146,"children":148},{"alt":7,"src":147},"https://pic1.zhimg.com/80/v2-9cef5fde51f29571a5b51a452d312714_720w.jpg",[],{"type":18,"tag":112,"props":150,"children":151},{},[152],{"type":18,"tag":116,"props":153,"children":154},{},[155],{"type":18,"tag":59,"props":156,"children":157},{},[158],{"type":24,"value":159},"算子融合",{"type":18,"tag":26,"props":161,"children":162},{},[163],{"type":24,"value":164},"算子融合时将多个算子融合成一个新算子，可以实现内存复用，并提高计算机资源的利用率。经典工具如TVM 采用相对固定的schedule模板，本文提出了将算子类型分类，并根据类别进行融合的方法，提高了处理过程中的灵活性和覆盖性。",{"type":18,"tag":26,"props":166,"children":167},{},[168],{"type":24,"value":169},"对于算子类别，本文作者将其分为One-to-One，One-to-Many, Many-to-Many, Reorganize, Shuffle五类，具体如下：",{"type":18,"tag":26,"props":171,"children":172},{},[173],{"type":18,"tag":133,"props":174,"children":176},{"alt":7,"src":175},"https://pic1.zhimg.com/80/v2-ceace76722e5b5842f22c24b169306a8_720w.jpg",[],{"type":18,"tag":26,"props":178,"children":179},{},[180],{"type":24,"value":181},"作者给予了各类的数学表达：",{"type":18,"tag":26,"props":183,"children":184},{},[185],{"type":18,"tag":133,"props":186,"children":188},{"alt":7,"src":187},"https://pic4.zhimg.com/80/v2-93031e96833f5aca30c001e3fda4f647_720w.jpg",[],{"type":18,"tag":26,"props":190,"children":191},{},[192],{"type":24,"value":193},"这里面我们考虑input和output tensor中不同index上的数字的映射关系，One-to-One表示",{"type":18,"tag":26,"props":195,"children":196},{},[197],{"type":24,"value":198},"input上的i位与output上i位存在一对一映射关系；One-to-Many表示input上的i位与output上多位是映射关系；One-to-Many表示input上多位与output上多位是映射关系；Reorganize和Shuffle同样也是一对一映射关系，但是二者相对One-to-One的不同是，从input到output的映射存在index的转换，比如input的i位数字可能映射到output的j位数字，其中Shuffle相对于Reorganize更为严格，其index映射关系须为permutation类。",{"type":18,"tag":26,"props":200,"children":201},{},[202],{"type":24,"value":203},"那么对于基础算子我们已经给予好了分类，接下来就是融合策略，在指定融合策略的时候我们只需考虑相邻两个算子是否融合即可，因为当相邻两个算子形成一个融合算子后，我们将这个融合算子视为一个新的独立算子，并通过递归继续考虑其与前后算子是否可以继续融合。",{"type":18,"tag":26,"props":205,"children":206},{},[207],{"type":24,"value":208},"那么如何定义融合后形成的新算子类型呢，作者给出的方案是：如果A和B都是同一种类型x，那么融合后的AB依旧是x；如何A是x，B是y, 那么选取x和y中较复杂的类型来作为AB的类型。具体来说One-to-One的复杂度最低，Reorganize和Shuffle的复杂度居中，One-to-Many 和Many-to-Many的复杂度最高。具体转换关系见下图：",{"type":18,"tag":26,"props":210,"children":211},{},[212],{"type":18,"tag":133,"props":213,"children":215},{"alt":7,"src":214},"https://pic1.zhimg.com/80/v2-a32e8fb554bcf0508c090f0a0e74d168_720w.jpg",[],{"type":18,"tag":26,"props":217,"children":218},{},[219],{"type":24,"value":220},"那么最后一个问题便是：什么时候可以融合呢？",{"type":18,"tag":26,"props":222,"children":223},{},[224],{"type":24,"value":225},"上图中的绿色区域代表一定可以融合的场景，红色区域代表（One-to-Many与Many-to-Many, Many-to-Many与Many-to-Many）代表一定不能融的场景，橙色区域部分代表不确定融合后是否有收益，作者用了ML的方式来根据具体场景来判断是否融合。",{"type":18,"tag":26,"props":227,"children":228},{},[229],{"type":24,"value":230},"具体为什么这么做的原因作者给予了解释：",{"type":18,"tag":26,"props":232,"children":233},{},[234],{"type":24,"value":235},"One-to-One与其它：One-to-One类型与其他类型融合可减少多余数据拷贝，占用寄存器少，融合有收益；",{"type":18,"tag":237,"props":238,"children":239},"ol",{},[240,245,250,255],{"type":18,"tag":116,"props":241,"children":242},{},[243],{"type":24,"value":244},"Reorganize、Shuffle与其它：Reorganize、Shuffle仅在One-to-One上加了特殊点对点映射函数，本质没有变化，理由同a",{"type":18,"tag":116,"props":246,"children":247},{},[248],{"type":24,"value":249},"One-to-Many与Many-to-Many：Expand+Conv为例，Conv希望可以连续的读取内存数据，而Expand可能将该数据打散，性能劣化；",{"type":18,"tag":116,"props":251,"children":252},{},[253],{"type":24,"value":254},"Many-to-Many 与Many-to-Many: Conv+Conv为例，算子过于复杂，影响cache和寄存器的合理使用，性能劣化",{"type":18,"tag":116,"props":256,"children":257},{},[258],{"type":24,"value":259},"Many-to-Many 与One-to-Many:需要分情况讨论：例如Conv+Expand，如Expand只针对一维扩展，则影响不到conv的计算；而Conv+Resize，Resize会影响多个维度的数据，从而影响conv的计算；所以这种模式是否有收益待定。",{"type":18,"tag":112,"props":261,"children":262},{},[263],{"type":18,"tag":116,"props":264,"children":265},{},[266],{"type":18,"tag":59,"props":267,"children":268},{},[269],{"type":24,"value":270},"后续优化",{"type":18,"tag":26,"props":272,"children":273},{},[274],{"type":24,"value":275},"主要包括两点，第一是一些变形算子的消除，比如在一些情况下变形算子的output只被一个算子用，变形后的data locality的好处并不能抵消拷贝数据带来的时间消耗，这种情况会对变形算子进行消除，下图为一个例子：",{"type":18,"tag":26,"props":277,"children":278},{},[279],{"type":18,"tag":133,"props":280,"children":282},{"alt":7,"src":281},"https://pic1.zhimg.com/80/v2-9288c7fe57e3044f7ebc660366381dc4_720w.jpg",[],{"type":18,"tag":26,"props":284,"children":285},{},[286],{"type":24,"value":287},"第二点是从全局角度消除不必要format转化，以Transpose为例，从算子图全局考虑往往会有多个transpose等算子对tensor进行format转换，作者希望在保证结果一致的前提下，尽可能消除不必要的format转换。作者使用了贪心算法，从受format影响最大的复杂算子（Conv、GEMM、Softmax等）出发，为其选取最优format，延伸开来，统一其他算子的format并消除不必要format转换。",{"type":18,"tag":77,"props":289,"children":291},{"id":290},"实验评估",[292],{"type":18,"tag":59,"props":293,"children":294},{},[295],{"type":24,"value":290},{"type":18,"tag":26,"props":297,"children":298},{},[299],{"type":24,"value":300},"作者选取了多种神经网络模型的推理部分进行mobile端实验，实验中DNNFusion会以PatDNN[2](该团队之前提出的针对算子的底层代码加速工具) 为基础，结果如下(OurB代表不开DNNFusion，即为baseline)：",{"type":18,"tag":26,"props":302,"children":303},{},[304],{"type":18,"tag":133,"props":305,"children":307},{"alt":7,"src":306},"https://pic2.zhimg.com/80/v2-68af3789fe35d3a3c0766df34be9a369_720w.jpg",[],{"type":18,"tag":26,"props":309,"children":310},{},[311],{"type":24,"value":312},"可见该模型在mobile端的模型推理上加速效果明显。",{"type":18,"tag":77,"props":314,"children":316},{"id":315},"reference",[317],{"type":18,"tag":59,"props":318,"children":319},{},[320],{"type":24,"value":321},"Reference",{"type":18,"tag":26,"props":323,"children":324},{},[325],{"type":24,"value":326},"1. Tianqi Chen, Thierry Moreau, Ziheng Jiang, Lianmin Zheng, Eddie Yan, Haichen Shen, Meghan Cowan, Leyuan Wang, Yuwei Hu, Luis Ceze, Carlos Guestrin, and Arvind Krishnamurthy. 2018. TVM: An automated end-to-end optimizing compiler for deep learning. In OSDI 2018. 578–594",{"type":18,"tag":26,"props":328,"children":329},{},[330],{"type":18,"tag":37,"props":331,"children":333},{"href":71,"rel":332},[41],[],{"type":18,"tag":26,"props":335,"children":336},{},[337],{"type":24,"value":338},"2. Wei Niu, Xiaolong Ma, Sheng Lin, Shihao Wang, Xuehai Qian, Xue Lin, Yanzhi Wang, and Bin Ren. 2020. Patdnn: Achieving real-time DNN execution on mobile devices with pattern-based weight pruning. In ASPLOS 2020. 907–922",{"title":7,"searchDepth":340,"depth":340,"links":341},4,[342,344,345,346,347],{"id":79,"depth":343,"text":79},2,{"id":92,"depth":343,"text":92},{"id":105,"depth":343,"text":105},{"id":290,"depth":343,"text":290},{"id":315,"depth":343,"text":321},"markdown","content:technology-blogs:zh:639.md","content","technology-blogs/zh/639.md","technology-blogs/zh/639","md",1776506139078]