標籤:

UC Berkeley提出新型分散式執行框架Ray:有望取代Spark

本文由 【AI前線】原創,原文鏈接:t.cn/RH6ePNb

譯者|馬卓奇 編輯|Natalie

AI 前線導讀:「下一代人工智慧應用程序需要不斷地與環境交互,並從這些交互中學習。這對系統的性能和靈活性提出了新的要求,而現有的機器學習計算框架大多無法滿足這些要求。為此,UC Berkeley AMP 實驗室開發了一個高性能分散式執行框架 Ray,並於近日在 Arxiv 上發表了相關論文:《Ray: A Distributed Framework for Emerging AI Applications》。」

當前 Ray 最新版本為 0.3,仍處於實驗室階段,感興趣的朋友可以看看該項目在 GitHub 上的代碼(github.com/ray-project/)。UC Berkeley AMP 實驗室顧問 Michael I. Jordan 表示,一年之內 Ray 將會準備好用於生產環境。據介紹,Ray 在開發之初就抱著要取代 Spark 的目的,也具有比 Spark 更優異的計算性能。

題外話:UC Berkeley AMP 實驗室曾開發出了一大批大獲成功的分散式技術,這些技術對高性能計算產生了深遠的影響,包括 Spark、Mesos、Tachyon 等。如今,原 AMP 實驗室的博士生,同時也是 Spark 和 Mesos 核心作者之一的 Matei 已經轉身去了斯坦福,並於最近推出了以普及機器學習實踐為目的的開源項目 DAWN(詳情見 AI 前線報道 )

下面讓我們來看看 UC Berkeley 的這個新項目 Ray 到底是怎麼回事。

目前的計算框架存在的短板

如今大部分人工智慧應用都是基於局限性較大的監督學習的範式而開發的,即模型在線下進行訓練,然後部署到伺服器上進行線上預測。隨著該領域的成熟,機器學習應用需要更多地在動態環境下運行,響應環境中的變化,並且採用一系列的動作來完成既定目標。這些要求自然地建立在增強學習(Reinforcement Learning,RL)範式中,即在不確定的環境中連續學習。

RL 應用與傳統的監督學習應用有三個不同之處:

  • RL 應用嚴重依賴模擬來探索所在狀態及操作結果。這需要大量的計算,現實情況下,一個應用大概需要進行億萬次模擬。
  • RL 應用的計算圖是異質的、動態變化的。一次模擬可能會花掉幾毫秒到幾分鐘的時間,模擬的結果又決定未來模擬的參數。
  • 許多 RL 應用程序,如機器人控制或自主駕駛,需要迅速採取行動,以響應不斷變化的環境。

因此,我們需要一個能支持異質和動態計算圖,同時以毫秒級延遲每秒處理數以百萬計任務的計算框架。而目前的計算框架或是無法達到普通 RL 應用的延遲要求(MapReduce、Apache Spark、CIEL),或是使用靜態計算圖(TensorFlow、Naiad、MPI、Canary)。

RL 應用對系統提出了靈活性、表現性能以及易開發的要求,Ray 系統則是為滿足這些要求而設計的。

代碼示例

經典 RL 訓練應用偽代碼

用 Ray 實現的 python 代碼樣例

在 Ray 中,通過 @ray.remote 聲明 remote 函數和 actor。當調用 remote 函數和 actor methods 時會立即返回一個 future(對象 id),使用 ray.get()可以同步獲取該 id 對應的對象,可以傳遞給後續的 remote 函數和 actor methods 來編碼任務依賴項。每個 actor 有一個環境對象 self.env,在任務之間共享狀態。

上圖是調用 train_policy.remote() 對應的任務圖。remote 函數和 actor methods 調用對應任務圖中的任務。圖中有 2 個 actor,每個 actor 之間的狀態邊(stateful edges)意味著他們共享可變狀態。從 train_policy 到它所調用的任務之間有控制邊(control edges)。要並行訓練策略(policy),可以多次調用 train_policy.remote()。

