热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

TVM编译器的介绍及用法

这篇文章主要讲解了“TVM编译器的介绍及用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“T

这篇文章主要讲解了“TVM编译器的介绍及用法”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“TVM编译器的介绍及用法”吧!



1.  整体结构

TVM编译器的介绍及用法  

TVM是一个端到端的指令生成器。它从深度学习框架中接收模型输入,然后进行图的转化和基本的优化,最后生成指令完成到硬件的部署。整个架构是基于图描述结构,不论是对指令的优化还是指令生成,一个图结构清晰的描述了数据流方向,操作之间的依赖关系等。基于机器学习的优化器是优化过程中的重点,指令空间很大,通过优化函数来寻找最优值是一个很合理的想法。它的主要特点如下:


1) 基于GPU、TPU等硬件结构,将张量运算作为一个基本的算符,通过把一个深度学习网络描述成图结构来抽象出数据计算流程。在这样的图结构基础上,更方便记性优化。同时能够有更好的向上向下兼容性,同时支持多种深度学习框架和硬件架构。


2) 巨大的优化搜索空间。在优化图结构方面,其不再局限于通过某一种方式,而是通过机器学习方法来搜索可能的空间来最大化部署效率。这种方式虽然会导致编译器较大的计算量,但是更加通用。


TVM提供了一个非常简单的端到端用户接口,通过调用TVM的API可以很方便的进行硬件部署。比如:

TVM编译器的介绍及用法  

以上就是将Keras的模型输入到TVM,指定部署的硬件GPU,然后进行优化和代码生成。

TVM也提供了Java、C++和Python界面供用户调用。


2.  图结构基本优化


图结构是大多数深度学习框架中普遍采用的描述方式。这种图是一种高层次的描述,将一个张量运算用一个算符描述,而不是拆分的更细。这样更有利于优化,而且也符合GPU、TPU的硬件架构,在这些芯片中计算核算力很大,通常可以完成一个较大的计算,比如卷积、矩阵运算等。以下是一个卷积计算的例子,整个计算图包含了2D卷积、ReLu,dense、softmas等。这样的图结构也正好符合FPGA加速器的结构,在FPGA中也是用一个计算核来专门计算某个大的计算。TVM图中节点描述一个张量数据或者算符,而边表示了不同计算的依赖关系。

TVM编译器的介绍及用法  

基于图结构,TVM采用了很多图优化策略。包括算符融合,将可以在硬件上用一个算符完成的多个连续运算合并;常量折叠,将可以预先计算的数据放在编译器中完成,减少硬件计算;存储规划,预先为中间数据分配存储空间来储存中间值,避免中间数据无法存储在片上而增加片外存储开销;数据规划,重新排列数据有利于硬件计算。


1) 算符融合

TVM中将运算划分为4种:1对1运算,比如加法、点乘;降运算,比如累加;复杂运算,比如2D卷积,融合了乘法和累加;不透明的,比如分类、数据排列等,这些不能被融合。算符融合可以减少存储开销,实现pipeline,特别是在FPGA中更有利。比如我们目前的项目中是开发一款通用RNN架构IP,其中涉及到矩阵乘法,加法。其中加法就可以融合到矩阵乘中,这样就减少了单独加法模块计算开销以及读写cache开销。


2) 数据规划

以我们XRNN来说,片上有一个矩阵运算阵列,由于阵列大小固定,一次计算矩阵大小也是固定的。比如计算一个32x32对应32x1的矩阵向量乘法,那么就要求权重和向量必须要按照32倍数进行对齐,这就需要对权重数据等进行规划。


3.  张量计算


TVM中使用的张量描述语言是透明的,可以根据硬件需要进行修改。这样更加灵活和有利于进行优化。但是这样可能增加了编译器优化的复杂性。TVM描述例子如下:

TVM编译器的介绍及用法  

