高榕,張良,梅魁志
(西安交通大學電子與信息工程學院,710049,西安)
深度學習在圖像處理、自動控制和智能機器人等方面表現出了良好的應用潛力,已經被廣泛應用到物體識別、手勢控制等諸多方面。目前,深度學習技術不再局限于各機構的基礎理論研究,已經形成了較為成熟的應用系統,例如人臉檢票系統、自動閱卷系統以及交通監控系統等。智能移動終端在當今互聯網時代背景下應用愈加廣泛。隨著便攜設備的不斷發展,人們對其能夠提供智能、穩定、高速的應用需求與日俱增。將深度學習技術應用于嵌入式設備中,用以改善用戶體驗并提高軟件智能,具有重要的現實意義。
卷積神經網絡是深度學習算法的基礎,Caffe(Convolutional architecture for fast feature embedding)[1]和TensorFlow[2]是目前應用范圍最廣、生命力最活躍的學習框架。Caffe結構清晰、可讀性高,主體以C++代碼編寫,硬件兼容性好,同時有著豐富的線上資源和活躍的開發社區,因此被廣泛采用。
ARM嵌入式處理器是當前移動設備主要的處理器,最新的Samsung Exynos 8895、Qualcomm Snapdragon 835以及Apple A10 CPU主頻可達2 GHz以上。深度學習算法在嵌入式終端的實現和加速是目前機器學習與人工智能領域的研究熱點。當前性能高的移動端深度學習框架有Facebook的Caffe2[3]、騰訊的ncnn[4]和百度的MDL[5]。Caffe2基于Caffe開發,代碼結構與TensorFlow更為類似,以輕量化、模塊化和張量化為特點,強調多平臺支持性和移動端高效性,但目前Caffe2尚未成熟,僅支持部分嵌入式GPU;ncnn支持多種神經網絡結構,不依賴第三方數學計算庫,具有極為精簡的代碼體積和高效的匯編級優化,但不支持異構計算;MDL旨在簡化卷積神經網絡的部署難度,體積小、速度快,僅支持iOS GPU。針對現今廣泛應用的Caffe模型格式,Caffe2、ncnn和MDL均需要額外的模型轉換操作。
在移動端加快神經網絡前向計算速度主要有修改神經網絡的模型和加快框架運行速度兩種策略。Han、Lin等從模型壓縮角度出發,采用剪枝、哈夫曼編碼和定點小數方式優化訓練模型[6-7];Zhang、Marat從矩陣乘法角度出發,采用Neon、快速傅立葉變換方式加速網絡計算[8-9]。Oskouei等使用RenderScript異構框架,卷積層計算最高提速達60倍[10]。
為探索深度學習框架如何在Android手機端高效部署的問題,最大化地精簡前向計算流程并保證兼容性,考慮到目前嵌入式GPU性能逐漸提升的事實,本文從框架優化角度出發,實現了基于Caffe的嵌入式移動端深度學習算法框架前向計算的多核同構并行和OpenCL[11]異構并行加速方案。
Caffe具有清晰的代碼結構,以高度模塊化的設計取得了良好的可擴展性。本文提出并實現了一種基于Caffe的嵌入式同構、異構深度學習算法框架加速方法,主要包括3個部分:基于CPU的卷積層im2col函數多核多線程同構并行化;基于CPU的卷積層、非線性激活、池化層多核多線程幀間同構并行化;基于GPU的卷積層im2col函數異構并行化,方法的框架如圖1所示。

圖1 Caffe移動端同構、異構并行方法框架
通過對深度神經網絡模型前向計算過程各層耗時進行分析表明:卷積層和池化層是深度神經網絡前向計算過程中具有并行化潛力的最耗時的結構;卷積層耗時約占整個過程耗時的60%,池化層耗時約占整個過程耗時的20%[12]。基于上述事實,利用多核多線程方法,對卷積層中的像素重排操作(即im2col函數)進行并行優化,將卷積核在每幀圖像的線性掃描操作按照位置對應規則分配到多個線程中做等間隔式處理;采用多核多線程方法對多幀圖像的深度神經網絡模型前向計算過程進行并行優化,將線性的卷積層、非線性激活和池化層按照數據優先規則分配到多個線程中做流水線式處理;利用異構的OpenCL框架,將卷積層中的像素重排操作遷移到GPU中進行,充分利用嵌入式移動終端的計算資源,進一步提高算法框架的性能。
卷積層、激活函數層和池化層是深度神經網絡模型中不可或缺的組成部分,并起著至關重要的作用。卷積層用來進行特征提取;激活函數層用來引入非線性因素;池化層主要用來降低數據維度、減少計算量、提高模型的泛化能力。
卷積算法的一般實現主要由2部分組成:第1部分是輸入二維矩陣轉一維向量操作,如圖2所示,對索引的圖像塊重排為矩陣列(im2col函數),逐通道、逐行、逐列將較為復雜的滑動卷積分解為像素重排和矩陣乘法;第2部分是基本矩陣乘法操作。
卷積核以一定步長沿著輸入圖像的長、寬和通道遍歷滑動,并行度較低。為了加快重排速度,增強函數的非線性性,最大限度地利用多核處理器的計算資源,提出了im2col同構并行化方法。卷積核滑動窗口在輸入幀的每一個位置處的二維數據相互獨立,能夠將像素重排操作分配給不同的線程處理;另外,重排結果在數學原理上有嚴格次序關系,能夠將不同線程的結果直接輸出到預定位置。采用全局指針共享輸入輸出的方式,避免了不必要的資源占用和時間損耗[13]。

