基于PYNQ-Z2实现BNN硬件加速
用HLS工具在PYNQ-Z2開發(fā)板上實(shí)現(xiàn)BNN(二值神經(jīng)網(wǎng)絡(luò))硬件加速——畢設(shè)小結(jié)
本文主要是本人本科畢業(yè)設(shè)計(jì)的主要工作。
主要工作有兩部分,一是使用Vivado HLS工具實(shí)現(xiàn)二值卷積神經(jīng)網(wǎng)絡(luò)模型并完成硬件加速工作,二是將二值神經(jīng)網(wǎng)絡(luò)的前向計(jì)算過程部署到PYNQ-Z2板上,并在Jupyter Notebook上實(shí)現(xiàn)IP核的調(diào)用。
BNN參考論文《Binarized Neural Networks Training Neural Networks with Weights and Activations Constrainedto +1 or ?1》、《FINN A Framework for Fast, Scalable Binarized Neural Network Inference》。因?yàn)楫呍O(shè)要求實(shí)現(xiàn)云圖像分類的功能,所以訓(xùn)練集由灰度云圖組成,格式與mnist數(shù)據(jù)集相同。訓(xùn)練采用深度學(xué)習(xí)框架theano,導(dǎo)出訓(xùn)練好的參數(shù),然后在Vivado HLS上實(shí)現(xiàn)BNN前向計(jì)算的加速過程。
BNN由卷積層、池化層和全連接層組成,主要問題其實(shí)只有一個(gè):如何加速卷積?(全連接層主要是乘累加運(yùn)算,此處可參考卷積層的加速)
卷積加速
卷積的加速主要分為4個(gè)層面:位寬加速、算法加速、HLS優(yōu)化指令加速、訪存加速。
位寬加速
位寬加速其實(shí)就是用數(shù)據(jù)精度換取計(jì)算速度,這也是二值神經(jīng)網(wǎng)絡(luò)參數(shù)二值化的主要作用,參數(shù)二值化后大大降低了參數(shù)量。參數(shù)二值化是指我們?cè)谟?xùn)練網(wǎng)絡(luò)的時(shí)候?qū)⑶跋蛴?jì)算的權(quán)重進(jìn)行二值化處理,但反向傳播過程中會(huì)出現(xiàn)梯度消失的問題(sign函數(shù)的導(dǎo)數(shù)幾乎處處為0),所以反向傳播時(shí)會(huì)進(jìn)行松弛化處理,將符號(hào)函數(shù)Sign變?yōu)榭蓪?dǎo)函數(shù)Htanh,并更新全精度的權(quán)重,這里的相關(guān)內(nèi)容可以參考XNOR-NET的論文或者相關(guān)文獻(xiàn)。主要過程如下圖所示:
算法加速
- 乘加優(yōu)化
算法方面的加速其實(shí)就是充分使用二值神經(jīng)網(wǎng)絡(luò)的特點(diǎn)進(jìn)行運(yùn)算符優(yōu)化,因?yàn)榍懊嫖覀円呀?jīng)將參數(shù)二值化,所以在進(jìn)行卷積操作的時(shí)候可以利用同或操作和計(jì)數(shù)器代替乘加運(yùn)算,即使用XNOR和PopCount實(shí)現(xiàn)乘加運(yùn)算,具體可以參考XNOR-Net。
以A=[1,-1,1,1,-1]和W=[-1,1,1,-1,-1]兩個(gè)向量進(jìn)行內(nèi)積運(yùn)算為例:
正常的乘法運(yùn)算為1×(-1)+(-1)×1+1×1+1×(-1)+(-1)×(-1)= -1;
從同或運(yùn)算的角度來看,A=[1,0,1,1,0],W=[0,1,1,0,0]
A 與W 進(jìn)行異或的結(jié)果為A^W=[1,1,0,1,0](HLS 中不存在同或操作,需對(duì)異或取反進(jìn)行同或操作)
PopCount 的作用是計(jì)算1的個(gè)數(shù)來對(duì)二進(jìn)制的乘積進(jìn)行求和。所以PopCount(A^W)= 3,即結(jié)果中有3個(gè)-1;所以最終二進(jìn)制的乘積的結(jié)果為(5-PopCount)×1+PopCount×(-1)= 5-2×PopCount= -1.
偽代碼如下,其中F 為卷積窗口大小,window_result 為當(dāng)前卷積窗口的計(jì)算結(jié)果,weight_buff 為卷積核參數(shù),bit_num 為卷積窗口內(nèi)數(shù)據(jù)的總位數(shù)。
- 池化優(yōu)化
普通的最大值池化就是對(duì)滑動(dòng)窗口內(nèi)的數(shù)據(jù)進(jìn)行比較,將其中最大的數(shù)據(jù)作為該滑動(dòng)窗口的結(jié)果。在BNN計(jì)算過程中,最大值池化后還要對(duì)輸出結(jié)果再次進(jìn)行二值化操作
因?yàn)榛瑒?dòng)窗口內(nèi)任意一個(gè)值滿足大于s 的條件都可以使當(dāng)前滑動(dòng)窗口的輸出為1,即最大池化操作與計(jì)算順序沒有關(guān)系,因此二值神經(jīng)網(wǎng)絡(luò)的最大值池化操作可以簡(jiǎn)化為或運(yùn)算
訪存加速
引入緩存,將緩存置于訪存速度更快的內(nèi)存塊中,從而加速整個(gè)卷積層的計(jì)算速度。同時(shí)相鄰的卷積窗口的數(shù)據(jù)重復(fù)率較高,無需讀取大量重復(fù)使用的數(shù)據(jù)。
本文使用了行緩存器和窗緩存器實(shí)現(xiàn)了卷積窗口的流水操作,下圖為窗口緩存結(jié)構(gòu)示意圖:
參數(shù)更新過程如下:
偽代碼如下:
HLS優(yōu)化指令加速
本文中主要用到的HLS的優(yōu)化指令主要包括以下三個(gè)方面:(詳細(xì)過程可參考Xilinx官方文檔UG902)
- 循環(huán)展開
循環(huán)展開是指將一個(gè)循環(huán)函數(shù)分為多個(gè)獨(dú)立操作,對(duì)應(yīng)的優(yōu)化指令為#pragma HLS UNROLL。一般來說,對(duì)內(nèi)層循環(huán)采用循環(huán)展開優(yōu)化較合適,若對(duì)外層循環(huán)進(jìn)行循環(huán)展開的話,會(huì)顯著提高資源的使用率。
- 流水優(yōu)化
在HLS 中,循環(huán)結(jié)構(gòu)默認(rèn)是折疊的,即只使用一組相同的硬件資源進(jìn)行計(jì)算。流水線操作可以改善啟動(dòng)間隔與時(shí)延,對(duì)應(yīng)的優(yōu)化指令為#pragma HLS PIPELINE。
上圖所示的函數(shù),每三個(gè)時(shí)鐘周期讀取一個(gè)輸入,兩個(gè)時(shí)鐘周期后輸出一個(gè)值。使用Pipeline 優(yōu)化指令后,每個(gè)時(shí)鐘周期都可以讀取一個(gè)新的輸入,但輸出的延遲不變。 - 數(shù)組分割
在進(jìn)行上述優(yōu)化后仍存在部分問題—讀寫操作的瓶頸問題。之前所示的循環(huán)展開中,對(duì)每個(gè)數(shù)組而言,每個(gè)時(shí)鐘周期需要執(zhí)行3個(gè)讀操作或3個(gè)寫操作,但是一個(gè)BRAM 最多只有兩個(gè)端口,即一個(gè)時(shí)鐘周期內(nèi)最多執(zhí)行兩個(gè)讀或?qū)懖僮鳌?br />
數(shù)組分割是通過將一個(gè)塊RAM 資源分割成多個(gè)較小的陣列,從而提高帶寬,有效增加端口的數(shù)量,提高讀/寫密集型算法的吞吐量。
改進(jìn)后的Resource Viewer如下,此時(shí)不存在讀寫瓶頸。
實(shí)驗(yàn)結(jié)果
硬件系統(tǒng)模塊的Block Design:
Jupyter Notebook結(jié)果:
PYNQ-Z2板硬件加速效果:
| CPU | 100 | 8032.8 |
| FPGA | 100 | 2.2 |
小結(jié)
論文前期用了一段時(shí)間學(xué)習(xí)HDL,用Verilog語言搭建了一些小模塊熟悉硬件搭建流程,熟悉PYNQ-Z2開發(fā)板的開發(fā)流程。后來參考BNN-PYNQ在PYNQ-Z2板上跑通了BNN的例程,參考HLS-BNN學(xué)習(xí)BNN各模塊在HLS的搭建及加速過程,實(shí)現(xiàn)BNN各模塊的加速。
同時(shí),畢設(shè)選擇硬件開發(fā)時(shí),可參考的中文資料較少,靠譜的英文文獻(xiàn)有UG871(官方提供的HLS例程,建議跟著步驟都做一遍)以及UG902(當(dāng)工具書查詢)
論文中提及的工作占時(shí)不是很多 ,主要時(shí)間都在熟悉HDL、HLS開發(fā)工具以及PYNQ-Z2的開發(fā)流程,期間也遇到了很多問題,比如如何定義接口類型、如何調(diào)用板子以及如何在Jupyter Notebook進(jìn)行數(shù)據(jù)格式轉(zhuǎn)換等。
完成大部分畢設(shè)工作已是立夏,回顧大學(xué)四年,我努力著,付出著。
在此十分感謝女友,同我交流感受,為我加油打氣;
非常感謝我的家人,替我燒水煮飯,喚我添衣保暖;
也很感謝大學(xué)摯友,與我交流思路,攜我共同進(jìn)步。
參考資料
PYNQ-Z2板卡簡(jiǎn)介與資源整理
Xilinx/BNN-PYNQ
板卡鏡像下載地址
PYNQ官方Getting Started
PYNQ官方例程—熟悉PYNQ的開發(fā)流程
PYNQ入門中文資料
HLS生成IP進(jìn)行硬件加速
FPGA并行編程
BitCount函數(shù)解釋
BNN-PYNQ安裝
模仿mnist制作數(shù)據(jù)集
FINN_Documentation
吳恩達(dá)深度學(xué)習(xí)課程第四課 — 卷積神經(jīng)網(wǎng)絡(luò)
HLS入門視頻
正點(diǎn)原子ZYNQ系列
[2020.8.27更新,添加BNN的HLS和Vivado工程復(fù)現(xiàn)教程]
BNN工程復(fù)現(xiàn)教程
[2020.11.26更新,更新Block Design框圖]
總結(jié)
以上是生活随笔為你收集整理的基于PYNQ-Z2实现BNN硬件加速的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 填问卷,得《2015中国呼叫中心知识库现
- 下一篇: “.公司”域名注册总量TOP15:新网问