Categories
程式開發

異構計算系列(三):Adlik在深度學習異構計算上的實踐


“異構計算”(Heterogeneous computing),是指在系統中使用不同體系結構的處理器的聯合計算方式。在 AI 領域,常見的處理器包括:CPU(X86,Arm,RISC-V 等),GPU,FPGA 和 ASIC。 (按照通用性從高到低排序)本文是異構計算系列的第三篇文章,重點介紹Adlik在深度學習異構計算上的實踐。

人工智能領域在近年發展迅速,不論是在圖像識別,目標檢測,機器翻譯,還是語音識別等多個領域,人工智能的表現均已超過人類水平,尤其是在AlphaGo戰勝了李世石之後,人們對人工智能可達到的成就有了新的認識。

機器學習(Machine Learning,ML)是人工智能的子領域,也是人工智能的核心,就是要設計讓機器可以進行自動學習的算法。而深度學習(Deep Learning,DL)是機器學習的一個子類,是一種包含多個隱含層的神經網絡結構,人們定義了神經網絡中各種神經元的連接方法,以及神經元的激活函數,並利用反向傳播技術完成神經網絡的訓練過程。深度學習技術在眾多AI領域取得很多成果,解決了很多複雜的模式識別難題,所以也成為最近幾年人工智能領域研究和應用上人氣最火熱的技術。

深度學習模型當前有多種訓練框架,如常見的TensorFlow,PyTorch,MxNet,Caffe,PaddlePaddle等等,訓練時大多是使用GPU,採用容器雲方式,進行大規模並發計算,減少模型訓練收斂時間。而在模型的應用上,則要使用深度神經網絡的推理能力,完成網絡前向計算,並將此計算部署為應用服務,產生商業價值。

Adlik做了什麼?

各種算法在訓練框架訓練後得到各種模型,其服務應用可能要部署在不同的硬件平台,可能使用不同的推理框架,對應用場景有著不同的要求,如低時延。所以在訓練中達到很好的收斂效果的深度學習模型,距離真正的投入應用,還有很多工作要做:

  • 針對不同設備的推理框架有很多,對用戶難以選擇,要付出較多的學習成本;
  • 不用應用場景的部署條件不同,有基於容器化部署場景,也有基於嵌入式硬件部署的場景,同樣的模型服務,不同部署方案要掌握不同的技術;
  • 根據性能需求有很多的模型調優工作;
  • 推理服務應用於不同硬件,需要多類異構計算引擎的支持。

異構計算系列(三):Adlik在深度學習異構計算上的實踐 1

Adlik就是一種可以將深度學習模型從訓練完成,到部署到特定硬件並提供應用服務的端到端工具鏈,其應用目的就是為了將模型從研發狀態快速部署到生產應用環境。 Adlik可以和多種推理引擎協作,支持多款硬件,提供統一對外推理接口,並提供多種靈活的部署方案,以及工程化的自適應參數優化方案,為用戶提供快速,高性能的應用服務提供助力。 Adlik的架構如下圖:

異構計算系列(三):Adlik在深度學習異構計算上的實踐 2

Adlik在架構上,可以分為模型優化模塊(Optimizer),模型編譯模塊(Compiler)和推理引擎模塊(Inference Engine)。

訓練好的模型,通過Adlik模型優化模塊處理,生產優化後的模型,然後通過模型編譯模塊,完成模型格式轉換,生成最終推理引擎支持的模型格式。

部署方案上,Adlik支持三種部署場景,並提供相應的特性支持:

1.雲側

Adlik支持原生容器化部署方案,優化和編譯完成的模型,可以和Adlik Serving Engine鏡像一起打包,發佈為應用服務鏡像,並在指定硬件的容器雲上運行。

2.邊緣側

Adlik支持在啟動的Adlik Serving Engine服務上,加載優化和編譯完成的模型,並支持模型版本管理,自動升級,以及多模型實例調度功能,減少邊緣側計算資源的佔用。

3.端側

Adlik可以為用戶提供C/C++的API接口,支持用戶直接在計算引擎上調用完成了優化和編譯的模型,並提供了模型編排能力,具備低延時和小體積的特性,可以在指定硬件運行模型應用。

異構計算系列(三):Adlik在深度學習異構計算上的實踐 3

Adlik目前的定位是深度學習模型工程化使用的工具鏈,是模型應用落地的加速器,包括端到端編譯優化能力,主流深度學習推理引擎的集成,支持多種靈活部署方式,以SDK方式提供用戶可擴展實現推理運行時的自定義開發能力,可以實現多模型協作推理,在工程化角度,Adlik還會引入工程參數自動優化的能力,提升易用性,給用戶提供訓練模型到推理應用上線的端到端優化能力。

Adlik在支持異構硬件計算的設計思路