圖2 像素重排函數操作示意圖
2.1.1 位置對應的任務分配規則 子線程是進行像素重排的最小操作單元,不同子線程有且僅有自己唯一的從0開始的線程ID;子線程數即為并行度。每一個子線程負責處理當前線程ID作為起始位置的滑動掃描過程,即位置對應規則,完成后以并行度作為步長等間隔處理,位置對應的任務分配規則如圖3所示。

圖3 位置對應的任務分配規則示意圖
2.1.2 數據同步與子線程協調 PthreadLib多線程編程機制中,線程創建時刻與線程執行時刻并不相同,主線程調用線程創建函數創建多個子線程后,系統根據優先級高低和搶占處理器資源的先后,無規律地啟動并執行子線程。
本文提出信號量控制線程創建、執行的方法。在每一次子線程創建后、下一次子線程創建前,強制等待信號量激活;在每一次子線程啟動執行后、線程ID參數正確賦值時,強制釋放信號量。通過信號量的等待與釋放操作,確保子線程ID參數賦值的正確性,即在每一次子線程創建后,主線程函數暫時掛起,避免了循環體連續執行造成的影響;在每個子線程ID參數正確賦值后,子線程函數體釋放信號量,通知主線程“參數已正確讀入,可以進行下次創建”;主線程在收到信號量的釋放通知后,解鎖等待并進行下一次循環體的執行。信號量同步方法原理如圖4所示,流程圖如圖5所示。

圖4 信號量同步方法原理示意圖

圖5 信號量同步方法流程圖
為進一步改善小圖像、小模型(MNIST)卷積并行化的加速效果,針對上述方法中存在的多次創建、銷毀子線程帶來的額外時間開銷的問題,提出了改進的信號量同步方法,方法流程如圖6所示。

圖6 改進的信號量同步方法流程圖
深度學習網絡模型的前向計算過程中,在全連接層之前,輸入圖像的幀與幀之間相互獨立。卷積和池化,卷積、非線性激活(Relu)和池化兩種結構是深度學習模型最基礎的結構。根據上述事實,為了充分利用幀間無關的特性,本文從模型并行的角度出發,對卷積層、非線性激活層和池化層進行了并行,基本原理如圖7所示,輸入組幀數假設為4。

圖7 卷積層、Relu層及池化層幀間并行原理圖
并行前卷積層、非線性激活層和池化層均為串行處理;并行后將每幀的非線性激活或池化分配給不同的核心和線程(以下簡稱計算單元),即數據優先規則下的流水線式處理方法,通過信號量作為不同計算單元間的通訊媒介,控制每幀圖像不同步驟的啟動順序。
2.2.1 模版匹配、網絡復制與CPU綁定 幀間并行的處理對象是卷積層、非線性激活層和池化層3層,所以首先需要進行模版匹配;深度神經網絡各層包含大量的模型信息,為正確的將網絡層結構和數據傳入子線程中,需要進行網絡復制,以保證卷積層、非線性激活層和池化層在不同計算單元的處理獨立性;為充分利用多核處理器的資源,合理分配計算權重,將卷積層、非線性激活層和池化層任務綁定到不同的處理器核心上。
2.2.2 層間觸發器和接收器的設計 為控制每幀圖像不同步驟的啟動順序,需要設置卷積層和非線性激活層的處理觸發器,以及非線性激活和池化層的處理接收器。各觸發器和接收器相互關系如圖8所示。
特別地,在上述卷積層、非線性激活函數層和池化層進行實際處理工作前,Caffe包含一個數據重構操作;非線性激活函數層通常會以“子層”的方式嵌入卷積層中,并與“父層”共享輸入、輸出數據。為避免卷積層和非線性激活層同時對數據重構產生沖突,需額外對重構操作進行時序控制,如圖8所示。