設計原理

為了支持 RL 應用所帶來的異質和動態工作負荷要求,Ray 採用與 CIEL 類似的動態任務圖計算模型。除了 CIEL 的任務並行簡化外,Ray 在執行模型頂層提供了代碼簡化,能夠支持諸如第三方模擬的狀態結構。

系統結構

為了在支持動態計算圖的同時滿足嚴格的性能要求,Ray 採取一種新的可橫向擴展的分散式結構。Ray 的結構由兩部分組成:application 層和 system 層。Application 層實現 API 和計算模型,執行分散式計算任務。System 層負責任務調度和數據管理,來滿足表現性能和容錯的要求。

Ray 系統結構

該結構基於兩個關鍵想法:

  • 全局狀態存儲 GSC(Global Control Store)。系統所有的控制狀態存儲在 GSC 中,這樣系統其他組件可以是無狀態的。不僅簡化了對容錯的支持(出現錯誤時,組件可以從 GSC 中讀取最近狀態並重新啟動),也使得其他組件可以橫向擴展(該組件的複製或碎片可以通過 GSC 狀態共享)。
  • 自底向上的分散式調度器。任務由 driver 和 worker 自底向上地提交給局部調度器(local scheduler)。局部調度器可以選擇局部調度任務,或將任務傳遞給全局調度器。通過允許本地決策,降低了任務延遲,並且通過減少全局調度器的負擔,增加了系統的吞吐量。

自底向上的分散式調度器

性能表現

可擴展性和表現性能

端到端可擴展性。 GCS 的主要優勢是增強系統的橫向可擴展性。我們可以觀察到幾乎線性的任務吞吐量增長。在 60 節點,Ray 可以達到超過每秒 100 萬個任務的吞吐量,併線性地在 100 個節點上超過每秒 180 萬個任務。最右邊的數據點顯示,Ray 可以在不到一分鐘的時間處理 1 億個任務(54s)。

全局調度器的主要職責是在整個系統中保持負載平衡。Driver 在第一個節點提交了 100K 任務,由全局調度器平衡分配給 21 個可用節點。

對象存儲性能。 對於大對象,單一客戶端吞吐量超過了 15GB/s(紅色),對於小對象,對象存儲 IOPS 達到 18K(青色),每次操作時間約 56 微秒。

容錯性

從對象失敗中恢復。隨著 worker 節點被終結,活躍的局部調度器會自動觸發丟失對象重建。在重建期間,driver 最初提交的任務被擱置,因為它們的依賴關係不能滿足。但是整體的任務吞吐量保持穩定,完全利用可用資源,直到丟失的依賴項被重建。

分散式任務的完全透明容錯。虛線表示集群中的節點數。曲線顯示新任務(青色)和重新執行任務(紅色)的吞吐量,到 210s 時,越來越多的節點加回到系統,Ray 可以完全恢復到初始的任務吞吐量。

從 actor 失敗中恢復。通過將每個 actor 的方法調用編碼到依賴關係圖中,我們可以重用同一對象重構機制。

t=200s 時,我們停止 10 個節點中的 2 個,導致集群中 2000 個 actor 中的 400 個需要在剩餘節點上恢復。(a)顯示的是沒有中間節點狀態被存儲的極端情況。調用丟失的 actor 的方法必須重新串列執行(t = 210-330s)。丟失的角色將自動分布在可用節點上,吞吐量在重建後完全恢復。(b)顯示的是同樣工作負載下,每 10 次方法調用每個 actor 自動進行了一次 checkpoint 存儲。節點失效後,大部分重建是通過執行 checkpoint 任務重建 actor 的狀態(t = 210-270s)。

