使用 TVMC 编译和优化模型

news2024/10/6 20:31:30

内容一览:本节讲解使用 TVMC 编译和优化模型。TVMC 是 TVM 的命令驱动程序,通过命令行执行 TVM 功能。本节是了解 TVM 工作原理的基础。

关键词:TVMC   TVM   机器学习   

本节将介绍 TVMC(TVM 的命令行驱动程序)。TVMC 通过命令行界面执行 TVM 功能(包括对模型的自动调优、编译、分析和执行)。

学完本节后,可用 TVMC 实现下面的任务:

  •  为 TVM runtime 编译预训练的 ResNet-50 v2 模型。

  •  用编译好的模型预测真实图像,并解释输出和模型性能。

  •  使用 TVM 在 CPU上调优模型。

  •  用 TVM 收集的调优数据,重新编译优化过的模型。

  •  通过优化的模型预测图像,并比较输出和模型性能。

本节对 TVM 及 TVMC 的功能进行了概述,并为了解 TVM 的工作原理奠定基础。

使用 TVMC

TVMC 是 Python 应用程序,也是 TVM Python 软件包的一部分。用 Python 包安装 TVM 时,会得到一个叫 tvmc 的命令行应用程序。平台和安装方法不同,此命令的位置也会发生变化。

另外,如果 $PYTHONPATH 上有 TVM 这个 Python 模块,则可通过可执行 Python 模块(用 python -m tvm.driver.tvmc 命令)来访问命令行驱动功能。

本教程用 tvmc 或 python -m tvm.driver.tvmc 来打开 TVMC 命令行。

使用如下命令查看帮助页:

tvmc --help

tvmc 可用的 TVM 的主要功能来自子命令 compilerun 和 tune。使用 tvmc--help 查看给定子命令的特定选项。

本教程将介绍这些命令,开始前请先下载一个预训练的模型。

获取模型

在本教程中,我们将使用 ResNet-50 v2。ResNet-50 是一个用来对图像进行分类的 50 层深的卷积神经网络。接下来要用的模型,已经在超过100万张具有1000种不同分类的图像上,进行了预训练。该网络的输入图像的大小为224x224。

推荐下载 Netron(免费的 ML 模型查看器)来更深入地探索 ResNet-50 模型的组织结构。

下载 Netron:https://netron.app/

本教程使用 ONNX 格式的模型:

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

Tips 1 支持的模型格式: 

TVMC 支持用 Keras、ONNX、TensorFlow、TFLite 和 Torch 创建的模型。可用 --model-format 选项指明正在使用的模型格式。执行 tvmc compile --help 来获取更多信息。

 Tips 2 向 TVM 添加对 ONNX 的支持 

TVM 依赖系统中可用的 ONNX Python 库。用命令 pip3 install --user onnx onnxoptimizer 来安装 ONNX。如果具有 root 访问权限并且希望全局安装 ONNX,则可以删除 --user 选项。onnxoptimizer 依赖是可选的,仅用于 onnx>=1.9 。

将 ONNX 模型编译到 TVM Runtime

下载 ResNet-50 模型后,用 tvmc compile 对其进行编译。编译的输出结果是模型(被编译为目标平台的动态库)的 TAR 包。用 TVM runtime 可在目标设备上运行该模型:

# 大概需要几分钟,取决于设备
tvmc compile \
--target "llvm" \
--input-shapes "data:[1,3,224,224]" \
--output resnet50-v2-7-tvm.tar \
resnet50-v2-7.onnx

查看 tvmc compile 在模块中创建的文件:

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

解压后有三个文件:

mod.so 是可被 TVM runtime 加载的模型,表示为 C++ 库。

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

mod.params 是包含预训练模型参数的文件。

模块可由应用程序直接加载,而模型可通过 TVM runtime API 运行。

Tips 3 定义正确的 TARGET

指定正确的 target(选项 --target )可大大提升编译模块的性能,因为可利用 target 上可用的硬件功能。参阅 针对 x86 CPU 自动调优卷积网络 获取更多信息。建议确定好使用的 CPU 型号以及可选功能,然后适当地设置 target。

使用 TVMC 运行来自编译模块的模型

将模型编译到模块后,可用 TVM runtime 对其进行预测。 TVMC 具有内置的 TVM runtime,允许运行已编译的 TVM 模型。

要用 TVMC 运行模型并预测,需要:

  •  刚生成的编译模块。

  •  用来预测的模型的有效输入。

模型的张量 shape、格式和数据类型各不相同。因此,大多数模型都需要预处理和后处理,确保输入有效,并能够解释输出。TVMC 采用了 NumPy 的 .npz 格式的输入和输出,可很好地支持将多个数组序列化到一个文件中。

