這篇文章介紹的是關于并行深度神經網絡的設計。在今年發布的兩個機器學習項目中,cxxnet是最精彩的一個。因為它包含了我們團隊可以發揮到的機器學習和系統的各個方面的極致: 除了前沿的深度學習之外,它的兩個獨到特點也是讓我們在設計實現中最為享受的
1) 靈活的公式支持和極致的C++模板編程;
深度神經網絡的實現大致分兩類:以python為主的編程效率派和以c++為核心的為代表的追逐性能派。前者支持直接tensor的計算,而后者往往需要給每個神經網絡的層和更新公式編寫獨立的cuda kernel。編程效率派認為機器學習程序員應該是寫公式來達到代碼最大的可讀性和易改寫性。而很多以C++為核心的代碼之所以沒有支持非常靈活的張量計算,是因為因為運算符重載和臨時空間的分配會帶來效率的降低。
cxxnet的核心mshadow在這兩者之間做了一個平衡。使得我們在不損失效率的前提下可以通過模板編程技術允許開發者編寫和matlab/numpy類似的代碼,并且在編譯時自動展開成優化的kernel。其背后的expressiontemplate技術是我最喜歡的c++ trick之一。非常值得最求效率抽象和優美的同學了解。
因為采用了mshadow作為核心,直接導致cxxnet的各種實現可以非常簡單可讀,編寫一份代碼就可以在GPU和CPU上面跑。使得其在代碼簡潔和可擴展上更加容易。
2) 通用的并行參數共享和更新方案
多卡和多機計算一直是大規模機器學習中一個讓人興奮的話題。提到神經網絡并行,最讓我頭疼的是可以選擇的方案很多,而都涉及到不同的hack。單機多卡到底是用P2P,還是拷貝到內存,是用stream開始開多線程。分布式到底是用parameter server,MPI還是自己寫一個框架??梢赃x擇的方法很多。設計出一個分布式的代碼不難,困難的是如何讓并行的接口自然的獨立出來,使得其不會影響其它部分的實現。經過不斷地考慮,最終我決定采用了mshadow-ps這樣一個統一的參數共享接口。
簡單的說,mshadow-ps是一個GPU的異步parameter server接口(應該也是目前為止唯一一個,因為GPU線程模型和CPU不同,原有的的ps庫并不能直接用于GPU)。異步通信對于神經網絡的更新非常重要。在backprop算法中,我們很早就可以獲得梯度并且進行梯度同步,而只有到下一次forward到對應層的時候才會需要這個weight。
我和limu合作設計了ps風格的三個接口來解決這樣的同步問題,Push/PullReq和Pullwait。當獲backprop得梯度的時候直接調用push把梯度發送出去,并且調用pullreq請求結果。Push和Pullreq都是異步操作,背后會有單獨的線程同時完成數據拷貝同步,以及拷回的操作。而當我們需要weight之前在調用Pullwait來等待可能沒有完成的操作。這樣簡單的三個接口,使得我們可以經過很少的改動就可以設計出多卡和分布式的神經網絡來,并且在調用這些接口的時候完全不需要關系同步的實現是什么。
值得一提的是,這樣的編程模式把多GPU,分布式以及各個通信框架直接結合起來。mshadow-ps支持單機多卡的GPU PS,以及基于parameter-server的分布式PS實現。同樣的也可以很容易MPI來支持多機通信。使得一個統一的接口,可以完成從單機多卡到分布式各種后端實現的支持。并且因為高效的異步通信,使得我們可以在alexnet上面達到linearspeedup(注:并行的難度在于計算和通信的時間比,weight少更加復雜的網絡反而更加容易線性加速,而alexnet是非常困難的例子)。
經過團隊里面大家不斷地努力,cxxnet的V2終于可以和大家見面了。除了上述介紹的技術亮點之外,還有各種好玩的特性。現在把特點總結如下:
1. 輕量而齊全的框架: 我們盡力維持最小的依賴庫實現最多的功能。推薦環境下僅需要CUDA, OpenCV, MKL或BLAS即可編譯。
2. 強大的統一的并行計算接口:基于mshadow-ps的并行計算接口采用了一份代碼解決了多GPU,多機的異步同步。同步和計算重疊,在多份測試中均可以得到線性加速比。
3. 易于擴展的代碼結構:cxxnet計算核心由mshadow提供。Mshadow使用戶可以編寫numpy/matlab風格的代碼,但仍具備手動優化cuda 代碼的靈活性。CPU和GPU共享同一份代碼,在編譯期間通過模板自動翻譯成CUDA/MKL調用。
另外一些特性包括:
4. CuDNN支持:Nvidia原生卷積支持,可加速計算30%!
5. 及時更新的最新技術:我們將及時跟進學術界的動態,例如現在已經支持MSRA的ParametricRelu和Google的Batch Normalization
6. Caffe模型轉換:支持將訓練好的Caffe模型直接轉化為cxxnet模型(本周內上線?。?/p>
7. 方便的語言接口:在Python中直接進行訓練,方便可視化。Matlab也將很快提供
我們相信可以通過最簡潔清晰的代碼來完成高效的C++深度神經網絡實現。我們也歡迎對于系統和機器學習有興趣的同學加入到項目中來