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

【AI编译优化】谈谈tvmansor

本文主要讨论一

 本文主要讨论一下 tvm ansor 的原理。

  参考论文:

  参考代码:

https://github.com/apache/tvm

1、深度学习系统堆栈

  深度学习系统堆栈,前端是各种 AI 框架(pytorch、tf、mxnet、caffe ... ),后端是各种硬件(NVGPU、ARMCPU、X86CPU、NPU ... )

  对于深度学习编译器来说,就是把前端 AI 框架出来的网络 算子 code_gen compiler 成对应 target 硬件后端高性能的机器码,而 tvm halide 把这个compiler 的过程拆成计算(compute)和调度(optimized code)两个过程,理由很简单,这样解耦后只需要关注调度优化,因为调度是和硬件强相关的,而不用担心调度影响了精度。拿 dense_layer + relu 这个 subgraph 来说,halide 和 tvm 的计算表达可能是这样的:

# halide  
dense(o, b) += data(i, b) * weight(i, o)
relu(o, b) = max(dense(o, b), 0.0)

# tvm
dense = compute(shape, lambda b, o: sum(data[b, i] * weight[o, i], i))
relu = compute(shape, lambda b, o: max(dense[b, o], 0.0))


2、相关的高性能张量生成工作

2.1 auto tvm

  做法是使用 template-guided 进行搜索,对于每个 op 使用 templates 去定义搜索空间。

  缺点是:

  (1)没有做到全自动:还需要大量的手动工作;

  (2)受限的搜索空间:不能达到更加好的优化性能;

2.2 halide auto-scheduler

  做法是基于 sequential construction 进行搜索,使用 beam search 算法搜索顺序生成。说一下 beam search 算法,beam search 是所谓的 束搜索,是对 greedy search(贪心搜索)的一个改进算,相对 greedy search 扩大了搜索空间,但远远不及穷举搜索指数级的搜索空间,是二者的一个折中方案。

  halide auto-scheduler 的缺点是:

  (1)因为它是顺序生成的,对于中间的算子优化来说是不连续不完整的,因此 cost model 没办法进行准确的预测,导致了错误的累积;

 (2)和 auto tvm 一样,搜索空间也是受限的;

  通过对以上两个调度搜索算法的讨论,得到三个痛点:(1)怎么样能够自动的获取一个很大的搜索空间;(2)如何让搜索更加的高效;(3)对于这么多的搜索任务我们怎么样去分配资源。对于这三个痛点,ansor 的解法是:对于(1)采用 hierarchical search space;对于(2)采用 sample complete programs and fine-tune them;对于(3)采用 task scheduler 程序对重要任务进行优先排序。

3、tvm ansor 原理

  先来看一下 tvm ansor 的逻辑栈,下面对主要的操作展开谈谈。

 前端接的还是 AI框架出来的 models,然后切分成很多 subgraphs 子图,对于每个 subgraph 都会进行如下的调度优化。

3.1 program sampling

  program sampling 的目标是自动地构建一个连续的大的搜索空间。这里要理解这个搜索空间到底是用于搜索个啥,我的理解是搜索计算的姿势或者说计算的调度方式,而不是计算本身。方法是使用 sketch generation 和 random annotation。其中 sketch 是 a few good high-level structures
,annotaion 是 billions of low-level details
,通俗一点理解 sketch 进行高层抽象,annotaion 进行底层映射,通过这两步操作就能构建了一个很大的搜索空间。

这个用于解决痛点(1)搜索空间大小问题。

3.1.1 sketch generation

  先贴一些论文里的描述:

 做法大致流程是这样:先出数学表达 -> 再出程序表达 -> 根据程序表达和数学表达出有向无环图描述计算节点和计算逻辑 -> 根据设计好的 sketch gen rules 来生成 sketch 表达(比如对于CPU,有 “SSRSRS”的循环展开结构)。所以 sketch 的整个流程可以用如下这个 dense_layer + relu 的例子展示,可以看到最后生成的 sketch 草图里有很多类似 TILE_I0 的参数,这些是超参,是需要调优搜索的值,也是 random annotation 的工作之一,所以最后生成的 sketch 草图不止一个,往往是一个草图列表。

  还有这个例子也是一样:

