Ubuntu20.04部署TVM流程及编译优化模型示例

前言:记录自己安装TVM的流程,以及一个简单的利用TVM编译模型并执行的示例。

1,官网下载TVM源码

git clone --recursive https://github.com/apache/tvmgit submodule init
git submodule update

顺便完成准备工作,比如升级cmake版本需要3.18及以上版本。还有如下库:

sudo apt-get update
sudo apt-get install -y python3 python3-dev python3-setuptools gcc libtinfo-dev zlib1g-dev build-essential cmake libedit-dev libxml2-dev

2,安装clang,llvm,ninja

llvm安装依赖clang和ninja,所以直接安装llvm即可顺便完成全部的安装。

llvm ,clang安装参考:Linux系统无痛编译安装LLVM简明指南_linux安装llvm11-CSDN博客

步骤如下:

git clone git@github.com:llvm/llvm-project.gitcd llvm-project
mkdir buildcd buildsudo cmake ../llvm -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_BUILD_TYPE=Debug
sudo make -j8
sudo make install

检查版本:

clang --version
llvm-as --version

3,安装NNPACK

NNPACK是为了优化加速神经网络的框架,可以提高在CPU上的计算效率

git clone --recursive https://github.com/Maratyszcza/NNPACK.git
cd NNPACK
# Add PIC option in CFLAG and CXXFLAG to build NNPACK shared library
sed -i "s|gnu99|gnu99 -fPIC|g" CMakeLists.txt
sed -i "s|gnu++11|gnu++11 -fPIC|g" CMakeLists.txt
mkdir build
cd build
# Generate ninja build rule and add shared library in configuration
cmake -G Ninja -D BUILD_SHARED_LIBS=ON ..
ninja
sudo ninja install# Add NNPACK lib folder in your ldconfig
sudo sh -c "echo '/usr/local/lib'>> /etc/ld.so.conf.d/nnpack.conf"
sudo ldconfig

4,编译TVM

如下步骤,在tvm建立build文件夹,把config.cmake复制到build中

cd tvm
mkdir buildcp cmake/config.cmake build

build里的config.cmake是编译配置文件,可以按需打开关闭一些开关。下面是我修改的一些配置(TENSORRT和CUDNN我以为之前已经配置好了,结果编译报了这两个的错误,如果只是想跑流程,可以不打开这两个的开关,这样就能正常编译结束了)

set(USE_RELAY_DEBUG ON)
set(USE_CUDA ON)
set(USE_NNPACK ON)
set(USE_LLVM ON)
set(USE_TENSORRT_CODEGEN ON)
set(USE_TENSORRT_RUNTIME ON)
set(USE_CUDNN ON)

编译代码:

cd build
cmake ..make -j12

5,配置python环境

从build文件夹出来进入到tvm/python文件夹下,执行如下命令,即可配置python中的tvm库了。

cd ../python
python setup.py install

python中使用tvm测试,导入tvm不出错即配置tvm安装成功

import tvmprint(tvm.__version__)

6,一个简单示例

该测试来自TVM官方文档的示例,包括编译一个测试执行一个分类网络和编译器自动调优测试。仅先直观的看到TVM如何作为一个工具对模型编译并部署的流程。

1) 下载onnx模型

wget https://github.com/onnx/models/raw/b9a54e89508f101a1611cd64f4ef56b9cb62c7cf/vision/classification/resnet/model/resnet50-v2-7.onnx

2) 编译onnx模型

python -m tvm.driver.tvmc compile --target "llvm" --input-shapes "data:[1,3,224,224]" --output resnet50-v2-7-tvm.tar resnet50-v2-7.onnx

如果报这样的警告:

就在git上下载一份tophub,把整个文件夹tophub复制到 ~/.tvm/路径下

git clone git@github.com:tlc-pack/tophub.git
sudo cp -r tophub ~/.tvm/

解压生成的tvm编译模型,得到3个文件:

  • mod.so  作为一个C++库的编译模型, 能被 TVM runtime加载

  • mod.json TVM Relay计算图的文本表示

  • mod.params onnx模型的预训练权重参数

mkdir model
tar -xvf resnet50-v2-7-tvm.tar -C model
ls model

3) 输入数据前处理

python preprocess.py

图像处理代码文件:preprocess.py