本教程中的图像输入使用的是一张猫的图像,你也可以根据喜好选择其他图像。

 

输入预处理

ResNet-50 v2 模型的输入应该是 ImageNet 格式。下面是 ResNet-50 v2 预处理图像的脚本示例。

首先用 pip3 install --user pillow 下载 Python 图像库,以满足脚本运行对图像库的依赖。

#!python ./preprocess.py
from tvm.contrib.download import download_testdata
from PIL import Image
import numpy as np

img_url = "https://s3.amazonaws.com/model-server/inputs/kitten.jpg"
img_path = download_testdata(img_url, "imagenet_cat.png", module="data")

# 重设大小为 224x224
resized_image = Image.open(img_path).resize((224, 224))
img_data = np.asarray(resized_image).astype("float32")

# ONNX 需要 NCHW 输入, 因此对数组进行转换
img_data = np.transpose(img_data, (2, 0, 1))

# 根据 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]

# 添加 batch 维度
img_data = np.expand_dims(norm_img_data, axis=0)

# 保存为 .npz(输出 imagenet_cat.npz)
np.savez("imagenet_cat", data=img_data)

运行编译模块

有了模型和输入数据,接下来运行 TVMC 进行预测:

tvmc run \
--inputs imagenet_cat.npz \
--output predictions.npz \
resnet50-v2-7-tvm.tar

.tar 模型文件中包括一个 C++ 库、对 Relay 模型的描述文件,以及模型的参数文件。TVMC 包括 TVM runtime(可加载模型,并对输入进行预测)。运行以上命令,TVMC 会输出一个新文件 predictions.npz,其中包含 NumPy 格式的模型输出张量。

在此示例中,用于编译模型的和运行模型的是同一台机器。某些情况下,可能会用 RPC Tracker 来远程运行它。查看 tvmc run --help 来了解有关这些选项的更多信息。

输出后处理

如前所述,每个模型提供输出张量的方式都不一样。

本示例中,我们需要用专为该模型提供的查找表,运行一些后处理(post-processing),从而使得 ResNet-50 v2 的输出形式更具有可读性。

下面的脚本是一个后处理示例,它从编译模块的输出中提取标签:

#!python ./postprocess.py
import os.path
import numpy as np

from scipy.special import softmax

from tvm.contrib.download import download_testdata

# 下载标签列表
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"

# 打开并读入输出张量
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]))

这个脚本的运行输出如下:

python postprocess.py
# class='n02123045 tabby, tabby cat' with probability=0.610553
# class='n02123159 tiger cat' with probability=0.367179
# class='n02124075 Egyptian cat' with probability=0.019365
# class='n02129604 tiger, Panthera tigris' with probability=0.001273
# class='n04040759 radiator' with probability=0.000261

用其他图像替换上述猫的图像,看看 ResNet 模型做了什么样的预测。

自动调优 ResNet 模型

以前的模型被编译到 TVM runtime 上运行,因此不包含特定于平台的优化。本节将介绍如何用 TVMC,针对工作平台构建优化模型。

用编译的模块推理,有时可能无法获得预期的性能。在这种情况下,可用自动调优器更好地配置模型,从而提高性能。TVM 中的调优是指,在给定 target 上优化模型,使其运行得更快。与训练或微调不同,它不会影响模型的准确性,而只会影响 runtime 性能。

作为调优过程的一部分,TVM 实现并运行许多不同算子的变体,以查看哪个性能最佳。这些运行的结果存储在调优记录文件(tune 命令的最终输出)中。

调优最少要包含:

  •  运行此模型的目标设备的平台要求

  •  存储调优记录的输出文件的路径

  •  要调优的模型的路径。

下面的示例演示了其工作流程:

# 默认搜索算法需要 xgboost,有关调优搜索算法的详细信息,参见下文
pip install xgboost

tvmc tune \
--target "llvm" \
--output resnet50-v2-7-autotuner_records.json \
resnet50-v2-7.onnx

此例中,为 --target 标志指定更具体的 target 时,会得到更好的结果。例如,在 Intel i7 处理器上,可用 --target llvm -mcpu=skylake。这个调优示例把 LLVM 作为指定架构的编译器,在 CPU 上进行本地调优。

TVMC 针对模型的参数空间进行搜索,为算子尝试不同的配置,然后选择平台上运行最快的配置。虽然这是基于 CPU 和模型操作的引导式搜索,但仍需要几个小时才能完成搜索。搜索的输出将保存到 resnet50-v2-7-autotuner_records.json 文件中,该文件之后会用于编译优化模型。

Tips 4 定义调优搜索算法:

这个搜索算法默认用 XGBoost Grid 算法进行引导。根据模型复杂度和可用时间,可选择不同的算法。完整列表可查看 tvmc tune --help

