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博客
相关文章:
Ubuntu20.04部署TVM流程及编译优化模型示例
前言:记录自己安装TVM的流程,以及一个简单的利用TVM编译模型并执行的示例。 1,官网下载TVM源码 git clone --recursive https://github.com/apache/tvmgit submodule init git submodule update顺便完成准备工作,比如升级cmake版本…...
华为OD机试真题-两个字符串间的最短路径问题-2023年OD统一考试(C卷)
题目描述: 给定两个字符串,分别为字符串A与字符串B。例如A字符串为ABCABBA,B字符串为CBABAC可以得到下图m*n的二维数组,定义原点为(0, 0),终点为(m, n),水平与垂直的每一条边距离为1,映射成坐标系如下图。 从原点(0, 0)到(0, A)为水平边,距离为1,从(0, A)到(A, C)为垂…...
python try-except
相比于直接raise ValueError,使用try-except可以使程序在发生异常后仍然能够运行。 在try的部分中,当遇到第一个Error,就跳转到except中寻找对应类型的error,后续代码不再执行,如果try中有多个Error,注意顺…...
flutter开发实战-ValueListenableBuilder实现局部刷新功能
flutter开发实战-ValueListenableBuilder实现局部刷新功能 在创建的新工程中,点击按钮更新counter后,通过setState可以出发本类的build方法进行更新。当我们只需要更新一小部分控件的时候,通过setState就不太合适了,这就需要进行…...
通过时间交织技术扩展ADC采样速率的简要原理
前言 数据采集是将自然界中存在的模拟信号通过模数转换器(ADC)转换成数字信号,再对该数字信号进行相应的接收和处理。数据采集系统作为数据采集的手段,在移动通信、图向采集、无线电等领域有重要作用。随着电子信息技术的飞速发展…...
FluxMQ—2.0.8版本更新内容
FluxMQ—2.0.8版本更新内容 前言 FLuxMQ是一款基于java开发,支持无限设备连接的云原生分布式物联网接入平台。FluxMQ基于Netty开发,底层采用Reactor3反应堆模型,具备低延迟,高吞吐量,千万、亿级别设备连接࿱…...
计算机寄存器是如何实现的
冯诺依曼体系 冯诺依曼体系为现代计算机的设计和发展奠定了基础,它的核心思想和原则在当今计算机体系结构中仍然被广泛采用和应用。所以只要谈论计算机的组成就离不开冯诺依曼体系 作为核心组成部分的CPU除了由运算器和控制器组成之外,还有一些寄存器…...
两数之和 三数之和 哈希方法
两数之和 package com; import java.util.*; public class Test5 { //两数之和 public static void main(String[] args) { int[] arr {1,2,3,4,5,6,7,94,42,35}; int target99; Arrays.sort(arr);//快速排序 for(int i0;i<arr.length;i) { int wtarget-arr[i]; int indexA…...
Object Detection in 20 Years: A Survey(2019.5)
文章目录 Abstract1. Introduction1.1. Difference from other related reviews1.2. Difficulties and Challenges in Object Detection 2. OBJECT DETECTION IN 20 YEARS2.1. 目标检测路线图2.1.1. 里程碑:传统探测器(粗略了解)2.1.2. 里程碑:基于CNN的…...
Springboot 设置时区与日期格式
1.配置文件修改(范围修改) spring:jackson:# 东8 北京时区time-zone: GMT8# 日期格式date-format: yyyy-MM-dd HH:mm:ss 2.Java代码修改(范围修改) 2.1 时区 import org.springframework.context.annotation.Bean; import org.…...
从零开始学Go web——第一天
文章目录 从零开始学Go web——第一天一、Go与web应用简介1.1 Go的可扩展性1.2 Go的模块化1.3 Go的可维护1.4 Go的高性能 二、web应用2.1 工作原理2.2 各个组成部分2.2.1 处理器2.2.2 模板引擎 三、HTTP简介四、HTTP请求4.1 请求的文本数据4.2 请求方法4.2.1 请求方法类型4.2.2…...
6.Eclipse里下载Subclipse插件
方法一:从Eclipse Marketplace里面下载 具体操作:打开Eclipse --> Help --> Eclipse Marketplace --> 在Find中输入subclipse搜索 --> 找到subclipse点击install 方法二:从Install New Software里下载 具体操作:打开…...
家用洗地机哪个品牌最好最实用?热门洗地机测评
随着社会的不断进步,我们逐渐意识到日常生活中的许多任务需要消耗大量的时间和体力。一个典型的例子是卫生清洁工作,尤其是在大面积地区,如大型建筑物、商场或工厂。这些任务不仅繁琐,还可能影响生活质量和工作效率。为了应对这一…...
【C语言:自定义类型(结构体、位段、共用体、枚举)】
文章目录 1.结构体1.1什么是结构体1.2结构体类型声明1.3结构体变量的定义和初始化1.4结构体的访问 2.结构体对齐2.1如何对齐2.2为什么存在内存对齐? 3.结构体实现位段3.1什么是位段3.2位段的内存分配3.3位段的跨平台问题3.4位段的应用3.5位段使用注意事项 4.联合体4…...
【1day】华天软件 OAworkFlowService接口SQL注入漏洞学习
注:该文章来自作者日常学习笔记,请勿利用文章内的相关技术从事非法测试,如因此产生的一切不良后果与作者无关。 目录 一、漏洞描述 二、影响版本 三、资产测绘 四、漏洞复现...
Oracle(2-11)RMAN Backups
文章目录 一、基础知识1、RMAN Backup Concepts RMAN备份概念2、RMAN Backup Modes RMAN备份的类型3、Backup File Types 备份文件类型4、RMAN Backup Destinations RMAN备份目标5、Backup Constraints 备份约束6、Recovery Manager Backups 恢复管理器备份7、Characteristics …...
使用docker搭建『Gitea』私有仓库
文章目录 一、安装 docker 环境1、移除以前的 docker 相关包2、配置yum源3、安装 docker4、启动 docker 二、安装 docker compose1、安装docker compose2、赋予下载的docker-compose执行权限 三、安装 gitea1. 创建工作目录2. 创建 Docker Compose 文件3. 启动 Gitea4. 访问 Gi…...
CopyOnWriteArrayList怎么用
什么是CopyOnWriteArrayListCopyOnWriteArrayList常用方法CopyOnWriteArrayList源码详解CopyOnWriteArrayList使用注意点CopyOnWriteArrayList存在的性能问题CopyOnWriteArrayList 使用实例基本应用实例并发应用实例 拓展写时复制 什么是CopyOnWriteArrayList CopyOnWriteArra…...
旋转设备状态监测与预测性维护:提高设备可靠性的关键
在工业领域的各个行业中,旋转设备都扮演着重要的角色。为了确保设备的可靠运行和预防潜在的故障,旋转设备状态监测及预测性维护变得至关重要。本文将介绍一些常见的旋转设备状态监测方法,并探讨如何利用这些方法来实施预测性维护,…...
类和对象——(7)this指针
归纳编程学习的感悟, 记录奋斗路上的点滴, 希望能帮到一样刻苦的你! 如有不足欢迎指正! 共同学习交流! 🌎欢迎各位→点赞 👍 收藏⭐ 留言📝 人生就像骑单车,想保持平衡…...
回溯算法题型分类
题型一:排列、组合、子集相关问题 提示:这部分练习可以帮助我们熟悉「回溯算法」的一些概念和通用的解题思路。解题的步骤是:先画图,再编码。去思考可以剪枝的条件, 为什么有的时候用 used 数组,有的时候设…...
ApplicationRunner 类
优质博文:IT-BLOG-CN 在开发中可能会有这样的情景。需要在容器启动的时候执行一些内容。比如读取配置文件,数据库连接之类的。SpringBoot给我们提供了两个接口来帮助我们实现这种需求。这两个接口分别为CommandLineRunner和ApplicationRunner。他们的执…...
QT中的 容器(container)-大全
一、介绍 Qt库提供了一套通用的基于模板的容器类,可以用这些类存储指定类型的项。比如,你需要一个大小可变的QString的数组,则使用QVector<QString>。 这些容器类比STL(C标准模板库)容器设计得更轻量、更安全并…...
Docker配置镜像加速器
Ubuntu 安装/升级Docker客户端 推荐安装1.10.0以上版本的Docker客户端,参考文档docker-ce配置镜像加速器 针对Docker客户端版本大于 1.10.0 的用户 您可以通过修改daemon配置文件/etc/docker/daemon.json来使用加速器 sudo mkdir -p /etc/docker sudo t…...
飞致云1panel + 雷池WAF
可能有许多人都有这个需求:为自己的个人站点套上WAF,增加安全性,本文将介绍如何将1panel面板深度结合长亭雷池防火墙,实现为个人站点套上WAF并且自动续签ssl证书。 前提条件: 服务器IP已绑定域名 完整的1panel环境 …...
策略梯度简明教程
策略梯度方法 (PG:Policy Gradient) 是强化学习 (RL:Reinforcement Learning) 中常用的算法。 1、从库里的本能开始 PG的原理很简单:我们观察,然后行动。人类根据观察采取行动。 引用斯蒂芬库里的一句话: 你必须依靠…...
鸿蒙原生应用/元服务开发-利用picker选择器来多选相册图片
前言 在之前的时候,测试一个应用进入相册选择图片demo,利用了startAbilityForResult()方法,启动相对应的Ability来完成效果,但是这种方法有限制,一次只能获取一张图片,在完成某些功能测试的时候就很不方便。…...
java:封装统一的响应体code、data、msg、paging
背景 我们在写接口的时候一般不会直接返回给前端数据,而是会有响应体,比如 code、data、msg,这样就有一个统一的结构方便前端处理,那么今天就来封装一个统一的响应体 封装基本响应体 1、在 config 包里新建 ApiResponse.java …...
leetcode算法之栈
目录 1.删除字符串中的所有相邻重复项2.比较含退格的字符串3.基本计算器II4.字符串解码5.验证栈序列 1.删除字符串中的所有相邻重复项 删除字符串中的所有相邻重复项 class Solution { public:string removeDuplicates(string s) {string ret;//使用数组模拟栈操作for(auto …...
电脑上mp4视频文件无缩略图怎么办
前言:有时候电脑重装后电脑上的mp4视频文件无缩略图,视频文件数量比较多的时候查找比较麻烦 以下方法亲测有效: 1、下载MediaPreview软件 2、软件链接地址:https://pan.baidu.com/s/1bzVJpmcHyGxXNjnzltojtQ?pwdpma0 提取码&…...
网站开发合同履约/天津seo网站管理
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
做美国市场哪个网站好/百度影音在线电影
【问题】 在进入docker镜像后,我们一般缺少vim,需要安装,但是在更新的过程中往往会卡在working 的进度为0上。 【解决方法】 mv /etc/apt/sources.list /etc/apt/sources.list.bak echo "deb http://mirrors.163.com/debian/ jessie …...
网站图片怎么做缓存/东莞百度网站排名优化
mysql编程 基本语法 语句块模式: 在mysql编程中,begin…end;基本代替了原来编程语句中的{…}语法。 但又有所区别:一个bigin…end;块,可以给定一个“标识符”,并且可以使用leave语句来“退出”该语句块。 流程控制…...
wordpress4.2.15漏洞/网上开店如何推广自己的网店
数据从业者常在多种工具之间跳来跳去,这种碎片化导致了协作、共享和生产力方面的问题。 企业云数据量的增加以及数据转换、模型构建和可视化工具的出现,推动了现代数据堆栈的崛起。大部分公司都在加大对数据团队的投入,以适应不断变化的需求…...
网站建设公司要求什么/chrome浏览器官网入口
一、 打开终端(Terminal)下载源码: git clone https://github.com/Sunnyyoung/WeChatTweak- - macOS.git进入目录:cd WeChatTweak-macOS编译安装:sudo make install卸载动态库 sudo make uninstall打开微信客户端 二…...
百度右侧相关网站/全球最牛的搜索引擎
2019独角兽企业重金招聘Python工程师标准>>> 一、jQuery fadeIn() 用于淡入已隐藏的元素。 <!DOCTYPE html> <html> <head> <script src"/jquery/jquery-1.11.1.min.js"></script> <script> $(document).ready(func…...