#!python ./preprocess.py
from tvm.contrib.download import download_testdata
from PIL import Image
import numpy as npimg_url = "https://s3.amazonaws.com/model-server/inputs/kitten.jpg"
img_path = download_testdata(img_url, "imagenet_cat.png", module="data")# Resize it to 224x224
resized_image = Image.open(img_path).resize((224, 224))
img_data = np.asarray(resized_image).astype("float32")# ONNX expects NCHW input, so convert the array
img_data = np.transpose(img_data, (2, 0, 1))# Normalize according to ImageNet
imagenet_mean = np.array([0.485, 0.456, 0.406])
imagenet_stddev = np.array([0.229, 0.224, 0.225])
norm_img_data = np.zeros(img_data.shape).astype("float32")
for i in range(img_data.shape[0]):norm_img_data[i, :, :] = (img_data[i, :, :] / 255 - imagenet_mean[i]) / imagenet_stddev[i]# Add batch dimension
img_data = np.expand_dims(norm_img_data, axis=0)# Save to .npz (outputs imagenet_cat.npz)
np.savez("imagenet_cat", data=img_data)

4) 运行编译模型

python -m tvm.driver.tvmc run --inputs imagenet_cat.npz --output predictions.npz resnet50-v2-7-tvm.tar

5) 输出后处理

python postprocess.py

执行之后得到分类结果的输出:

class='n02123045 tabby, tabby cat' with probability=0.621104
class='n02123159 tiger cat' with probability=0.356378
class='n02124075 Egyptian cat' with probability=0.019712
class='n02129604 tiger, Panthera tigris' with probability=0.001215
class='n04040759 radiator' with probability=0.000262

后处理代码:postprocess.py

#!python ./postprocess.py
import os.path
import numpy as npfrom scipy.special import softmaxfrom tvm.contrib.download import download_testdata# Download a list of labels
labels_url = "https://s3.amazonaws.com/onnx-model-zoo/synset.txt"
labels_path = download_testdata(labels_url, "synset.txt", module="data")with open(labels_path, "r") as f:labels = [l.rstrip() for l in f]output_file = "predictions.npz"# Open the output and read the output tensor
if os.path.exists(output_file):with np.load(output_file) as data:scores = softmax(data["output_0"])scores = np.squeeze(scores)ranks = np.argsort(scores)[::-1]for rank in ranks[0:5]:print("class='%s' with probability=%f" % (labels[rank], scores[rank]))

6) 编译器自动调优

调优的算法使用的是xgboost,所以需要python安装一下这个库。

pip install xgboostpython -m tvm.driver.tvmc tune --target "llvm" --output resnet50-v2-7-autotuner_records.json resnet50-v2-7.onnx

7) 重新编译并执行调优后的模型

python -m tvm.driver.tvmc compile --target "llvm" --tuning-records resnet50-v2-7-autotuner_records.json  --output resnet50-v2-7-tvm_autotuned.tar resnet50-v2-7.onnxpython -m tvm.driver.tvmc run --inputs imagenet_cat.npz --output predictions.npz resnet50-v2-7-tvm_autotuned.tarpython postprocess.py

预测结果:
 

class='n02123045 tabby, tabby cat' with probability=0.610552
class='n02123159 tiger cat' with probability=0.367180
class='n02124075 Egyptian cat' with probability=0.019365
class='n02129604 tiger, Panthera tigris' with probability=0.001273
class='n04040759 radiator' with probability=0.000261

8) 比较编译前后执行模型的速度

python -m tvm.driver.tvmc run --inputs imagenet_cat.npz --output predictions.npz  --print-time --repeat 100 resnet50-v2-7-tvm_autotuned.tarpython -m tvm.driver.tvmc run --inputs imagenet_cat.npz --output predictions.npz  --print-time --repeat 100 resnet50-v2-7-tvm.tar

执行时间如下,上面是自动调优过的的,可以明显看出推理时间上的优化效果。 

Execution time summary:mean (ms)   median (ms)    max (ms)     min (ms)     std (ms)  84.6208      74.9435      143.9276     72.8249      19.0734 mean (ms)   median (ms)    max (ms)     min (ms)     std (ms)  131.1953     130.7819     140.6614     106.0725      3.5606

比较了一下两个编译后模型的Relay计算图json文件的区别,就看到了算子数据layout的区别,更多细节还是要看源码吧

参考:TVM Ubuntu20安装_ubuntu20.04配置tvm_shelgi的博客-CSDN博客

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

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

相关文章

DockerCompose修改某个服务的配置(添加或编辑端口号映射)后如何重启单个服务使其生效

场景 docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例: docker-compose入门以及部署SpringBootVueRedisMysql(前后端分离项目)以若依前后端分离版为例_docker-compose部署java mysql redis-CSDN博客 上面讲了docker c…

