1. 程式人生 > >分散式機器學習的叢集方案介紹之HPC實現

分散式機器學習的叢集方案介紹之HPC實現

機器學習的基本概念

機器學習方法是計算機利用已有的資料(經驗),得出了某種模型(遲到的規律),並利用此模型預測未來(是否遲到)的一種方法。目前機器學習廣泛應用於廣告投放、趨勢預測、影象識別、語音識別、自動駕駛和產品推薦等眾多領域。


在確定了問題模型之後,根據已知資料尋找模型引數的過程就是訓練,訓練過程就是不斷依據訓練資料來調整引數的迭代,從而使依據模型作出的預測結果更加準確。


HPC的基本概念

HPC就是高效能運算或高效能運算叢集的簡寫。為了追求高效能,HPC的工作負載一般直接執行在Linux系統上,有些甚至直接在裸機上執行。HPC應用一般將問題分解為可在叢集節點上執行的較小的、並行的分散式問題。HPC應用通常大量使用程序間通訊,通訊通過共享儲存或網路實現。HPC系統中同時執行著大量的應用,這些應用可通過叢集排程系統進行管理。

以前HPC的主要應用是科學計算,近年來隨著深度學習技術的發展,HPC上執行的深度學習應用也在增加。HPC的典型應用包括

  • 高能物理模擬
  • 天氣建模預測
  • 流體、結構、材料分析
  • 電磁與熱力學模擬
  • 沉積與儲層模擬
  • 3D渲染與視覺化
  • 深度學習的訓練與預測


完整部署一套HPC系統是相當複雜的過程,要綜合考慮到安全、能源、散熱、網路等諸多方面問題。


為什麼需要分散式機器學習

大資料時代的機器學習有如下趨勢:

Big Model 隨著深度學習的進展,許多問題需要一個大的模型,這個模型必須有能力去儘量接近你所要解決問題的具體功能。例如,將圖片內容用文字描述出來這個功能是非常複雜的,要表達這個功能需要非常多的引數,這個問題的模型必須要足夠大才能實現這樣複雜的功能。

Big Data 在訓練的資料集較小時,深度學習的效果並不理想,這也是前些年深度學習沒有引起大家重視的一個原因。在小資料集上訓練的深度學習模型效果還不如一些相對簡單的機器學習方法,不過當資料集增大之後,深度學習的效果開始超過其它機器學習方法。在語音識別上的研究表明,如果訓練資料集的規模增加10倍,語音識別的誤差率會相對降低約40%。HPC有能力使用更大的資料集來訓練模型,因而也成為人工智慧發展的一個重要部分。

從下圖可以看出當前機器學習系統的規模已經很大。


Big Compute 當前超級計算機已經由規模更大的叢集及並行度更高架構組成,如雲計算技術,GPU叢集和FPGA Farm。這些超級計算機的處理能力相當強大,目前超級計算機Top500中排名第一的是神威-太湖之光系統,屬於國家超級計算無錫中心,天雲軟體已經與其成功合作,將使用OpenLava進行任務排程管理。


分散式機器學習是隨著大資料概念興起的。在有大資料之前,有很多研究工作為了讓機器學習演算法更快,而利用多個處理器。這類工作通常稱為平行計算或者並行機器學習,其核心目標是把計算任務拆解成多個小任務,分配到多個處理器上做計算。


分散式計算或者分散式機器學習除了要把計算任務分佈到多個處理器上,更重要的是把計算資料(包括訓練資料以及中間結果)分佈開來。因為在大資料時代,一臺機器的硬碟往往裝不下全部資料,或者即使裝下了,也會受限於機器的I/O通道頻寬,以至於訪問速度很慢。為了更大的儲存容量、吞吐量以及容錯能力,我們都希望把資料分佈在多臺計算機上。

深度學習作為機器學習演算法研究中的一個新的技術,其動機在於建立、模擬人腦進行分析學習的神經網路。深度學習可以簡單理解為傳統神經網路的拓展。


