編者按:本文來自微信公眾號"InfoQ"(ID: infoqchina),作者:李永會;36氪經授權發布。
2017 年 9 月 25 日,百度在 GitHub 開源了移動端深度學習框架 mobile-deep-learning(MDL)的全部代碼以及腳本,希望這個項目在社區的帶動下能夠更好地發展。
寫在前面
深度學習技術已經在網際網路的諸多方向產生影響,每天科技新聞中關於深度學習和神經網絡的討論越來越多。深度學習技術在近兩年飛速發展,各種網際網路產品都爭相應用深度學習技術,產品對深度學習的引入也將進一步影響人們的生活。隨著行動裝置的廣泛使用,在移動網際網路產品應用深度學習和神經網絡技術已經成為必然趨勢。
與深度學習緊密聯繫在一起的圖像技術同樣在業界廣泛應用。傳統計算機視覺和深度學習的結合使圖像技術得以快速發展。
GitHub 地址:https://github.com/baidu/mobile-deep-learning
移動端深度學習技術應用
百度應用案例
在移動端應用深度學習技術比較典型的就是 CNN(Convolutional Neural Network)技術,即常被人提起的卷積神經網絡。mobile-deep-learning(MDL)是一個基於卷積神經網絡實現的移動端框架。
MDL 在移動端主要有哪些應用場景呢?比較常見的如分辨出一張圖片中的物體是什麼,也就是 分類;或者識別出一張圖片中的物體在哪、有多大,也就是 主體識別。
下面這個 App 叫拾相,可以在 Android 平臺的應用寶中找到。它可以自動為用戶將照片分類,對於擁有大量照片的用戶來講,這個功能很有吸引力。
另外,在手機百度搜索框右側可以打開圖像搜索,打開圖像搜索後的界面效果如下圖。當用戶在通用垂直類別下開啟自動拍開關(圖中下方標註)時,手停穩它就會自動找到物體進行框選,並無需拍照直接發起圖像搜索。整個過程可以給用戶帶來流暢的體驗,無需用戶手動拍照。圖片中的框體應用的就是典型的深度學習主體識別技術,使用的就是 mobile-deep-learning(MDL)框架。MDL 目前在手機百度中穩定運行了多個版本,經過數次迭代後可靠性大幅提升。
業界其他案例
網際網路行業在移動端應用神經網絡的案例已經越來越多。
目前的流派主要有兩種,其一是完全在客戶端運行神經網絡,這種方式的優點顯而易見,那就是不需要經過網絡,如果能保證運行速度,用戶體驗會非常流暢。如果能保證移動端高效運行神經網絡,可以使用戶感覺不到加載過程。使用完全脫離網際網路網絡在移動端運算神經網絡的 App 已經舉例,如前述拾相和手機百度中的圖像搜索。
其二是另一種,運算神經網絡過程依賴網際網路網絡,客戶端只負責 UI 展示。在客戶端神經網絡落地之前,絕大部分 App 都使用了這種運算在服務端、展示在客戶端的方式。這種方式的優點是實現相對容易,開發成本更低。
為了更好理解上述兩種神經網絡的實現方法,下面展示兩個識別植物花卉的例子,分別用到了識花和形色兩個 App。這兩款 App 都使用了典型分類方法,都可以在 iOS 平臺的 App Store 中找到。下圖是一張蓮花圖片,這張圖片使用識花和形色兩個 App 分類都能得到較好的分類結果。你可以嘗試安裝這兩款 App 並根據使用效果來判斷它們分別使用了上述哪一種方法。
識花
近一年來湧現出很多花卉識別的 App。微軟「識花」是微軟亞洲研究院推出的一款用於識別花卉的 App,用戶可以在拍攝後選擇花卉,App 會給出該類花卉的相關信息。精準的花卉分類是其對外宣傳的一大亮點。
形色
這款「形色」App,只需要對準植物 (花、草、樹) 拍照,就能快速給出植物的名字,還有不少有趣的植物知識,如這個植物還有什麼別名、植物的花語、相關古詩詞、植物文化、趣味故事以及養護方法,看完收穫不少。
移動端應用深度學習的難點
一直以來由於技術門檻和硬體條件的限制,在移動端應用深度學習的成功案例不多。傳統移動端 UI 工程師在編寫神經網絡代碼時,可以查閱到的移動端深度學習資料也很少。另一方面,時下的網際網路競爭又頗為激烈,先入鹹陽者王,可以率先將深度學習技術在移動端應用起來,就可以更早地把握時代先機。
移動端設備的運算能力相對 PC 端非常弱小。由於移動端的 CPU 要將功耗指標維持在很低的水平,制約了性能指標的提升。在 App 中做神經網絡運算會使 CPU 運算量猛增。如何協調好用戶功耗指標和性能指標就顯得至關重要。
百度圖像搜索客戶端團隊在 2015 年底就開始針對移動端深度學習技術應用進行攻關。最終,挑戰性問題被逐一解決,現今相關代碼已經在很多 App 上運行,這些 App 有日 PV 億級的產品,也有創業期的產品。
在移動端應用深度學習技術本已困難重重,而在手機百度這種量級的產品上應用,更是要面對各種機型和硬體、手機百度的指標要求。如何使神經網絡技術穩定高效運轉是最大的考驗。拆解問題就是移動端團隊面對的首要問題。我們簡單總結後發現移動端與伺服器端進行對比更容易呈現問題和難點,繼而在伺服器端和客戶端做了以下深度學習技術應用對比。
難點與伺服器端對比內存內存:伺服器端弱限制 - 移動端內存有限耗電量耗電量:伺服器端不限制 - 移動端嚴格限制依賴庫體積依賴庫體積:伺服器端不限制 - 移動端強限制模型體積模型大小:伺服器端常規模型體積 200M 起 - 移動端不宜超過 10M性能性能:伺服器端強大 GPU BOX - 移動端 CPU 和 GPU
在開發過程中,團隊逐步解決掉以上困難,形成了現在的 MDL 深度學習框架。為了讓更多移動端工程師能夠快速用輪子、專注業務,百度開源了全部相關代碼,社區也歡迎任何人加入到造輪子的開發過程中來。
MDL 框架設計
設計思路
作為一款移動端深度學習框架,我們充分考慮到移動應用自身及運行環境的特點,在速度、體積、資源佔用率等方面提出了嚴格的要求,因為其中任何一項指標對用戶體驗都有重大影響。
同時,可擴展性、魯棒性、兼容性也是我們設計之初就考慮到了的。為了保證框架的可擴展性,我們對 layer 層進行了抽象,方便框架使用者根據模型的需要,自定義實現特定類型的層,我們期望 MDL 通過添加不同類型的層實現對更多網絡模型的支持,而不需要改動其他位置的代碼;為了保證框架的魯棒性,MDL 通過反射機制,將 C++ 底層異常拋到應用層,應用層通過捕獲異常對異常進行相應處理,如通過日誌收集異常信息、保證軟體可持續優化等;目前行業內各種深度學習訓練框架種類繁多,而 MDL 不支持模型訓練能力,為了保證框架的兼容性,我們提供 Caffe 模型轉 MDL 的工具腳本,使用者通過一行命令就可以完成模型的轉換及量化過程,後續我們會陸續支持 PaddlePaddle、TensorFlow 等模型轉 MDL,兼容更多種類的模型。
總體架構
MDL 框架的總體架構設計圖如下:
MDL 框架主要包括模型轉換模塊(MDL Converter)、模型加載模塊(Loader)、網絡管理模塊(Net)、矩陣運算模塊(Gemmers)及供 Android 端調用的 JNI 接口層(JNI Interfaces)。其中,模型轉換模塊主要負責將 Caffe 模型轉為 MDL 模型,同時支持將 32bit 浮點型參數量化為 8bit 參數,從而極大地壓縮模型體積;模型加載模塊主要完成模型的反量化及加載校驗、網絡註冊等過程,網絡管理模塊主要負責網絡中各層 Layer 的初始化及管理工作;MDL 提供了供 Android 端調用的 JNI 接口層,開發者可以通過調用 JNI 接口輕鬆完成加載及預測過程。
MDL 定位簡單可用
MDL 開源項目在實施之初就已經有了清晰定位。在設備繁雜且性能較低的移動端平臺技術研發過程中,能夠為新穎的深度學習技術找到合適場景並應用到自己的產品中是非常吸引人的。但如果讓每個移動端工程師在應用深度學習過程中都要重新寫一次全部神經網絡的實現,會增加較大成本。MDL 的定位是簡單地使用和部署神經網絡,如果使用基本功能則不需要進行過多配置和修改,甚至連機器學習庫的編譯過程都不需要,只需要關注具體業務實現、如何使用即可。
與此同時 MDL 簡單清晰的代碼結構也可以作為學習材料,為剛剛接觸深度學習的研發工程師提供參考。因為我們在支持手機平臺交叉編譯同時,也支持 Linux 和 Mac 的 x86 平臺編譯,在調整深度學習代碼的同時可以直接在工作電腦上編譯運行,而不需要部署到 arm 平臺。所需要的只是簡單的幾行代碼,具體可以查閱 MDL 的 GitHub Readme。
# https://github.com/baidu/mobile-deep-learning
# mac or linux:
./build.sh mac
cd build/release/x86/build
./mdlTest
複雜的編譯過程往往比開發的時間更長,在 MDL 中只要一行./build.sh android 就能把 so、測試 test 都搞定,部署非常簡便。
./build.sh android
MDL 的性能及兼容性
體積 armv7 300k+
速度 iOS GPU mobilenet 可以達到 40ms、squeezenet 可以達到 30ms
MDL 從立項到開源,已經迭代了一年多。移動端比較關注的多個指標都表現良好,如體積、功耗、速度。百度內部產品線在應用前也進行過多次對比,和已開源的相關項目對比,MDL 能夠在保證速度和能耗的同時支持多種深度學習模型,如 mobilenet、googlenet v1、squeezenet 等,且具有 iOS GPU 版本,squeezenet 一次運行最快可以達到 3-40ms。
同類框架對比
框架Caffe2TensorFlowncnnMDL(CPU)MDL(GPU)硬體CPUCPUCPUCPUGPU速度慢慢快快極快體積大大小小小兼容Android&iOSAndroid&iOSAndroid&iOSAndroid&iOSiOS
與支持 CNN 的移動端框架對比,MDL 速度快、性能穩定、兼容性好、demo 完備。
兼容性
MDL 在 iOS 和 Android 平臺均可以穩定運行,其中 iOS10 及以上平臺有基於 GPU 運算的 API,性能表現非常出色,在 Android 平臺則是純 CPU 運行。高中低端機型運行狀態和手機百度及其他 App 上的覆蓋都有絕對優勢。
MDL 同時也支持 Caffe 模型直接轉換為 MDL 模型。
MDL 特性一覽
在移動 AI 相關研發啟動之初,百度圖像搜索團隊對比了大部分已經開源的同類 CNN 框架,百家爭鳴的同時也暴露了該方向的問題。一些框架實驗數據表現優秀,實際產品中或是表現較差且性能極不穩定,或是機型無法全覆蓋,或是體積達不到上線標準。為了避免這些問題,MDL 加入了以下 Features:
一鍵部署,腳本參數就可以切換 iOS 或者 Android
支持 Caffe 模型全自動轉換為 MDL 模型
支持 GPU 運行
已經測試過可以穩定運行 MobileNet、GoogLeNet v1、squeezenet 模型
體積極小,無任何第三方依賴,純手工打造
提供量化腳本,直接支持 32 位 float 轉 8 位 uint,模型體積量化後在 4M 上下
與 ARM 相關算法團隊線上線下多次溝通,針對 ARM 平臺會持續優化
NEON 使用涵蓋了卷積、歸一化、池化等運算過程
loop unrolling 循環展開,為提升性能減少不必要的 CPU 消耗,全部展開判斷操作
將大量繁重的計算任務前置到 overhead 過程
後續規劃
為了讓 MDL 體積進一步縮小,MDL 並未使用 protobuf 做為模型配置存儲,而是使用了 Json 格式。目前 MDL 支持 Caffe 模型轉換到 MDL 模型,未來會支持全部主流模型轉換為 MDL 模型。
隨著移動端設備運算性能的提升,GPU 在未來移動端運算領域將會承擔非常重要的角色,MDL 對於 GPU 的實現極為看重。目前 MDL 已經支持 iOS GPU 運行,iOS10 以上版本機型均可以使用。根據目前得到的統計數據顯示,iOS10 已經涵蓋絕大部分 iOS 系統,在 iOS10 以下可以使用 CPU 運算。除此之外,雖然 Android 平臺目前的 GPU 運算能力與 CPU 相比整體偏弱,但日益湧現的新機型 GPU 已經越來越強大。MDL 後面也將加入 GPU 的 Feature 實現,基於 OpenCL 的 Android 平臺 GPU 運算會讓高端機型的運算性能再提升一個臺階。
歡迎開發者貢獻代碼
移動端神經網絡的穩定高效運行,離不開諸多開發者的編碼。MDL 長期本著靠譜運行、實用而不虛美的宗旨,希望能為移動端深度學習技術添磚加瓦。強烈歡迎有識之士濟濟加入,將深度學習技術在移動端廣泛應用、播揚海內。
最後再次奉上 MDL 的 GitHub 目錄:
https://github.com/baidu/mobile-deep-learning