分佈式機器學習框架-百度的PADDLE(計劃開源)


基於Spark的異構分佈式深度學習平臺

導 讀:本文介紹百度基於Spark的異構分佈式深度學習系統,把Spark與深度學習平臺PADDLE結合起來解決PADDLE與業務邏輯間的數據通路問題,在此基礎上使用GPU與FPGA異構計算提高每臺機器的數據處理能力,使用YARN對異構資源作分配,支持Multi-Tenancy,讓資源的使用更有效。html

深層神經網絡技術最近幾年取得了巨大的突破,特別在語音和圖像識別應用上有質的飛躍,已經被驗證可以使用到許多業務上。如何大規模分佈式地執行深度學習程 序,使其更好地支持不一樣的業務線成爲當務之急。在過去兩年,百度深度學習實驗室在徐偉的帶領下開發了分佈式深度學習平臺PADDLE(Parallel Asynchronous Distributed Deep Learning),很好地知足了許多業務需求。但因爲PADDLE是獨立的深度學習平臺,不能很好地跟其餘業務邏輯結合,致使PADDLE與其餘業務邏 輯間的數據通路成爲了性能的瓶頸。爲了讓更多的業務使用上深度學習技術,咱們開發了Spark on PADDLE平臺,讓PADDLE變成百度Spark生態系統的一個功能模塊。在初版完成以後,咱們發現CPU計算能力已經知足不了百度巨大的數據量需 求,因而咱們在Spark on PADDLE的基礎上增長了對異構的支持,充分利用了GPU和FPGA等資源去加速PADDLE上的做業。前端

深度學習系統PADDLE的設計

PADDLE是一個成熟的分佈式深度學習平臺,普遍應用於百度的圖像識別、天然語言理解、語音、無人車等領域,其主要的特色是訓練算法高度優化,支持多GPU/CPU訓練,訓練效率高,對稀疏特徵有獨特的優化。算法

現有的深度學習平臺,通常都是經過單機方式進行訓練,如開源的Caffe平臺也是經過單機多卡的方式進行訓練。但當數據或者模型規模上去之後,要提升訓練效率,必然要進行分佈式訓練,主要有數據並行和模型並行兩種方法。編程

數 據並行是分佈式深度學習用得最多的並行方法。所謂數據並行,就是由於訓練數據規模很是大,須要把數據拆分,把模型分佈到N個機器訓練。可是由於最終訓練的 是一個模型,同時每一個機器只能分配到一部分數據,訓練的同步和收斂性必須獲得保證。最經典的作法是在《Parameter Server for Distributed Machine Learning》中提到的用參數服務器(Parameter Server)的方法。具體的想法是用模型參數服務的方法來同步參數的更新,每一個參數服務器只負責同步公共參數的一部分。舉個例子來講,若是模型M,被分 布到N個機器上面訓練,每一個機器拿到一部分數據圖片描述,假設訓練的參數集合是W,每一個機器首先進行本地訓練,假設他們初始化參數都是圖片描述,根據圖片描述,每臺機器都能算出相應的代價函數的梯度,通常按照單機神經網絡反向傳播的方式,每一個層均可以梯度來獲得參數的修正值,這樣參數就變成圖片描述由於是多機,每一個節點對參數的修正量不一樣,就會多了一個步驟把各自參數的修正量push給參數服務器,由它統一決策下個訓練循環的修正量,這樣你們的訓練模型就會被統一塊兒來。 
圖片描述
服務器

圖1 數據並行網絡

圖1展現了深度學習數據並行的部署架構。通常分爲如下步驟;架構

  • 訓練數據預處理,把數據切分爲data shards;機器學習

  • 每一個機器獲得一樣的模型定義,而且統一初始化參數;異步

  • 對於每一個訓練循環,每一個機器算各自的梯度,而且把梯度修正量push給參數服務器,參數服務器統一計算,而且把下一輪迭代的參數push給本地訓練機器;分佈式

  • 不斷循環,直到模型收斂。

參 數服務器的更新算法還分爲同步和異步的區別。由於嚴格同步的方法會讓本地訓練機在每個訓練迭代都會進行參數的同步更新,這樣在有慢節點的狀況下,整個訓 練都會被拖慢。異步參數更新的想法是讓參數同步的頻率變長,這樣可讓本地訓練機迭代好幾個回合之後再進行參數同步,這樣的作法有利有弊,好處是慢節點對 這個訓練的影響變小,壞處是每一個模型訓練可能會浪費訓練週期,由於同步之後的修正量可能跟本地訓練機作的修正量有很大的不一樣。這其中對於同步頻率的把握和 異步收斂性的問題都是研究的方向。

