不需要Python多處理的更快的並行Python

不需要Python多處理的更快的並行Python

Python的多處理庫已經成功地應用於廣泛的應用程序,在這篇博文中,我們發現它對於一些重要的應用程序來說是不夠的,包括數值數據處理、狀態計算和初始化開銷昂貴的計算。有兩個主要原因:

  • 數字數據處理效率低下。
  • 缺少有狀態計算的抽象(即無法在不同的“任務”之間共享變量)。
  • 關注,轉發,私信小編“01”即可免費領取Python學習資料~
不需要Python多處理的更快的並行Python


是一個快速、簡單的框架,用於構建和運行分佈式應用程序。解決這些問題。有關一些基本概念的介紹,請參見這篇博客文章..射線槓桿阿帕奇箭用於高效的數據處理,並提供任務演員分佈式計算的抽象。

這個博客發佈了三個不容易用Python多處理表達的工作負載,並進行了比較。、Python多處理和串行Python代碼。請注意與優化的單線程代碼相比總是很重要的。 .

在這些基準中, 10-30 x 比串行Python還快, 5-25x 比多處理快,而且 5-15x 比這兩個更快在一臺大機器上。

不需要Python多處理的更快的並行Python

不需要Python多處理的更快的並行Python

在一臺有48個物理核心的機器上,Ray是9X比Python多處理和28x比單線程Python快。錯誤條被描繪出來,但在某些情況下太小,看不見。複製這些數字的代碼如下所示。工作負載被縮放到核心的數量,所以在更多的核心上做更多的工作(這就是為什麼串行Python在更多的核上花費更長的時間)。

基準測試在EC2上運行,使用M5實例類型(1顆物理核的m5.大,48顆物理核的m5.24 x大)。運行所有基準測試的代碼在這裡可用。..這篇文章中包含了簡短的片段。主要區別在於,完整的基準測試包括:(1)定時和打印代碼;(2)對Ray對象存儲進行熱身的代碼;以及(3)將基準測試應用於較小機器的代碼。

基準1:數值數據

許多機器學習、科學計算和數據分析工作負載都大量使用大量的數據數組。例如,數組可能表示大型圖像或數據集,應用程序可能希望有多個任務對圖像進行分析。有效地處理數值數據至關重要。

每次通過下面的for循環0.84s和雷7.5秒使用Python多處理,以及24S使用串行Python(在48個物理核上)。這種性能差距解釋了為什麼可以構建如下所示的庫莫丁在Ray之上,但不在其他庫之上。

代碼如下所示 .

不需要Python多處理的更快的並行Python

使用Ray的玩具圖像處理示例的代碼。

打電話ray.put(image),大型數組存儲在共享內存中,所有工作進程都可以訪問該數組,而無需創建副本。這不僅適用於數組,也適用於包含數組的對象(如數組列表)。

當工作人員執行f任務時,結果再次存儲在共享內存中。然後當腳本調用ray.get([...]),它創建由共享內存支持的numpy數組,而不必反序列化或複製值。

這些優化是通過Ray的阿帕奇箭作為底層數據佈局和序列化格式以及等離子體共享內存對象存儲 .

代碼如下所示Python多處理 .

不需要Python多處理的更快的並行Python

使用多處理的玩具圖像處理示例的代碼。

這裡的不同之處在於,Python多處理在進程之間傳遞大型對象時使用泡菜來序列化它們。這種方法要求每個進程創建自己的數據副本,這增加了大量內存使用以及昂貴反序列化的開銷,Ray通過使用阿帕奇箭數據佈局零拷貝序列化連同等離子存儲 .

基準2:有狀態計算

需要在許多小工作單元之間共享大量“狀態”的工作負載是對Python多處理提出挑戰的另一類工作負載。這種模式非常常見,我用一個玩具流處理應用程序來說明它。

不需要Python多處理的更快的並行Python

不需要Python多處理的更快的並行Python

在一臺有48個物理核心的機器上,Ray是6x比Python多處理和17x比單線程Python快。在少於24個內核上,Python的多處理性能並不優於單線程Python。工作負載被縮放到核心的數量,所以在更多的核心上做更多的工作(這就是為什麼串行Python在更多的核上花費更長的時間)。

狀態通常封裝在Python類中,並且提供一個演員抽象這樣,類就可以在並行和分佈式設置中使用。相反,Python多處理並不提供一種並行Python類的自然方式,因此用戶通常需要在map打電話。這個策略在實踐中很難實現(許多Python變量並不容易序列化),而且當它工作時會很慢。

下面是一個玩具示例,它使用並行任務一次處理一個文檔,提取每個單詞的前綴,並在末尾返回最常見的前綴。前綴計數存儲在參與者狀態中,並由不同的任務進行變異。

本例以3.2 s和雷21S使用Python多處理,以及54S使用串行Python(在48個物理核上)。

這個版本如下。

不需要Python多處理的更快的並行Python

使用Ray處理玩具流示例的代碼。

Ray在這裡表現很好,因為Ray的抽象符合當前的問題。此應用程序需要一種在分佈式設置中封裝和變異狀態的方法,並且參與者符合要求。

這個多處理版本如下。

不需要Python多處理的更快的並行Python

使用多處理的玩具流處理示例的代碼。

