TVM:编译深度学习模型快速上手教程

本文将展示如何使用 Relay python 前端构建一个神经网络,并使用 TVM 为 Nvidia GPU 生成一个运行时库。 注意我们需要再构建 TVM 时启用了 cuda 和 llvm。

TVM支持的硬件后端总览

在本教程中,我们使用 cuda 和 llvm 作为目标后端。我们先导入 Relay 和 TVM:

import numpy as np
from tvm import relay
from tvm.relay import testing
import tvm
from tvm import te
from tvm.contrib import graph_executor
import tvm.testing

使用Relay定义一个神经网络

首先,我们使用 relay 的 python 前端定义一个神经网络。简单起见,我们这里直接使用 relay 中预定义好的 resnet-18 网络。参数按照 Xavier 初始化进行初始化。Relay 同样支持其他的模型格式如 MXNet,CoreML,ONNX 和 TensorFlow。

本教程中,我们假设我们将会在自己的设备上进行推理,batch size 设为1。输入是尺寸为 224 * 224 的 RGB 彩色图像。我们可以调用 tvm.relay.expr.TupleWrapper.astext() 来查看网络结构,

batch_size = 1
num_class = 1000
image_shape = (3, 224, 224)
data_shape = (batch_size,) + image_shape
out_shape = (batch_size, num_class)
mod, params = relay.testing.resnet.get_workload(
    num_layers=18, batch_size=batch_size, image_shape=image_shape
# set show_meta_data=True if you want to show meta data
print(mod.astext(show_meta_data=False))
#[version = "0.0.5"]
def @main(%data: Tensor[(1, 3, 224, 224), float32], %bn_data_gamma: Tensor[(3), float32], %bn_data_beta: Tensor[(3), float32], %bn_data_moving_mean: Tensor[(3), float32], %bn_data_moving_var: Tensor[(3), float32], %conv0_weight: Tensor[(64, 3, 7, 7), float32], %bn0_gamma: Tensor[(64), float32], %bn0_beta: Tensor[(64), float32], %bn0_moving_mean: 
Tensor[(64), float32], %bn0_moving_var: Tensor[(64), float32], %stage1_unit1_bn1_gamma: 
  %88 = nn.dense(%87, %fc1_weight, units=1000) /* ty=Tensor[(1, 1000), float32] */;
  %89 = nn.bias_add(%88, %fc1_bias, axis=-1) /* ty=Tensor[(1, 1000), float32] */;
  nn.softmax(%89) /* ty=Tensor[(1, 1000), float32] */

下一步就是使用 Relay/TVM 的流程进行编译。用户可以指定编译的优化等级。目前优化等级可以设置为 0 到 3。优化的 pass 包括算子融合,预先计算,排布变换等。

relay.build() 返回三个组件:json 格式的执行图、目标硬件上专门为此图编译函数的 TVM 模块库以及模型的参数 blob。 在编译过程中,Relay 进行图级优化,TVM 进行张量级优化,从而为模型推理服务提供优化的运行时模块。

我们将首先为 Nvidia GPU 编译。 relay.build() 首先在幕后进行了一些图级优化,例如剪枝、融合等,然后将算子(即优化图的节点)注册到 TVM 实现以生成 tvm.module。 为了生成模块库,TVM 将首先将高层 IR 转换为指定目标后端的低层固有 IR,在本例中为 CUDA。 然后生成机器代码,得到模块库。

opt_level = 3
target = tvm.target.cuda()
with tvm.transform.PassContext(opt_level=opt_level):
    lib = relay.build(mod, target, params=params)
/home/areusch/ws/tvm3/python/tvm/target/target.py:259: UserWarning: Try specifying cuda arch by adding 'arch=sm_xx' to your target.
  warnings.warn("Try specifying cuda arch by adding 'arch=sm_xx' to your target.")

运行生成的库

现在,我们可以创建 graph executor 来将模块运行在 Nvidia GPU 上。

# create random input
dev = tvm.cuda()
data = np.random.uniform(-1, 1, size=data_shape).astype("float32")
# create module
module = graph_executor.GraphModule(lib["default"](dev))
# set input and parameters
module.set_input("data", data)
# run
module.run()
# get output
out = module.get_output(0, tvm.nd.empty(out_shape)).numpy()
# Print first 10 elements of output
print(out.flatten()[0:10])
[0.00089283 0.00103331 0.0009094  0.00102275 0.00108751 0.00106737
 0.00106262 0.00095838 0.00110792 0.00113151]

保存 / 加载编译好的模块

我们可以将 graph,lib 和 parameters 保存到文件中,并在部署的场景下来加载它们。(译者注:这里的代码会将模型保存在临时文件中,想要保存模型,可以自己修改路径)

# save the graph, lib and params into separate files
from tvm.contrib import utils
temp = utils.tempdir()
path_lib = temp.relpath("deploy_lib.tar")
lib.export_library(path_lib)
print(temp.listdir())
['deploy_lib.tar']
# load the module back.
loaded_lib = tvm.runtime.load_module(path_lib)
input_data = tvm.nd.array(data)
module = graph_executor.GraphModule(loaded_lib["default"](dev))
module.run(data=input_data)
out_deploy = module.get_output(0).numpy()
# Print first 10 elements of output
print(out_deploy.flatten()[0:10])
# check whether the output from deployed module is consistent with original one
tvm.testing.assert_allclose(out_deploy, out, atol=1e-5)
[0.00089283 0.00103331 0.0009094  0.00102275 0.00108751 0.00106737
 0.00106262 0.00095838 0.00110792 0.00113151]
                    TVM:编译深度学习模型快速上手教程本文将展示如何使用 Relay python 前端构建一个神经网络,并使用 TVM 为 Nvidia GPU 生成一个运行时库。 注意我们需要再构建 TVM 时启用了 cuda 和 llvm。TVM支持的硬件后端总览在本教程中,我们使用 cuda 和 llvm 作为目标后端。我们先导入 Relay 和 TVM:import numpy as npfrom tvm import relayfrom tvm.relay import testingimpor
				
在Cuda上部署量化模型 本文是使用TVM进行自动量化的入门教程。自动量化是TVM中的一种量化模式。有关TVM中量化过程的更多详细信息,请参见 此处。在本教程中,我们将在ImageNet上导入GluonCV预训练模型以进行中继,量化中继模型,然后执行推理。 https://discuss.tvm.ai/t/solved-cant-run-tutorials-ssd-model-on-my-own-cpu/2005 2、编译gpu模型编译时,打开编译cuda选项:tvm_option(USE_CUDA "Build with CUDA" ON) 在jetson na...
Author: Tianqi Chen https://docs.tvm.ai/tutorials/tensor_expr_get_started.html Tensor Expression入门 这是TVM中Tensor表达语言的入门教程TVM使用特定于域的张量表达式来进行有效的内核构造。 在本教程中,我们将演示使用张量表达式语言的基本工作流程。 from __future__ import ...
文章目录TVM如何优化GPU卷积准备和算法内存层次结构分块虚拟线程分裂并发数据获取生成CUDA内核 TVM如何优化GPU卷积 本教程,我们将演示如何在TVM中编写高性能卷积实现。我们使用方形尺寸的输入张量和滤波器作为示例,并假设卷积的输入具有大批量。在此示例中,我们使用不同的布局来存储数据,以实现更好的数据局部性。缓冲区布局为HWCN,代表高度,宽度,通道,批次。 准备和算法 我们使用固定尺寸14...
Author: Yao Wang, Truman Tian 这个例子展示了如何使用 Relay python 前端构建一个神经网络,并为带有 TVM 的 Nvidia GPU 生成一个运行时库。 请注意,您需要在启用 cuda 和 llvm 的情况下构建 TVMTVM 支持的硬件后端概述 下图显示了 TVM 当前支持的硬件后端: 在本教程中,我们将选择 cuda 和 llvm 作为目标后端。 首先,让我们导入 Relay 和 TVM。 import numpy as np from tvm impor
本文翻译自Introduction to TOPI — tvm 0.9.dev0 documentation这是TVM算子库(TOPI)的入门教程。TOPI提供numpy风格的通用操作和调度,具有比TVM更高的抽象。在本教程中,我们将看到TOPI如何使我们不用在TVM中编写样板代码。 让我们重温按行加和运算(等价于B = numpy.sum(A, axis=1))求二维TVM张量A的行和,我们需要指定符号运算和调度 为了检查可读的IR代码,我们可以 然而,对于这样一个
Author: Ehsan M. Kermani 这是 TVM Operator Inventory (TOPI) 的介绍性教程。 TOPI 提供了 numpy 风格的通用操作和调度,其抽象程度高于 TVM。 在本教程中,我们将了解 TOPI 如何使我们免于在 TVM 中编写模板代码。 from __future__ import absolute_import, print_function import tvm import tvm.testing from tvm import te from t
TVM-LeNet 本文完成了自己搭建、训练和打包LeNet模型,并用TVM对其进行简单的优化,比较两者的异同,发现TVM的计算图更为简捷,准确率二者几乎相同,并且TVM的推理速度是普通模型的2倍左右。 版本:TVM 0.7.dev1 ; pytorch 1.6.0 ; GTX1650 , cuda10.2 文章目录TVM-LeNet@[toc]1.LeNet模型搭建:2.模型训练:3.模型推理:4.使用TVM进行推理:5.结果比较: 1.LeNet模型搭建: LeNet-5是1998年Yann Lecun
docker gpu报错Error response from daemon: could not select device driver ““ with capabilities: [[gpu]] 烟云之路: 遇到"pg: invalid option "-问题的,到这里下载脚本: https://github.com/inisis/doc/blob/master/docker/nvidia-container-runtime-script.sh 估计是格式或编码问题吧 Vision Transformer(ViT)PyTorch代码全解析(附图解) dc520111: attention类中的heads是不是应该为16 使用docker构建自己的机器学习开发环境 大白菜的烂菜叶: docker 本身不支持英伟达显卡设备···这怎么可能···19.0版本开始就支持了啊···这是哪边弄来的前代文章啊 Vision Transformer(ViT)PyTorch代码全解析(附图解) weixin_42537251: 应该是num_patch*channel