模型並行方法如圖2所示,針對參數規模達到單機沒法載入的量級或者模型間存在不多鏈接的區塊的場景,能夠考慮作模型並行,可是模型並行通訊開銷和同步消耗超過數據並行,效率可能沒有數據並行高。 
圖片描述

圖2 模型並行

PADDLE的設計主要採用了單機作到模型並行、多機作到數據並行的方式,從而達到億級模型規模以上,大規模數據量的分佈式訓練。

PADDLE與業務邏輯結合的痛點

PADDLE 是一個獨立的深度學習平臺,不能很好地支持把數據從其餘平臺接入的需求。研發人員一般要等上一階段的工做完成產生PADDLE的輸入數據後,把數據先存入 HDFS,再讀到PADDLE集羣的本地內存與硬盤,等數據準備好之後再用PADDLE去訓練模型。等模型訓練好後,再把模型存在HDFS裏,讓下一個業 務邏輯去讀取。這個過程不只耗時長,成爲整個計算流程的瓶頸,而且都是重複性的枯燥工做,影響了PADDLE平臺的推廣,讓不少有須要的團隊無法用上深度 學習技術。

爲 瞭解決這個問題,咱們設計了Spark on PADDLE架構,把Spark與PADDLE耦合起來,讓PADDLE成爲Spark的一個模塊。如圖3所示,模型訓練能夠與前端的功能整合,好比特徵 提取經過RDD的形式進行數據傳遞,無需經過HDFS進行數據導流。這樣一來,PADDLE與業務邏輯間的數據通路再也不是性能瓶頸。 
圖片描述

圖3 基於百度Spark的通用業務邏輯

Spark on PADDLE架構1.0版

Spark 是近幾年快速興起的大數據處理平臺,不只僅在於它的計算模型比傳統的Hadoop MapReduce要高效不少,同時在於它所帶來的生態系統很是強大。基於Spark計算引擎構建的上層應用如Spark SQL、Spark Streaming、Spark MLlib等,都是很優秀的應用,比傳統應用性能好幾倍,而且更加穩定。同時與Yarn/Mesos的結合讓Spark對計算資源的管理和分配更加靈活。

Spark 在百度內部已經普遍應用,主要用於數據處理和數據分析。可是傳統的數據處理平臺一定會有根據數據訓練模型的機制,廣告系統的CTR預測就是一個例子,對於 用戶產生大量的點擊和瀏覽日誌,Spark能夠進行處理和清洗。可是對於大規模模型的訓練,Spark MLlib的支持仍是有限,特別是對於深度學習的支持,因此須要解決在Spark上支持PADDLE的問題。

對 於用戶的應用程序,Spark叫驅動節點(Driver),能夠視爲Spark用戶分佈式程序調度和程序流控制的主節點。Spark程序的具體運算都分佈 在Worker Node上面的Executor跑。Spark還有一個很是重要的概念叫RDD,這是一個分佈式的分區(partitioned)數據抽象集。Spark 全部輸入和輸出數據都是以RDD爲導向的,它不只描述了數據集的依賴關係,同時還對數據進行了邏輯上的切分,對一個RDD操做通常都是partition 來並行的。

圖片描述

圖4 Spark DNN訓練運行構架

Spark DNN訓練運行構架如圖4所示,訓練通常分爲如下5個步驟:

  • DNN 數據預處理和訓練特徵準備

通常這是Spark的強項,無論是流式數據仍是已經落盤的數據都經過Spark來進行數據處理,其中包括數據清洗、特徵準備,而後把獲得的訓練數據用RDD輸出。

  • 資源申請

Spark訓練任務提交的時候先從Yarn那裏拿到對於DNN訓練任務的節點資源,好比說一個訓練任務須要4個有4 GPU機器的節點。Yarn會對資源作Container式的管理,無論CPU仍是GPU對於Yarn來講都是一個虛擬的資源。後文會作具體介紹。

  • 訓練初始化

Driver會根據Yarn分配的資源相應分發模型配置。模型訓練資源庫,而且啓動訓練機和參數服務器,同時初始化模型的初始參數。

  • 模型訓練

訓練的數據會以RDD的方式輸入到訓練機接口,以數據並行的方式進行訓練,而且啓動的訓練機會跟參數服務器通訊,完成梯度交換和參數同步,當訓練最大迭代達到或者模型收斂,則訓練終止。

  • 模型預測

模型能夠傳入某一個服務器集羣或者以Spark Streaming的方式進行載入而且預測。

在Spark on PADDLE 1.0開發的過程當中,咱們驗證了Spark確實能夠把ETL、訓練數據預處理和深度學習訓練結合起來,同時發現百度內部有不少深度學習需求,須要在1.0 的基礎上考慮把Spark on PADDLE平臺化,作到Multi-Tenancy的資源管理、訓練監控、訓練容錯等等。

Spark on PADDLE 架構2.0版

