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

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

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

TVM支持的硬件后端总览

在这里插入图片描述

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

import numpy as npfrom 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.001067370.00106262 0.00095838 0.00110792 0.00113151]

保存 / 加载编译好的模块

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

# save the graph, lib and params into separate files
from tvm.contrib import utilstemp = 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.001067370.00106262 0.00095838 0.00110792 0.00113151]

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/532536.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

TVM:设计与架构

TVM:设计与架构 本文档适用于想要了解 TVM 架构和/或积极开发项目的开发人员。页面组织如下: 示例编译流程概述了 TVM 将模型的高层描述转换为可部署模块所采取的步骤。要开始使用,请先阅读本节。 逻辑架构组件部分描述了逻辑组件。后面的部…

递归+回溯

递归-回溯 本文参考自代码随想录视频: https://www.bilibili.com/video/BV1cy4y167mM https://www.bilibili.com/video/BV1ti4y1L7cv 递归回溯理论基础 只要有递归,就会有回溯,递归函数的下面的部分通常就是回溯的逻辑。 回溯是纯暴力的搜索…

Nvidia CUDA初级教程1 CPU体系架构综述

Nvidia CUDA初级教程1 CPU体系架构综述 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p2 讲师:周斌 本节内容:了解现代CPU的架构和性能优化: 流水线 Pipelining分支预测 Branch Prediction超标量 Superscalar乱序执行 Out…

Nvidia CUDA初级教程2 并行程序设计概述

Nvidia CUDA初级教程2 并行程序设计概述 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p3 讲师:周斌 本节内容: 为什么需要?怎么做?一些技术和概念 串并行计算模式 串行计算模式 常规软件时串行的 设计运行…

Nvidia CUDA初级教程4 GPU体系架构概述

Nvidia CUDA初级教程4 GPU体系架构概述 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p5 讲师:周斌 本节内容: 为什么需要GPU三种方法提升GPU的处理速度实际GPU的设计举例: NVDIA GTX 480: FermiNVDIA GTX 680: Kepler GP…

Nvidia CUDA初级教程5 CUDA/GPU编程模型

Nvidia CUDA初级教程5 CUDA/GPU编程模型 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p6 讲师:周斌 本节内容: CPU和GPU互动模式GPU线程组织模型(需要不停强化)GPU存储模型基本的编程问题 CPU与GPU交互 各自…

Nvidia CUDA初级教程6 CUDA编程一

Nvidia CUDA初级教程6 CUDA编程一 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p7 讲师:周斌 GPU架构概览 GPU特别使用于: 密集计算,高度可并行计算图形学 晶体管主要被用于: 执行计算而不是 缓存数据控制指令…

由前中后遍历序列构建二叉树

由前/中/后遍历序列构建二叉树 基础 首先,我们需要知道前中后序三种深度优先遍历二叉树的方式的具体顺序: 前序:中左右中序:左中右后序:左右中 另外,要知道只有中序前/后序可以唯一确定一棵二叉树&…

手写nms

手写nms 计算宽高的时候加1是为什么? 本文总结自互联网的多种nms实现,供参考,非博主原创,各原文链接如下,也建议大家动手写一写。 Ref: 浅谈NMS的多种实现 目标窗口检测算法-NMS非极大值抑制 一、fas…

目标检测综述

目标检测综述 转自:https://zhuanlan.zhihu.com/p/383616728 论文参考:[Object Detection in 20 Years: A Survey][https://arxiv.org/abs/1905.05055] 引言 目标检测领域发展至今已有二十余载,从早期的传统方法到如今的深度学习方法&#x…

Nvidia CUDA初级教程7 CUDA编程二

Nvidia CUDA初级教程7 CUDA编程二 视频:https://www.bilibili.com/video/BV1kx411m7Fk?p8 讲师:周斌 本节内容: 内置类型和函数 Built-ins and functions线程同步 Synchronizing线程调度 Scheduling threads存储模型 Memory model重访 Matr…

详解优酷视频质量评价体系

万字长文 | 详解优酷视频质量评价体系 分享嘉宾|李静博士,阿里巴巴文娱集团资深算法专家,阿里巴巴大文娱摩酷实验室视频体验与质量团队负责人 整理出品|AICUG人工智能社区 本文地址:https://www.6aiq.com/article/1617…

视频质量评价:挑战与机遇

视频质量评价:挑战与机遇 转自:https://zhuanlan.zhihu.com/p/384603663 本文整理自鹏城实验室助理研究员王海强在LiveVideoStack线上分享上的演讲。他通过自身的实践经验,详细讲解了视频质量评价的挑战与机遇。 文 / 王海强 整理 / LiveVi…

关于二分法的边界问题及两种写法

关于二分法的边界问题及两种写法 二分查找法大家很熟悉了,对于一个有序序列,我们可以通过二分查找法在 O(logN)O(logN)O(logN) 的时间内找到想要的元素。但是,在代码实现的过程中,如果没有仔细理解清楚,二分法的边界条…

LeetCode上的各种股票最大收益

LeetCode上的各种股票最大收益 对于力扣平台上的股票类型的题目: 121 买卖股票的最佳时机 122 买卖股票的最佳时机 II 123 买卖股票的最佳时机 III 124 买卖股票的最佳时机 IV 309 最佳买卖股票时机含冷冻期 714 买卖股票的最佳时机含手续费 剑指 Offer 63. …

建设专业化运维服务团队必要性

信息系统的生命周期涵盖:设计、开发、测试、部署上线、运行维护。其中,运行维护阶段是信息系统生命周期中的关键环节,其执行效果直接影响系统是否能达到预期的运行目标。为了实现这个目标,我们必须建立一个以业务服务为导向的专业…

docker初探

docker初探 本文旨在介绍 docker 基本的安装、常用命令和常见概念的辨析,方便新手入门和笔者日后查阅,大部分内容整理自互联网,原出处在文中注明。 文章目录docker初探docker安装(mac)版本、信息相关命令version/info…

ubuntu安装zsh、oh-my-zsh及常用配置

ubuntu安装zsh、oh-my-zsh及常用配置 目前,ubuntu默认的shell是bash,但还有一种shell,叫做zsh它比bash更加强大,功能也更加完善,zsh虽说功能强大,但是配置比较复杂导致流行度不是很高 但是好东西终究是好…

Segmentaion标签的三种表示:poly、mask、rle

Segmentaion标签的三种表示:poly、mask、rle 不同于图像分类这样比较简单直接的计算机视觉任务,图像分割任务(又分为语义分割、实例分割、全景分割)的标签形式稍为复杂。在分割任务中,我们需要在像素级上表达的是一张…

tensorboard报错:ValueError Duplicate plugins for name projector 问题的出现及解决过程

tensorboard报错:ValueError: Duplicate plugins for name projector 问题的出现及解决过程 记录如题问题的出现及解决过程。 报错命令及信息 笔者在终端调用 tensorboard 时: tensorboard --logdirruns/ --bind_all报错: raise ValueEr…