使用Relay部署编译ONNX模型

本文介绍如何使用Relay部署ONNX模型的入门。

首先,必须安装ONNX软件包。

一个快速的解决方案是安装protobuf编译器,然后

pip install onnx --user

或参考官方网站。 https://github.com/onnx/onnx

import onnx
import numpy as np
import tvm
from tvm import te
import tvm.relay as relay
from tvm.contrib.download import download_testdata

加载预训练的ONNX模型

使用的示例超分辨率模型与onnx教程http://pytorch.org/tutorials/advanced/super_resolution_with_caffe2.html中的模型完全相同,跳过pytorch模型构建部分,下载保存的onnx模型

model_url = "".join(
    [
        "https://gist.github.com/zhreshold/",
        "bcda4716699ac97ea44f791c24310193/raw/",
        "93672b029103648953c4e5ad3ac3aadf346a4cdc/",
        "super_resolution_0.2.onnx",
    ]
)
model_path = download_testdata(model_url, "super_resolution.onnx", module="onnx")
# now you have super_resolution.onnx on disk
onnx_model = onnx.load(model_path)

输出:

File /workspace/.tvm_test_data/onnx/super_resolution.onnx exists, skip.

加载测试图像

一只猫占主导地位的例子!此模型采用尺寸为224x224的单个输入图像,并输出比沿每个轴的输入大3x的缩放图像672x672图像。重新缩放猫咪图像以适合此输入形状,然后转换为YCbCr。然后,超分辨率模型将应用于亮度(Y)通道。

from PIL import Image
 
img_url = "https://github.com/dmlc/mxnet.js/blob/main/data/cat.png?raw=true"
img_path = download_testdata(img_url, "cat.png", module="data")
img = Image.open(img_path).resize((224, 224))
img_ycbcr = img.convert("YCbCr")  # convert to YCbCr
img_y, img_cb, img_cr = img_ycbcr.split()
x = np.array(img_y)[np.newaxis, np.newaxis, :, :]

输出:

File /workspace/.tvm_test_data/data/cat.png exists, skip.

用Relay编译模型

ONNX模型将模型输入值与参数值混合,输入的名称为1。此模型取决于模型,查阅模型的文档,确定完整的输入和参数名称空间。

将形状字典传递给relay.frontend.from_onnx方法,告诉中继哪些ONNX参数是输入,哪些是参数,并提供输入大小的静态定义。

target = "llvm"
 
input_name = "1"
shape_dict = {input_name: x.shape}
mod, params = relay.frontend.from_onnx(onnx_model, shape_dict)
 
with tvm.transform.PassContext(opt_level=1):
    intrp = relay.build_module.create_executor("graph", mod, tvm.cpu(0), target)

输出:

/workspace/docs/../python/tvm/relay/frontend/onnx.py:3132: UserWarning: Mismatched attribute type in ' : kernel_shape'
 
==> Context: Bad node spec: input: "1" input: "2" output: "11" op_type: "Conv" attribute { name: "kernel_shape" ints: 5 ints: 5 } attribute { name: "strides" ints: 1 ints: 1 } attribute { name: "pads" ints: 2 ints: 2 ints: 2 ints: 2 } attribute { name: "dilations" ints: 1 ints: 1 } attribute { name: "group" i: 1 }
  warnings.warn(str(e))

在TVM上执行

dtype = "float32"
tvm_output = intrp.evaluate()(tvm.nd.array(x.astype(dtype)), **params).asnumpy()

显示结果

将输入和输出图像并列放置。亮度通道Y是模型的输出。调整色度通道CbCr的大小,以与简单的双三次算法匹配。然后将图像重新组合并转换回RGB

from matplotlib import pyplot as plt
 
out_y = Image.fromarray(np.uint8((tvm_output[0, 0]).clip(0, 255)), mode="L")
out_cb = img_cb.resize(out_y.size, Image.BICUBIC)
out_cr = img_cr.resize(out_y.size, Image.BICUBIC)
result = Image.merge("YCbCr", [out_y, out_cb, out_cr]).convert("RGB")
canvas = np.full((672, 672 * 2, 3), 255)
canvas[0:224, 0:224, :] = np.asarray(img)
canvas[:, 672:, :] = np.asarray(result)
plt.imshow(canvas.astype(np.uint8))
plt.show()

Readme

默认情况下,ONNX根据动态形状定义模型。ONNX导入器在导入时会保留这种动态性,并且编译器会在编译时尝试将模型转换为静态形状。如果失败,则模型中可能仍存在动态操作。并非所有的TVM内核当前都支持动态形状,如果在使用动态内核时遇到错误,在ask.tvm.apache.org上提出问题。

该特定模型是使用较旧版本的ONNX构建的。在导入阶段,ONNX导入程序将运行ONNX验证程序,这可能会引发不匹配的属性类型警告。由于TVM支持许多不同的ONNX版本,中继模型仍然有效。

