TVM:在樹莓派上部署預訓練的模型

TVM:在樹莓派上部署預訓練的模型

之前我們已經介紹如何通過Python接口(AutoTVM)來編譯和優化模型。本文將介紹如何在遠程(如本例中的樹莓派)上部署預訓練的模型。

在設備上構建 TVM Runtime

首先我們需要再遠程設備上安裝 TVM。

注意:本節和下一節中的所有指令都應在目標設備上執行,例如 樹莓派。 我們假設它運行著 Linux。

由于我們在本地機器上進行編譯,因此遠程設備僅用于運行生成的代碼。 我們只需要在遠程設備上構建 TVM Runtime。這里在我們安裝 tvm 的文章中已經詳細介紹過了,不再贅述。需要提一下的是建議在樹莓派上也安裝 llvm,并在安裝 tvm 時指定對應的路徑。

可參考:TVM:源碼編譯安裝

git clone --recursive https://github.com/apache/tvm tvm
cd tvm
mkdir build
cp cmake/config.cmake build
cd build
cmake ..
make runtime -j4

構建成功后配置 Python 包路徑:

export PYTHONPATH=$PYTHONPATH:/path/to/tvm/python

在遠程設備上設置 RPC 服務器

在遠程設備(如本例中的樹莓派)上運行以下命令來開啟 RPC 服務器:

python -m tvm.exec.rpc_server --host 0.0.0.0 --port=9090

如果看到下面這行說明遠程設備上的 RPC 服務已經成功開啟了:

INFO:root:RPCServer: bind to 0.0.0.0:9090

準備預訓練的模型

回到我們的主機(其上應該安裝了完整的 TVM),不同與之前使用onnx模型,這次我們使用mxnet的模型(起始都一樣,這里只是介紹另外一種模型來源)。

不同于之前在本機上的程序,我們這里通過 MXNet 來加載模型。

加載模型、測試圖像和 sysnet(用來將 ImageNet 的標簽轉換成類別名):

from mxnet.gluon.model_zoo.vision import get_model
from PIL import Image
import numpy as np# 一行即獲取模型
block = get_model("resnet18_v1", pretrained=True)# 獲取圖像并做相應轉換
img_url = "https://github.com/dmlc/mxnet.js/blob/main/data/cat.png?raw=true"
img_name = "cat.png"
img_path = download_testdata(img_url, img_name, module="data")
image = Image.open(img_path).resize((224, 224))def transform_image(image):image = np.array(image) - np.array([123.0, 117.0, 104.0])image /= np.array([58.395, 57.12, 57.375])image = image.transpose((2, 0, 1))image = image[np.newaxis, :]return imagex = transform_image(image)# sysnet 用來將 ImageNet 的類別標簽轉換為類別名稱
synset_url = "".join(["https://gist.githubusercontent.com/zhreshold/","4d0b62f3d01426887599d4f7ede23ee5/raw/","596b27d23537e5a1b5751d2b0481ef172f58b539/","imagenet1000_clsid_to_human.txt",]
)
synset_name = "imagenet1000_clsid_to_human.txt"
synset_path = download_testdata(synset_url, synset_name, module="data")
with open(synset_path) as f:synset = eval(f.read())

現在我們將 Gluon 模型移植到可移植的計算圖上:

# 我們在 mxnet.gluon 中支持 MXNet 靜態圖(符號)和 HybridBlock
shape_dict = {"data": x.shape}
mod, params = relay.frontend.from_mxnet(block, shape_dict)
# 我們要的是概率值,所以加上 softmax 算子
func = mod["main"]
func = relay.Function(func.params, relay.nn.softmax(func.body), None, func.type_params, func.attrs)

以下是一些基本的數據工作負載配置:

batch_size = 1
num_classes = 1000
image_shape = (3, 224, 224)
data_shape = (batch_size,) + image_shape

編譯圖

我們調用帶有圖配置和參數的 relay.build() 函數來編譯圖。 但是,我們不能在具有 ARM 指令集的設備上部署 x86 程序。 也就是說我們還需要告訴 Relay 目標設備的編譯選項,除了 net 和 params 參數來指定深度學習工作負載。 選項也很重要,不同的選項會導致性能有巨大差異。

如果我們在 x86 服務器上運行示例進行演示,直接將其設置為 llvm 即可。 如果在遠程設備樹莓派上運行,我們需要指定它的指令集。 如果要在真實設備上運行本教程,請將 local_demo 設置為 False。

另外,要注意的是,官方給出的例程是針對樹莓派3B,其指令集是ARMv7,而這里如果是樹莓派4B,需要修改 target 為 aarch64。即在下面改為 target = 'llvm -mtriple=aarch64-linux-gnu'

