深度学习编译器的理解

参考介绍https://blog.csdn.net/just_sort/article/details/114892689添加链接描述
本质上技术把模型转换成硬件能识别的机器码,然后这个过程需要优化,并且能适配特定的硬件,最终的落地还是芯片和硬件

为什么需要深度学习编译器?

深度学习编译器这个词语,我们可以先拆成两个部分来看。

首先谈谈深度学习领域。从训练框架角度来看,Google的TensorFlow和FaceBook的Pytorch是全球主流的深度学习框架,另外亚马逊的MxNet,百度的Paddle,旷视的MegEngine,华为的Mindspore以及一流科技的OneFlow也逐渐在被更多人接受和使用。这么多训练框架,我们究竟应该选择哪个?如果追求易用性,可能你会选择Pytorch,如果追求项目部署落地,可能你会选择TensorFlow,如果追求分布式训练最快可能你会体验OneFlow。所以这个选择题没有确定答案,在于你自己的喜好。从推理框架角度来看,无论我们选择何种训练框架训练模型,我们最终都是要将训练好的模型部署到实际场景的,在模型部署的时候我们会发现我们要部署的设备可能是五花八门的,例如Intel CPU/Nvidia GPU/Intel GPU/Arm CPU/Arm GPU/FPGA/NPU(华为海思)/BPU(地平线)/MLU(寒武纪),如果我们要手写一个用于推理的框架在所有可能部署的设备上都达到良好的性能并且易于使用是一件非常困难的事。

一般要部署模型到一个指定设备上,我们一般会使用硬件厂商自己推出的一些前向推理框架,例如在Intel的CPU/GPU上就使用OpenVINO,在Arm的CPU/GPU上使用NCNN/MNN等,在Nvidia GPU上使用TensorRT。虽然针对不同的硬件设备我们使用特定的推理框架进行部署是最优的,但这也同时存在问题,比如一个开发者训练了一个模型需要在多个不同类型的设备上进行部署,那么开发者需要将训练的模型分别转换到特定框架可以读取的格式,并且还要考虑各个推理框架OP实现是否完全对齐的问题,然后在不同平台部署时还容易出现的问题是开发者训练的模型在一个硬件上可以高效推理,部署到另外一个硬件上性能骤降。并且从之前几篇探索ONNX的文章来看,不同框架间模型转换工作也是阻碍各种训练框架模型快速落地的一大原因。

接下来,我们要简单描述一下编译器。实际上在编译器发展的早期也和要将各种深度学习训练框架的模型部署到各种硬件面临的情况一下,历史上出现了非常多的编程语言,比如C/C++/Java等等,然后每一种硬件对应了一门特定的编程语言,再通过特定的编译器去进行编译产生机器码,可以想象随着硬件和语言的增多,编译器的维护难度是多么困难。还好现代的编译器已经解决了这个问题,那么这个问题编译器具体是怎么解决的呢?

为了解决上面的问题,科学家为编译器抽象出了编译器前端,编译器中端,编译器后端等概念,并引入IR (Intermediate Representation)的概率。解释如下:

编译器前端:接收C/C++/Java等不同语言,进行代码生成,吐出IR
编译器中端:接收IR,进行不同编译器后端可以共享的优化,如常量替换,死代码消除,循环优化等,吐出优化后的IR
编译器后端:接收优化后的IR,进行不同硬件的平台相关优化与硬件指令生成,吐出目标文件

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

作用

为了不用直接手写机器码,我们可以用汇编语言;为了不用手写汇编,我们开发出了高级语言,并用编译器将我们写的高级语言编译成汇编。因此,传统编译器主要解决的问题是要降低编程的难度,其次是优化程序性能。其输入是高级语言,输出是硬件可执行码。而对于神经网络编译器,其输入是一个深度学习模型(这里可以看作是一种 DSL),输出也是硬件可执行码。即神经网络编译器通常是不需要传统编译器的厚重的前端部分(即词法分析、语法分析、语义分析等)的,其输入直接就是一种描述深度学习模型的IR,我们对这个输入进行优化,并针对特定的硬件目标生成可执行代码。
对于深度学习模型,我们设计神经网络编译器主要是为了提高推理时的速度。即神经网络编译器主要解决的问题是要优化模型的推理性能。另外,为了同时前端简单方便地使用 Python 代码和后端对算子进行高效优化,神经网络编译器通常采用多层IR的形式。由于神经网络编译器是近几年才开始大规模发展的领域,因此,其在设计上会借用一些传统编译器的通用代码优化方式,如表达式化简,常量折叠等。而更关键的是,作为一种专用于深度模型推理的DSL,神经网络编译器可以根据AI模型的常见计算范式(如矩阵乘法、卷积等),做一些更强、更激进的假设,有更 domain specific 的优化。

在这里插入图片描述
DL编译器主要目的是将深度学习框架描述的模型在各种硬件平台上生成有效的代码实现,其完成的模型定义到特定代码实现的转换将针对模型规范和硬件体系结构高度优化。具体来说,它们结合了面向深度学习的优化,例如层融合和操作符融合,实现高效的代码生成。此外,现有的编译器还采用了来自通用编译器(例如LLVM、OpenCL)的成熟工具链,对各种硬件体系结构提供了更好的可移植性。与传统编译器类似,深度学习编译器也采用分层设计,包括前端、中间表示(IR)和后端。但是,这种编译器的独特之处在于多级IR和特定深度学习模型实现优化的设计。

扫描二维码关注公众号,回复: 14340983 查看本文章

AI编译器的定义

在这里插入图片描述

昇思-MindSpore的AI编译器全景图

在这里插入图片描述

深度学习编译器和推理引擎的区别

就目前实际而言,很多时候深度学习编译器也会被当做推理引擎来用,但是深度学习编译器和传统的推理引擎实现会有所不同。在深度学习编译器中,很多时候在后端会被Lower成IR的表示,而优化加速的方式也是IR层面的优化,然后最后的生成也是IR进行Code Generation(这一层的IR往往是很少的,所以Code Generation很快就可以搞完),生成更底层的LLVM IR / OpenCL / CUDA / …,传统的推理引擎往往缺失这一层,更多的会在算子的层面进行实现与优化,如convolution在arm cpu / OpenCL / CUDA分别实现一遍,这样相比深度学习编译器很容易出现某某平台支持,但是换个平台就不支持,这在以TVM为代表的深度学习编译器很少见。深度学习编译器在设备爆炸时的优势会比较明显。

深度学习框架与深度学习编译器区别

目前对于这方面比较浅的理解是:最大的不同点应该体现在与后端硬件映射的粒度或是否自动性上,深度学习框架一般都是图中节点一对一有后端算子,算子手写;而编译器要做的就是不需要这种一对一性,可以对节点进行计算拆分,比如转成for形式和一些细粒度指令(通过像ansor这种自动搜索等的方式)所以我在想现在深度学习编译器这个概念一出来,框架的作用是否将被局限在仅生成模型(计算图)上,如pytorch生成pt模型,或者可以说给model编写者一个编程模型,或许框架的作用本该如此,不应和后端硬件耦合太多

猜你喜欢

转载自blog.csdn.net/qq_15821487/article/details/125536616