新聞中心

                        EEPW首頁 > 設計應用 > PYNQ中實現SoftMax函數加速器

                        PYNQ中實現SoftMax函數加速器

                        作者:孫齊偉時間:2019-05-29來源:電子產品世界收藏

                          孫齊偉

                        本文引用地址:http://www.xinfa15808.cn/article/201905/401026.htm

                         ?。ㄎ髂辖煌ù髮W 信息科學與技術學院,四川 成都 611756)

                          摘要:函數通常在深度學習中作為激活函數使用,但其計算涉及自然指數和除法運算,傳統PC機上計算較慢,拖累了一個神經網絡的訓練。本文針對自然指數運算的特點,提出了一種名為基底拆分法的新方法。該方法將函數中自然指數計算拆分為多個由查找表實現的特定基底上,通過這種方法,一個復雜的自然指數計算過程即可由查找表過程和乘法過程實現。這種方法有效的降低了硬件復雜度以及邏輯傳播延時。由于該方法中使用了自定義的數據結構,因此本文采用了CPU + FPGA的架構,通過合理分工,加速函數計算。同時,本文將基于這種方法設計的IP核在-Z2開發板上進行了板級調試。

                          關鍵詞:,,SoftMax,,

                          * 本作品獲得第二屆“全國大學生集成電路創新創業大賽”全國一等獎

                          0 引言

                          Xilinx推出的系列FPGA中嵌入了一顆雙核ARM,既能發揮FPGA的定制特性,也能發揮處理器的通用特性,而且兩個部分之間接口豐富、官方文檔齊全,可玩性極高。同時相應的開發板也很多。傳統的開發板(Zedboard等)需要結合vivado和SDK兩大工具分別對PL、PS端進行硬件和軟件開發。本次我介紹的平臺為開發板可使用Python將軟件操作和硬件控制進行無縫銜接,目前已經出到Z2版本,由依元素進行代理銷售,999塊極具性價比。

                        1.png

                          PYNQ是Xilinx一項旨在使用Python和一些lib讓SoC開發更加簡單的開源項目,以我的理解其本質是Python的一些第三方庫,是對PS端操作的封裝。傳統的ZYNQ開發板也能使其變為PYNQ開發板,當引入Python后就可以使用一些Python中強大的第三方庫了例如Numpy、Matplotlib等。

                          1 SoftMax函數介紹及計算方案介紹

                          SoftMax 函數是神經網絡中的一種輸出層函數,計算輸出層的值,主要用于神經網絡最后一層。其表達式如下所示:

                        2.png

                          設計中的關鍵問題是 自然指數的計算 ,傳統的方案有:

                         ?。?)查表法:同等規格定點數下精度極高,但若要在較大范圍上計算需要消耗大量資源。

                         ?。?)CORDIC:利用迭代特性,資源復用,占用資源極小,常用于計算器中,但在大規模計算中需要進行流水線化改造,且需要想辦法克服最大旋轉角度限制的問題。

                         ?。?)泰勒級數展開:也即多項式擬合,該法較為靈活,多項式次數越高精度越高,劃分區間越細精度越高,是較為常用的方法。

                          本文針對指數計算的特性,設計了一種原理簡單的計算方案,并且通過了板級測試。根據其計算特性稱其為基底查表法。

                        1559616708925171.jpg

                        1559616708645912.jpg

                        5.png

                          在十進制中,若要計算3.68的自然指數我們可以通過公式(1)分別計算e3,e0.6,e0.08,所以可以事先將需要的自然指數值存在ROM表中,計算時將待計算數字通過基底拆分分別得到個位、十分位、百分位,并作為ROM的尋址地址,最后將查表得到的值進行乘法操作即可得到最終結果。但數字電路中實現十進制取整取余操作時較為復雜的,因此實際使用時對二進制情況進行了優化。

                          圖2為基于二進制移位操作的基底拆分示意圖,待計算的16bit數據,高三位表示的是小數點的位置信息,低十三位為數據位。經過左移并按照人為設計的格式輸出即可還原數據。這種方法僅采用移位操作進行基底劃分,因此硬件結構簡單、傳播延時小。

                          工程中設計的IP核內部結構,見圖3。

                          其中的關鍵流水線如圖4。

                          大致原理就是如此,可以看出這種方法也是很靈活的,可以通過簡單地增加ROM和乘法器數量即可擴大計算范圍,而且精度可以通過增減ROM表存儲的定點數位寬進行改變,乘法器可以使用ZYNQ中的DSP資源來提高性能。本次設計的范圍針對[-10,10]。

                          2 誤差結果

                          測試時分別使用[-10,10],[-5,5]兩個區間中4096個點進行誤差分析,大致過程如圖5。

                          最后得到的絕對誤差圖,見圖6。

                          誤差在10^-7數量級上,可以說是很小了。

                          3 IP核接口介紹

                          深度學習又被稱為煉丹,究其原因就是其訓練速度較慢,因此考慮深度學習中的加速問題十分有意義。FPGA由于其定制特性,可以通過邏輯門電路十分高效的完成計算過程。

                        1559616546480625.jpg

                          本次我使用FPGA實現了一款AXI接口的激活函數softmax的加速器,并且通過PYNQ開發板對其進行驗證同時完成了精度測試。輸入輸出均為形式,內部采用了一個AXI_S和一個AXI_M,其中,輸入AXI_S用于ARM端向ip核傳遞寫地址、讀地址、數據個數、輸出數據16/8bit切換,AXI_M完成對PS端DDR的讀寫操作,這樣設計的目的是為了最大化減小ARM端的工作量,使整個系統更加高效,因為AXI_M可以主動的讀寫AXI_S并且AXI_S只能被動的被AXI_M進行讀寫,這個過程設計好后無需ARM端干預。其結構圖如圖7所示。

                          因此涉及的操作為 GPIO口操作,AXI寫操作,DDR操作。這里原本設計采用ZYNQ上的AXI-HP端口,但是調試時發現該端口在數據格式配置為32 bit時仍采用的64bit數據位,估計是個bug,因此不得不換成AXI-GP端口了。

                         ?。?)從ARM引出的兩個GPIO一個作為復位信號,另一個作為觸發信號

                         ?。?)AXI_M接口,用于配置ip核的一些信息。

                          4 任務劃分

                          為了充分發揮ARM對通用任務的處理特性以及PL的定制特性,本次設計的系統中PS完成了讀取數據、數據的定點化和數據移動任務,PL端利用其定制化特性完成計算的加速。整體結構框圖如圖8。

                          圖中的CPU即為ARM,工作時將模擬輸入的數據寫入DDR,并且完成定點化工作。圖中硬件即為PL端設計的加速器,其工作分為兩個階段,一是計算元素的自然指數值并對其進行求和,二是利用第一個階段的自然指數值和和做除法求得每個元素的softmax值。

                          5 PYNQ平臺的優勢

                          我的設計在曾在傳統的ZYNQ開發板上進行過調試。設計好硬件后需要結合SDK工具對ARM核進行C語言開發,結果最后需要通過串口返回PC機進行處理。

                          在SDK中返回的數據,返回的數據經過上位機的處理才能得到想要的誤差數據,較為繁瑣。

                          但PYNQ不一樣,PYNQ上使用了Jupyter可以使用瀏覽器進行在線Pyhthon編程,而且Python中numpy科學計算庫可以只使用3句話就實現softmax的高精度計算,結合pynq的相應庫可以實現軟件處理和硬件控制的無縫銜接,PL端加載bit文件、PL端控制、軟件計算、matplotlib繪制均使用Python完成,最后的結果都可以在網頁中顯示出來,極其方便。

                          圖中我使用了matplotlib庫將軟件計算結果與硬件計算結果進行了絕對誤差計算,可直接在網頁中顯示出圖像,更加形象化。本次我的設計中,使用PYNQ完成了 從SD卡中讀入數據,數據定點化,數據寫入DDR,控制PL端進行加速計算,讀DDR,將軟件結果與硬件結果對比通過誤差散點圖來測試設計的IP核的精度。

                          ZYNQ與PYNQ平臺的差異可通過對比兩個平臺的系統框圖得到

                          可以看出,傳統ZYNQ通常為裸機開發,而且PYNQ一般為在自身運行的Ubuntu上進行Python開發,因此PYNQ相對而言上手簡單加上一些強大的第三方庫的支持使用起來也十分方便、有趣。

                          6 PYNQ使用方法

                          一些基礎操作可以參考官方Get Start我總結有如下步驟:

                        1560412924331554.jpg

                         ?。?)vivado中設計PL端的硬件結構--PC操作,如圖13。

                         ?。?)vivado導出設計tcl文件和bit文件--PC操作

                          write_bd_tcl -force C:/Users/Administrator/Desktop/test.tcl

                         ?。?)將tcl文件和bit文件放入PYNQ中--PC操作,如圖14。

                          windows上運行 \\pynq 即可通過sdb功能連接PYNQ開發板,進行文件移動

                         ?。?)使用Overlay將bit文件進行加載--PYNQPython操作

                          overlay = Overlay('/home/xilinx/pynq/overlays/softmax/design_1.bit')

                          至此設計就初始化在PL端,使用Python控制相應外設即可。

                          7 Python中相關lib的基本使用

                          1.Overlay

                          from pynq import Overlayov

                          overlay = Overlay('/home/xilinx/pynq/overlays/softmax/design_1.bit')

                          用于加載比特流文件至PL端

                          2.GPIO

                          from pynq import GPIO

                          rst = GPIO(GPIO.get_gpio_pin(0), 'out')

                          triggle = GPIO(GPIO.get_gpio_pin(1), 'out')

                          triggle.write(1)

                          rst.write(1)

                          rst.write(0)

                          rst.write(1)

                          操作PS端的GPIO口,操作的是64bit的PS-PL端的EMIO

                          3.Xlnk

                          from pynq import Xlnk

                          xlnk = Xlnk()

                          buf = xlnk.cma_array(shape=(num,), dtype=np.uint32, cacheable=0)

                          addr = buf.physical_address

                          結合numpy在DDR中分配空間,用于PL端AXI_M使用其中physical_address可以得到DDR中的物理地址在分配空間時,有個cacheable屬性,由于PS和PL端都要對DDR進行操作,所以為了防止PS的cache導致讀到的數據未被更新,所以通常需要關閉緩存功能。

                          4.AXI從端操作

                          myip = overlay.axi_s_control_0

                          myip.write(0x00,addr)

                          myip.write(0x04,addr)

                          myip.write(0x08,num)

                          myip.write(0x0c,bool_16)

                          myip.read(0x08)

                          其中axi_s_control_0是我AXI_S的模塊名稱,這個是python從導出的原理圖tcl文件讀出的,因此需要保證tcl和bit文件的一致性,而且需要兩者同名

                          注:這些信息都在上文提到的Get Start連接中可以找到,具體請參考官方的說明。

                          8 結論

                          此次借助“全國大學生集成電路創新創業大賽”契機,我們分別在傳統ZYNQ和PYNQ平臺上完成了SoftMax函數的加速,獲得了比較好的效果。

                          在傳統的ZYNQ平臺上開發SoC需要具備數字電路和ARM嵌入式開發知識,比較偏向于底層。反觀PYNQ平臺,利用Python這一優美的語言對ZYNQ操作的封裝極大的降低了開發難度,同時結合Python強大的第三方庫,可玩性極高。

                          當今數字電路工程師僅僅掌握數字集成電路的知識是遠遠不夠的,項目開發更加需要復合型人才。我在項目中采用Verilog作為硬件開發語言,使用HLS做雛形開發,同時使用Python及Matlab進行建模及數據分析,使用的軟件工具有Xilinx的VIVADO、ISE,以及Synopsys的DC,ICC,Synplify??梢钥闯鰞H僅掌握一門技能是遠遠不夠支撐一個項目的。時代在進步,科技在發展,因此數字IC工程師應該保持住學習的狀態,就比如說近幾年大火的深度學習,十幾年前這個領域還是沒有人愿意去碰的,但現在該領域已經讓很多停滯不前的方向又迎來新春。

                          世界上還是存在很多機會的,但機會都是留給有準備的人。

                          附件:本文設計的softmax ip核在PYNQ運行所需的所有文件https://pan.baidu.com/s/1OuaoS34nIp4Ci96gMCEmug 密碼:ifme

                          本文來源于科技期刊《電子產品世界》2019年第6期第69頁,歡迎您寫論文時引用,并注明出處




                        評論


                        相關推薦

                        技術專區

                        關閉
                        广东快乐十分开奖结果