天天看點

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

deep learning, deep convolutional neural network (cnn), mobile gpu, performance optimization, low energy con- sumption, open source software, android, renderscript

智能手機、可穿戴裝置、微型機器人、物聯網等越來越多的移動平台都在深度學習的領域找到了相應的應用方向(如圖1)。例如在移動裝置上,語音識别和圖像識别等許多app都受益于機器學習的本地算法。如果允許将模型等資料直接放在用戶端,就可以避免和伺服器的上下行資料互動而導緻的網絡延遲等體驗的問題。cnn卷積網絡在預測的精确性和可擴充性上都取得了很先進的成果,然而像此類密集計算型的網絡結構必須依賴硬體級加速才可能在移動裝置上得到廣泛的應用。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖1:cnn在移動裝置上的應用

許多基于深度學習的硬體加速平台都有相應的解決方案了,ibm也正在開發一種用于神經網絡的cmos的晶片,用于在移動裝置和物聯網裝置上。與此同時,類似的解決方案依然處于早期的研發階段,也并沒有商用到現有的移動裝置上。

和基于硬體的加速平台不同的是,gpu已經大規模的商用到現在的移動裝置上了,同時在軟體層面的編碼支援也做的非常完善了。利用gpu現成的并行計算能力去實作cnn神經網絡在移動端裝置上的計算加速是完全可行的。

現存的gpu加速方案的深度學習cnn的開源庫有很多種,都是基于伺服器和桌面平台的[見附錄的6, 7, 8, 9, 10, 11, 12].然而,由于平台架構的差異,簡單的把這些開源庫移植到移動端上,在某些case下效果是欠佳的(見2.2節)。目前在移動端上,據我們所知,并沒有相應的帶有gpu加速的深度學習計算架構的開源庫,這些庫 [見附錄的13, 14, 15, 16]僅僅能夠利用移動裝置的cpu多核計算能力,而這樣局限性很大。

如今,我們提供一個支援gpu加速的開源庫,稱為“cnndroid”,可以在android平台用來通過訓練資料集的方式設計和優化cnn的網絡。以下是cnndroid的幾個主要亮點。

1. 支援幾乎所有的cnn的layer type(section 3.1) 2. 相容caffe[6]、torch[7]、theano[8]這些開源架構在pc平台、伺服器平台上已經訓練好的模型(section 3.2) 3. 現有的android app可以快速的加入這個庫,無需額外的軟體依賴(section 3.3) 4. 開發者可以指定最大的記憶體消耗(section 3.4) 5. cnn layer的gpu和cpu加速均支援(section 3.5) 6. 自動的硬體條件檢測(section 3.6) 7. 在移動裝置上超過60倍的性能提升以及減少130倍的能耗(section 4)

現代圖形處理單元(gpu)不僅僅能做圖形計算,也能夠被用來做可程式設計的通用計算。桌上型電腦的gpu長期以來都是可程式設計的,近期移動裝置上的gpu也開放了通用計算的硬體級支援。但受限于gpu的尺寸和功耗,移動gpu和桌面gpu裝置還是有很大的差異。

現代移動gpu的shader cores(sc)通常成為若幹可程式設計并行計算單元。每個shader core都是由若幹個alu并行組成。比如,三星的exynos 5433晶片是由arm a53/a57 cpu和mali t-760 gpu組成(見圖2)。t-760 gpu中的每一個sc都具有兩個vliw格式的128位alu。每個128位alu能夠執行simd操作,即并行的兩個64位,四個32位或八個16位操作[17]。與桌面平台gpu相比,移動裝置的并行alu架構在并行線程的有效執行中更多地依賴于軟體和編譯器,而不是動态硬體排程器。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖2: exynos 5433 mobile processor with arm a53 / a57 cpu and mali t-760 gpu