深度學習概念源於人工神經網路的研究。含多隱層的多層感知器就是一種深度學習結構。深度學習通過組合低層特徵形成更加抽象的高層表示屬性類別或特徵,以發現數據的分散式特徵表示。典型的神經網路有深度神經網路(DNN),卷積神經網路(CNN),和迴圈神經網路(RNN)等。


分散式機器學習相關研究進展

近年來,與分散式機器學習相關的研究大量湧現,特別是深度學習方向取得顯著進展。

Dropout:一種防止神經網路過擬合的簡單方法,其關鍵思想是在神經網路的訓練過程中隨機丟棄單元(連同它們的連線點)。這能防止單元適應過度,顯著減少過擬合,並相對於其它正則化方法有重大改進。

批標準化:通過減少內部協移加速深度神經網路訓練,訓練深度神經網路的過程很複雜,原因在於每層的輸入分佈隨著訓練過程中引起的前面層的引數變化而變化。這種現象稱為內部協變數轉移,可利用歸一化層輸入來解決此問題。通過將此方法應用到最先進的影象分類模型,批標準化在訓練次數減少了 14 倍的條件下達到了與原始模型相同的精度,這表明批標準化具有明顯的優勢。

其它研究進展包括影象識別的深度殘差學習、大規模視訊分類、生成對抗網路、自然語言處理等等,覆蓋了深度學習的方方面面。

分散式機器學習的實現

分散式機器學習的實現方式有資料並行,即將資料分佈多個部分,分別進行處理,增量更新是提高處理速度的關鍵;模型並行,即將機器學習所用到的模型引數分散到多個共享的引數伺服器上。資料並行與模型並行兩種實現方式並沒有本質區別,此外還可以按照資料的處理過程進行劃分為多個任務來處理。


在進行分散式機器學習時,要考慮對引數進行更新是採用同步方式還是非同步方式,或是無鎖(lock-free,如Hogwild)方式,還要考慮不同程序間的通訊方式。


分散式機器學習在HPC叢集上的實現

如果應用需要長時間進行機器學習,可以根據企業自身的具體需求及技術積累,選用某種符合自身需要的分散式機器學習架構,從零開始構建分散式機器學習叢集,這需要較大的資源投入。如果只是一次性地對模型進行訓練,或每次訓練的計算量並不大,訓練次數也不多,之後只要用訓練好的模型計算,或者是原本已經擁有了HPC叢集,那麼可以考慮在HPC叢集上構建自己的分散式機器學習任務。


在HPC叢集上實現分散式機器學習,設計深度學習程式通常要用到MPI。MPI是高效能運算應用中廣泛使用的程式設計介面,用於並行化大規模問題的執行,在大多數情況下,需要通過叢集作業排程管理軟體來啟動和監視在叢集主機上執行的MPI任務。

MPI是一種基於資訊傳遞的並行程式設計技術。訊息傳遞介面是一種程式設計介面標準,而不是一種具體的程式語言。簡而言之,MPI標準定義了一組具有可移植性的程式設計介面。一個使用了MPI的hello world程式如下

#include <mpi.h>

#include <stdio.h>

int main(int argc, char** argv) {

    // Initialize the MPI environment

    MPI_Init(NULL, NULL);

    // Get the number of processes

    int world_size;

    MPI_Comm_size(MPI_COMM_WORLD, &world_size);

    // Get the rank of the process

    int world_rank;

    MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);

    // Get the name of the processor

    char processor_name[MPI_MAX_PROCESSOR_NAME];

    int name_len;

    MPI_Get_processor_name(processor_name, &name_len);

    // Print off a hello world message

    printf(“Hello world from processor %s, rank %d”

           ” out of %d processors\n”,

           processor_name, world_rank, world_size);

    // Finalize the MPI environment.

    MPI_Finalize();

}

MPI中有兩種訊息傳遞模式,一種是點到點通訊模式,直接在兩個程序之間傳遞訊息,主要是通過傳送MPI_Send和接收MPI_Recv函式實現。


