?今天給大家介紹一下FPGA上部署深度學習的算法模型的方法以及平臺。希望通過介紹,算法工程師在FPGA的落地上能“稍微”緩和一些,小白不再那么迷茫。阿chai最近在肝一個開源的項目,等忙完了會給大家出幾期FPGA上從零部署的教程,包括一些底層的開發、模型的量化推理等等,因為涉及的東西太多了,所以得分開寫。
?
這個到底有多方便,我們看一段代碼,首先我們調用模型:
我們首先clone下來項目并且編譯: 對于ZYNQ+DPU的開發過程阿chai會單獨出一期,因為涉及的東西太多了。。。
其實部署的思路小伙伴們應該有一些眉目了,就是將自己訓練的深度學習模型轉換成Paddle Lite模型,然后移植到EdgeBoard開發板上進行測試。接下來我們簡單看看是怎樣操作的。EdgeBoard中模型的測試由json文件做管理:?g_predictor; ????PaddleMobileConfig?config; ????std::string?model_dir?=?j["model"]; ????config.precision?=?PaddleMobileConfig::FP32; ????config.device?=?PaddleMobileConfig::kFPGA; ????config.prog_file?=?model_dir?+?"/model"; ????config.param_file?=?model_dir?+?"/params"; ????config.thread_num?=?4; ????g_predictor?=?CreatePaddlePredictor(config); 2、輸入輸出參數?paddle_tensor_feeds; ????PaddleTensor?tensor; ????tensor.shape?=?std::vector<int>({1,?3,?input_height,?input_width}); ????tensor.data?=?PaddleBuf(input,?sizeof(input)); ????tensor.dtype?=?PaddleDType::FLOAT32; ????paddle_tensor_feeds.push_back(tensor); ????PaddleTensor?tensor_imageshape; ????tensor_imageshape.shape?=?std::vector<int>({1,?2}); ????tensor_imageshape.data?=?PaddleBuf(image_shape,?1?*?2?*?sizeof(float)); ????tensor_imageshape.dtype?=?PaddleDType::FLOAT32; ????paddle_tensor_feeds.push_back(tensor_imageshape); ????PaddleTensor?tensor_out; ????tensor_out.shape?=?std::vector<int>({}); ????tensor_out.data?=?PaddleBuf(); ????tensor_out.dtype?=?PaddleDType::FLOAT32; ????std::vector?outputs(1,?tensor_out) ; 3、預測
安裝paddlemobile-python SDK,在根目錄中解壓
FPGA與“迷宮”
深度學習這里就不多介紹了,我們接下來介紹一下FPGA是什么。FPGA是現場可編程邏輯門陣列,靈活性非常高,現場編程真的香。說到這里小伙伴們可能還是不太明白,那么我們和ARM對比一下,ARM可以理解為比如這有一個迷宮,迷宮有很多進口也有對應的出口,道路中間有很多“暗門”可以走,對ARM芯片做編程就是觸發當中一條通路,路是死的,我們不好改變。FPGA是如果我們想要一個迷宮,FPGA給提供了一個大的“盒子”,里面有很多的“隔板”,我們自己搭建一條就可以了,你想要什么樣的路就什么樣子,類似玩我的世界,只不過“礦”是各種邏輯門。那就意味著,FPGA可以設計外圍電路也可以設計CPU,是不是很爽,當然,爽的背后開發難度也是相當的大的,這種“特定屬性”非常時候做人工智能的算法加速。由于制作特殊電路,FPGA之前經常用做信號處理中,配合DSP或者ARM使用,后來也有用FPGA或者CPLD搭建“礦機”當“礦老板”(祝愿”挖礦“的天天礦難)。小白入門A:PYNQ
PYNQ是Python + ZYNQ,用Python進行FPGA開發,首先強調一點,Python近幾年非常火,雖然很強大,但是他開發硬件不是真的就做硬件,希望大家不要迷。教程:https://github.com/xupsh/Advanced-Embedded-System-Design-Flow-on-Zynq我們類比一下很火的MicroPython,使用Python開發硬件是得有特定的電路設計的,除非自己是大佬修改底層的固件,但是都修改底層了,是不是可以自己開發就好了。當然這個是面向小白的,對應的開發板如下圖。 ?這個板子類似我們之前玩MicroPython,也是各種調包。實際上ZYNQ是一個雙核ARM Cortex-A9處理器和一個FPGA,使用Python的話可以通過Jupyter進行開發,是不是很香,所以這個非常適合小白。FPGA上跑BNN(二值神經網絡)是非常不錯的,“PYNQ-Z1不同的機器學習數據集(dataset)的測試結果顯示:對于MNIST數據集PYNQ-Z1能實現每秒168000張圖片的分類,延遲102微妙,準確率達98.4%;對于CIFAR-10、SVHN、GTSRB數據集PYN1-Z1能實現每秒1700張圖片的分類,延遲2.2毫秒,準確率分別為80.1%、96.69%和97.66%,系統功耗均保持在2.5W左右。”
import?bnn hw_classifier?=?bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_HW) sw_classifier?=?bnn.CnvClassifier(bnn.NETWORK_CNVW1A1,'cifar10',bnn.RUNTIME_SW) 進行測試:
from?IPython.display?import?display im?=?Image.open('car.png') im.thumbnail((64,?64),?Image.ANTIALIAS) display(im)? car_class?=?hw_classifier.classify_image_details(im) print("{:?>10}{:?>13}".format("[CLASS]","[RANKING]")) for?i?in?range(len(car_class)): ????print("{:?>10}{:?>10}".format(hw_classifier.classes[i],car_class[i])) 同樣支持matplotlib進行數據可視化:
%matplotlib?inline import?matplotlib.pyplot?as?plt x_pos?=?np.arange(len(car_class)) fig,?ax?=?plt.subplots() ax.bar(x_pos?-?0.25,?(car_class/100.0),?0.25) ax.set_xticklabels(hw_classifier.classes,?rotation='vertical') ax.set_xticks(x_pos) ax.set plt.show() 這不就是Python嘛,真的是非常的方便,而且圖像處理也兼容使用Pillow。文件中給出了一些圖像識別的例子,大家可以去看看。改天阿chai給大家出一個從零搭建PYNQ的教程,包括模型的量化推理等等。
小白入門B:DPU
DPU是一個用于卷積神經網絡的可編程引擎。該單元包含寄存器配置模塊、數據控制器模塊和卷積計算模塊。當然,強大的PYNQ也是支持使用DPU的,如果用這個直接看Python的API就可以了,開發板可以使用ZCU104。大神很多直接用ZYNQ開整的,但是那個難度真的不適合初學者去看,等忙完了項目阿chai給小伙伴們整個這個的教程。
git?clone?https://github.com/Xilinx/DPU-PYNQ.git cd?DPU-PYNQ/upgrade make 安裝pynq-dpu:
pip?install?pynq-dpu 啟動jupyter-notebook:
pynq?get-notebooks?pynq-dpu?-p?. 模型庫在如下鏈接中。模型庫:https://github.com/Xilinx/Vitis-AI/tree/v1.3對于DPU的設計,我們需要在自己的電腦上進行,在添加模塊后,我們使用如下命令進行編譯:
make?BOARD=
支持國產框架:Paddle-Lite
既然python都可以,那肯定Paddle-Lite這種推理框架也是可行的,百度也有專門的部署開發套件 EdgeBoard。EdgeBoard是基于Xilinx Zynq UltraScale+ MPSoC系列芯片打造的計算卡,芯片內部集成ARM處理器+GPU+FPGA的架構,既具有多核處理能力、也有視頻流硬解碼處理能力,還具有FPGA的可編程的特點。
{ ?"model":"測試的模型",? ?"combined_model":true,? ?"input_width":224, ?"input_height":224, ?"image":"測試的路徑", ?"mean":[104,117,124], ?"scale":1, ?"format":"BGR" ????"threshold":0.5 } 詳細的操作請前往Paddle Lite的GitHub,這里只做簡單的流程介紹。GitHub:?https://github.com/PaddlePaddle/Paddle-Lite如果不想編譯,直接在如下網址中下載編譯好的文件即可。編譯后的文件:https://ai.baidu.com/ai-doc/HWCE/Yk3b95s8o
1.安裝測試
我們首先在有在開發板上編譯Paddle Lite,編譯的時候需要設置cmake的參數,設置LITE_WITH_FPGA=ON
和LITE_WITH_ARM=ON
,問就是我們都用到。對應的FPGA的編譯腳本是lite/tools/build_FPGA.sh,我們執行即可。sh?./lite/tools/build_fpga.sh make?publish_inference?-j2 接下來我們編譯示例demo,demo也在剛才的下載鏈接中。板子的使用過程請參考百度官方的文檔,文檔介紹的非常的清楚,阿chai這里就不花時間去講解使用過程了。然后進入demo中進行編譯:
#?classification cd?/home/root/workspace/sample/classification/???? mkdir?build cd?build cmake?.. make build目錄下會出現image_classify和video_classify兩個可執行文件,圖片預測運行image_classify文件。使用FPGA 進行resnet50進行測試:
./image_classify_fpga_preprocess?../configs/resnet50/drink.json?? 可以看到對應的輸出結果,同樣detection的模型測試方式也這樣操作。
2.可調用的接口
C++
C++的主要包括預處理以及預測庫的接口。- 預處理接口主要是使用FPGA完成圖片的縮放、顏色空間轉換和mean/std操作。
- 預測庫接口主要完成模型的初始化、輸入參數構造、預測和結果獲取。
/** ??*?判斷輸入圖像是否是wc?16對齊 ??*?width?輸入圖像寬度 ??*?channel?輸入圖像高度 ??**/ ?bool?img_is_align(int?width,?int?channel); ?/** ??*?對齊后的大小 ??*?width?輸入圖像寬度 ??*?channel?輸入圖像高度 ??**/ ?int?align_size(int?width,?int?channel); ?/** ??*?分配存放圖片的內存,析構函數會自動釋放?(目前支持BGR->RGB?RGB->BGR?YUV422->BGR?YUV->RGB)?圖像最大分辨率支持1080p ??*?height?輸入圖像的框 ??*?width?輸入圖像寬度 ??*?in_format?輸入圖像格式?參考image_format ??*?return?uint8_t*??opencv?Mat?CV_8UC3 ??**/ ?uint8_t*?mem_alloc(int?img_height,?int?img_width,?image_format?in_format); 預測庫使用步驟1、模型初始化,構建預測對象
?std::unique_ptr
????std::vector
?g_predictor->Run(paddle_tensor_feeds,?&outputs); 4、獲取結果
?float?*data?=?static_cast<float?*>(outputs[0].data.data()); ????int?size?=?outputs[0].shape[0];
Python
EdgeBoard系統已經安裝了python環境,用戶可直接使用即可,同時python接口為用戶提供了paddlemobile的python安裝包以及示例工程。文件名稱說明? | ? |
paddlemobile-0.0.1.linux-aarch64-py2.tar.gz | paddlemobile的python2安裝包 |
edgeboard.py | 基于python的模型預測示例 |
api.py | edgeboard.py的api示例 |
configs.classification | 分類模型的配置文件目錄,同C++示例的配置文件 |
configs.detection | 檢測模型的配置文件目錄,同C++示例的配置文件 |
models.classification | 分類模型的模型文件目錄,同C++示例的模型文件 |
models.detection | 檢測模型的模型文件目錄,同C++示例的模型文件 |
tar?-xzvf??home/root/workspace/paddlemobile-0.0.1.linux-aarch64-py2.tar.gz 例如使用分類模型的測試如下:
python?api.py?-j?你測試的json文件 詳細的使用說明請關注Paddle-Lite的GitHub。 ?介紹了這幾種,其實大家可以看出來,入門使用并不難,難的是底層的硬件設計與算法加速量化等等,這些都是打包好的東西,我們真的開發還是得慢慢的扣底層的。在這里借用一位大神說的話,現在人工智能算法工程師和十年前的嵌入式工程師差不多,從需求到硬件、軟件、算法、應用等等都能做,貌似真的是這樣,太卷了,不多學點真的要涼。工具是越來越好用,難的是輪子怎么造,一起加油。
? ? ? 審核編輯:彭靜
?
評論