橫向對比三大分佈式機器學習平臺:Spark、PMLS、TensorFlow 2017-08-04 11:47 程序設計/谷歌/對比 選自muratbuffalohtml
做者:Murat Demirbas算法
參與:Panda編程
分佈式機器學習是機器學習領域的一大主要研究方向。近日紐約州立大學布法羅分校計算機科學與工程教授、Petuum Inc. 顧問 Murat Demirbas 和他的兩位學生一塊兒發表了一篇對比現有分佈式機器學習平臺的論文,對 Spark、PMLS 和 TensorFlow 等平臺的架構和性能進行了比較和介紹。Murat Demirbas 教授在論文公佈後還發表了一篇解讀博客文章,機器之心對這篇文章進行了編譯介紹,論文原文可訪問:https://www.cse.buffalo.edu/~demirbas/publications/DistMLplat.pdf數組
這篇論文調查了分佈式機器學習平臺所用的設計方法,並提出了將來的研究方向。我與個人學生 Kuo Zhang 和 Salem Alqahtani 合做完成了這一工做。咱們在 2016 年秋季完成了這篇論文,而且這篇論文還將出如今 ICCCN'17(溫哥華)會議上。服務器
機器學習(尤爲是深度學習)最近已經在語音識別、圖像識別、天然語言處理和推薦/搜索引擎等方面取得了變革性的成功。這些技術在自動駕駛汽車、數字醫療系統、CRM、廣告、物聯網等方面的應用很是有前途。固然,資本帶領/推進着機器學習加速發展,咱們看到近段時間以來已經誕生了不少機器學習平臺。網絡
由於訓練過程涉及到巨大的數據集的模型,機器學習平臺每每是分佈式的,它們每每會使用並行的幾十個或幾百個工做器(worker)來訓練模型。據估計,在不久的未來,數據中心中運行的絕大多數任務都將會是機器學習任務。架構
我有分佈式系統的研究背景,因此咱們決定從分佈式系統的角度研究這些機器學習平臺並分析其通訊和控制侷限。咱們也調查了這些平臺的容錯能力和編程難度。併發
咱們將這些分佈式機器學習平臺歸類爲了三大基本設計方法:框架
基本數據流(basic dataflow)機器學習
參數服務器模型(parameter-server model)
先進數據流(advanced dataflow)
咱們對這三種方法進行了簡要介紹並舉例進行了說明,其中基本數據流方法使用了 Apache Spark、參數服務器模型使用了 PMLS(Petuum)、先進數據流模型使用了 TensorFlow 和 MXNet。咱們提供了幾個比較性能的評估結果。論文裏還有更多評估結果。不幸的是,做爲學術界的一個小團隊,咱們沒法進行大規模的評估。
在本文末尾,我給出了對分佈式機器學習平臺將來研究工做的總結和建議。若是你已經瞭解這些分佈式機器學習平臺,能夠直接跳至末尾查看結論。
Spark
在 Spark 中,計算被建模成有向無環圖(DAG:directed acyclic graph),其中每個頂點都表明一個彈性分佈式數據集(RDD:Resilient Distributed Dataset),每一條邊都表明對 RDD 的一個運算。RDD 是被分到了不一樣邏輯分區的對象的集合,這些邏輯分區是做爲 in-memory 存儲和處理的,帶有到磁盤的 shuffle/overflow。
在一個 DAG 中,從頂點 A 到頂點 B 的邊 E 表示:RDD B 是在 RDD A 上執行運算 E 後獲得的結果。運算有兩種:變換(transformation)和動做(action)。變換(好比:映射、過濾、鏈接)是指在一個 RDD 上執行一種運算生成一個新的 RDD。
Spark 用戶須要將計算建模爲 DAG,從而在 RDD 上進行變換或運行動做。DAG 須要被編譯爲 stage。每一個 stage 做爲一系列並行運行的任務執行(每一個分區執行一個任務)。簡單狹窄的依賴關係有利於高效執行,而寬廣的依賴關係會引入瓶頸,由於它們會擾亂流程,並且須要通訊密集的 shuffle 運算。
Spark 中的分佈式執行是經過將這種 DAG stage 分割到不一樣的機器上執行的。這張圖清晰地顯示了這種 master-worker 架構。驅動器(driver)包含了任務和兩個調度器(scheduler)組件——DAG 調度器和任務調度器;而且還要將任務對應到工做器。
Spark 是爲通常的數據處理設計的,並不特定於機器學習。可是使用 MLlib for Spark,也能夠在 Spark 上進行機器學習。在基本的設置中,Spark 將模型參數存儲在驅動器節點,工做器與驅動器通訊從而在每次迭代後更新這些參數。對於大規模部署而言,這些模型參數可能並不適合驅動器,而且會做爲一個 RDD 而進行維護更新。這會帶來大量額外開銷,由於每次迭代都須要創造一個新的 RDD 來保存更新後的模型參數。更新模型涉及到在整個機器/磁盤上重排數據,這就限制了 Spark 的擴展性。這是 Spark 的基本數據流模型(DAG)的不足之處。Spark 並不能很好地支持機器學習所需的迭代。
PMLS
PMLS 是專爲機器學習設計的,沒有其它雜亂的歷史。它引入了參數服務器(PS: parameter-server)的抽象概念,支持密集迭代的機器學習訓練過程。
其中 PS(圖中綠色方框)被用做分佈式的內存鍵值存儲(distributed in-memory key-value store)。它會被複制和共享:每一個節點都被用做這個模型(參數空間)一個分片的主節點以及其它分片的次要節點/副本。所以在節點數量方面,PS 能夠很好地擴展。
PS 節點會存儲和更新模型參數以及響應來自工做器的請求。工做器會請求來自它們的局部 PS 副本的最新模型參數,並在分配給它們的數據集部分上執行計算。
PMLS 還採用了 SSP(Stale Synchronous Parallelism)模型,這比 BSP(Bulk Synchronous Parellelism)模型更寬鬆——其中工做器在每次迭代結束時同步。SSP 爲工做器的同步減小了麻煩,確保最快的工做器不能超過最慢的工做器 s 次迭代。寬鬆的一致性模型仍然能夠用於機器學習訓練,由於這個過程有必定的噪聲容錯能力,我在 2016 年 4 月的這篇文章中談過這個問題:https://muratbuffalo.blogspot.com/2016/04/petuum-new-platform-for-distributed.html
TensorFlow
谷歌有一個基於參數服務器模型的分佈式機器學習平臺 DistBelief。參閱我對 DistBelief 論文的評論:https://muratbuffalo.blogspot.com/2017/01/google-distbelief-paper-large-scale.html。在我看來,DistBelief 的主要缺陷是:爲了編寫機器學習應用,須要操做低級代碼。谷歌想要本身的全部員工無需精通分佈式執行就能編寫機器學習代碼——基於一樣的理由,谷歌爲大數據處理編寫了 MapReduce 框架。
因此爲了實現這一目標,谷歌設計了 TensorFlow。TensorFlow 採用了數據流範式,可是是一種更高級的版本——其中計算圖無需是 DAG,並且包含循環且支持可變狀態。我認爲 Naiad 設計可能對 TensorFlow 設計有所影響。
TensorFlow 使用節點和邊的有向圖來表示計算。節點表示計算,狀態可變。而邊則表示多維數據數組(張量),在節點之間傳輸。TensorFlow 須要用戶靜態聲明這種符號計算圖,並對該圖使用複寫和分區(rewrite & partitioning)將其分配到機器上進行分佈式執行。(MXNet,尤爲是 DyNet 使用了圖的動態聲明,這改善了編程的難度和靈活性。)
TensorFlow 中的分佈式機器學習訓練使用瞭如圖所示的參數服務器方法。當你在 TensorFlow 中使用 PS 抽象時,你就用到了參數服務器和數據並行。TensorFlow 讓你還能作更復雜的事情,但那須要編寫自定義代碼並進入全新的疆域。
一些評估結果
咱們的評估使用了 Amazon EC2 m4.xlarge 實例。每一個實例包含 4 個由 Intel Xeon E5-2676 v3 驅動的 vCPU 和 16 GiB RAM。EBS 帶寬爲 750Mbps。咱們使用了兩個常見的機器學習任務進行評估:二分類 logistic 迴歸和使用多層神經網絡的圖像分類。我在這裏僅給出了幾張圖,查看咱們的論文能夠了解更多實驗。但咱們的實驗還有一些侷限性:咱們使用了少許機器,不能大規模測試。咱們也限制了 CPU 計算,沒有測試 GPU。
這幅圖展現了各平臺的 logistic 迴歸執行速度。Spark 表現不錯,但落後於 PMLS 和 MXNet。
這幅圖展現了各平臺的深度神經網絡(DNN)執行速度。相比於單層的 logistic 迴歸,Spark 在兩層神經網絡上有更大的性能損失。這是由於兩層網絡須要更多迭代計算。在 Spark 中咱們將參數保存在驅動器中,這樣它們能夠擬合;若是咱們將參數保存在一個 RDD 中而且在每次迭代後更新,狀況還會變得更加糟糕。
這幅圖給出了各平臺的 CPU 利用率。Spark 應用彷佛有明顯很高的 CPU 利用率,這主要是由於序列化(serialization)的額外開銷。咱們更早期的工做已經指出了這一問題:https://muratbuffalo.blogspot.com/2017/05/paper-summary-making-sense-of.html
總結與將來方向
機器學習/深度學習應用的並行處理讓人爲難,並且從併發算法(concurrent algorithms)的角度看並不很是有趣。能夠至關確定地說參數服務器方法在分佈式機器學習平臺的訓練上更好。
至於侷限性方面,網絡仍然是分佈式機器學習應用的一個瓶頸。提供更好的數據/模型分級比更先進的通用數據數據流平臺更有用;應該將數據/模型看做頭等公民。
可是,可能會有一些讓人驚奇和微妙的地方。在 Spark 中,CPU 開銷會先於網絡限制變成瓶頸。Spark 使用的編程語言 Scala/JVM 顯著影響了其性能表現。所以分佈式機器學習平臺尤爲須要更好的監控和/或性能預測工具。最近已經有人提出了一些解決 Spark 數據處理應用的問題的工具,好比 Ernest 和 CherryPick。
在機器學習運行時的分佈式系統支持上還有不少懸而未決的問題,好比資源調度和運行時的性能提高。對應用使用運行時監控/性能分析,下一代分佈式機器學習平臺應該會提供任務運行的計算、內存、網絡資源的詳細的運行時彈性配置/調度。
最後,在編程和軟件工程支持方面也有一些待解決的問題。什麼樣的(分佈式)編程抽象思想適用於機器學習應用?另外在分佈式機器學習應用的檢驗和驗證(尤爲是使用有問題的輸入來測試 DNN)上也還須要更多研究。
原文連接:http://muratbuffalo.blogspot.jp/2017/07/a-comparison-of-distributed-machine.html
本文爲機器之心編譯