local_demo = Trueif local_demo:target = tvm.target.Target("llvm")
else:target = tvm.target.arm_cpu("rasp3b")# 上面這行是下面這行的簡單形式# target = tvm.target.Target('llvm -device=arm_cpu -model=bcm2837 -mtriple=armv7l-linux-gnueabihf -mattr=+neon')with tvm.transform.PassContext(opt_level=3):lib = relay.build(func, target, params=params)# 在 `relay.build` 之后, 我們將得到三個返回值:圖(graph),庫(library)和新的參數(new parameter), 因為我們需要做一些優化,這可能會改變某些參數但是保證模型的輸出結果不變# 將庫(library)保存為本地臨時目錄
tmp = utils.tempdir()
lib_fname = tmp.relpath("net.tar")
lib.export_library(lib_fname)

此處輸出:

/workspace/python/tvm/relay/build_module.py:333: DeprecationWarning: Please use input parameter mod (tvm.IRModule) instead of deprecated parameter mod (tvm.relay.function.Function)DeprecationWarning,

通過 RPC 將模型進行遠程部署

通過 RPC,我們可以將模型從本機遠程部署到樹莓派上。

# 與遠程設備建立 RPC會話
if local_demo:remote = rpc.LocalSession()
else:# 這里是筆者ip,要改成你自己的host = "10.206.205.11"port = 9090remote = rpc.connect(host, port)# 將庫(library)上傳到遠程設備并加載它
remote.upload(lib_fname)
rlib = remote.load_module("net.tar")# 建立遠程 runtime模塊
dev = remote.cpu(0)
module = runtime.GraphModule(rlib["default"](dev))
# 設置輸入數據
module.set_input("data", tvm.nd.array(x.astype("float32")))
# 運行
module.run()
# 得到輸出
out = module.get_output(0)
# 得到 top1 分類結果
top1 = np.argmax(out.numpy())
print("TVM prediction top-1: {}".format(synset[top1]))

此處輸出:

TVM prediction top-1: tiger cat

Ref:

https://tvm.apache.org/docs/how_to/deploy_models/deploy_model_on_rasp.html

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

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

相關文章

2.2線性表的順序表

2.2.1線性表的順序表示和實現------順序映像 【順序存儲】在【查找時】的時間復雜度為【O(1)】,因為它的地址是連續的,只要知道首元素的地址,根據下標可以很快找到指定位置的元素 【插入和刪除】操作由于可能要在插入前或刪除后對元素進行移…

TVM:交叉編譯和RPC

TVM:交叉編譯和RPC 之前我們介紹了 TVM 的安裝、本機demo和樹莓派遠程demo。本文將介紹了在 TVM 中使用 RPC 進行交叉編譯和遠程設備執行。 通過交叉編譯和 RPC,我們可以在本地機器上編譯程序,然后在遠程設備上運行它。 當遠程設備資源有限…

2.3單鏈表的基本使用及其cpp示例