3.1.2 random annotation

  annotaion 是获得 sketch 草图的后续动作,annotaion 操作是 randomly 选择一个sketch,randomly 填充 tile sizes,randomly parallelize 外部循环,randomly vectorize 内部循环,randomly change 计算节点位置以对 tile stucture 做微调等。还是接着上面的 dense_layer + relu 的例子展示:

3.2 performance fine-tuning

 接着 program sampling 后的操作就到了 performance tuner 了。这里这要包含搜索算法设计和代价评估模型的设计,使 ansor 能够更加高效的进行搜索和收敛。

  这个用于解决痛点(2)搜索效率问题。

3.2.1 evolutionary search

 random annotation 的随机生成/抽样不能保证性能,ansor 采用类似遗传算法的进化搜索算法来进一步对 annotation 抽样程序进行进化搜索。主要涉及 基因突变和基因交叉。

 (1)突变:随机改变 tile size;随机改变 parallel/unroll/vectorize 因子和粒度;随机改变 computation location;

 (2)交叉:从算子计算有向无环图的角度解释,如下:

3.2.2 learned cost model

  预测每个 non-loop innermost statement 的得分,可能比较抽象,上一些论文里的解释

  再上个例子进行说明,如下,statement B 和 statement C 就是所谓的 non-loop innermost statement 了,这个比较直观一点。

 每个 non-loop innermost statement 提取的特征包括:使用的 cache lines、使用的 memory、reuse distance、arithmetic intensity 等


3.3 task scheduler

 ansor 中的 task scheduler 会对重要任务进行优先排序。

 这个是用于解决痛点(3)多任务调度资源分配问题。

 我们拿 resnet50 来说,在 ansor 中会把它切成 29 个独立的 subgraphs。如果按照传统的任务调度方式,一般会顺序地对这些 subgraphs 进行调度,就像这样。

 ansor 中的 task scheduler 会将时间进行切片并对重要的子图优先排序,就像这样,这种优化很像推理里的 pipeline 优化。


4、性能数据

 下面给出一些测试的性能数据,论文里也有:

  (1) 单算子

  测试平台是 Intel-Platinum 8124M (18 cores):


 (2) subgraph

 测试平台是 ''@C'' for Inter CPU (8124M)、''@G'' for NVIDIA (V100)。


 (3) 整网

 测试平台是 Intel CPU (8124M)、NVIDIA GPU (V100)、ARM CPU (A53)。


 从上面给出的数据可以看出,不管是单算子、subgraph、整网来说,ansor 的表现都很棒。

 以上讨论了我目前对 tvm ansor 的理解。


  收工~


声明:转载请说明出处

扫描下方二维码关注【极智视界】公众号,获取更多实践项目资源和读书分享,让我们用极致+极客的心态来迎接AI !