平臺化是Spark on PADDLE 2.0的主要目標。它引入了更多的功能,主要包括在訓練過程當中引入了監控機制、容錯機制,加入了ML決策模塊作超參數選擇等。下面是對Spark on PADDLE 2.0設計的分析。

如 圖五、圖6所示,客戶能夠直接與Spark DNN Driver通訊啓動DNN訓練,Spark DNN Driver啓動一個訓練實例(Training Instance),而且透傳訓練數據、訓練網絡配置等信息。一個訓練實例包括了訓練所需的總體服務,包括一組訓練器以及對應的參數服務器。而後有一個訓 練Master(Training Master)來管理整個的訓練進程。同時訓練Master管理訓練器和超參數服務器的生存週期和失敗重啓。參數服務器和訓練器會按期給訓練Master 發送heartbeat,確保其正常運行。

圖片描述

圖5 Spark on PADDLE 2.0 整體架構

圖片描述

圖6 Spark on PADDLE 2.0 Training Instance架構

訓練過程當中的監控機制

當 訓練開始之後,用戶會對訓練過程當中的一些數據進行監控,包括訓練的每一個迭代的loss值、錯誤率、所用的時間以及訓練機和參數服務器的日誌進行監控,咱們 在實現的過程當中會在Worker端用消息傳遞的方式(AKKA)向Driver端彙報訓練的數據。對於整個Spark Job的性能數據會依賴Spark自己提供的監控功能,全部信息都反饋在監控頁面中(Web UI)。

訓練過程當中的容錯機制

因 爲DNN在訓練過程當中,訓練機和參數服務器都是有可能失敗的地方。最簡單的容錯方式是按期對模型的參數和訓練信息作備份,當模型訓練失敗之後,從備份點開 始重啓模型訓練就能夠。訓練Master會把這些信息收集起來,而且彙報給Spark DNN Driver。對於參數服務器的容錯,能夠採起增長冗餘的方法,若是一個參數服務器掛掉,訓練Master會負責重啓相應服務,可是會有一個備份的參數服 務器去負責掛掉的參數服務器的參數更新。

超參數選擇

圖片描述

圖7 超參數選擇訓練

超 參數是確立模型訓練的基礎,Spark在MLlib中引入了超參數選擇模塊,主要的作法就是經過必定的超參數選擇算法對模型進行並行訓練,最終選擇的超參 數將會被用作最終的模型訓練。超參數的選擇對於深度學習頗有意義,包括網絡拓撲、參數的衰減率、觸發函數的選擇都是影響深度學習的超參數。圖7顯示了一個 大概的超參數選擇流程,模型的特徵選擇到歸化係數(Regulation Parameter)一塊兒配對來訓練一個模型,最終評估模塊選擇最終超參數。在Spark的場景中,DNN Driver端會跟評估端經過RPC通訊來決策須要嘗試什麼超參數。評估端邏輯是在Spark DNN Driver依賴的MLApplication服務。若是用戶須要對DNN訓練模型進行超參數選擇,則Spark DNN Driver會根據不一樣參數配對啓動多個訓練實例,而後根據訓練來是否須要進一步搜索。

Spark異構分佈式計算平臺架構

如 上所述,咱們已經看到Spark on PADDLE可以使得傳統的深度學習能夠在更大規模的分佈式系統上運行。可是,百度面臨很是現實的問題就是巨量的數據。在百度內部,天天處理的數據量都遠 遠超出了傳統平臺的能力,會使用到巨量的模型參數、特徵以及訓練數據。這些巨量數據對分佈式系統的性能和擴展性都提出了更高的要求。一方面,咱們但願提供 能夠比擬傳統MapReduce集羣規模的深度學習計算集羣,能夠並行運行大量的深度學習任務;另外一方面,每一個深度學習模型不可能無限制地切分紅更小的單 元,所以每一個節點的模型處理能力也是相當重要的。

目 前以CPU爲主的計算節點受到自己計算能力的限制,遠遠不能知足計算的需求,所以,咱們須要經過更強大的異構計算來加速如今的計算平臺。目前咱們的項目主 要涉及到兩種計算資源:GPU和FPGA。GPU能夠提供強大的計算能力,適用於高密度的計算類型;FPGA有低功耗、高度可定製的特色,適合加速不少特 定的動態任務(本項目使用的FPGA硬件加速由百度美國研發中心的計算團隊提供)。

我 們的項目正是基於Spark on PADDLE,探索瞭如何有效地把異構資源整合到如今的大規模分佈式系統,以提供高應用性能和易用性爲目標。在知足前述要求的基礎上,系統須要動態地對 GPU/FPGA資源進行管理,進行無縫的調度,正如CPU和Memory等資源的調度同樣。這一功能是經過把資源調度整合到開源的Yarn系統來實現 的,而資源隔離方案基於業界流行的Container技術。