這裡的挑戰是pool.map執行無狀態函數,這意味著在一個pool.map你想在另一個電話裡使用的電話pool.map需要從第一個呼叫返回呼叫,並將其傳遞到第二個呼叫。對於小型對象,這種方法是可以接受的,但是當需要共享大型中間結果時,傳遞它們的成本是非常高的(請注意,如果變量是在線程之間共享的,但是由於這些變量是跨進程邊界共享的,所以必須使用類似於這樣的庫將變量序列化為一個字節串。泡菜 ).

由於多處理版本必須經過如此多的狀態,所以看起來非常尷尬,最終只能在串行Python上實現一小部分加速比。實際上,您不會編寫這樣的代碼,因為您根本不會將Python多處理用於流處理。相反,您可能會使用專用的流處理框架。這個例子表明Ray非常適合構建這樣的框架或應用程序。

一個警告是,使用Python多處理的方法很多。在這個例子中,我們比較了Pool.map因為它提供了最接近的API比較。在本例中,通過啟動不同的進程並設置多個進程,應該可以獲得更好的性能。多處理隊列然而,在它們之間,這導致了一個複雜而脆弱的設計。

基準3:昂貴的初始化

與前面的示例不同,許多並行計算不一定需要在任務之間共享中間計算,但無論如何都會從中受益。即使是無狀態計算,在狀態初始化開銷很大時,也可以從共享狀態中獲益。

下面是一個例子,在這個例子中,我們希望從磁盤加載一個保存下來的神經網絡,並使用它來並行地對一組圖像進行分類。

不需要Python多處理的更快的並行Python

不需要Python多處理的更快的並行Python

在一臺有48個物理核心的機器上,Ray是25x比Python多處理和13x比單線程Python快。在本例中,Python多處理的性能並不優於單線程Python。錯誤條被描繪出來,但在某些情況下太小,看不見。工作負載被縮放到核心的數量,所以在更多的核心上做更多的工作。在這個基準測試中,“串行”Python代碼實際上通過TensorFlow使用多個線程。Python多處理代碼的可變性來自於從磁盤重複加載模型的可變性,而其他方法不需要這樣做。

本例以5S和雷126 S使用Python多處理,以及64 s使用串行Python(在48個物理核上)。在這種情況下,串行Python版本使用許多核心(通過TensorFlow)並行計算,因此它實際上不是單線程的。

假設我們最初通過運行以下命令創建了模型。

不需要Python多處理的更快的並行Python

將神經網絡模型保存到磁盤的代碼。

現在,我們希望加載模型並使用它對一組圖像進行分類。我們分批這樣做,因為在應用程序中,圖像可能並不都是同時可用的,圖像分類可能需要與數據加載並行進行。

這個版本如下。

不需要Python多處理的更快的並行Python

使用Ray的玩具分類示例代碼。

加載模型的速度足夠慢,我們只想做一次。Ray版本通過在參與者的構造函數中加載模型來分攤這一成本。如果模型需要放在GPU上,那麼初始化就會更加昂貴。

多處理版本速度較慢,因為它需要在每個映射調用中重新加載模型,因為映射函數被假定為無狀態函數。

這個多處理版本如下。注意,在某些情況下,可以使用initializer爭論multiprocessing.Pool..但是,這僅限於對每個進程初始化相同的設置,不允許不同的進程執行不同的設置功能(例如加載不同的神經網絡模型),也不允許針對不同的工作人員執行不同的任務。

不需要Python多處理的更快的並行Python

使用多處理的玩具分類示例的代碼。

我們在所有這些例子中看到的是,Ray的性能不僅來自於它的性能優化,還來自於具有適合於當前任務的抽象。狀態計算對於許多應用程序來說都是很重要的,強迫有狀態計算成為無狀態抽象是要付出代價的。

運行基準

在運行這些基準之前,您需要安裝以下內容。

pip install numpy psutil ray scipy tensorflow

然後以上所有數字都可以通過運行這些腳本來再現。

如果你在安裝上有困難psutil,然後嘗試使用Anaconda Python .

最初的基準測試是使用M5實例類型在EC2上運行的(一個物理內核的m5.Large和48個物理核的m5.24xLarge)。

為了在AWS或GCP上啟動具有正確配置的實例,可以使用射線自動分頻器然後運行以下命令。

ray up config.yaml

一個例子config.yaml是在此提供(用於啟動m5.4xLarge實例)。

更多關於雷的事

而這篇博客文章則集中在以下幾個方面:而Python多處理,一種蘋果對蘋果的比較是很有挑戰性的,因為這些庫不是很相似。不同之處包括以下幾點。

  • Ray是為可伸縮性而設計的,它可以在筆記本電腦和集群上運行相同的代碼(多處理只能在一臺機器上運行)。
  • 射線工作負載自動從機器和進程故障中恢復。
  • Ray是以一種語言不可知論的方式設計的,並且對爪哇 .

更相關的鏈接如下。

  • 這個基於GitHub的編碼 .
  • 這個射線文獻 .
  • 射線使用問題StackOverflow .
  • Ray包括用於強化學習 , 超參數調諧,和加速潘達斯 .
  • 射線包括自動分頻器用於在AWS和GCP上啟動集群。

相關推薦

推薦中...