描述算符中包含结果大小,计算方式。但是这其中没有涉及到循环结构和更多数据操作细节。TVM采用了Halide思想,通过使用schedule来对张量计算进行等价变换,从中计算出执行效率最高的schedule结构。整个schedule流程如下图:

TVM编译器的介绍及用法  

从中可以看出,TVM除了采用了Halide的schedule方式外,还增加了三种针对GPU和TPU的schedule方式:specile memory scope,tensorization,latency hiding。这些schedule方式可以对一个张量运算进行等价变换,产生多种代码结构,从中选择出最有利于硬件执行的代码结构。


3.1  并行优化


并行计算是提高硬件执行效率的重要一步,因为诸如卷积、矩阵计算等都是大量的可以并发进行的计算,如何优化并行结构对改善硬件性能很关键。在这里需要考虑两点问题:一个是并行度,另外一个是数据共享。如果数据不共享那么就会增加数据读写消耗。而尽量利用可共享数据,则需要尽心设计一个计算结构。

TVM提出了memory scope的概念,其将数据计算进行可并行和不可并行分类,对于可以并行计算的,就可以使用多线程来并行计算,而不可并行,则需要等待被依赖数据计算完成。比如一个矩阵乘法例子:

TVM编译器的介绍及用法  

在XRNN中也会遇到类似的问题,对于不同的计算比如矩阵乘法和激活函数,如果没有依赖的话,就是可以并行执行的。


3.2  存储读写优化


在FPGA中读写cache或者external ddr也是一笔开销。如何将存储读写开销降低也有利于提高硬件执行效率。比如在我们的XRNN中,save数据到ddr会消耗很多时间,而这个数据下一次又会被利用,同时又增加了load的时间。如果将数据缓存到片上,那么就减少了load和save开销。还有比如片上cache也会来回读写数据,如果可以将一个计算完成的数据直接送给下一个计算核,实现流水,那么读写cache开销也节省了。


对于隐藏存储读写开销还有一种方法,在下一次计算开始前而这一次计算正在进行的时候,就进行片外数据加载,就将加载和计算重合了,减少额外加载消耗的时间。

TVM编译器的介绍及用法  


4.  自动优化器


TVM在丰富的schedule方式基础上,提出了一个机器学习模型来寻找最优化的schedule结构。其包含两部分:一部分是基于schedule方式产生所有可能的计算结构;另外一个是机器学习代驾模型来预测性能。


Schedule空间是巨大的,它可能产生很多种计算流结构,而对其中进行探索,找到最合适的结构。这会产生大量的计算。不过在我们的XRNN结构中,因为受到硬件内核的限制,还是可以对空间进行缩减的。只采用最可能影响性能schedule方式。比如矩阵乘、加法、点乘、激活这些不同的计算可以进行并发和非并发安排,这样的空间相对小,有利于加速编译器生成工作。


机器学习代价模型主要考虑了不同操作的延时来预测性能:存储访问方式,数据重利用,pipeline等。TVM中对代价函数的求解不是通过随机统计方式,而是使用实时的配置数据进行训练,周期性更替代码结构。人为的探寻更合理的优化结构,然后提供给模型,让其不断更替。这种方式避免了探索大量schedule空间的时间消耗,同时也能更接近于实际情况。

TVM编译器的介绍及用法  


总结


以上简要介绍了TVM的整体架构和基本方法,其实还挺符合FPGA加速硬件结构的。很多方法还是可以借用的。而且TVM是一个兼容更广的编译器架构,针对我们自身的FPGA特性,也会有很多不一样的设计。

感谢各位的阅读,以上就是“TVM编译器的介绍及用法”的内容了,经过本文的学习后,相信大家对TVM编译器的介绍及用法这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程笔记,小编将为大家推送更多相关知识点的文章,欢迎关注!