目前Adlik支持的推理引擎,包括常見的用於深度學習推理的TensorFlow Serving,TensorRT,OpenVINO,以及CNNA(FPGA特定運行時),併計劃支持Tf Lite。而支持的異構硬件包括了GPU,CPU(x86),以及FPGA,計劃支持CPU(ARM)。 Adlik在框架層上提供了多種形式,支持用戶擴展異構硬件的運行和部署。

Adlik Serving提供了模型的推理服務。它以插件的方式部署和隔離各種運行時的環境。 Adlik Serving內置常見的運行時組件,包括TensorFlow Serving,OpenVINO,TensorRT,CNNA(FPGA特定運行時),Tf Lite等,各類應用可按需加載,開箱即用。
部署推理引擎時,需要根據具體場景靈活選擇推理運行時,及其相應的異構硬件。例如,在CPU嵌入式環境下部署,因為只存在CPU環境,此時用戶可以選擇TensorFlow Serving on CPU,或OpenVINO on CPU等兩種部署方式,如果環境使用ARM的CPU架構,那麼也可以選擇Tf Lite on CPU(ARM)的部署方式。

更為高級地,用戶也可以通過Adlik提供的Serving SDK,開髮用戶自定義推理運行時環境,並在Adlik Serving框架下執行推理服務,滿足極高的時延性的部署環境。 Adlik Serving SDK提供了模型上載,模型升級,模型調度,模型推理,模型監控,運行時隔離等基礎模型管理的功能特性,及其用戶定制與開發推理服務的C++ API。用戶要根據自己的需求,定制開發自己的模型和運行時。 Serving SDK提供了標準的擴展點,方便用戶高效地定制新的模型和運行時環境。基於Serving SDK,用戶也可以開發組合式的模型,在進程內控制多模型之間的交互,而模型之間的運行時可以相互獨立。例如,模型1的輸出可以作為模型2的輸入,模型1和模型2分別TensorFlow Serving和TensorRT運行時的模型。

默認地,Adlik Serving/Serving SDK不包含任何運行時組件,實現最小的依賴管理,應用根據部署環境靈活選擇組裝。也就是說,Adlik Serving/Serving SDK可以提供不同運行時組合的鏡像集合,應用根據具體的部署環境選擇合適的基礎鏡像。

以新增一款運行時引擎為例,介紹一下Adlik的框架是如何支持創建新運行時的,這對很多有自定義運行時和指定硬件平台的場景有重要的意義。假設A是要支持的新運行時。

  1. 定義A_Model類。這個指定的A_Model就是要創建的新運行時
  2. 定義具體計算引擎的實現類,A_Processor類,A_Processor類可以直接調用A計算引擎的執行API
  3. 調用Adlik提供的API接口,將A_Processor類其註冊到Adlik運行時調度器,作為可調度的一個推理引擎
  4. 調用Adlik提供的API接口,將A_Model類註冊到Adlik系統,這樣Adlik在啟動後就能夠使用基於A_Model的運行時來執行推理任務

異構計算系列(三):Adlik在深度學習異構計算上的實踐 4

在上面簡單的流程示意圖中,Server收到推理請求後,runtime可以識別到A_Model運行時的請求數據,就通過調度器和具體調度算法,找到註冊在調度器的A_Processor實現類,最終調到A引擎提供的計算API,完成整個推理過程。框架提供了豐富的管理和運行時調度功能,用戶只需要關注計算引擎實現即可。

實現上述代碼後,用戶可以根據指定硬件平台依賴的編譯器對代碼進行編譯,即可生成指定硬件上可執行的推理應用程序,完成對異構硬件的支持。

Adlik在支持FPGA異構計算上的實踐

在計算密集型任務中(在深度學習模型推理領域),相比起僅具有數據並行能力的GPU,FPGA基於特定的門陣列硬件結構,可以同時實現數據並行和流水線並行,使得計算的延遲更小;對於特定結構的硬件電路,FPGA的計算延遲也相對穩定。同時,與CPU和GPU相比,FPGA具有較低的功耗,這在大規模的計算中具有一定的優勢。此外,FPGA還具有動態可重配置邏輯資源的功能,可以根據不同的配置文件,加載相應的編譯文件,比ASIC更具靈活性。因此FPGA深度學習模型推理領域日益受到重視,並在CNN網絡的實現領域中佔據了很重要的位置。

FPGA的特點是善於進行並行乘加計算,所以在實施深度學習計算時,我們要考慮將深度學習算法進行適當優化,將捲積、池化、下採樣等大運算量的算子在FPGA中實現,從而提升整體計算引擎的效率和算力。在實踐種,我們在xilinx zcu102單板上實現了卷積神經網絡中卷積算子、池化算子、下採樣算子以及全連接算子。此外,如resnet網絡中涉及的scale和batchnorm算子也在建模中進行了適當優化,得以在FPGA中實現。

我們採用了深鑑科技的笛卡爾架構進行了研究和實踐。笛卡爾架構,如下圖,是典型的zynq工程架構。片上ARM與邏輯資源之間由AXI接口連接,網絡配置信息由axi-lite接口傳送,圖像數據和權重則通過DMA由PS傳送至PL外掛的DDR中,在卷積計算中由PL與DDR通過AXI4協議通信存取。

