TVM:編譯深度學習模型快速上手教程

TVM:編譯深度學習模型快速上手教程

本文將展示如何使用 Relay python 前端構建一個神經網絡,并使用 TVM 為 Nvidia GPU 生成一個運行時庫。 注意我們需要再構建 TVM 時啟用了 cuda 和 llvm。

TVM支持的硬件后端總覽

在這里插入圖片描述

在本教程中,我們使用 cuda 和 llvm 作為目標后端。我們先導入 Relay 和 TVM:

import numpy as npfrom tvm import relay
from tvm.relay import testing
import tvm
from tvm import te
from tvm.contrib import graph_executor
import tvm.testing

使用Relay定義一個神經網絡

首先,我們使用 relay 的 python 前端定義一個神經網絡。簡單起見,我們這里直接使用 relay 中預定義好的 resnet-18 網絡。參數按照 Xavier 初始化進行初始化。Relay 同樣支持其他的模型格式如 MXNet,CoreML,ONNX 和 TensorFlow。

本教程中,我們假設我們將會在自己的設備上進行推理,batch size 設為1。輸入是尺寸為 224 * 224 的 RGB 彩色圖像。我們可以調用 tvm.relay.expr.TupleWrapper.astext() 來查看網絡結構,

batch_size = 1
num_class = 1000
image_shape = (3, 224, 224)
data_shape = (batch_size,) + image_shape
out_shape = (batch_size, num_class)mod, params = relay.testing.resnet.get_workload(num_layers=18, batch_size=batch_size, image_shape=image_shape
)# set show_meta_data=True if you want to show meta data
print(mod.astext(show_meta_data=False))

輸出:

#[version = "0.0.5"]
def @main(%data: Tensor[(1, 3, 224, 224), float32], %bn_data_gamma: Tensor[(3), float32], %bn_data_beta: Tensor[(3), float32], %bn_data_moving_mean: Tensor[(3), float32], %bn_data_moving_var: Tensor[(3), float32], %conv0_weight: Tensor[(64, 3, 7, 7), float32], %bn0_gamma: Tensor[(64), float32], %bn0_beta: Tensor[(64), float32], %bn0_moving_mean: 
...
Tensor[(64), float32], %bn0_moving_var: Tensor[(64), float32], %stage1_unit1_bn1_gamma: %88 = nn.dense(%87, %fc1_weight, units=1000) /* ty=Tensor[(1, 1000), float32] */;%89 = nn.bias_add(%88, %fc1_bias, axis=-1) /* ty=Tensor[(1, 1000), float32] */;nn.softmax(%89) /* ty=Tensor[(1, 1000), float32] */
}

編譯

下一步就是使用 Relay/TVM 的流程進行編譯。用戶可以指定編譯的優化等級。目前優化等級可以設置為 0 到 3。優化的 pass 包括算子融合,預先計算,排布變換等。

relay.build() 返回三個組件:json 格式的執行圖、目標硬件上專門為此圖編譯函數的 TVM 模塊庫以及模型的參數 blob。 在編譯過程中,Relay 進行圖級優化,TVM 進行張量級優化,從而為模型推理服務提供優化的運行時模塊。

我們將首先為 Nvidia GPU 編譯。 relay.build() 首先在幕后進行了一些圖級優化,例如剪枝、融合等,然后將算子(即優化圖的節點)注冊到 TVM 實現以生成 tvm.module。 為了生成模塊庫,TVM 將首先將高層 IR 轉換為指定目標后端的低層固有 IR,在本例中為 CUDA。 然后生成機器代碼,得到模塊庫。

opt_level = 3
target = tvm.target.cuda()
with tvm.transform.PassContext(opt_level=opt_level):lib = relay.build(mod, target, params=params)

輸出:

/home/areusch/ws/tvm3/python/tvm/target/target.py:259: UserWarning: Try specifying cuda arch by adding 'arch=sm_xx' to your target.warnings.warn("Try specifying cuda arch by adding 'arch=sm_xx' to your target.")

運行生成的庫

現在,我們可以創建 graph executor 來將模塊運行在 Nvidia GPU 上。