推荐阅读
  • 开发笔记:加密&json&StringIO模块&BytesIO模块
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了加密&json&StringIO模块&BytesIO模块相关的知识,希望对你有一定的参考价值。一、加密加密 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 在Android开发中,使用Picasso库可以实现对网络图片的等比例缩放。本文介绍了使用Picasso库进行图片缩放的方法,并提供了具体的代码实现。通过获取图片的宽高,计算目标宽度和高度,并创建新图实现等比例缩放。 ... [详细]
  • Android中高级面试必知必会,积累总结
    本文介绍了Android中高级面试的必知必会内容,并总结了相关经验。文章指出,如今的Android市场对开发人员的要求更高,需要更专业的人才。同时,文章还给出了针对Android岗位的职责和要求,并提供了简历突出的建议。 ... [详细]
  • 本文介绍了Java工具类库Hutool,该工具包封装了对文件、流、加密解密、转码、正则、线程、XML等JDK方法的封装,并提供了各种Util工具类。同时,还介绍了Hutool的组件,包括动态代理、布隆过滤、缓存、定时任务等功能。该工具包可以简化Java代码,提高开发效率。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 原文地址:https:www.cnblogs.combaoyipSpringBoot_YML.html1.在springboot中,有两种配置文件,一种 ... [详细]
  • 基于事件驱动的并发编程及其消息通信机制的同步与异步、阻塞与非阻塞、IO模型的分类
    本文介绍了基于事件驱动的并发编程中的消息通信机制,包括同步和异步的概念及其区别,阻塞和非阻塞的状态,以及IO模型的分类。同步阻塞IO、同步非阻塞IO、异步阻塞IO和异步非阻塞IO等不同的IO模型被详细解释。这些概念和模型对于理解并发编程中的消息通信和IO操作具有重要意义。 ... [详细]
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • Tomcat/Jetty为何选择扩展线程池而不是使用JDK原生线程池?
    本文探讨了Tomcat和Jetty选择扩展线程池而不是使用JDK原生线程池的原因。通过比较IO密集型任务和CPU密集型任务的特点,解释了为何Tomcat和Jetty需要扩展线程池来提高并发度和任务处理速度。同时,介绍了JDK原生线程池的工作流程。 ... [详细]
  • 本文介绍了Java高并发程序设计中线程安全的概念与synchronized关键字的使用。通过一个计数器的例子,演示了多线程同时对变量进行累加操作时可能出现的问题。最终值会小于预期的原因是因为两个线程同时对变量进行写入时,其中一个线程的结果会覆盖另一个线程的结果。为了解决这个问题,可以使用synchronized关键字来保证线程安全。 ... [详细]
  • 本文介绍了在Oracle数据库中创建序列时如何选择cache或nocache参数。cache参数可以提高序列的存取速度,但可能会导致序列丢失;nocache参数可以避免序列丢失,但在高并发访问时可能导致性能问题。文章详细解释了两者的区别和使用场景。 ... [详细]
  • 开发笔记:计网局域网:NAT 是如何工作的?
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了计网-局域网:NAT是如何工作的?相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 如何使用Java获取服务器硬件信息和磁盘负载率
    本文介绍了使用Java编程语言获取服务器硬件信息和磁盘负载率的方法。首先在远程服务器上搭建一个支持服务端语言的HTTP服务,并获取服务器的磁盘信息,并将结果输出。然后在本地使用JS编写一个AJAX脚本,远程请求服务端的程序,得到结果并展示给用户。其中还介绍了如何提取硬盘序列号的方法。 ... [详细]
  • Metasploit攻击渗透实践
    本文介绍了Metasploit攻击渗透实践的内容和要求,包括主动攻击、针对浏览器和客户端的攻击,以及成功应用辅助模块的实践过程。其中涉及使用Hydra在不知道密码的情况下攻击metsploit2靶机获取密码,以及攻击浏览器中的tomcat服务的具体步骤。同时还讲解了爆破密码的方法和设置攻击目标主机的相关参数。 ... [详细]
author-avatar
无敌BUG
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有