雲上深度學習實踐分享——雲上MXNet實踐

HitTwice發表於2018-07-16

作者:擷峰  原文連結: https://yq.aliyun.com/articles/610218?spm=a2c4e.11155435.0.0.676074056SagTf


1 MXNet 簡介

1.1 MXNet特點

MXNet是一個全功能,靈活可程式設計和高擴充套件性的深度學習框架。所謂深度學習,顧名思義,就是使用深度神經網路進行的機器學習。神經網路本質上是一門語言,我們通過它可以描述實際的應用問題。比如,使用卷積神經網路(CNN)可以表達空間相關性的問題,使用迴圈神經網路(RNN)可以表達時間連續性方面的問題。MXNet支援深度學習模型中的最先進技術,當然也包括卷積神經網路(CNN),迴圈神經網路(RNN)中比較有代表性的長期短期記憶網路(LSTM)。根據問題的複雜性和資訊如何從輸入到輸出一步一步提取,我們通過將不同大小的不同層按照一定的原則連線起來,最終形成完整的深層的神經網路。

MXNet有三個特點,便攜(Portable),高效(Efficient),擴充套件性(Scalable)。

首先看第一個特點,便攜(Portable)指方便攜帶,輕便以及可移植。MXNet支援豐富的程式語言,如常用的C++,python,Matlab,Julia,JavaScript,Go等等。同時支援各種各樣不同的作業系統版本,MXNet可以實現跨平臺的移植,支援的平臺包括Linux,Windows,IOS和Android等等。

第二點,高效(Efficient)指的是MXNet對於資源利用的效率。而資源利用效率中很重要的一點是記憶體,因為在實際的運算當中,記憶體通常是一個非常重要的瓶頸,尤其對於GPU,嵌入式裝置而言,記憶體顯得更為寶貴。神經網路通常需要大量的臨時空間,例如每層的輸入,輸出變數,每個變數需要獨立的記憶體空間,這會帶來高額度的記憶體開銷。如何優化記憶體開銷,對於深度學習框架而言是非常重要的事情。MXNet在這方面做了特別的優化,有資料表明,在執行多達1000層的深層神經網路任務時,MXNet只需要消耗4GB的記憶體。我們使用Caffe與MXNet做過相同任務的比較之後也驗證了MXNet記憶體消耗小的這項特點。

第三點,擴充套件性(Scalable)在深度學習當中一個非常重要的效能指標。更高效的擴充套件可以讓訓練新模型的速度得到顯著提高,或者在相同的時間內,大幅度提高模型複雜性。擴充套件性指兩方面,首先是單機擴充套件性,另一個是多機擴充套件性。MXNet在單機擴充套件性和多機擴充套件性方面都有非常優秀的表現。所以擴充套件性(Scalable)是MXNet最大的一項優勢,也是最突出的特點。

1.2 MXNet程式設計模式

對於一個優秀的深度學習系統,或者一個優秀的科學計算系統,最重要的是如何設計程式設計介面,它們都採用一個特定領域的語言,並將其嵌入到主語言當中。比如numpy將矩陣運算嵌入到python當中。嵌入一般分為兩種,其中一種嵌入較淺,每種語言按照原來的意思去執行,叫指令式程式設計,比如numpy和Torch都屬於淺深入,指令式程式設計。另一種則是使用更深的嵌入方式,提供了一整套針對具體應用的迷你語言,通常稱為宣告式程式設計。使用者只需要宣告做什麼,具體執行交給系統去完成。這類程式設計模式包括Caffe,Theano和TensorFlow等。

這兩種方式各有利弊:

目前現有的系統大部分都採用上圖所示兩種程式設計模式的一種,兩種程式設計模式也各有優缺點。所以MXNet嘗試將兩種模式無縫的結合起來。在指令式程式設計上MXNet提供張量運算,而宣告式程式設計中MXNet支援符號表示式。使用者可以自由的混合它們來快速實現自己的想法。例如我們可以用宣告式程式設計來描述神經網路,並利用系統提供的自動求導來訓練模型。另一方面,模型的迭代訓練和更新模型法則中可能涉及大量的控制邏輯,因此我們可以用指令式程式設計來實現。同時我們用它來進行方便地調式和與主語言互動資料。

1.3 MXNet架構

下圖是MXNet架構圖,從上到下是分別為各種主從語言的嵌入,程式設計介面(矩陣運算NDArray,符號表示式Symbolic Expression,分散式通訊KVStore),還有兩種程式設計模式的統一系統實現,其中包括依賴引擎,還有用於資料通訊的通訊介面,以及CPU,GPU等各硬體的支援,還有對Android,IOS等多種作業系統跨平臺支援。在三種主要程式設計介面(矩陣運算NDArray,符號表示式Symbolic Expression,分散式通訊KVStore)中,重點介紹KVStore。