# create random input
dev = tvm.cuda()
data = np.random.uniform(-1, 1, size=data_shape).astype("float32")
# create module
module = graph_executor.GraphModule(lib["default"](dev))
# set input and parameters
module.set_input("data", data)
# run
module.run()
# get output
out = module.get_output(0, tvm.nd.empty(out_shape)).numpy()# Print first 10 elements of output
print(out.flatten()[0:10])

輸出:

[0.00089283 0.00103331 0.0009094  0.00102275 0.00108751 0.001067370.00106262 0.00095838 0.00110792 0.00113151]

保存 / 加載編譯好的模塊

我們可以將 graph,lib 和 parameters 保存到文件中,并在部署的場景下來加載它們。(譯者注:這里的代碼會將模型保存在臨時文件中,想要保存模型,可以自己修改路徑)

# save the graph, lib and params into separate files
from tvm.contrib import utilstemp = utils.tempdir()
path_lib = temp.relpath("deploy_lib.tar")
lib.export_library(path_lib)
print(temp.listdir())

輸出:

['deploy_lib.tar']
# load the module back.
loaded_lib = tvm.runtime.load_module(path_lib)
input_data = tvm.nd.array(data)module = graph_executor.GraphModule(loaded_lib["default"](dev))
module.run(data=input_data)
out_deploy = module.get_output(0).numpy()# Print first 10 elements of output
print(out_deploy.flatten()[0:10])# check whether the output from deployed module is consistent with original one
tvm.testing.assert_allclose(out_deploy, out, atol=1e-5)

輸出:

[0.00089283 0.00103331 0.0009094  0.00102275 0.00108751 0.001067370.00106262 0.00095838 0.00110792 0.00113151]

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/532536.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/532536.shtml
英文地址,請注明出處:http://en.pswp.cn/news/532536.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

TVM:設計與架構

TVM:設計與架構 本文檔適用于想要了解 TVM 架構和/或積極開發項目的開發人員。頁面組織如下: 示例編譯流程概述了 TVM 將模型的高層描述轉換為可部署模塊所采取的步驟。要開始使用,請先閱讀本節。 邏輯架構組件部分描述了邏輯組件。后面的部…

遞歸+回溯

遞歸-回溯 本文參考自代碼隨想錄視頻: https://www.bilibili.com/video/BV1cy4y167mM https://www.bilibili.com/video/BV1ti4y1L7cv 遞歸回溯理論基礎 只要有遞歸,就會有回溯,遞歸函數的下面的部分通常就是回溯的邏輯。 回溯是純暴力的搜索…

Nvidia CUDA初級教程1 CPU體系架構綜述

Nvidia CUDA初級教程1 CPU體系架構綜述 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p2 講師:周斌 本節內容:了解現代CPU的架構和性能優化: 流水線 Pipelining分支預測 Branch Prediction超標量 Superscalar亂序執行 Out…

Nvidia CUDA初級教程2 并行程序設計概述

Nvidia CUDA初級教程2 并行程序設計概述 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p3 講師:周斌 本節內容: 為什么需要?怎么做?一些技術和概念 串并行計算模式 串行計算模式 常規軟件時串行的 設計運行…

Nvidia CUDA初級教程4 GPU體系架構概述

Nvidia CUDA初級教程4 GPU體系架構概述 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p5 講師:周斌 本節內容: 為什么需要GPU三種方法提升GPU的處理速度實際GPU的設計舉例: NVDIA GTX 480: FermiNVDIA GTX 680: Kepler GP…

Nvidia CUDA初級教程5 CUDA/GPU編程模型

Nvidia CUDA初級教程5 CUDA/GPU編程模型 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p6 講師:周斌 本節內容: CPU和GPU互動模式GPU線程組織模型(需要不停強化)GPU存儲模型基本的編程問題 CPU與GPU交互 各自…

Nvidia CUDA初級教程6 CUDA編程一

Nvidia CUDA初級教程6 CUDA編程一 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p7 講師:周斌 GPU架構概覽 GPU特別使用于: 密集計算,高度可并行計算圖形學 晶體管主要被用于: 執行計算而不是 緩存數據控制指令…

由前中后遍歷序列構建二叉樹

由前/中/后遍歷序列構建二叉樹 基礎 首先,我們需要知道前中后序三種深度優先遍歷二叉樹的方式的具體順序: 前序:中左右中序:左中右后序:左右中 另外,要知道只有中序前/后序可以唯一確定一棵二叉樹&…