異構計算系列(三):Adlik在深度學習異構計算上的實踐 5

在整體設計上,我們考慮使用了int8量化和DSP復用技術,多點滑窗卷積計算以及多算子融合技術,結合FPGA傳統設計中常用的流水線及乒乓存取技術,使加速器獲得了更高的算力,以及更短的網絡處理時間。

1.Int8量化和復用DSP技術

基於Xilinx xczu9eg系列芯片中的DSP資源的特點,可以實現DSP的乘加複用。該系列芯片的DSP資源可以實現27×18bit的乘法計算,且某一級DSP的乘法輸出結果可以級聯到下一級DSP的加法輸入端,從而實現乘加級聯功能,無需額外使用邏輯資源搭建加法器。
如果將輸入的圖像和權重信息量化為int8格式,則可以使用權重移位的方式將某一權重左移18位後與另一權重相加,作為乘法器27bit的輸入數據,從而使用一個DSP實現兩次乘加計算,可以做到算力加倍。

2.基於multi-sliding的捲積計算

傳統的二維卷積計算中,每個時鐘沿參與卷積的因子為M個輸入通道圖像中的某個單點與對應輸出通道的捲積核的對應單點相乘加,得到對應N個輸出通道中對應位置的單點部分和。如下圖,完成一個卷積核為3×3的捲積計算,需要9個時鐘沿。如果stride=1,則完成一行輸出圖像的計算需要9×6=54個時鐘沿。

異構計算系列(三):Adlik在深度學習異構計算上的實踐 6

傳統的捲積單點計算示意圖

使用multi-sliding window的捲積方式,引入PIX變量,表示每個時鐘沿裡,每個輸入通道的圖像參與卷積的像素點數,傳統卷積中的PIX通常為1,即每個輸入通道只有一個像素點參與乘加計算,而現在PIX可以取大於1的其他值,這樣就使每個時鐘沿參與卷積的圖像像素點得到了伸展。

如下圖,當卷積計算的參數pad=1,kernel=7,stride=1,ciWidth=28,PIX=8時,每輸入通道在每個時鐘沿裡參與卷積的像素點數擴展為8,與對應的捲積核相乘加,作為對應輸出通道的部分和。

異構計算系列(三):Adlik在深度學習異構計算上的實踐 7

multi-sliding window卷積計算示意圖

如圖,對於ibuf中的某一個輸入通道中的每一行輸入圖像,每個時鐘沿都有PIX個像素點參與卷積計算。隨著sbuf中的權重由行首滑窗至行尾,每一個滑窗經過的像素點會在一個時鐘沿的時間裡完成所有在這一里要參與的捲積計算,不會在之後的時鐘沿裡被重複使用,使得整行的計算時間是傳統的捲積方式的1/PIX,大大縮短了計算時間。

3.多算子融合

推理時的BatchNorm算子運算非常耗時,但由於其是線性運算,可以在建模初期將BatchNorm+Scale的線性變換參數融合到卷積層,替換原來的weights和bias。與單獨計算BatchNorm相比,這種算子融合大大減少了內存的讀寫操作,有效提高了處理幀率。

4.流水線計算和乒乓加載技術

流水線技術和乒乓加載技術是FPGA設計中常用的手段。使用流水線可以使串行計算並行化,大大減少運算時間,乒乓加載技術則利用片上存儲器實現了輸入圖像和權重的預加載,使輸入圖像由FPGA片外DDR傳至片上的時間被捲積計算時間覆蓋,同樣起到了減小圖像處理時間的作用。

結語

在深度學習計算這類計算密集型的應用場景下,通用硬件設計中的某些特點,如復雜任務調度等,很可能會成為計算瓶頸,導致降低計算效率,所以針對應用部署硬件的特徵完成異構硬件上的計算優化,在當前已經成為研究的熱點。 Adlik首先在架構上支持多類異構硬件和計算引擎,也在FPGA異構計算上完成了一些技術實踐,後續將繼續進行特定硬件上的計算優化技術的研究,來加速推動AI模型的工程應用。

參考文獻:

[1] https://github.com/Adlik/Adlik
[2] Xilinx-ug579-UltraScale Architecture DSP Slice User Guide
[3] Xilinx-WP486-Deep Learning with INT8 Optimization on Xilinx Devices
[4] Google Inc. Quantization and Training of Neural Networks for Efficient Integer-Arithmetic-Only Interface.

作者簡介:

[1]劉濤,中興通訊算法高級系統工程師,Adlik開源項目負責人。
[2]李瑩,中興通訊技術規劃部FPGA工程師,負責對FPGA加速器時序優化。

相關文章:

《異構計算系列文章(一):定義、場景及局限性》
《異構計算系列(二):機器學習領域湧現的異構加速技術》