【Vue】【uni-app】实现发起工单页面

修改了上次的导航栏为二级导航 <template><view class"leftNav"><div class"logo">显鹅易见</div><uni-collapse class"item" accordion"true"><uni-collapse-item title"养殖场总部">…

多线程(补充知识)

STL库&#xff0c;智能指针和线程安全 STL中的容器是否是线程安全的? 不是. 原因是, STL 的设计初衷是将性能挖掘到极致, 而一旦涉及到加锁保证线程安全,会对性能造成巨大的影响. 而且对于不同的容器, 加锁方式的不同, 性能可能也不同(例如hash表的锁表和锁桶). 因此 STL 默认…

基于LNMP快速搭建WordPress平台

目录 1 LNMP简介 2 WordPress简介 3 安装MySQL环境 3.1 安装MySQL 3.1.1 下载wget工具 3.1.2 下载MySQL官方yum源安装包 3.1.3 安装MySQL官方yum源 3.1.4 mysql安装 3.2 启动MySQL 3.3 获取默认密码 3.4 登录MySQL ​ 3.5 修改密码 3.6 创建WordPress数据库并授权 3.6.1 创…

医疗影像数据集—CT、X光、骨折、阿尔茨海默病MRI、肺部、肿瘤疾病等图像数据集

最近收集了一大波关于CT、X光等医疗方面的数据集包含骨折、阿尔茨海默病MRI、肺部疾病等类型的医疗影像数据&#xff0c;废话不多说&#xff0c;给大家逐一介绍&#xff01;&#xff01; 1、彩色预处理阿尔茨海默病MRI(磁共振成像)图像数据集 彩色预处理阿尔茨海默病MRI(磁共…

【沐风老师】3DMAX拼图建模工具MaxPuzzle2D插件使用方法详解

MaxPuzzle2D拼图建模工具使用帮助 MaxPuzzle2D拼图建模工具&#xff0c;拼图建模“彩虹系列”插件&#xff0c;是一款用MAXScript脚本语言开发的3dMax拼图建模小工具&#xff0c;可以创建2D或3D的拼图图形阵列。这让需要拼图建模的设计师大大节省了时间。 MaxPuzzle2D工具界面&…

电荷泵升压/降压电路

一、升压\降压电路原理分析 1、升压电路 电荷泵升压电路 VoutVa5V 5V_PLUS0V时&#xff0c;Va给C2充电&#xff0c;C2上节点电压比C2下节点电压高Va&#xff1b; 5V_PLUS5V时&#xff0c;C2电压不能突变&#xff0c;C2上节点电压依然比C2下节点电压高Va&#xff0c;但C2下节点…

C++单调向量(栈):好子数组的最大分数

作者推荐 利用广度优先或模拟解决米诺骨牌 题目 给你一个整数数组 nums &#xff08;下标从 0 开始&#xff09;和一个整数 k 。 一个子数组 (i, j) 的 分数 定义为 min(nums[i], nums[i1], …, nums[j]) * (j - i 1) 。一个 好 子数组的两个端点下标需要满足 i < k <…

STM32之模数转换器ADC

目录 1、ADC介绍 1.什么是ADC&#xff1f; ADC的全称是Analog-to-Digital Converter&#xff0c;指模拟/数字转换器 2.ADC的性能指标 3.ADC特性 12位分辨率 4.ADC通道 5.ADC转换顺序 6.ADC触发方式 7.ADC转化时间 8.ADC转化模式 9.模拟看门狗 实验&#xff1a;使用ADC读…

SpringSecurity+JWT实现权限控制以及安全认证

一.简介 Spring Security 是 Spring家族中的一个安全管理框架。相比与另外一个安全框架Shiro&#xff0c;它提供了更丰富的功能&#xff0c;社区资源也比Shiro丰富。 认证&#xff1a;验证当前访问系统的是不是本系统的用户&#xff0c;并且要确认具体是哪个用户​ 授权&…

Cesium 添加一个立方体实体。

Cesium 添加一个立方体实体 初始化地球 viewer new Cesium.Viewer(content, {terrainProvider: Cesium.createWorldTerrain({requestVertexNormals: true,requestWaterMask: true})})添加一个立方体 const redBox viewer.entities.add({name: 一个红色的正方形,position: …

【08】Python运算符

文章目录 1.算术运算符2.赋值运算符3.条件运算符4.逻辑运算符5.比较运算符6.运算符的优先级本期博客中,我们将学习python中常用的运算符的用法。              1.算术运算符 1.加法运算符(+): a = 10 b = 5 c = a + b print(c