神經網路加速器應用例項:影象分類

暗海風發表於2019-07-26

深度學習飛速發展過程中,人們發現原有的處理器無法滿足神經網路這種特定的大量計算,大量的開始針對這一應用進行專用晶片的設計。谷歌的張量處理單元(Tensor Processing Unit,後文簡稱TPU)是完成較早,具有代表性的一類設計,基於脈動陣列設計的矩陣計算加速單元,可以很好的加速神經網路的計算。本系列文章將利用公開的TPU V1相關資料,對其進行一定的簡化、推測和修改,來實際編寫一個簡單版本的谷歌TPU,以更確切的瞭解TPU的優勢和侷限性。

動手寫一個神經網路加速器系列目錄

    谷歌TPU概述和簡化

    TPU中的脈動陣列及其實現

    神經網路中的歸一化和池化的硬體實現

    TPU中的指令並行和資料並行

    Simple TPU的設計和效能評估

    SimpleTPU例項:影象分類

    擴充

    TPU的邊界(規劃中)

    重新審視深度神經網路中的並行(規劃中)

 

1. 不僅僅是硬體的AI Inference

    在Simple TPU的設計和效能評估中,一個神經網路加速器的硬體雛形已經搭建完成了;在https://github.com/cea-wind/SimpleTPU上給出了相應的程式碼,和RTL模擬結果。在TPU中的脈動陣列及其實現神經網路中的歸一化和池化的硬體實現中,針對硬體實現中的關鍵模組也進行了模擬分析。但是,最終並沒有給出一個可以實際執行的例子。這意味著,即使將這一部分程式碼應用到FPGA上,或者是實現在ASIC上後,也只有紙面效能卻並不可用。

    和很多其他的硬體設計不同,以Xilinx的AI Inference 解決方案為例(即之前的深鑑科技),用於AI Inference的設計需要考慮神經網路計算中的多樣性,神經網路加速器是一個軟體+硬體的解決方案。Xilinx敘述如下圖(原始連結:https://www.xilinx.com/products/design-tools/ai-inference.html)。

image

    從上往下看,這一套解決方案包括

  •     主流的神經網路的框架的支援,包括caffe、Tensorflow和mxnet
  •     提供模型壓縮和優化的工具,以期在硬體上又更好的效能
  •     提供模型量化的功能,使得浮點模型轉化為定點模型
  •     提供了Compiler,將模型對映為二進位制指令序列
  •     和Compiler相結合的Hardware

     這意味著想真正使用之前設計的神經網路加速器——SimpleTPU,還需要軟體的配合。即便模型壓縮不在考慮範圍內,也需要將模型量化為int8精度(SimpleTPU只支援int8乘法),同時利用Compiler生成指令序列。受限於個人能力,由於配套軟體的缺失,下面的例子中的量化和指令均由手工生成。也正是由於這一原因,網路結構會盡可能簡單,僅以保證本系列文章完整性為目的。

2. MLP分類例項

    利用MLP對MNIST資料集進行手寫數字分類的網路結構定義如下

class MLP(nn.Module):
    def __init__(self):
        super(MLP, self).__init__()
        self.hidden = nn.Linear(784,64)
        self.fc = nn.Linear(64,10)

    def forward(self, x):
        x = x.view(-1,784)
        x = self.hidden(x)
        x = self.fc(x)
        return F.log_softmax(x, dim=1)

    生成指令後將其作為SimpleTPU的輸入,並對其進行RTL模擬(testbench已經寫好,直接執行即可),模擬結果如下圖所示

result

    前16張圖的分類結果如下圖所示

result

    根據計算結果,可以分析得到其效率為84%。(去除了13K個用於讀取圖片和寫回結果的時間,實際應用中,這一事件也會被計算時間覆蓋)

LOC Layers Nonlinear function Weights Batch Size % of Deployed
2 2 FC Relu 5M 512 16%

    作為參考,谷歌TPU中的數值為(儘管Simple TPU效率較高,但由於規模不同,無法直接對比效率;由於SimpleTPU完全按TPU設計,實際效能不可能高於TPU

image

3. MLP執行分析

    通過模擬波形,可以更直觀的看出SimpleTPU的執行狀態。下圖中,讀取Weight、乘加運算單元和Pooling共同工作可以反應TPU中的指令並行和資料並行中提到的指令並行。(由上倒下的ap_start分別是MXU,POOL,LOAD WEIGHT和INSTR FETCH的工作指示訊號,同時拉高代表同時工作)

    觀察MXU內部的訊號,可以看到計算過程中的資料並行(一條指令控制多組資料,且一個週期完成多組計算)。MXU每個週期都輸出psum取值,一共有32個psum,計算一個psum需要32次乘加計算。

 

    SimpleTPU為什麼不夠快(效率並沒有接近100%)?這一問題可有下面的模擬波形看出(每次MXU啟動前後都有若干個週期沒有輸出有效結果)

    由於每次MXU執行一條向量計算指令會又若干個空閒的週期(超過64個週期,損失了10%以上的效能),導致了SimpleTPU在這一個網路上效能只有84%。MXU在啟動之前需要32個週期來填滿整個脈動陣列,而在輸入結束後還需要32個週期來輸出最後的結果。當採用HLS編寫程式碼是,難以以這一控制力度來優化MXU的效能。如果採用Verilog HDL或者VHDL,可以採用指令之間的流水設計來消除這一延時。

4. CNN

    由於手工對神經網路進行量化和layer間融合以及生成指令的複雜性,基於CNN的影象分類/分割網路的執行例項被無限期暫停了。

    但是一個卷積計算的例項已經在TPU中的脈動陣列及其實現中給出,證明了SimpleTPU計算卷積的能力。

    根據Simple TPU的設計和效能評估給出的特性,SimpleTPU可以高效支援絕大多數Operator,完成計算機視覺中的多種任務。當然,最大的缺陷在於SimpleTPU不顯式支援ResNet,無法直接計算residual connection中的加法;只能進行channel concatenate之後再利用一次乘加計算完成。

相關文章