2.3線性表的鏈式表現與實現 2.3.1.1單鏈表 【特點: *用一組任意的存儲單元存儲線性表的數據元素 *利用指針實現用不同相鄰的存儲單元存放邏輯上相鄰的元素 *每個元素ai,除存儲本身信息外,還存儲其直接后繼的元素(后一個元素的地址…

TVM:簡介

TVM:簡介概述 Apache TVM 是一個用于 CPU、GPU 和機器學習加速器的開源機器學習編譯器框架。它旨在使機器學習工程師能夠在任何硬件后端上高效地優化和運行計算。本教程的目的是通過定義和演示關鍵概念,引導您了解 TVM 的所有主要功能。新用戶應該能夠從…

2.3.3單鏈表的雙向鏈表

2.3.3雙向鏈表 插入、刪除 指在前驅和后驅方向都能游歷(遍歷)的線性鏈表 雙向鏈表的每個結點有兩個指針域 【結構】:prior data next 雙鏈表通常采用帶頭結點的循環鏈表形式 可理解為首位相接的數據“圈”,每個結點都可以向前…

nvidia-smi 命令詳解

nvidia-smi 命令詳解 簡介 nvidia-smi - NVIDIA System Management Interface program nvidia smi(也稱為NVSMI)為來自 Fermi 和更高體系結構系列的 nvidia Tesla、Quadro、GRID 和 GeForce 設備提供監控和管理功能。GeForce Titan系列設備支持大多數…

2.4一元多項式的表示及相加,含cpp算法

2.4一元多項式的表示及相加 n階多項式的表示: n階多項式有n1項 指數按升冪排序 【 優點: 多項式的項數可以動態增長,不存在存儲溢出的問題插入,刪除方便,不移動元素 【表示: 有兩個數據域,一…

TVM:使用Tensor Expression (TE)來處理算子

TVM:使用Tensor Expression (TE)來處理算子 在本教程中,我們將聚焦于在 TVM 中使用張量表達式(TE)來定義張量計算和實現循環優化。TE用純函數語言描述張量計算(即每個表達式都沒有副作用)。當在 TVM 的整體…

4-數據結構-串的學習

4.1串類型的定義 1.串:(或字符串) 串是由多個字符組成的有限序列,記作:S‘c1c2c3…cn’ (n>0) 其中S是串的名字,‘c1c2c3…cn’ 是串值 ci是串中字符 n是串的長度,表示字符的數目 空串&a…

Linux下rm誤刪恢復 extundelete

Linux下rm誤刪恢復 extundelete 誤刪之后要第一時間卸載(umount)該分區,或者以只讀的方式來掛載(mount)該分區,否則覆寫了誰也沒辦法恢復。如果誤刪除的是根分區,最好直接斷電,進入…

5-數據結構-數組的學習

5.1數組的定義 定義: 由一組類型相同的數據元素構成的有序集合,每個數據元素稱為一個數據元素(簡稱元素),每個元素受n(n>1)個線性關系的約束,每個元素在n個線性關系中的序號i1、…

timm 視覺庫中的 create_model 函數詳解

timm 視覺庫中的 create_model 函數詳解 最近一年 Vision Transformer 及其相關改進的工作層出不窮,在他們開源的代碼中,大部分都用到了這樣一個庫:timm。各位煉丹師應該已經想必已經對其無比熟悉了,本文將介紹其中最關鍵的函數之…

C--數據結構--樹的學習

6.2.1二叉樹的性質 1.二叉樹 性質: 1.若二叉樹的層次從1開始,則在二叉樹的第i層最多有2^(i-1)個結點 2.深度為k的二叉樹最多有2^k -1個結點 (k>1) 3.對任何一顆二叉樹,如果其葉結點個數為n0,度為2的非葉結點個數…

TVM:使用 Schedule 模板和 AutoTVM 來優化算子

TVM:使用 Schedule 模板和 AutoTVM 來優化算子 在本文中,我們將介紹如何使用 TVM 張量表達式(Tensor Expression,TE)語言編寫 Schedule 模板,AutoTVM 可以搜索通過這些模板找到最佳 Schedule。這個過程稱為…

TVM:使用 Auto-scheduling 來優化算子

TVM:使用 Auto-scheduling 來優化算子 在本教程中,我們將展示 TVM 的 Auto-scheduling 功能如何在無需編寫自定義模板的情況下找到最佳 schedule。 與基于模板的 AutoTVM 依賴手動模板定義搜索空間不同,auto-scheduler 不需要任何模板。 用…

C語言—sort函數比較大小的快捷使用--algorithm頭文件下

sort函數 一般情況下要將一組數從的大到小排序或從小到大排序&#xff0c;要定義一個新的函數排序。 而我們也可以直接使用在函數下的sort函數&#xff0c;只需加上頭文件&#xff1a; #include<algorithm> using namespace std;sort格式&#xff1a;sort(首元素地址&…

散列的使用

散列 散列簡單來說&#xff1a;給N個正整數和M個負整數&#xff0c;問這M個數中的每個數是否在N中出現過。 比如&#xff1a;N&#xff1a;{1,2,3,4}&#xff0c;M{2,5,7}&#xff0c;其中M的2在N中出現過 對這個問題最直觀的思路是&#xff1a;對M中每個欲查的值x&#xff0…

關于C++中的unordered_map和unordered_set不能直接以pair作為鍵名的問題

關于C中的unordered_map和unordered_set不能直接以pair作為鍵名的問題 在 C STL 中&#xff0c;不同于有序的 std::map 和 std::set 是基于紅黑樹實現的&#xff0c;std::unordered_map 和 std::unordered_set 是基于哈希實現的&#xff0c;在不要求容器內的鍵有序&#xff0c…

AI編譯器與傳統編譯器的聯系與區別

AI編譯器與傳統編譯器的區別與聯系 總結整理自知乎問題 針對神經網絡的編譯器和傳統編譯器的區別和聯系是什么&#xff1f;。 文中提到的答主的知乎主頁&#xff1a;金雪鋒、楊軍、藍色、SunnyCase、貝殼與知了、工藤福爾摩 筆者本人理解 為了不用直接手寫機器碼&#xff0…

python學習1:注釋\變量類型\轉換函數\轉義字符\運算符

python基礎學習 與大多數語言不同&#xff0c;python最具特色的就是使用縮進來表示代碼塊&#xff0c;不需要使用大括號 {} 。縮進的空格數是可變的&#xff0c;但是同一個代碼塊的語句必須包含相同的縮進空格數。 &#xff08;一個tab4個空格&#xff09; Python語言中常見的…