KVStore是MXNet提供的一個分散式的key-value儲存,用來進行資料交換。KVStore的本質上的實現是基於引數伺服器。

1)通過引擎來管理資料一致性,這使得引數伺服器的實現變得相當簡單,同時使得KVStore的運算可以無縫的與其他部分結合在一起。

2)使用一個兩層的通訊結構,原理如下圖所示。第一層的伺服器管理單機內部的多個裝置之間的通訊。第二層伺服器則管理機器之間通過網路的通訊。第一層的伺服器在與第二層通訊前可能合併裝置之間的資料來降低網路頻寬消費。同時考慮到機器內和外通訊頻寬和延時的不同性,可以對其使用不同的一致性模型。例如第一層用強的一致性模型,而第二層則使用弱的一致性模型來減少同步開銷。在第3節會介紹KVStore對於實際通訊效能的影響。

2 阿里雲上部署和執行MXNet

2.1 阿里雲提供的彈性GPU服務

深度學習的發展依賴於三個重要的要素。第一,演算法的大幅改進;第二個是大資料的提供;第三個是算力的大幅提升。其中GPU的效能大幅度提升是對算力的巨大貢獻。阿里雲提供的彈性GPU計算計算服務,提供了豐富的GPU例項、軟體(映象市場)和服務(如容器服務)來給客戶。

1)GPU例項支援M40、P4、P100、V100多種GPU,和豐富的CPU、記憶體配置,覆蓋深度學習訓練和推理場景。

2)映象市場提供了預裝NVIDIA GPU 驅動和CUDA 庫的映象,以及預裝開源深度學習框架(包括MXNet)的映象。同時還支援在購買頁選擇GPU驅動和CUDA庫在例項啟動時實現自動安裝: 參考建立GPU計算型例項

3)提供容器服務一鍵部署、執行深度學習任務,提供ROS資源編排服務建立需要的GPU例項資源等等。

阿里雲的容器服務可以提供分散式的運算模型,並且可以利用阿里雲豐富的儲存資源,如使用高效雲盤或者SSD雲盤,OSS物件儲存,可以使用NAS檔案儲存來儲存使用者訓練資料。

阿里雲可以基於容器,實現彈性GPU服務一鍵式部署,包括支援GPU資源排程,掛載共享儲存,負載均衡,彈性伸縮,CPU、GPU監控以及豐富的日誌管理。

基於容器的工作方式相對於很多傳統的方式有非常多巨大便利。我們需要搭建深度學習環境,對資料做準備,對模型進行開發,然後對開發的模型進行訓練和預測。而傳統的部署過程全部都需要手動完成,這是極其複雜的過程。利用容器的一鍵式部署可以極大縮短部署時間。

2.2 使用容器服務部署MXNet

下面是使用容器服務部署MXNet的過程。首先可以在阿里雲控制檯上找到容器服務解決方案,如下圖所示。在當中選擇機器學習,可以看到支援模型開發,模型訓練及模型預測。選擇建立資料卷,可以選擇OSS,NAS雲盤等多種不同的儲存裝置,之後將訓練資料放到儲存裝置上;可以選擇模型開發,並且建立一個GPU叢集,選擇需要的訓練框架,GPU資料,資料來源。資料來源可以是主機目錄,或者是之前建立的資料來源。之後便可以部署MXNet框架任務,部署過程是非常方便的。

在容器服務解決方案中選擇機器學習:

建立資料來源:

建立模型開發應用:

2.3 基於Docker使用NVIDIA GPU CLOUD部署

我們還可以使用開源Docker部署NGC(NVIDIA GPU CLOUD)容器映象。

NVIDIA GPU CLOUD實際上是一個開放的深度學習的容器映象的倉庫。我們可以通過安裝最新的Docker,以及安裝nvidia-docker的外掛:https://github.com/NVIDIA/nvidia-docker,之後註冊NGC,pull最新的MXNet容器映象。在MXNet容器映象當中,NVIDIA裝了最新的CUDA Driver,最新的深度學習加速庫cuDNN,以及多GPU加速庫NCCL等。所以我們可以使用已經優化好的整套軟體來部署到系統之上。

另外,阿里雲還是中國首家官方支援NGC服務的雲廠商,阿里雲通過雲市場的方式為客戶提供了NVIDIA官方的NGC容器映象服務、在GPU雲主機上全面支援Nivida GPU Cloud(NGC)生態系統。詳見: 在gn5例項上部署NGC環境

2.4 一個簡單MXNet單機訓練任務的執行例子

我們選擇一個單機影像分類模型的訓練作為示例

1)選擇CNN網路Inception-v3,選擇Imagenet資料集

2)Github下載最新的MXNet原始碼,並且在Example中找到影像分類