(sc: shader core, vliw: very long instruction word, simd: single instruction multiple data

更重要的是,在桌面gpu中廣泛應用的線程塊快速記憶體共享機制在移動gpu中并不可用,同時許多基于cuda的桌面平台的library在移動gpu上也不可以用。

更不幸的是,在軟體層面這兩端的差異也是巨大的。比如android提供的renderscript[18]是一個用于并行計算的庫,但是并發線程的機制并不可用。另外,并行線程和并行線程使用的記憶體中的資料部分必須是一對一的關系。

在伺服器和桌面端,已經有很多現成的基于gpu加速的并行計算架構可用于cnn網絡,諸如caffe[6],torch [7], theano [8],tensor- flow [9], cudnn [10], cuda-convnet [11],,and velesnet [12],然而由于兩端的硬體和軟體的差異,這種加速和并行計算的方法并不能直接的被移植到移動裝置上。比如說,caffe[6]中的卷積操作被展開并轉換為矩陣乘法,這些操作對記憶體的要求比較高,這在移動裝置上是不現實的。再舉一個例子,theano [8]中的并行算法雖然與cnndroid類似,但是在移動gpu中沒有使用simd單元(詳見section 3.5)。

更不幸的是,桌面的計算庫利用桌面gpu和cuda架構提供的線程管理功能,如快速共享記憶體和線程同步,這些在移動gpu和android提供的renderscript中均不可用。

在移動裝置上,就目前所知的支援cnn深度學習的架構隻有[13,14,15,16]。包括了caffe mobile[13]和torch mobile[14],均受限于多核的cpu計算能力,而隻有cnndroid支援cpu和gpu(詳見section 3.5)。

另外,cnndroid還相容caffe[6]、torch[7]、和theano[8]訓練出來的cnn模型,友善快速将模型部署到移動裝置上(詳見section 3.2)。

開發環境上,不需要安裝android ndk,隻需要安裝android sdk即可。

cnndroid庫支援幾乎大部分的cnn layers,比如說卷積層,max/mean池化層,全連結層,relu(rectified linear units)激活函數,lrn(local response normalization)層,softmax等。相關的描述和每一層的參數設定在開源庫中的文檔裡有說明[1]。由于庫的開源特性,其它的層也可以随時加入。

模型轉換腳本:圖3展示了如何将訓練好的模型部署到移動端

cnndroid庫提供了一系列的腳本,可以把不同架構訓練的庫轉成cnndroid格式的模型,目前已經支援caffe[6],torch[7],theano[8],是以可以使用以上架構訓練模型然後轉為cnndroid庫支援的格式,最終運作在android移動裝置上。當然你也可以模仿這些腳本寫出其它平台的轉換腳本,cnndroid使用messagepack序列化和存儲模型中不同層的參數。具體的細節可以參考開源庫的說明文檔[1]。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖3:cnndroid的模型部署流程

netfile:開發者需要準備一個名為netfile.txt的文本檔案,類似于caffe的.prototxt配置檔案,netfile.txt檔案用于配置已經訓練好的模型的層次,比如說,cnn layer的各層的順序,卷積層中的padding和stride的值。圖4是一個該檔案的樣例,更詳細的細節可以參考說明文檔[1]。

netfile中也可以配置如下參數,allocated_ram:用于指定本架構可以配置設定的最大記憶體上線(見section 3.4),execution_mode:用于指定是采用并行模式還是串行模式(見section 3.5),auto_tuning:用于指定auto-tuning是否預設開啟(見section 3.6)。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖4:netfile示例,如何配置alexnet[20]的三層網絡結構, 以及allocated_ram, execution_mode,auto_tuning參數的配置

一旦将訓練好的模型和相應的netfile檔案上傳到了移動裝置後(圖3),這個模型可以被所在的android app輕易的調用(圖5),具體的有如下幾個步驟:

第一步,在自己的app中依賴cnndroid庫,cnndroid庫隻依賴android sdk,而不需要安裝android ndk的,也就是說,不依賴其他的第三方庫。

第二步,構造renderscript和cnndroid對象(圖5所示的steps 2和3)。cnndroid的構造函數需要提供netfile檔案作為輸入,并會自動的建立相應的網絡層次。

最後,compute函數負責利用訓練好的模型,計算傳入的單個圖像或者批量圖像并傳回結果。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖5: 使用cnndroid庫的幾個關鍵調用步驟,

詳細的使用方法可以參見開源庫中的說明文檔 [1].

我們将已經訓練好的cnn模型,上傳到手機的sd卡上,這些模型中包含了矩陣式的各層參數。在執行每一層前,在compute函數裡(圖5,step5),相應層的矩陣參數被自動的從sd卡上加載記憶體裡,這會導緻大量的記憶體開銷。

為了減少這種記憶體開銷,cnndroid采用的方法是:保持一部分的層長期駐留在記憶體中,而其他的層每次都會被建立和銷毀。該選擇過程開發者無需關心,在cnndroid構造函數中自動完成(圖5,step3)。選擇器從最大的層開始,讓盡量多的層進入選擇器,直到達到netfile中allocated_ram參數指定的記憶體上限。

注意:allocated_ram參數不宜設定的過大,比如說,android 5.0在系統層就會限制每個app的記憶體上限為512mb。

在cnndroid中,不同的層有不同的加速方法。比如資料并行的卷積層和需要大量密集計算的全連接配接層,就需要用到renderscript的架構來實作移動端的gpu加速。

這兩層的大部分計算可以表示為點積。具體地來說,在卷積層中kernels與input frames進行卷積;而在全連接配接層中,計算可以表示為矩陣和向量的乘法。在移動裝置上使用gpu的simd單元可以高效的進行點積的計算。是以,我們分離了大量的向量,并且使用基于renderscript架構的預定義點積函數來完成運算。也就是說,我們在軟體層面展現了這種計算的并行性,而不像是基于cuda的桌面計算架構庫那樣把這類問題交給gpu的硬體排程程式。

相對于卷積層和全連接配接層,其它層的密集型計算相對較少。是以,它們通過多線程并發在多核cpu上進行加速。比較特殊的是,由于relu層通常出現在卷積層或全連接配接層之後,是以把它嵌入到之前的層中,可以在将多個圖像傳輸時提高cnndroid的性能。

除了上述并行計算的實作之外,cnndroid還包括所有層的單線程順序執行的實作。可以通過配置netfile中的execution_mode參數,指定執行将是順序模式還是并行模式(圖4)。

為了能夠在移動裝置上達到最好的性能,cnndroid架構的gpu并行加速算法支援在每個gpu線程上執行自動配額,比如說調配該gpu線程的工作量以及simd alus的工作量。配額的參數調整決定了并行的粒度。

如果在netfile(圖4)中打開了auto-tuning,那麼auto-tuner就會在android app首次啟動時執行。auto-tuner會記錄該移動裝置上多個預定義的情景下cnn模型的運作時長,用于調整最佳的配額參數。是以,首次啟動app需要花費較長的時間。為了公平性以及更清晰的表述我們的實驗,在第4節中,我們将關掉auto-tuning。

我們在三星的galaxy note 4和htc one m9進行了實驗。采用的模型是幾個标準的cnn網絡:lenet network for mnist dataset [21],alex krizhevsky’s network for cifar-10 (alex’s cifar-10) [22], alex krizhevsky’s network for imagenet 2012 dataset (alexnet) [20].

基準cnn的層設定如圖6所示。當移植到cnndroid格式時,我們還統計了檔案大小和記憶體占用。具體的結果如圖7所示。

我們的實驗環境是将手機充滿電,同時進入飛行模式并且将螢幕亮度調為最低。以下的實驗中,并沒有每次都從sd卡加載配置和模型,因為在第一次運作時候就加載到記憶體中了。每次我們都會将16張圖檔作為輸入傳給cnndroid app,接下來測量輸出的準确性以及運作耗時和耗電量。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖6: 三種标準的cnn網絡的層次

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖7: 在cnndroid格式下使用三種标準cnn網絡的檔案大小以及記憶體消耗

為了測量cnndroid的準确度,我們同時使用了cnndroid和caffe作對比實驗。結果顯示兩者的結果方差是10的-12次方,也就意味着cnndroid的準确度和caffe幾乎一樣。

圖8顯示了僅使用cpu的線性運作cnn的運作耗時以及使用gpu加速的運作耗時和加快的倍速。報告顯示的值是十次運作結果的平均值。

CNNdroid:在 Android 上利用 GPU 加速執行 CNN (卷積神經網絡)

圖8:(a)是cnn運作的平均耗時和加速的速率,(b)是整個cnn中最耗時的卷積層的耗時和加速速率

我們使用“qualcomm trepn profiler”應用程式[25]測量htc one m9手機基于alexnet網絡結構的每一幅圖像的功耗和能耗。

gpu加速執行時,消耗約523 mw功率和0.4 j能量,而僅僅使用cpu執行時消耗2338 mw功率和51.6 j能量。 是以,gpu加速執行消耗的電池消耗減少51.6÷0.4 = 129x。值得注意的是,我們的測量中有大約20%的波動。

我們介紹了cnndroid:一個在android平台上基于gpu加速cnn網絡的開源庫。經過實驗評估證明該庫可以提升60倍速,以及130倍的能耗節省。相關的代碼以及說明文檔都已經開源并釋出在github上[1]。

[1] cnndroid open source gpu-accelerated library.

<a href="https://github.com/encp/cnndroid" target="_blank">https://github.com/encp/cnndroid</a>

[2] inchul song, hyun-jun kim, and paul barom jeon. deep learning for real-time robust facial expression recognition on a smartphone. in ieee international conference on consumer electronics, pages 564–567, jan 2014.

[3] yu-hsin chen, tushar krishna, joel emer, and vivienne sze. 14.5 eyeriss: an energy-e cient reconfigurable accelerator for deep convolutional neural networks. in ieee international solid-state circuits conference, pages 262–263, jan 2016.

[4] mohammad motamedi, philipp gysel, venkatesh akella, and soheil ghiasi. design space exploration of fpga-based deep convolutional neural networks. in asia and south pacific design automation conference, pages 575–580, jan 2016.

[5] paul a merolla, john v arthur, rodrigo alvarez-icaza, andrew s cassidy, jun sawada, filipp akopyan, bryan l jackson, nabil imam, chen guo, yutaka nakamura, bernard brezzo, ivan vo, steven k esser, rathinakumar appuswamy, brian taba, arnon amir, myron d flickner, william p risk, rajit manohar, and dharmendra s modha. a million spiking-neuron integrated circuit with a scalable communication network and interface. science, 345(6197):668–673, 2014.

[6] yangqing jia, evan shelhamer, jeff donahue, sergey karayev, jonathan long, ross girshick, sergio guadarrama, and trevor darrell. caffe: convolutional architecture for fast feature embedding. arxiv preprint arxiv:1408.5093, 2014.

[8] james bergstra, olivier breuleux, fr ́ed ́eric bastien,

pascal lamblin, razvan pascanu, guillaume desjardins, joseph turian, david warde-farley, and yoshua bengio. theano: a cpu and gpu math expression compiler. in proceedings of the python for scientific computing conference, 2010.

[13] caffe android library.

[14] torch-7 for android.

[15] a convolutional neural network for the android

awesome-cnn-android-python. accessed 2016-08-01.

[17] arm. mali-t600 series gpu opencl, version 1.1.0,

developer guide. accessed 2016-08-01.

[18] android renderscript developers guide.

renderscript/compute.html. accessed 2016-08-01.

[19] messagepack. http://msgpack.org/index.html.

[20] alex krizhevsky, ilya sutskever, and geoffrey e.hinton. imagenet classification with deep convolutional neural networks. in advances in neural information processing systems, 2012.

[21] y. lecun, l. bottou, y. bengio, and p. haffner. gradient-based learning applied to document recognition. proceedings of the ieee, 86(11):2278–2324, nov 1998.

[22] alex krizhevsky. learning multiple layers of features from tiny images. technical report, university of toronto, 2009.

本文作者:恒亮

繼續閱讀