推荐阅读
  • 关于如何快速定义自己的数据集,可以参考我的前一篇文章PyTorch中快速加载自定义数据(入门)_晨曦473的博客-CSDN博客刚开始学习P ... [详细]
  • 深度学习中的Vision Transformer (ViT)详解
    本文详细介绍了深度学习中的Vision Transformer (ViT)方法。首先介绍了相关工作和ViT的基本原理,包括图像块嵌入、可学习的嵌入、位置嵌入和Transformer编码器等。接着讨论了ViT的张量维度变化、归纳偏置与混合架构、微调及更高分辨率等方面。最后给出了实验结果和相关代码的链接。本文的研究表明,对于CV任务,直接应用纯Transformer架构于图像块序列是可行的,无需依赖于卷积网络。 ... [详细]
  • 上图是InnoDB存储引擎的结构。1、缓冲池InnoDB存储引擎是基于磁盘存储的,并将其中的记录按照页的方式进行管理。因此可以看作是基于磁盘的数据库系统。在数据库系统中,由于CPU速度 ... [详细]
  • 在本教程中,我们将看到如何使用FLASK制作第一个用于机器学习模型的RESTAPI。我们将从创建机器学习模型开始。然后,我们将看到使用Flask创建AP ... [详细]
  • 1.ArrayList是实现了基于动态数组的数据结构,LinkedList基于链表的数据结构。 2.对于随机访问get和set,ArrayList优于LinkedList,因为Ar ... [详细]
  • 干货 | 携程AI推理性能的自动化优化实践
    作者简介携程度假AI研发团队致力于为携程旅游事业部提供丰富的AI技术产品,其中性能优化组为AI模型提供全方位的优化方案,提升推理性能降低成本࿰ ... [详细]
  • 在Docker中,将主机目录挂载到容器中作为volume使用时,常常会遇到文件权限问题。这是因为容器内外的UID不同所导致的。本文介绍了解决这个问题的方法,包括使用gosu和suexec工具以及在Dockerfile中配置volume的权限。通过这些方法,可以避免在使用Docker时出现无写权限的情况。 ... [详细]
  • Python正则表达式学习记录及常用方法
    本文记录了学习Python正则表达式的过程,介绍了re模块的常用方法re.search,并解释了rawstring的作用。正则表达式是一种方便检查字符串匹配模式的工具,通过本文的学习可以掌握Python中使用正则表达式的基本方法。 ... [详细]
  • 摘要: 在测试数据中,生成中文姓名是一个常见的需求。本文介绍了使用C#编写的随机生成中文姓名的方法,并分享了相关代码。作者欢迎读者提出意见和建议。 ... [详细]
  • 本文讨论了如何使用IF函数从基于有限输入列表的有限输出列表中获取输出,并提出了是否有更快/更有效的执行代码的方法。作者希望了解是否有办法缩短代码,并从自我开发的角度来看是否有更好的方法。提供的代码可以按原样工作,但作者想知道是否有更好的方法来执行这样的任务。 ... [详细]
  • 本文详细介绍了如何使用MySQL来显示SQL语句的执行时间,并通过MySQL Query Profiler获取CPU和内存使用量以及系统锁和表锁的时间。同时介绍了效能分析的三种方法:瓶颈分析、工作负载分析和基于比率的分析。 ... [详细]
  • Android自定义控件绘图篇之Paint函数大汇总
    本文介绍了Android自定义控件绘图篇中的Paint函数大汇总,包括重置画笔、设置颜色、设置透明度、设置样式、设置宽度、设置抗锯齿等功能。通过学习这些函数,可以更好地掌握Paint的用法。 ... [详细]
  • 都会|可能会_###haohaohao###图神经网络之神器——PyTorch Geometric 上手 & 实战
    篇首语:本文由编程笔记#小编为大家整理,主要介绍了###haohaohao###图神经网络之神器——PyTorchGeometric上手&实战相关的知识,希望对你有一定的参考价值。 ... [详细]
  • 程序分析与优化9附录XLA的缓冲区指派
    本章是系列文章的案例学习,不属于正篇,主要介绍了TensorFlow引入的XLA的优化算法。XLA也有很多局限性,XLA更多的是进行合并,但有时候如果参数特别多的场景下,也需要进行 ... [详细]
  • navicat生成er图_实践案例丨ACL2020 KBQA 基于查询图生成回答多跳复杂问题
    摘要:目前复杂问题包括两种:含约束的问题和多跳关系问题。本文对ACL2020KBQA基于查询图生成的方法来回答多跳复杂问题这一论文工作进行了解读 ... [详细]
author-avatar
chenshu华
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有