GCS 複製消耗。為了使 GCS 容錯,我們複製每個資料庫碎片。當客戶端寫入 GCS 的一個碎片時,它將寫入複製到所有副本。通過減少 GCS 的碎片數量,我們人為地使 GCS 成為工作負載的瓶頸,雙向複製的開銷小於 10%。

RL 應用

我們用 Ray 實現了兩種 RL 演算法,與專為這兩種演算法設計的系統進行對比,Ray 可以趕上甚至超越特定的系統。除此之外,使用 Ray 在集群上分布這些演算法只需要在演算法實現中修改很少幾行代碼。

ES 演算法(Evolution Strategies)

Ray 和參考系統實現 ES 演算法在 Humanoid v1 任務上達到 6000 分所需時間對比。

在 Ray 上實現的 ES 演算法可以很好地擴展到 8192 核,而特製的系統在 1024 核後便無法運行。在 8192 核上,我們取得了中值為 3.7 分鐘的效果,比目前最好效果快兩倍。

PPO 演算法(Proximal Policy Optimization)

為了評估 Ray 在單一節點和更小 RL 工作負載的性能,我們在 Ray 上實現了 PPO 演算法,與 OpenMPI 實現的演算法進行對比。

  • MPI 和 Ray 實現 PPO 演算法在 Humanoid v1 任務上達到 6000 分所需時間對比。
  • 用 Ray 實現的 PPO 演算法超越了特殊的 MPI 實現,並且使用 GPU 更少。

控制模擬機器人

實驗表明,Ray 可以達到實時控制模擬機器人的軟實時要求。Ray 的驅動程序能運行模擬機器人,並在固定的時間間隔採取行動,從 1 毫秒到 30 毫秒,以模擬不同的實時要求。

未來工作

考慮到工作負載的普遍性,特殊的優化比較困難。例如,必須在沒有完全獲取計算圖的情況下採取調度決策。Ray 的調度決策或將需要更複雜的設置。除此之外,每個任務的存儲譜系需要執行垃圾回收策略,以在 GCS 中限制存儲成本,這個功能目前正在開發中。

當 GCS 的消耗成為瓶頸時,可以通過增加更多的碎片來擴展全局調度器。目前還需要手動設置 GCS 碎片和全局調度器的數量,未來作者將開發自適應演算法進行自動調整。考慮到 GCS 結構為該系統帶來的優勢,作者認為集中化控制狀態是未來分散式系統的關鍵設計要素。

專家點評

Murat Demirbas 是紐約州立大學布法羅分校(SUNY Buffalo)的計算機科學與工程教授,同時擔任 Petuum Inc. 顧問。Murat 教授在個人博客上對 Ray 的另一篇論文進行了簡單解讀(muratbuffalo.blogspot.com),他表示:

這個平台在「易用性」方面很薄弱。Ray 太渺小了,我甚至懷疑,我們是不是連與使用系統編程語言 Rust(支持並發原語和線程安全)同等級的技術支持都得不到。Rust 也使用 actor 模型,並且最近經過在 Rust 上重寫 Naiad 之後,已經非常適合構建數據流執行應用。

雖然 Ray 的目標是實時機器學習,但它沒有辦法減輕負載。為了提供減載支持,Ray 可能會採用 SEDA 架構,這樣當一次性提交太多任務時,系統就不會突然停轉。

未來Ray會如何發展,是否真的能夠實現它在開發之初的目標:取代Spark,AI前線將持續關注報道。

查看論文原文:

arxiv.org/pdf/1712.0588

相關論文:

arxiv.org/abs/1703.0392

項目鏈接:

github.com/ray-project/

項目文檔:

Ray - Ray 0.3.0 documentation

關注後回復「AI」你懂的

推薦閱讀:

深入淺出Spark(二) 什麼是RDD
如何看UCBerkeley RISELab即將問世的Ray,replacement of Spark?
Scaling Memcache in Facebook 筆記(三)
幾個有意思的開源庫/工具
SparkSQL的3種Join實現

TAG:分布式计算 |