手寫nms

手寫nms 計算寬高的時候加1是為什么? 本文總結自互聯網的多種nms實現,供參考,非博主原創,各原文鏈接如下,也建議大家動手寫一寫。 Ref: 淺談NMS的多種實現 目標窗口檢測算法-NMS非極大值抑制 一、fas…

目標檢測綜述

目標檢測綜述 轉自:https://zhuanlan.zhihu.com/p/383616728 論文參考:[Object Detection in 20 Years: A Survey][https://arxiv.org/abs/1905.05055] 引言 目標檢測領域發展至今已有二十余載,從早期的傳統方法到如今的深度學習方法&#x…

Nvidia CUDA初級教程7 CUDA編程二

Nvidia CUDA初級教程7 CUDA編程二 視頻:https://www.bilibili.com/video/BV1kx411m7Fk?p8 講師:周斌 本節內容: 內置類型和函數 Built-ins and functions線程同步 Synchronizing線程調度 Scheduling threads存儲模型 Memory model重訪 Matr…

詳解優酷視頻質量評價體系

萬字長文 | 詳解優酷視頻質量評價體系 分享嘉賓|李靜博士,阿里巴巴文娛集團資深算法專家,阿里巴巴大文娛摩酷實驗室視頻體驗與質量團隊負責人 整理出品|AICUG人工智能社區 本文地址:https://www.6aiq.com/article/1617…

視頻質量評價:挑戰與機遇

視頻質量評價:挑戰與機遇 轉自:https://zhuanlan.zhihu.com/p/384603663 本文整理自鵬城實驗室助理研究員王海強在LiveVideoStack線上分享上的演講。他通過自身的實踐經驗,詳細講解了視頻質量評價的挑戰與機遇。 文 / 王海強 整理 / LiveVi…

關于二分法的邊界問題及兩種寫法

關于二分法的邊界問題及兩種寫法 二分查找法大家很熟悉了,對于一個有序序列,我們可以通過二分查找法在 O(logN)O(logN)O(logN) 的時間內找到想要的元素。但是,在代碼實現的過程中,如果沒有仔細理解清楚,二分法的邊界條…

LeetCode上的各種股票最大收益

LeetCode上的各種股票最大收益 對于力扣平臺上的股票類型的題目: 121 買賣股票的最佳時機 122 買賣股票的最佳時機 II 123 買賣股票的最佳時機 III 124 買賣股票的最佳時機 IV 309 最佳買賣股票時機含冷凍期 714 買賣股票的最佳時機含手續費 劍指 Offer 63. …

建設專業化運維服務團隊必要性

信息系統的生命周期涵蓋:設計、開發、測試、部署上線、運行維護。其中,運行維護階段是信息系統生命周期中的關鍵環節,其執行效果直接影響系統是否能達到預期的運行目標。為了實現這個目標,我們必須建立一個以業務服務為導向的專業…

docker初探

docker初探 本文旨在介紹 docker 基本的安裝、常用命令和常見概念的辨析,方便新手入門和筆者日后查閱,大部分內容整理自互聯網,原出處在文中注明。 文章目錄docker初探docker安裝(mac)版本、信息相關命令version/info…

ubuntu安裝zsh、oh-my-zsh及常用配置

ubuntu安裝zsh、oh-my-zsh及常用配置 目前,ubuntu默認的shell是bash,但還有一種shell,叫做zsh它比bash更加強大,功能也更加完善,zsh雖說功能強大,但是配置比較復雜導致流行度不是很高 但是好東西終究是好…

Segmentaion標簽的三種表示:poly、mask、rle

Segmentaion標簽的三種表示:poly、mask、rle 不同于圖像分類這樣比較簡單直接的計算機視覺任務,圖像分割任務(又分為語義分割、實例分割、全景分割)的標簽形式稍為復雜。在分割任務中,我們需要在像素級上表達的是一張…

tensorboard報錯:ValueError Duplicate plugins for name projector 問題的出現及解決過程

tensorboard報錯:ValueError: Duplicate plugins for name projector 問題的出現及解決過程 記錄如題問題的出現及解決過程。 報錯命令及信息 筆者在終端調用 tensorboard 時: tensorboard --logdirruns/ --bind_all報錯: raise ValueEr…