3)執行命令,執行train_imagenet.py(這是一個效能benchmark):python train_imagenet.py --benchmark1 --gpus 0 --network inception-v3 --batch-size 64 --image-shape 3,299,299 --num -epochs 1 --kv-store local

執行效果如下圖中所示,我們可以發現執行之後螢幕會實時列印出當前執行的效能及精度,效能單位:每秒處理的影像張數。

3 阿里雲上的MXNet效能實踐

3.1 阿里雲GPU伺服器MXNet效能資料

首先來看單GPU效能資料,選擇Inception-V3網路,用MXNet在ImageNet資料集上做影像分類模型訓練的Benchmark效能測試。從下圖中的測試資料來看,我們發現搭載V100的GN6例項因為使用TensorCore混合精度,效能接近搭載P100的GN5例項的3倍。可以看到由於NVIDIA每年在GPU硬體上的效能巨大的提升,使得在GPU上執行深度學習的速度大幅度提升。

之後看單機多GPU效能資料,使用GN5(P100)8卡例項,同樣測試了MXNet的影像分類模型訓練的單機擴充套件性。從下圖中發現AlexNet,GoogleNet,Inception-V3和ResNet152等四種經典的卷積神經網路測試當中,單機多卡接近線性加速。這證明了MXNet在單機的擴充套件性上的確非常優秀。

3.2 KVStore策略對效能的影響

在第1節有提到KVStore是MXNet資料通訊的模組。KVStore策略對最終效能有巨大影響。深度學習過程有兩部分組成,前向和後向。前向指的是通過正向運算取得結果,然後利用損失函式,計算結果與基準結果的偏差,再對偏差進行反向求導,計算偏差減小的最大梯度方向,在最大梯度方向減少偏差從而更新新的權值,再利用新的權值運算新的結果。不斷反覆迭代運算,最終結果會無限逼近最終想要達到的基準結果。那麼在迭代運算的過程當中,會涉及到兩個主要資料流向。平行計算當中,會有很多的裝置。以GPU為例,就是有很多GPU worker,每個workers計算完自己的梯度之後要彙集到一起合成完整梯度,所以會有梯度聚合的梯度流向。第二個資料流向,計算完梯度後,在梯度反向對網路權值進行更新,之後更新後的權值會更新到每個GPU worker上。

KVStore的不同引數主要是兩個不同資料流向的選擇,目前的KVStore可以支援local和device兩種引數,在1.0版本之後,新增了nccl引數。

1)local:所有的梯度都拷貝到CPU記憶體完成聚合,同時在CPU記憶體上完成權值的更新並拷貝回每個GPUworker。這種方式主要在於CPU與GPU,主要的效能負載在於CPU拷貝的負載。

2)device:梯度聚合和權值更新都在GPU上完成。GPU之間的如果支援Peer to Peer通訊(PCIe or NVLink),將避免CPU拷貝的負載,可以大大減輕CPU的負擔,僅受限於通訊頻寬。PCIe 與NVLink通訊頻寬不同,NVLink具備告訴的Peer to Peer通訊頻寬

3)nccl:1.0版本後新增,類似於device,利用NVIDIA的NCCL通訊庫,相比device,會有潛在的效能提升(尤其是針對NVLink有特別優化),但是NCCL本身會消耗GPU資源,所以往往GPU數量較多時效果明顯,目前MXNet對NCCL的支援還屬於實驗版本,在PCIe上的效果並不好。從下圖資料來看,對於Inception-V3網路來說,使用local引數效能最優,使用device較差,nccl最差。當然因為nccl對於NVLink有特別優化,後續阿里雲上會推出最新NVLink版本的V100的例項。可以期待在新的裝置之上,會有更優的表現。

3.3 分散式通訊效能

前面提到的都是單機通訊,主要取決於通訊基礎設施,比如PCle和NVLink頻寬。在多機通訊中效能主要瓶頸在於網路通訊。普通的我們使用的乙太網因為通訊延遲的原因,會大大影響多機擴充套件性。從下圖中可以看到,InfiniBand(IB)網路和RoCE網路因為支援RDMA,大大降低了通訊延遲,相比之下,20G的乙太網格延遲會大大提升。為了改善延遲,阿里雲超級計算機叢集使用InfiniBand或者RoCE網路,支援GPUDirect RDMA,可以大大降低延遲,增加多機擴充套件性。

當然,對於現有的普通乙太網路,也可以通過別的方法優化通訊頻寬的減少,比方說梯度壓縮。通過梯度壓縮,能夠在減少通訊頻寬消耗的同時,保證收斂速度和精度不會有明顯下降。MXNet官方提供了梯度壓縮演算法,按照官方資料,最佳的時候可以達到兩倍的訓練速度提升,同時收斂速度和精度的下降不會超過百分之一。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31473948/viewspace-2157887/,如需轉載,請註明出處,否則將追究法律責任。

相關文章