使用Relay部署编译ONNX模型
使用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是模型的輸出。調整色度通道Cb和Cr的大小,以與簡單的雙三次算法匹配。然后將圖像重新組合并轉換回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模型的全部內容,希望文章能夠幫你解決所遇到的問題。
                            
                        - 上一篇: TVM交叉编译和远程RPC
 - 下一篇: Deep Learning部署TVM G