使用Relay部署编译ONNX模型的更多相关文章

  1. 编译ONNX模型Compile ONNX Models

    编译ONNX模型Compile ONNX Models 本文是一篇介绍如何使用Relay部署ONNX模型的说明. 首先,必须安装ONNX包. 一个快速的解决方案是安装protobuf编译器,然后 pi ...

  2. TVM部署预定义模型

    TVM部署预定义模型 本文通过深度学习框架量化的模型加载到TVM中.预量化的模型导入是在TVM中提供的量化支持之一. 本文演示如何加载和运行由PyTorch,MXNet和TFLite量化的模型.加载后 ...

  3. 使用protobuf编译onnx.proto过程中的一些问题总结

    使用git clone下载protobuf的源代码,然后git checkout到branch2.7.0: 编译protobuf,先在代码顶层目录执行./configure,然后执行make,成功后执 ...

  4. OpenStack部署的简单模型

    记录下看到的openstack部署的简单模型,方便自己以后定位问题 规划网络部署节点为一个controller节点(包含网络节点),两个compute节点.controller节点有3个网卡,分别为e ...

  5. 区块链学习(四)truffle部署编译智能合约以太坊私有链

    前面我们介绍了以太坊私有链的搭建以及多节点私有链网络,这次我们介绍如何使用truffle框架来部署编译智能合约到我们之前搭建的私有链网络中. 搭建环境及需使用的工具:ubuntu18.04  Truf ...

  6. flask部署深度学习模型

    flask部署深度学习模型 作为著名Python web框架之一的Flask,具有简单轻量.灵活.扩展丰富且上手难度低的特点,因此成为了机器学习和深度学习模型上线跑定时任务,提供API的首选框架. 众 ...

  7. 【推理引擎】ONNX 模型解析

    定义模型结构 首先使用 PyTorch 定义一个简单的网络模型: class ConvBnReluBlock(nn.Module): def __init__(self) -> None: su ...

  8. 使用ML.NET + ASP.NET Core + Docker + Azure Container Instances部署.NET机器学习模型

    本文将使用ML.NET创建机器学习分类模型,通过ASP.NET Core Web API公开它,将其打包到Docker容器中,并通过Azure Container Instances将其部署到云中. ...

  9. 深度学习Tensorflow生产环境部署(下·模型部署篇)

    前一篇讲过环境的部署篇,这一次就讲讲从代码角度如何导出pb模型,如何进行服务调用. 1 hello world篇 部署完docker后,如果是cpu环境,可以直接拉取tensorflow/servin ...

随机推荐

  1. 为什么有时博客中的代码复制进自己的VS中报错

    昨天写代码时遇到一个问题,我搜了一篇博客,然后复制到我的WPF中, 然后,全报错(当时快给我气死了,一篇有一篇的不能用,试了一次又一次,时间全浪费在这上面了,没打游戏,做的东西也没出来) 问题原因: ...

  2. UVA10970大块巧克力

    题意:       题意,给你一块n*m的巧克力,最终是要把他切成n*m快小蛋糕,问最小切多少刀?每一刀只能把一个整体切成两个整体,不可以把两个整体分成四个整体,就是说只能切一个地方. 思路:     ...

  3. Windows核心编程 第26章 窗口消 息

    窗 口 消 息 Wi n d o w s允许一个进程至多建立10 000个不同类型的用户对象(User object):图符.光标.窗口类.菜单.加速键表等等.当一个线程调用一个函数来建立某个对象时, ...

  4. 利用DNS进行命令控制和搭建隧道

    目录 利用DNS进行命令控制(DNS-Shell) 利用DNS搭建隧道 利用DNS进行命令控制(DNS-Shell) DNS-Shell是一款通过DNS信道实现交互式Shell的强大工具,该工具的服务 ...

  5. 【python】Leetcode每日一题-二叉搜索迭代器

    [python]Leetcode每日一题-二叉搜索迭代器 [题目描述] 实现一个二叉搜索树迭代器类BSTIterator ,表示一个按中序遍历二叉搜索树(BST)的迭代器: BSTIterator(T ...

  6. 使用git rebase去掉无谓的融合

    git pull 預設的行為是將遠端的 repo. 與本地的 repo. 合併,這也是 DVCS 的初衷,將兩個 branch 合併.但是,很多時候會發生以下這種情形: 這是因為,我們團隊的開發模式是 ...

  7. UVA OJ 10035 - Primary Arithmetic

    Primary Arithmetic Children are taught to add multi-digit numbers from right-to-left one digit at a ...

  8. win10下卸载ubuntu的合理操作

    这里不推荐使用第三方软件,因为可能会被植入病毒,而且windows自带的命令行工具足以完成任务! win10系统自带的一个命令行工具--diskpart 在cmd中输入"diskpart&q ...

  9. 【BUAA软工】Beta阶段设计与计划

    一.需求再分析 根据用户反馈,是否发现之前的需求分析有偏差?为什么会出现这种偏差?beta阶段你们是否能真的分析清楚用户需求?如何做到? 根据alpha阶段同学们以及课程组老师和助教的使用反馈,总结起 ...

  10. 『动善时』JMeter基础 — 15、使用JMeter实现上传文件

    目录 1.用于演示的项目说明 2.测试计划内包含的元件 3.HTTP请求界面内容 4.查看结果 5.总结 6.补充:MIME类型简介 (1)MIME说明 (2)常见类型 在上一篇文章[使用JMeter ...