圖8 卷積層、Relu層和池化層觸發器、接收器配置示意圖
為利用部分移動設備攜帶高性能GPU的優點,消除im2col同構并行時子線程搶占式等待的影響,提高CPU的計算效率,本文實現了im2col函數的異構并行化。
OpenCL由多維度的工作組構成,每個工作組承擔一次計算任務。im2col函數一共有3層循環,用來定位與卷積核匹配的輸出位置。采用三維工作組獲取索引的方式將循環展開,每一組索引映射到對應卷積核位置上并分發給各自的工作組并行處理,完成后將結果從GPU取出。im2col異構并行方法原理如圖9所示。
在對多幀圖片進行前向計算時,OpenCL需要頻繁地創建銷毀上下文、命令隊列和程序,并反復申請釋放固定大小的內存塊。為最大程度地提升異構并行效率,本文提出“一次創建,多次使用,一次銷毀”的OpenCL優化方法,在首幀、末幀圖片創建、銷毀GPU內存空間,所有圖片共享計算資源[14]。

圖9 im2col異構并行方法原理圖
本文在PC平臺和嵌入式Android平臺,對MNIST、Cifar-10和CaffeNet 3種經典網絡模型進行了測試,驗證了同構、異構并行化方案對加速神經網絡前向計算過程的可行性、正確性和有效性。
原嵌入式Android系統不支持Caffe,無法直接在移動端進行編譯和運行,為解決上述問題本文采用交叉編譯方案,在桌面Ubuntu系統使用Android NDK Build工具編譯生成能夠運行于目標平臺的Caffe及其第三方庫,并下載到嵌入式平臺[15]。移植框架流程如圖10所示。

圖10 Caffe嵌入式移植框架流程圖
本文的PC測試平臺為Intel Core i7 3930k、Ubuntu x64系統、Caffe CPU版本;嵌入式測試平臺為Cortex-A9 Samsung S5P4418 CPU,動態運行主頻400 MHz~1.4 GHz,4核心,系統為Android 5.1 ADB shell;同構、異構測試平臺為Qualcomm SnapDragon 820 CPU,運行主頻為1.8 GHz,4核心,Adreno 530 GPU,運行主頻為510 MHz,3 GB運行內存,系統為Android 7.0,測試環境為Android 7.0 ADB shell。MNIST、Cifar-10和CaffeNet 3種模型的Caffe網絡配置見表1。

表1 MNIST、Cifar-10、CaffeNet三種模型網絡配置
MNIST輸入圖像為28像素×28像素單通道灰度圖,輸入幀大小為100,循環次數為50次;Cifar-10輸入圖像為32像素×32像素三通道彩色圖,輸入幀大小為100,循環次數為50次;CaffeNet輸入圖像為256像素×256像素三通道彩色圖,輸入幀大小為5,循環次數為50次。
本文選用前向計算的驗證過程;驗證過程用于模型驗證,區別于前向計算的部署過程,驗證過程復雜度更高,具有代表性。
PC平臺用來做性能預估測試,測試結果為MNIST、Cifar-10、CaffeNet整個網絡驗證過程耗時,見表2。本文不對幀間并行進行單獨測試,將CPU卷積并行與幀間并行的組合優化記作同構并行,將GPU卷積并行與幀間并行的組合優化記作異構并行,后文均沿用上述說法。
加速比是同一任務在未并行前和并行后運行消耗時間的比率,由表2可知,同構并行算法在PC平臺下對3種模型的最優加速比分別為1.67、1.60、1.12。

表2 4線程PC平臺同構并行前向計算時間測試結果
Cortex-A9 Samsung S5P4418平臺同構并行前向計算時間測試結果見表3。

表3 2線程S5P4418同構并行前向計算時間測試結果
由圖3可見,MNIST輸入圖片較小,復雜度較低,卷積并行優化收益小于線程調用開銷,所以實際測試耗時不降反升。為避免計算密集型應用阻塞所有核心而影響平臺自身性能,S5P4418同構并行化測試只使用2線程。由表3可知,同構并行算法在S5P4418平臺下對3種模型的最優加速比分別為1.52、1.44、1.44。
Qualcomm SnapDragon 820平臺(以下簡稱820平臺)同構并行前向計算時間測試結果見表4。

