赞
踩
基于编译优化思想的推理框架,为了算法模型在所有可能部署的设备上都达到良好性能。
曾经出现了很多种编程语言,有很多种硬件,历史上最开始也是一种语言对应一种硬件,从而造成编译器的维护困难与爆炸。
而编译器后面解决了这个问题,其具体解决办法是这样的:抽象出编译器前端,编译器中端,编译器后端等概念,引入IR (Intermediate Representation)
而对于现在多种训练框架训练的算法模型与硬件对应关系混乱,可得出以下架构:
通过模型优化,让部署到硬件上的机器学习模型有良好性能。
从不同的深度学习框架导出的模型。
它是TVM高层次图的结构表示,可以进行一些高层次的优化。
TVM的Tensor级别IR,更接近底层的IR。
TVM编译栈的最底层IR,直接对接Runtime在目标设备上运行
负责将外部框架生成的神经网络模型转化为TVM的图级别模型Relay IR
负责在图级别优化IR的计算过程,常见的图优化Pass包括常量折叠、死代码消除、推理简化、内存布局转化、Op融合等
负责转化Relay Passes优化后的Relay IR为TensorIR,大致的流程是对于每个层/融合层对应的算子,执行graph_runtime_codegen.cc的Codegen,根据TVM框架中注册的算子compute和schedule函数,将每个算子转化为具体的计算调度过程
AutoTVM则是辅助Schedule功能选择参数的一种特殊算法,其主要思想就是基于强化学习的方法,搜寻一个最优的优化空间,实现网络调优。
负责Tensor IR优化,常见的如access index simplification,也有负责IR lower的function entry decoratation等
将TIR转化为TVM Runtime所需的Module
TVM的一个特色是借鉴Halide语言的计算和调度分离定义的设计方法,将深度学习模型的算子计算方法定义和具体计算调度方式做了解耦:
•计算(Compute)定义了每个Relay Op的具体计算过程
•调度(Schedule)则细化了计算过程每个具体步骤的实际计算细节
之所以做这样的分离式设计,是因为一般情况下,特定算子的计算方式是不变的,而算子的调度却有几乎无限种配置方法,显然对于不同的目标硬件如CPU、GPU,其最优调度配置必然大相径庭;即使对于同一种硬件如不同型号的CPU,也会导致最优配置相差甚远。
默认情况下,TVM为定义的所有算子针对常见的Target(x86/ARM/CUDA等)各提供了一套默认的调度配置。但一方面指定Target的默认配置不可能在所有型号的硬件下最大程度地利用运行环境的计算资源;另一方面调度的可选配置空间巨大,人工手动调整调度效率低且无法保证调度性能。为了解决该问题,TVM开发了AutoTVM模块通过搜索的方式获得具体硬件下的最优调度配置,总体步骤如:
针对每个Relay子函数,定义一系列调度原语(Schedule primitives),通过调度原语的组合实现计算结果等价的Relay子函数
在海量的配置组合中为每个Relay子函数搜索最优的调度配置
对于卷积这样的计算密集算子,调度配置的搜索空间通常有几十亿种选择,比较棘手的问题就是如何高效的在搜索空间中获得最优/局部最优解。常见的做法有两种:
遍历所有可能的参数编译模型并评估
评估部分参数模型,训练一个性能评估函数,用于指导搜索过程寻找更好的调度配置
由于搜索空间过于巨大,第一种方法需要花费的时间难以估量;AutoTVM采用的是第二种,用一个XGBoost模型(其他回归预测模型也可)作为评估调度配置性能的模型(CostModel),用以指导模拟退火算法(默认)寻找最优调度配置。
搜索过程完毕后AutoTVM会将过程中记录的最优配置保存下来,编译模型时可用于代替默认的Target调度配置。
赞
踩
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。