对于消费级的 Skylake CPU,输出如下:

 

使用调优数据编译优化模型

从上述调优过程的输出文件 `resnet50-v2-7-autotuner_records.json 可获取调优记录。

该文件可用来:

  •  作为进一步调优的输入(通过 tvmc tune --tuning-records )

  •  作为编译器的输入

执行 tvmc compile --tuning-records 命令让编译器利用这个结果为指定 target 上的模型生成高性能代码。查看 tvmc compile --help 来获取更多信息。

模型的调优数据收集到后,可用优化的算子重新编译模型来加快计算速度。

tvmc compile \
--target "llvm" \
--tuning-records resnet50-v2-7-autotuner_records.json  \
--output resnet50-v2-7-tvm_autotuned.tar \
resnet50-v2-7.onnx

验证优化模型是否运行并产生相同结果:

tvmc run \
--inputs imagenet_cat.npz \
--output predictions.npz \
resnet50-v2-7-tvm_autotuned.tar

python postprocess.py

验证预测值是否相同:

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

比较调优和未调优的模型

TVMC 提供了模型之间的基本性能评估工具。可指定重复次数,也可指定 TVMC 报告模型的运行时间(独立于 runtime 启动)。可大致了解调优对模型性能的提升程度。

例如,对 Intel i7 系统进行测试时,调优后的模型比未调优的模型运行速度快 47%:

tvmc run \
--inputs imagenet_cat.npz \
--output predictions.npz  \
--print-time \
--repeat 100 \
resnet50-v2-7-tvm_autotuned.tar

# Execution time summary:
# mean (ms)   max (ms)    min (ms)    std (ms)
#     92.19     115.73       89.85        3.15

tvmc run \
--inputs imagenet_cat.npz \
--output predictions.npz  \
--print-time \
--repeat 100 \
resnet50-v2-7-tvm.tar

# Execution time summary:
# mean (ms)   max (ms)    min (ms)    std (ms)
#    193.32     219.97      185.04        7.11

写在最后

本教程介绍了 TVMC( TVM 的命令行驱动程序),演示了如何编译、运行和调优模型,还讨论了对输入和输出进行预处理和后处理的必要性。调优后,演示如何比较未优化和优化模型的性能。

本文档展示了一个在本地使用 ResNet-50 v2 的简单示例。然而,TVMC 支持更多功能,包括交叉编译、远程执行和分析/基准测试。

用 tvmc --help 命令查看其他可用选项。

下个教程 Compiling and Optimizing a Model with the Python Interface 将介绍用 Python 接口的相同编译和优化步骤。

​持续关注,不要错过~

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

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

相关文章

单片机扫盲

一、从电路到集成电路 集成电路:使用微器件为“积木”,去搭建一个具备一定功能的电路板 微器件出现之前,一个电路功能需要很大一块电路板才能实现,有了微器件电路板的体积可以降到mm级别。 IC芯片就是将电路的所有微器件集成到一…

大数据时代,数据仓库究竟是干嘛的?

前言 无论你是否专门从事大数据开发,作为一个开发人员,应该都听说过数据仓库的概念,那你知道为什么会出现数据仓库?数据仓库究竟是干嘛的吗?有什么价值和意义呢?那么本文就带到入门,揭开数据仓…

大数据分析工具-FineReport地产行业通用单选按钮组控件插件

1. 概述 1.1 版本 报表服务器版本 JAR 包版本 插件版本 10.0 2018-09-05 V1.3.4 9.0 2015-08-09 V1.3.2 8.0 2015-08-09 V1.3.2 1.2 应用场景 地产行业具有比较特殊的筛选需求,而现有的单选按钮组控件不能很好的满足这一点。我们希望可以实现多层级多…

空间音频技术与生态发展高峰论坛成功举办,业界首个Audio Vivid创作工具花瓣三维声亮相

11月26日至27日,UWA世界超高清视频产业联盟(以下简称“UWA联盟”)、上海交通大学-南加州大学文化创意产业学院、华为联合举办了“互联智慧,共赢未来” 超高清音视频技术与生态发展高峰论坛暨Audio Vivid空间音频工具花瓣三维声训练…

Nocas环境隔离

Nocas环境隔离配置 为了做数据和服务的管理,引出了环境隔离的一个概念。 Nocas中服务存储和数据存储的最外层都是一个名为namespace的东西,用来做最外层隔离。 .yml 配置文件中配置: spring:application:name: orderservicecloud:nacos:se…

OH----Usb rndis,mtp等function添加,config配置

1、驱动侧添加对应功能的驱动代码: 在linux中usb驱动代码中添加rndis或者mtp等功能驱动代码, 路径: linux-5.10/drivers/usb/gadget/function linux usb驱动原生功能代码一般可以直接使用,添加进去参与编译就能继续往下做调试了&…

【校招项目】基于C++11的muduo库

基于C11的网络库 文章目录基于C11的网络库项目介绍项目地址项目特点开发环境并发模型构建项目运行案例模块讲解ChannelPollerEventLoopBufferTimerHTTP异步日志内存池数据库连接池优化计划感谢项目介绍 本项目是参考 muduo 实现的基于 Reactor 模型的多线程网络库。使用 C 11 …

如何高效存储中高频多因子

2022年12月1日晚7点半,DolphinDB 进行了以「中高频多因子库存储最佳实践」为主题的直播,吸引了众多专业观众的注意。本文将回顾直播精彩内容。 DolphinDB 的因子库: 为了使广大用户更方便地实现因子计算和管理,助力更高效的投研…

[附源码]Node.js计算机毕业设计大学生专业实习管理系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

C/C++ 高精度(加减乘除)算法简单实现

文章目录前言一、基本原理1、存储方式2、计算方式二、辅助方法1、字符串转高精度2、整型转高精度3、比较4、打印三、算法实现1、加法2、减法3、乘法4、除法四、使用示例1、加法2、减法3、乘法4、除法总结前言 由于上一章《C/C 高精度(加减乘除)算法实现…

NetSuite资产负债表编制技巧

在最近的项目上,发现大家对NetSuite资产负债的编制参数缺乏足够的了解,导致对客户需求的支支吾吾,产生了沟通上的浪费。所以今朝对三个典型应用做个介绍。 1. 如何在资产负债表中选择“会计期间区间”? 2. 期初、发生、结余报表…

【元宇宙欧米说】Web3如何为漫画产业创造更多玩法和可能性

漫画和NFT的碰撞会产生什么火花?NFT如何为传统的漫画收藏增加额外价值?Web3时代如何为漫画带来更多玩法和可能性? 12月15日下午三点,MadManga 创始人Jun将以“Web3如何为漫画产业创造更多玩法和可能性”为题,与大家共…

构建文本摘要Baseline并且开始训练

构建文本摘要Baseline并且开始训练 基于前面word2vec的原理与训练实践、seq2seq模型的原理与实践以及attention机制,已经分别写了相关的文章来记录,此篇文章就是基于前面所学,开始着手训练文本摘要模型,当然仅是一个比较普通的ba…

[附源码]Node.js计算机毕业设计大学体育馆预约系统Express

项目运行 环境配置: Node.js最新版 Vscode Mysql5.7 HBuilderXNavicat11Vue。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分离等等。 环境需要 1.运行环境:最好是Nodejs最新版,我…

vue框架搭建大屏自适应方案

vue框架搭建大屏自适应方案 1.可使用flexible.js rem实现宽高,字体自适应 附上flexible.js代码 (function flexible(window, document) {var docEl document.documentElement;var dpr window.devicePixelRatio || 1;// adjust body font sizefunction setBody…

NocasRule负载均衡与服务实例的权重设置

NocasRule负载均衡 .yml 配置文件配置 server:port: 8080 spring:application:name: orderservicecloud:nacos:server-addr: localhost:8848 #nocas服务地址discovery:cluster-name: HZ #集群名字 userservice: #要做配置的微服务名称ribbon:NFLoadBalancerRuleClassName: com…

游戏开发57课 性能优化14

5. 内存优化 内存优化目的是加快IO,防止卡主线程,防止频繁操作(创建/删除)内存,避免内存碎片化和占用过高。 5.1 缓存法 与CPU的缓存计算类似,思路是将需要重复创建的对象缓存起来,销毁时将它…

安装、启动与停止Apache服务

安装、启动与停止Apache服务 安装Apache相关软件 [rootcentos7 ~]# rpm -q httpd [rootcentos7-1 ~]# mkdir /opt/centos //创建目录/opt/centos [rootcentos7-1 ~]# mount /dev/cdrom /opt/centos //挂载光盘到/opt/centos 下 mount: /dev/sr0 写保护…

Spring Boot 3.0.0正式发布,Banner不再支持图片增强可观测性

本文已被https://yourbatman.cn收录;女娲Knife-Initializr工程可公开访问啦;程序员专用网盘https://wangpan.yourbatman.cn;技术专栏源代码大本营:https://github.com/yourbatman/tech-column-learning;公号后台回复“…

openCV(一)基础背景

1 认识计算机视觉 2012年AlexNet模型在ImageNet图像分类中获得比赛冠军,深度学习开始在计算机视觉领域流行。早期的计算机视觉主要集中在重建方面,2012年以后在感知和重建两个领域都受到了深度学习的影响。应用场景包括自动驾驶、机器视觉、安防监控、其…