表4 4線程820平臺同構并行前向計算時間測試結果
由表4可知,同構并行算法在820平臺下對3種模型的最優加速比分別為1.98、2.04、1.55。
通過3種平臺同構并行化前后測試結果可以看出,同構并行算法能較大幅度地改善深度神經網絡前向計算的時間性能,在沒有任何精度損失的情況下最大加速比可達2倍。
CaffeNet模型復雜度高,網絡深度高于20,基本包含所有常用的深度學習結構,具有一般性,因此異構并行僅對CaffeNet進行測試。820平臺異構并行單幀處理時間測試結果見表5。異構并行算法在820平臺下對CaffeNet模型的最優加速比為1.76。

表5 820平臺異構并行單幀處理時間測試結果
針對異構并行提出的“一次創建,多次使用,一次銷毀”的OpenCL優化方案,本文進行了單獨測試,測試結果見表6。

表6 異構OpenCL優化方案單幀處理時間測試結果
本文對CaffeNet前向部署過程也進行了并行化,在820平臺下最優單幀處理時間可達124 ms。
本文在分析當前深度學習框架對于Android移動端前向計算部署局限性的基礎上,結合現有嵌入式中央處理器和圖形處理器性能飛速發展的特點,提出了一種基于Caffe的嵌入式同構、異構并行化設計。本文使用Android NDK Build對Caffe進行了嵌入式移植,針對卷積層線性度高的事實,結合輸入組幀間無關的特點,實現了Caffe前向計算過程的并行化。對比優化前后的測試結果,本文所提方法取得了較好的加速效果,CaffeNet的移動端實現具有可行性,便于從PC遷移應用。在未來工作中,將利用OpenCL對Caffe中矩陣乘法進行異構并行優化。
參考文獻:
[1] JIA Yangqing,SHELHAMER E,DONAHUE J,et al. Caffe: convolutional architecture for fast feature embedding [C]//Proceedings of the 22nd ACM International Conference on Multimedia. New York,USA: ACM,2014: 675-678.
[2] Google Inc. Tensorflow [EB/OL]. (2017-09-23)[2017-10-10]. https: //github.com/tensorflow/tenso-rflow.
[3] Facebook Inc. caffe2 [EB/OL]. (2017-05-22)[2017-06-24]. https: //github.com/caffe2/caffe2.
[4] Tencent Inc. ncnn [EB/OL]. (2017-09-23)[2017-11-04]. https: //github.com/Tencent/ncnn.
[5] Baidu Inc. Mobile-deep-learning [EB/OL]. (2017-09-03)[2017-10-02]. https: //github.com/baidu/mobi-le-deep-learning.
[6] HAN Song,MAO Huizi,DALLY W J. Deep compression: compressing deep neural networks with pruning,trained quantization and Huffman coding [J]. Fiber,2015,56(4): 3-7.
[7] LIN D D,TALATHI S S,ANNAPUREDDY V S. Fixed point quantization of deep convolutional networks [J]. Computer Science,2016: arXiv: 1511. 06393.
[8] ZHANG Xianyi. OpenBLAS [EB/OL]. (2017-02-03)[2017-02-24]. https: //github.com/xianyi/OpenBLAS.
[9] MARAT D. NNPACK [EB/OL]. (2017-07-21)[2017-09-07]. https: //github.com/Maratyszcza/NNPACK.
[10] OSKOUEI S S L,GOLESTANI H,KACHUEE M,et al. GPU-based acceleration of deep convolutional neural networks on mobile platforms [J]. Computer Science,2015: arXiv: 1511.07376v1.
[11] Apple Inc. OpenCL reference guide [EB/OL]. (2017-08-17)[2017-08-22]. https: //www.khronos.org/files/opencl22-reference-guide.pdf.
[12] SONG I,KIM H J,JEON P B. Deep learning for real-time robust facial expression recognition on a smartphone [C]//Proceedings of the IEEE International Conference on Consumer Electronics. Piscataway,NJ,USA: IEEE,2014: 564-567.
[13] FARABET C,MARTINI B,AKSELROD P,et al. Hardware accelerated convolutional neural networks for synthetic vision systems [J]. IEEE International Symposium on Circuits and Systems,2010,54(3): 257-260.
[14] 崔繼岳,梅魁志,劉冬冬,等. 面向OpenCL的MaliGPU仿真器構建研究 [J]. 西安交通大學學報,2015,49(2): 20-24.
CUI Jiyue,MEI Kuizhi,LIU Dongdong,et al. Construction of embedded Mali GPU simulator for OpenCL [J]. Journal of Xi’an Jiaotong University,2015,49(2): 20-24.
[15] SH1R0. Caffe-android-lib [EB/OL]. (2017-01-01)[2017-01-15]. https: //github.com/sh1r0/caffe-and-roid-lib.