TVM: End-to-End Optimization Stack for Deep Learning 论文阅读

TVM: End-to-End Optimization Stack for Deep Learning 论文阅读
摘要很多目前最为流行的深度学习框架如 TensorFlow、MXNet、Caffe 和 PyTorch支持在有限类型的服务器级 GPU 设备上获得加速这种支持依赖于高度特化、供应商特定的 GPU 库。然而专用深度学习加速器的种类越来越多这意味着现代编译器与框架越来越难以覆盖所有的硬件。TVM旨在架起多种深度学习前端框架与后端硬件之间的桥梁能够将深度学习模型高效地部署到异构的后端上并进行自动调优。轻松地将深度学习工作负载部署到各种硬件目标上包括嵌入式设备、gpu、fpga和asic例如TPU它们在内存组织、计算等方面存在显著差异。1. 引言深度学习模型现在可以识别图像处理自然语言并在具有挑战性的策略游戏中击败人类。现代硬件稳步提升的计算能力在深度学习中存在的普遍性和在许多问题领域的相关性中发挥了突出作用。许多最流行的深度学习框架如TensorFlowMXNetCaffe和PyTorch通过将支持集中在一小类服务器级GPU设备上来利用现代硬件的强大功能 - 这种支持取决于高度工程化的使用和供应商特定的GPU库。然而专业深度学习加速器的数量和多样性在野外迅速增加。这些加速器引入了采用挑战因为它们引入了现代编译器和框架无法处理的新硬件抽象。在当前特定方式中为各种硬件后端提供各种深度学习框架的支持是不可持续的。最终目标是轻松地将深度学习工作负载部署到各种硬件目标包括嵌入式设备GPUFPGA和ASIC例如TPU这在内存组织计算等方面存在显着差异如图1所示。鉴于这些要求开发可以将深度学习程序的高级规范降低到任何硬件后端的低级优化代码的优化框架至关重要。当前的深度学习框架依赖于计算图形中间表示来实现优化例如自动微分和动态内存管理[3,7,4]。但是图形级优化通常过于高级无法处理硬件后端特定的操作员级转换。另一方面深度学习框架所依赖的当前运营商级库过于严格且专业化无法轻松跨硬件设备移植。为了解决这些弱点我们需要一个编译器框架它可以在图形和操作员级别上公开优化机会从而在硬件后端提供有竞争力的性能。图 1CPU、GPU 与类 TPU 加速器需要不同的片上存储架构和计算基元。在生成优化代码时我们必须考虑这一问题图 2TVM堆栈图。当前的堆栈支持来自许多深度学习框架的描述并针对主要的CPUGPU和专用加速器。基本优化挑战深度学习的优化编译器需要公开高级和低级优化。我们总结了计算图级别和张量运算符级别的四个基本挑战高级数据流重写不同的硬件设备可能具有截然不同的内存层次结构因此启用运算符融合和优化数据布局的策略对于优化内存访问至关重要。跨线程的内存重用现代GPU和专用加速器具有可跨计算内核共享的内存。传统的无共享嵌套并行模型不再是最优的。优化内核需要加载共享内存上的线程之间的协作。Tensorized计算内在函数最新的硬件提供超越向量运算的新指令如TPU中的GEMM运算符或NVIDIA Volta中的张量核。因此调度过程必须将计算分解为张量算术内在函数而不是标量或向量代码。延迟隐藏虽然具有同步多线程和自动管理缓存的传统架构隐含地隐藏了现代CPU / GPU中的延迟但专门的加速器设计通常倾向于更精简控制并且将大部分调度复杂性转移到编译器堆栈。但是必须谨慎执行调度以隐藏内存访问延迟。TVM端到端优化堆栈我们提供TVM如图2所示这是一个端到端优化编译器堆栈用于降低和调整深度学习工作负载到各种硬件后端。TVM旨在分离算法描述调度和硬件接口。这个原则受到Halide [22]的计算/调度分离的启发但通过将调度与目标硬件内在函数分离来扩展概念。这种额外的分离支持新型专用加速器及其相应的新内在函数。TVM提供了两个优化层用于解决第一个调度挑战的计算图优化层以及具有新调度原语的张量优化层以解决剩余的三个挑战。通过组合这些优化层TVM可以从大多数深度学习框架中获取模型描述执行联合高级和低级优化并为后端生成特定于硬件的优化代码例如Raspberry PiGPU和基于FPGA的专用加速器。我们的论文做出了以下贡献我们构建了一个端到端的编译优化堆栈允许将高级框架包括CaffeMXNetPyTorchCaffe2CNTK中指定的深度学习工作负载部署到各种硬件后端包括CPUGPU和基于FPGA的加速器。我们确定了在跨多种硬件后端为深度学习工作负载提供性能可移植性方面的主要优化挑战。我们引入了新颖的调度原语以利用跨线程内存重用新颖的硬件内在函数和延迟隐藏。我们在基于FPGA的通用加速器上评估TVM以提供有关如何针对专用加速器进行最佳定位的具体案例研究。我们的编译器生成的可部署代码与最先进的供应商特定库具有竞争性并且可以针对新的专用加速器后端。在本文的其余部分安排如下。我们在第2节中描述了图优化在第3节中描述了张量算子调度。我们在这两个部分中包含实验结果以定量评估我们提出的优化。我们将在第4节讨论运行时支持。我们的端到端评估在第5节中。相关工作在第6节中讨论。图 3双层卷积神经网络的示例计算图。图中的每个节点表示消耗一个或多个张量并产生一个或多个张量的操作。可以通过属性来参数化张量操作以配置其行为例如填充或步幅。2. 优化计算图计算图计算图是在深度学习框架中表示程序的常用方法[3, 6, 7, 4]。图3示出了两层卷积神经网络的示例计算图表示。这种高级表示与低级编译器IR如LLVM之间的主要区别在于中间数据项是大型多维张量。TVM利用计算图形表示来应用高级优化节点表示静态已知维度的张量上的操作边缘表示张量操作之间的数据流数据依赖性。计算图提供了计算任务的全局视图但避免指定每个计算任务需要如何实现。可以在图上执行静态存储器规划传递以预分配存储器以保持每个中间张量。图6融合的操作张量化操作之间的比较指示数据布局变换。图 4TVM中的高级数据流优化图 5操作融合传递的规则图 6 卷积、批量卷积、RELU的融合与非融合操作在NVIDIA Tesla K80上的表现二者都由TVM生成图 7数据布局要求可能受到张量的影响这里是2×2结果。此分配阶段类似于传统编译器中的寄存器分配过程。与 LLVM IR类似可以将计算图转换为功能等效的图以应用优化。例如可以应用常量折叠传递来预先计算可以静态确定的图形部分从而节省执行成本。图4概述了在TVM中实现的新颖图形级优化运算符融合和数据布局转换。操作员融合将多个操作员融合在一起是一种优化可以大大缩短执行时间特别是在GPU和专用加速器中。我们的想法是将多个运算符组合在一起而不会将中间结果保存回全局内存。具体而言我们认识到四类图运算符内射一对一映射简化复杂可熔可以融合元素映射到输出和不透明不能融合。我们应用图5中列出的规则将计算图转换为融合版。图6通过比较三个工作负载中融合和非融合版本的性能来演示此优化的影响。数据布局转换张量操作是计算图的基本运算符。涉及计算的张量可以在不同的操作中具有不同的布局要求。例如深度学习加速器可能会利用张量化操作要求将数据平铺到块中以优化访问位置。图7显示了如何转换矩阵的数据布局以适应其数据上的张量化操作。优化数据布局首先要指定每个运算符的首选数据布局因为约束条件规定了它们在硬件中的实现。然后如果数据布局不匹配我们将在生产者和消费者之间执行适当的布局转换。图 8TVM中用于算法描述的张量表达式语言。每个计算操作都包含输出张量的形状以及描述如何计算输出张量的每个元素的表达式。图形级优化的局限性虽然高级数据流图优化可以极大地提高深度学习工作负载的效率但它们只能与运算库提供的一样有效。目前支持运算符融合的少数深度学习框架要求运算符库提供融合模式的实现。随着定期引入更多网络运营商可能的融合内核数量可能会急剧增长。当针对越来越多的硬件后端时这种方法不再可持续因为所需数量的融合模式实现与需要支持的数据布局数据类型和硬件加速器内在函数的数量组合增长。为后端特定运营商的这个庞大空间手工操作运算符内核是不可行的。为此我们提出了一种代码生成方法可以在下一节中生成张量运算符。3. 张量优化操作本节介绍了TVM如何为各种硬件后端生成相同运算符的精细版本。3.1. 张量表达式语言我们引入了一种数据流量张量表达式语言来支持自动代码生成。与高级计算图语言不同其中张量操作的实现是不透明的每个操作都以索引公式表达式语言描述如图8所示。我们的张量表达语言来自Halide [22]Darkroom [13]和TACO [18]等语言。我们的张量表达式语言支持常见语言如C语言中的常见算术和数学运算。我们明确地引入了一个可交换减少运算符以便轻松地跨多个线程安排可交换减少。我们进一步介绍了一种高阶扫描运算符它可以组合基本的计算运算符以便随着时间的推移形成循环计算。TVM计算操作还支持缩放元组之间的减少从而可以轻松支持argmax等功能。该表示可以描述高级数据流图中使用的所有张量操作并涵盖深度学习中展示的常见模式。3.2. 时间表空间给定张量表达式为每个硬件后端创建高性能实现仍然具有挑战性。作为示例图9突出显示了应用于CPUGPU和深度学习加速器设计的典型优化。每个优化的低级程序都是调度策略的不同组合的结果给内核编写者带来了很大的负担。我们采用从Halide [22]中解决计划描述与计划优化的原则。计划是将计算描述降低到后端优化实现的特定规则。我们的想法是正式建模时间表空间和用于遍历此空间的转换从而提供生成低级代码的不同方法。TVM的调度空间如图10所示。图 9矩阵乘法代码示例说明每个硬件后端公开的突出优化挑战。CPU需要跨并行组进行平铺和工作分配以优化缓存局部性。GPU需要线程协作以允许线程组之间的共享内存重用。ASIC和FPGA加速器利用张量计算并依赖显式同步来隐藏内存访问延迟。为了快速浏览计划空间我们需要提供有效的计划基元来转换计划。图11显示了TVM中使用的常见调度基元的集合。许多这些原语反映了高性能计算中的实践。我们采用Halide的有用调度原语并引入新的原语来解决GPU和专用硬件加速器带来的挑战。我们将在接下来的三个小节中详细描述这些原语。3.3. 嵌套并行与合作并行编程是提高深度学习工作负载中计算密集型内核的效率的关键。现代GPU提供大规模并行性要求我们将并行编程模型烘焙到调度转换中。大多数现有解决方案采用并行编程模型称为嵌套并行程序这是一种fork-join并行机制。具体而言我们可以使用并行调度原语来并行化数据并行任务。每个并行任务可以进一步递归地细分为子任务以利用目标体系结构上的多级线程层次结构例如GPU中的线程组。我们将此模型称为无共享嵌套并行性因为一个工作线程无法在同一并行计算阶段查看其兄弟的数据。兄弟线程之间的交互发生在连接阶段当子任务完成时下一阶段可以消耗前一阶段产生的数据。该编程模型不允许线程彼此协作以便在同一并行级内执行集体任务。图12提供了证明此限制的矩阵乘法示例。GPU上的矩阵乘法需要将工作划分为在线程组之间分布的切片然后分配给每个单独的线程。在无共享嵌套并行性下每个线程必须在还原阶段独立地获取其计算块所需的数据。1无共享方法的更好替代方案是跨线程协同获取数据。这种模式在使用CUDAOpenCL和Metal等语言的GPU编程中是众所周知的但尚未实现为调度原语。我们将内存范围的概念引入调度空间以便可以将阶段标记为共享。如果没有内存范围自动范围推断会将相关阶段标记为线程本地如图12所示。共享任务需要计算组中所有工作线程的依赖关系。通过使用线程绑定原语在同一组线程中分配加载任务我们可以有效地调度输入数据加载。值得注意的是我们被迫使用相同的线程来处理共享工作负载的划分因此线程可以在负载和计算阶段持续存在。此改进的实现需要额外的编译器支持具体而言绑定推理算法需要能够通过将所有协作线程的任务合并在一起来推断共享任务的界限。此外需要正确插入内存同步障碍以确保消费者可以看到共享的加载数据。图 10在TVM中计划空间表示。此示例显示了显式平铺矩阵乘法。数据流表示提供指定每个张量元素的计算的表达式。轴关系超图定义了原始环轴和变换环轴之间的双射关系。调度树表示计算结构的循环嵌套结构和生产者存储位置。调度树表示源自Halide [22]特别强调商店位置关系。数据流表示轴关系图和调度树一起描述了可以降低到最右侧面板中显示的代码的调度。图 11TVM中使用的计划基元即转换图 12协作嵌套并行性的时间表。引入了内存范围以实现并行作业之间的任务共享。由此产生的新计划可以更好地利用现代GPU中的共享内存层次结构。图 13 协作并行程序的内存装载图图 14. 矩阵乘法性能比较使用HalideTVM有和没有合作的合作并行程序子的存储器加载模式以及Nvidia K80上的cuBLAS。通过采用新的schedule原语我们可以生成一个接近vendoroptimized性能的内核。3.4. Tensorization推广硬件接口深度学习工作负载具有高算术强度通常可以分解为张量运算符如矩阵-矩阵乘法或1D卷积。这些自然分解导致了最近添加超出向量指令的张量计算基元的趋势。新兴的计算内在函数非常多样化包括矩阵-矩阵乘法[17]矩阵-向量乘积[1]和1D卷积[9]等示例。这些新原语为张量运算符调度创建了新的挑战调度必须使用这些原语来加速。我们将此称为张量化问题类似于SIMD架构的矢量化问题。Tensorization与矢量化显着不同。张量计算基元的输入是多维的具有固定或可变长度并指示不同的数据布局。更重要的是我们不能求助于一套固定的原语因为新的深度学习加速器正在出现带有自己的张量指令。因此我们需要一种能够支持新一代专用加速器的未来解决方案。为了解决这一挑战我们将硬件接口与计划分开。具体而言我们引入了张量内在声明机制。我们可以使用张量表达式语言来声明每个新硬件内在的行为以及与之相关的降低规则。另外我们引入了一个tensorize schedule原语来用相应的张量内在函数替换计算单元。编译器将计算模式与硬件声明匹配并将其降低到相应的硬件内部。图15显示了张量化的示例。张量表达式语言描述了用户的预期计算描述和硬件公开的抽象。Tensorization将时间表与特定的硬件原语分离使TVM易于扩展以支持新的硬件架构。生成的张量调度代码与高性能计算中常见的实践一致将复杂操作分解为重复的微内核调用序列。因此我们也可以使用tensorize原语来利用手工组装微内核这在某些平台上可能是有益的。例如在AMD Vega GPU上将半精度GEMM张量化为手工微内核可以比最佳非张量版本产生超过的加速。图 16具有显式同步的低级程序。此示例演示如何计算。硬件包含两个需要显式同步的指令流。仔细制作同步消息可以在指令流之间执行重叠。图 17降低使用虚拟线程转换高级并行程序到显式同步程序模型的过程。3.5. 编译器支持延迟隐藏延迟隐藏是指通过计算重叠内存操作以最大化内存和计算利用率的过程。它需要不同的策略具体取决于所针对的硬件后端。在CPU上内存延迟隐藏是通过同步多线程[11]或硬件预取技术[16,8]隐式实现的。GPU依赖于许多线程的快速上下文切换以最大限度地利用功能单元[26]。另一方面专门的深度学习加速器通常倾向于更精简控制并将此问题转移到编译器堆栈。图16演示了如何期望编译器显式处理遵循解耦访问/执行原理的流水线深度学习加速器的数据依赖性[23,17]。我们假设硬件流水线由内存和计算阶段组成这些阶段可以在每个阶段由独立指令流控制的情况下同时执行。显式同步指令用于在流水线级之间发送信号以指示给定任务何时完成以便下一个从属级可以开始消耗或覆盖数据。这种类型的显式依赖性跟踪在具有FIFO队列的硬件中实现并且直接控制程序员和编译器如何执行硬件任务。通过使用硬件公开的低级同步原语我们可以有效地隐藏延迟。使用显式同步操作在如此低级别的硬件编程是一项艰巨而艰巨的任务。为了减轻程序员的负担我们提供了一个虚拟线程调度原语允许程序员指定一个高级数据并行程序TVM自动降低到低级显式数据依赖程序。降低过程如图17所示。算法以高级并行程序开始然后插入必要的同步指令以保证每个线程内操作的正确执行顺序。最后将所有虚拟线程的操作交错到一个单独的线程中。图 18降低过程可视为虚拟化。降低是正确的。降低后保留原始虚拟流中每个发送者/接收者对之间的顺序。图19延迟隐藏在基于FPGA的硬件线程本地指令上的影响流到硬件中较少量的物理指令流。只要加速器设计运行ResNet推断虚拟线程降低的正确性虚拟线程的错误交错可能导致死锁。从概念上讲在降低之前每个线程都有自己的私有虚拟指令流。降低过程将这些虚拟指令流的指令映射到有限的物理指令流中。此过程需要正确性保证因为物理指令流之间的物理消息队列需要在线程之间共享以传递依赖性。只要根据图18中显示的规则保留排序我们就可以证明降低是正确的。以下定理为这种降低过程的正确性提供了必要且充分的条件。定理3.1。设降低后指令的部分顺序在降低之前设置所有成对的推送弹出指令。发送者发送的每个推送消息都会被相应的pop指令接收降低是正确的当且仅当换句话说同步消息的接收者的相对顺序需要与每个发送 - 接收对的发送者的相对顺序相同。证明了这种情况。证明。矛盾证明。让a成为物理队列中的第一个发送者将其消息发送给错误的接收者d。然后是。a c因为a是发送错误消息的第一个发件人。由于定理条件b d这意味着b在某些发送方h之前从队列中弹出消息而由于消息队列的FIFO属性而在h a中弹出消息。这与以下事实相矛盾a是队列中的第一个发送方发送给错误的接收方h也发送给错误的接收方。当每个虚拟指令流降低到物理指令流时可以通过以循环方式迭代虚拟线程来强制执行该条件。这种情况不仅适用于两个物理指令流的情况而且还可用于将线程虚拟化为任意数量的物理指令流。图 20. TVM运行时中的RPC支持可以轻松交叉编译部署和配置嵌入式设备。延迟隐藏的硬件评估我们证明了延迟隐藏在自定义硬件加速器设计上的有效性我们将在5.3小节中对其进行更深入的描述。我们在加速器上运行ResNet的每一层并使用TVM生成两个时间表一个具有延迟隐藏一个没有。具有延迟隐藏的调度在程序上应用虚拟线程以隐藏内存访问延迟。结果显示在图19中。通过隐藏将数据加载到加速器中的一些延迟总体延迟隐藏在每个内核上实现了7到54的延迟减少。在计算资源方面没有延迟隐藏最多可以获得52的利用率而延迟隐藏可以获得高达74的利用率。4. 代码生成与运行支撑在优化计划之后剩下的任务是生成可以在目标平台上运行的代码并促进生成的内核的部署和配置。代码生成对于数据流声明轴关系超图和调度树的特定元组我们可以通过迭代遍历调度树来生成降低的代码推断输入张量的相关边界使用轴关系超图并在低级代码中生成循环嵌套。代码被降低为命令式C风格循环程序的内存表示。我们在此过程中重用了Halide的变体循环程序数据结构。我们重复使用Halide中的传递以用于常见的降低基元例如存储器注册和展开以及添加GPU /加速器特定的转换例如同步点检测虚拟线程注入和模块生成。最后循环程序转换为LLVM或CUDA / Metal / OpenCL源代码。运行时支持对于GPU程序我们单独构建主机和设备模块并提供运行时模块系统以使用相应的驱动程序API启动内核。我们使用C运行时API为我们的评估中使用的基于FPGA的深度学习加速器构建驱动程序库该运行时API可以构造指令并将它们推送到目标加速器以供执行。然后我们的代码生成算法将加速器程序转换为对运行时API的一系列调用。自动调整本文着重于提供一种新颖的优化框架以实现深度学习系统的性能竞争编译。我们提供的优化为编译器提供了大量的时间表来探索以便生成具有性能竞争力的代码。我们探索了初步的自动调度技术和自动内联运算的传递。高维卷积矩阵乘法和深度卷积等复杂操作通过一组计划模板自动调整。我们相信将我们的优化与更复杂的搜索技术相结合[20]可以在未来产生进一步的改进。表 1. 在Raspberry Pi上ResNet的卷积运算符上的TVM和NNPack的比较。H / W表示高度和宽度IC表示输入通道OC表示输出通道K表示内核大小S表示步幅大小。表 2Raspberry Pi上MobileNet的深度卷积运算符的TVM和MXKernelMXNet中的本地运算符的比较。H / W表示高度和宽度C表示通道M表示乘数K表示内核大小S表示步幅大小。由于深度卷积架构相对较新且尚未通过DNN库进行优化因此我们选择了MXNet中的简单实现。TVM生成的运营商在MXNet中胜过执行。远程部署Profling TVM还包括用于在嵌入式设备上轻松实现配置和自动调整的基础架构。传统上针对嵌入式设备进行调优需要在主机端进行交叉编译复制到目标设备并对执行进行计时。此过程必须手动完成并阻止编译运行和自动调整流程的自动化。我们在编译器堆栈中提供远程函数调用支持通过RPC接口我们可以在主机编译器上编译程序上传到远程嵌入式设备远程运行函数并在主机上的相同脚本中访问结果图20。我们发现这种方法非常有助于优化嵌入式设备如Raspberry Pi和基于FPGA的加速器的工作负载。5. 评估我们在三种类型的平台上评估TVM--嵌入式CPU服务器级GPU以及在基于低功耗FPGA的SoC上实现的深度学习加速器。基准测试基于真实世界的深度学习推理工作负载包括ResNet [12]和MobileNet [15]。我们将我们的方法与现有的深度学习框架进行比较包括依赖于高度设计的供应商特定库的MxNet [7]和TensorFlow [2]。5.1. Raspberry Pi评估我们在Raspberry Pi 3B四核1.2GHz上评估了TVM的性能。我们使用Apache MXNetcommit35ceea作为我们的基线系统。MXNet使用NNPack中最先进的运算符commit57fc2c进行卷积使用OpenBLAS进行矩阵乘法。我们仔细调整了基线以获得最佳性能。我们还在NNPack实现中启用了Winograd卷积用于3x3卷积和多线程。表 3Raspberry Pi的端到端实验结果图 21NVIDIA Tesla K80和GTX 1080上的TVMMXNetTensor流媒体和Tensor流媒体XLA之间的ResNet和MobileNet工作负载的GPU端到端比较。表1和表2显示了TVM张量运算符与ResNet和MobileNet的手动优化运算符之间的比较。我们观察到TVM生成的运算符优于针对神经网络工作负载的手动优化NNPack版本。结果还证明了TVM能够快速优化新兴的张量运算符例如现有DNN库不支持的深度[15]卷积运算符。最后表3显示了两个网络工作负载的端到端比较其中TVM分别比ResNet和MobileNet的基线性能高出2倍和12倍。5.2. GPU评估我们首先在NVIDIA Tesla K80和GTX 1080 GPU上比较TVMMXNetTensor流量和Tensor流量XLA的ResNet和MobileNet工作负载的端到端性能。MXNet和Tensor流程都使用cuBLAS v8和cuDNN v7用于ResNet工作负载并在MobileNet工作负载中实现自己的深度卷积版本因为此操作相对较新并且最新库尚不支持。另一方面Tensorflow XLA使用JIT编译。图21显示除了GTX 1080上的ResNet工作负载其中TVM比MXNet稍微慢一点 (1.6)之外TVM在几乎所有配置下的端到端执行时间都优于其他框架。与Tesla K80上ResNet和MobileNet的第二次最佳实施相比TVM将推理时间缩短了22和5而GTX 1080上的MobileNet则推迟了7.7。我们对Nvidia Tesla K80的Resnet和MobileNet阶段进行了细分比较如表4和表5所示。我们可以看到与特定供应商相比TVM可以生成具有竞争力的GPU内核。这是因为TVM具有大的设计空间来搜索以生成优化的时间表。更重要的是对于深度卷积等新操作表5TVM可以生成优化良好的GPU内核。AMD GPU案例研究为了突出TVM针对多个GPU后端的能力我们尝试将现有的时间表移植到AMD Vega FE Air (gfx900)。从默认的GPU计划模板开始我们处于GTX 1080性能的一个数量级分别为ResNet和MobileNet实现10.2 ms和3.3 ms的端到端时间。在几个小时内快速调整计划进一步提高了ResNet性能约40MobileNet性能提高了约10。这些结果强调尽管AMD和NVIDIA GPU具有表面上不同的架构和不同的指令但TVM通常足以捕捉它们的相似之处主要在于它们的内存层次结构和线程组织。尽管如此我们仍然期望通过AMD GPU特定结构更改默认计划进一步提高性能。5.3. FPGA加速器评估Vanilla Inference Tensor Accelerator我们演示了TVM如何处理我们在FPGA上原型化的通用推理加速器设计中的加速器特定代码生成。我们介绍了Vanilla Inference Tensor Accelerator (VITA)它将以前的加速器提案[19,9,17]的特征提炼成极简主义的硬件架构。我们在此评估中使用VITA来演示TVM生成高效计划的能力这些计划可以针对专门的加速器。图22显示了VITA体系结构的高级硬件组织。VITA被编程为张量处理器以便以高计算强度例如矩阵乘法高维卷积有效地执行操作。VITA可以执行加载/存储操作将阻塞的三维张量从DRAM带入SRAM的连续区域。VITA还为网络参数层输入窄数据类型和层输出宽数据类型提供专用的片上存储器。最后VITA为连续的加载计算和存储操作提供显式同步控制以最大化内存和计算操作之间的重叠。方法我们在低功耗PYNQ板上实现VITA设计该板采用时钟频率为667MHz的ARM Cortex A7双核CPU和基于Artix-7的FPGA架构。在适当的FPGA资源上我们实现了一个时钟频率为200MHz的矩阵向量单元它执行8位值的乘积并在每个周期将它们累加到32位寄存器中。这种VITA设计的理论峰值吞吐量约为102.4GOPS / s。我们为激活存储分配32kB资源为参数存储分配32kB为微代码缓冲区分配32kB为寄存器文件分配128kB。这些片上缓冲器远远不足以为单层ResNet提供足够的片上存储因此可以进行有效内存重用和延迟隐藏的案例研究。端到端的ResNet评估我们利用TVM在PYNQ平台上生成ResNet推理内核并尽可能多地向VITA提供层。我们利用TVM生成仅用于CPU和CPU FPGA实现的调度。由于其较浅的卷积深度第一个ResNet卷积层无法在FPGA上有效地进行淹没而是在CPU上进行计算。然而ResNet中的所有其他卷积层都适合于絮凝。由于VITA不支持这些操作因此还在CPU上执行残差层批量标准化和激活等操作。图23显示了仅CPU执行和CPU FPGA执行之间的ResNet推理时间细分。大部分计算都花费在可以转换为VITA的卷积层上。对于那些卷积层实现的加速是40倍。遗憾的是由于Amdahl定律FPGA加速系统的整体性能受到必须在CPU上执行的工作负载部分的瓶颈。我们设想扩展VITA设计以包含对这些。图 22. 的支持VITA硬件设计概述。图 23. 我们将ResNet工作负载中的卷积转换为基于FPGA的加速器。灰色条对应于不能加速的图层由FPGA驱动因此必须在CPU上运行。FPGA可以通过ARM Cortex A9在浮动卷积层上提供40倍的加速度。其他运营商将进一步减少推理时间。这个基于FPGA的实验展示了TVM适应新架构的能力以及它们所暴露的硬件内在函数。6. 相关工作深度学习框架[3, 6, 7, 4]为用户提供了方便的界面以表达深度学习工作负载并在不同的硬件后端轻松部署它们。虽然现有框架目前依赖供应商特定的运营商库来执行其工作负载但他们可以利用TVM的堆栈来生成更大的硬件设备的优化代码。高级计算图DSL是表示和执行高级优化的典型方式。Tensorflow的XLA [3]和最近推出的DLVM [27]属于这一类。这些工作中计算图的表示是相似的本文还使用了高级计算图DSL。虽然图级别表示对于高级优化是一个很好的选择但它们太高级别无法在各种硬件后端下优化张量运算符。以前的工作依赖于特定的降低规则来直接生成低级LLVM或度假村到供应商制作的库。这些方法需要为每个硬件后端和运营商变体组合进行重大的工程设计。Halide [22]介绍了计算和调度之间的分离原则。我们采用Halide的洞察力并在我们的编译器中重用其现有的有用调度原语。张量运算符调度还与GPU上的其他工作有关[24, 14]也适用于基于多面体的循环变换[5,25]。TACO [18]介绍了一种在CPU上生成稀疏张量运算符的通用方法。Weld [21]是用于数据处理任务的DSL。我们特别关注解决GPU和专用加速器深度学习工作负载的新调度挑战。在这些工作中我们的调度原语可能被用于优化管道。更重要的是我们提供了一个端到端的堆栈可以直接从深度学习框架中获取描述并与高级堆栈一起进行联合优化。尽管趋势域特定的加速器用于深度学习[17,10]但尚不清楚如何构建编译堆栈以有效地针对这些设备。评估中使用的VITA设计提供了一种通用的方法来总结这些加速器的属性并且能够进行关于如何对加速器进行此类编译的具体案例研究。本文提供了一种通用的解决方案通过张量化和编译器驱动的延迟隐藏有效地针对专用加速器。7. 结论我们的工作提供端到端堆栈以解决各种硬件后端的基本优化挑战。我们希望我们的工作可以鼓励更多的编程语言研究编译并为深度学习系统开辟硬件协同设计技术的新机会。我们开源了我们的编译器堆栈并将开源VITA设计以鼓励进一步研究这个方向。参考文献TVM: End-to-End Optimization Stack for Deep LearningTVM: End-to-End Optimization Stack for Deep Learning - 灰信网软件开发博客聚合陈天奇等人提出TVM深度学习自动优化代码生成器_网易订阅TVM: End-to-End Optimization Stack for Deep Learning_诗蕊的博客-CSDN博客_tvm end to endhttps://tongtianta.site/paper/39342