编译 ONNX 模型
备注
单击 此处 下载完整的示例代码
本文将介绍如何用 Relay 部署 ONNX 模型。
首先安装 ONNX 包,最便捷的方法推荐安装 protobuf 编译器:
pip install --user onnx onnxoptimizer
或参考官方网站: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 教程 中的模型完全相同,跳过 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")
# 现在磁盘上有 super_resolution.onnx 模型
onnx_model = onnx.load(model_path)
加载测试图像
该模型接收大小为 224x224 的单个图像作为输入,输出沿每个轴放大 3 倍的图像(即大小为 672x672)。为适配输入的 shape,重新缩放猫图像,并转换为 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, :, :]
使用 Relay 编译模型
通常 ONNX 模型将输入值与参数值混合在一起,输入名称为 1,具体要查看模型文档来确定完整的输入和参数名称空间。
将 shape 字典传给 relay.frontend.from_onnx 方法,以便 Relay 知道哪些 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):
executor = relay.build_module.create_executor(
"graph", mod, tvm.cpu(0), target, params
).evaluate()
输出结果:
/workspace/python/tvm/relay/frontend/onnx.py:5785: UserWarning: Mismatched attribute type in ' : kernel_shape'
==> Context: Bad node spec for node. Name: OpType: Conv
warnings.warn(str(e))
/workspace/python/tvm/driver/build_module.py:268: UserWarning: target_host parameter is going to be deprecated. Please pass in tvm.target.Target(target, host=target_host) instead.
"target_host parameter is going to be deprecated. "