同 時,咱們還須要提供簡單易用的編程接口,以便現有的應用程序能夠更快地遷移到咱們的系統上來。由於Spark全部的數據都是基於RDD的,咱們建立了一類 新的RDD,經過這個RDD,程序能夠直接使用到底層的GPU/FPGA來加速相應的計算。咱們知道,真正在GPU/FPGA上完成程序的功能,還須要提 供Kernels,這裏咱們採用了業界最爲流行的標準OpenCL接口,以便於將程序移植到不一樣的GPU/FPGA。能夠看到,一個特定的功能實現須要3 個部分:一個Scala Driver,一個C++的Worker以及一個OpenCL Kernel(on GPU/FPGA)。若是經常使用的功能已經集成在MLlib中,那麼用戶只須要建立本身的Scala Driver,經過新的RDD調用庫裏面已經支持的函數,就能夠無縫享受到GPU/FPGA資源的加速。

圖片描述

圖8 Spark異構計算平臺架構

異構系統架構如圖8所示。系統的運行過程以下:

  • 首先用戶應用程序(Scala Driver)會由App Master啓動;

  • 而後用戶應用程序會向Yarn請求其所需的資源,其中GPU、FPGA做爲不一樣的資源類別,與請求CPU資源方式徹底一致;

  • 用戶應用程序取得全部資源,由App Master在相應的App Slave上啓動Container運行用戶程序的一個Scala Worker;

  • 這時,按照程序Scala Worker的需求,若是使用到了新的RDD,便會調用相應的C++的OpenCL程序,若是函數功能是MLlib內嵌的,那麼這部分對用戶也是徹底透明的。

  • OpenCL程序啓動後,會把所分配的數據傳輸到GPU或FPGA上,而後在GPU或者FPGA上動態啓動特定的OpenCL Kernel,處理這些已經傳輸過來的數據。

  • OpenCL Kernel計算完成後,數據會自動被拉回到主存,這時OpenCL的程序就能夠把結果返回給Scala Worker;

  • 最後全部Scala Worker把結果提交給在App Master上運行的用戶程序Scala Driver。

能夠看到,整個流程支持加入了新的GPU/FPGA計算資源,還有須要用戶使用新的RDD。其餘方面對用戶程序來講沒有任何額外的改動。

Spark異構平臺性能評估

在 異構平臺架構搭建好後,咱們首先測試了機器學習底層矩陣運算庫的CPU與GPU性能對比。結果顯示,在執行同一個計算方程時,GPU的加速效果很好,對 CPU的加速比大約是30倍。與此同時,百度美國研發中心計算團隊也對Kmeans算法用FPGA進行加速,取得了15到20倍的加速化,並且FPGA能 耗只是CPU的20%。在第二個實驗中,咱們對比了Spark on PADDLE在訓練ImageNet時的GPU與 CPU加速比,發現使用GPU能夠加速30倍,也就是說,在使用異構平臺後咱們只用3%的機器資源就能夠完成一樣的計算。

在很好地瞭解了異構平臺加速比後,咱們也研究了異構平臺的可擴展性。測試結果如圖9所示,基本上隨着GPU資源的增長,計算時間也在線性地下降,表現出很強的可擴展性,能夠承受很大的數據量與計算量。 
圖片描述

圖9 Spark異構計算平臺性能數據

總結

本 文介紹了百度基於Spark的異構分佈式深度學習系統。把Spark與深度學習平臺PADDLE結合起來解決了PADDLE與業務邏輯間的數據通路問題, 使業務方能夠很容易地使用深度學習技術。在此基礎上,咱們使用GPU與FPGA的異構平臺極大地提高了每臺機器的數據處理能力。在異構平臺上,咱們使用 YARN對異構資源作分配,以支持Multi-Tenancy,讓資源的使用更有效。下一步工做咱們打算把平臺推廣到百度不一樣的業務平臺,好比語音、百度 祕書、百度圖搜、百度無人車等,讓平臺在不一樣業務上錘鍊。在平臺更成熟後,咱們打算把Spark on PADDLE以及異構計算平臺開源,回饋社區。


張偉德:百度美國硅谷研發中心高級架構師,負責大數據、深度學習架構和開發。曾在Yahoo、微軟等公司負責大型分佈式搜索構架設計。

曲寧:百度美國研發中心高級架構師,負責基礎架構以及異構計算平臺架構與開發。CMU大學Cylab研究院研究員。曾在Nvidia以及Google工做。

劉少山:百度美國研發中心高級架構師,從事深度學習以及異構計算平臺架構與開發。曾在LinkedIn、微軟、微軟研究院、INRIA、Intel以及Broadcom工做。

相關文章
相關標籤/搜索