另一種訊息傳遞模式是組通訊模式,此時一個特定組內所有程序都參加全域性的資料處理和通訊操作 。主要的通訊型別有

1)資料移動:廣播Mpi_Bcast,收集Mpi_Gather,散射Mpi_Scater,組收集Mpi_All gather等。

2)聚集:Mpi_Reduce將組內所有的程序輸入緩衝區中的資料按指定操作(OP)進行運算,並將運算結果返回到root程序;Mpi_Reduce中支援的操作有返回最大元素(MPI_MAX),返回最小元素(MPI_MIN),對所有元素求和(MPI_SUM)等多種,詳細情況可查詢MPI文件。


Mpi_AllReduce與Mpi_Reduce的不同在於,在操作結束時,操作結果將返回給參與到操作的所有程序,這種特性非常適合於分散式機器學習,可以方便地達到對引數伺服器進行更新的目的。


3)同步:路障Mpi_Barrier實現通訊域內所有程序互相同步,它們將處於等待狀態,直到所有程序執行它們各自的Mpi_Barrier呼叫。

大多數主流的並行程式語言都支援對MPI介面的呼叫,包括C/C++,Java,Python,R,Go等。MPI的具體實現也有多種,有MPICH,OpenMPI,MVAPICH, IBM Platform MPI等。

隨著GPU在高效能運算中的普及,MPI也開始支援使用GPU來加速平行計算,MPI與CUDA程式設計模型完全相容。使用MPI+CUDA可以做到

  • 解決單個GPU的記憶體不能將問題的資料全部裝下的問題;
  • 解決只用單個節點計算,可能需要非常長的計算時間的問題;
  • 應用GPU加速現有的MPI程式;
  • 可以將現有的單節點-多GPU應用擴充套件到多個節點上執行。

常規MPI實現在GPU間傳遞訊息時需要先使用cudaMemcopy將GPU中的內容複製到主機記憶體中。在使用CUDA-aware MPI時,可以直接使用MPI來發送和接收GPU中的內容(如點對點通訊部分的配圖所示)。


在應用MPI支援GPU應用時,為取得最佳效果,要注意以下兩點:

  • 使用非阻塞的MPI;
  • 將計算時間與通訊時間儘量重疊。

在HPC系統上實現分散式機器學習系統,與專門設計的分散式機器學習框架的不同之處在於,HPC系統中的資源不是由單個機器學習應用所獨佔,而是由排程系統根據不同應用的請求,按照一定的排程策略完成排程。在實現過程中,使用者不需要擔心GPU資源的申請(前提是HPC系統中有GPU),天雲軟體SkyForm OpenLava支援對GPU的管理排程,下圖給出了OpenLava的部分特性,詳細瞭解可訪問官網(http://openlava.net/)。


一種在HPC系統上實現分散式機器學習的方案是針對現有的開源專案進行改造,這些專案的開發語言大多都支援MPI,使其可以在HPC系統中執行。開發過程中需要注意針對特定HPC系統環境,可能對系統及程式語言的具體版本有要求。實現時可將學習過程分解成多個小的子任務,子任務間可以通過MPI通訊。在資源允許時,應用就可以被排程器排程到多個節點上執行,通過MPI來實現模型引數的更新。

使用者還可以利用Docker容器來開發分散式機器學習應用,這樣開發與部署比較容易,對執行環境的依賴較少,只要HPC上能執行Docker就可以,但是執行時的效能會受到一定影響。具體採用哪種方法可根據應用的效能需求及自身技術儲備綜合考慮。

隨著深度學習技術的發展,機器學習應用將要面臨更多的資料、更大的模型和更強的計算需求。HPC將會與深度學習緊密結合,相互推動前進。


結束語

經過連續四次專題的分享,我們介紹了機器學習的基本概念,GPU的加速原理、深度學習的進展,分散式機器學習叢集的構建和排程。如果要進一步瞭解深度學習還需要再深入學習相關知識。