PARL1.1一個修飾符實現並行強化學習演算法

PaddlePaddle發表於2019-04-28

WAVE SUMMIT 2019深度學習開發者峰會,基於PaddlePaddle打造的深度強化學習框架PARL釋出了聚焦於並行的1.1版本。本篇文章為大家帶來PARL在並行演算法優化方面的最新進展。

強化學習是近年來機器學習領域的研究熱點,在遊戲操作、圍棋對弈、多智慧體控制等場景取得了不少令人矚目的進展。在逐步挑戰這些難題的同時,訓練強化學習模型的計算力要求也在大幅度提升。雖然顯示卡裝置經歷了K40/P40/V100等提升,CPU主頻也在不斷提升,但是大規模的並行化仍然是提供巨大算力的主要手段。在並行化這個問題上,python由於其全域性鎖的存在使得自身的多執行緒在計算密集型任務上顯得雞肋。多程式雖然可以繞開全域性鎖問題,但是程式間通訊會提升開發複雜度,並且效能提升空間受限於機器的CPU數量。

專案地址:https://github.com/PaddlePaddle/PARL

PARL1.1 

PARL是一款基於百度PaddlePaddle打造的深度強化學習框架,繼1.0版本開源了NeurIPS 2018假肢挑戰賽冠軍訓練程式碼以及主流強化學習模型後,我們釋出了聚焦於並行的1.1版本。PARL1.1新增支援高質量的並行演算法,包括IMPALA、GA3C、A2C,並提供了高效能的並行開發介面。以通過PARL實現的IMPALA演算法的評估結果為例,在雅達利這個經典評測環境中 ,pong 遊戲最快可在7分鐘內達到20分,breakout遊戲在25分鐘達到400分(1個P40GPU +32CPU)。


PARL1.1一個修飾符實現並行強化學習演算法並行修飾符

PARL1.1通過一個簡單的修飾符(@parl.remote_class)即可實現並行化。資料預處理以及simulator模擬等計算密集型的任務經過這個修飾符之後,會自動部署到使用者指定的計算資源上執行,不再佔用主執行緒的計算資源。下面我們先通過一個簡單的Hello World程式來了解這種設計的簡單易用之處。

      #============Agent.py=================         @parl.remote_class         class Agent(object):             def say_hello(self):                 print("Hello World!")             def sum(self, a, b):                 return a+b                  #============Server.py=================       remote_manager = parl.RemoteManager()      agent = remote_manager.get_remote()      agent.say_hello()      ans = agent.sum(1,5) #在遠端執行,不佔用當前執行緒計算資源。

並行化改造:單看Agent的定義是一個很普通的python類定義,但是通過@parl.remote_class修飾之後,Agent就完成了並行化的改造。

Server端獲取計算資源:通過把Agent類部署到別的機器上或者CPU叢集中,Server這端通過RemoteManager就可以獲取到遠端的Agent類,此後在Server這邊可以通過獲取到的Agent執行任何函式。

遠端計算資源呼叫:但與沒有修飾符的Agent不同的是,並行化後的Agent執行所有函式時不再佔用當前執行緒的計算資源,Server這邊只需要執行Agent的計算函式,等待部署在其他計算資源上的Agent計算完成之後返回結果。

從這個簡單的例子可以看出,使用者實現單機到多機並行的改造成本相當低——利用修飾符來Wrap一個需要在遠端調起的類。在Server端可以通過相應介面獲取遠端的物件,通過執行該物件的函式就可以實現遠端計算資源的呼叫。

新增並行演算法示例:IMPALA

PARL1.1 新增了對IMPALA、A2C、GA3C等並行演算法的支援,下面以實現難度最大的IMPALA演算法為例,介紹下如何通過並行修飾符輕鬆實現這個演算法。IMPALA是強化學習領域目前引用數量最多的並行演算法,相對之前主流的A3C演算法擁有更高的資料吞吐量以及收斂速度。IMPALA演算法為了實現效能的最大化,將整個實現分為Actor/Learner兩個部分:Actor負責與simulator互動,生成資料提供給Learner;Learner 負責收集資料來進行訓練,同時把最新的模型推送給Actor。

PARL1.1一個修飾符實現並行強化學習演算法

在IMPALA演算法這種Actor與Learner的組成結構中,Actor與Learner間需要進行兩種資料互動:訓練資料傳輸以及模型傳輸。如果用傳統的多程式實現這種資料互動的話,使用者需要維護兩個單獨的程式間佇列來進行資料傳輸,開發成本相當高。

在PARL中,我們通過parl.remote_class對Actor進行並行化改造,就可以像在本地操作一樣對Actor進行操作,比如Leaner需要給Actor傳輸引數,只需要在Learner端執行actor.set_param(params)函式即可。從這裡可以看出,在實際的編碼過程中,使用者不需要關心資料是如何通過網路傳輸過去的,也不需要維護多執行緒佇列這些資料結構來實現資料的同步,使用者寫並行程式碼和寫多執行緒程式碼一樣簡單,十分容易上手。


PARL1.1一個修飾符實現並行強化學習演算法

目前,IMPALA演算法的實現已經完整開源在PARL倉庫中,相關的效能指標見下圖。


PARL1.1一個修飾符實現並行強化學習演算法

值得一提的是,PARL繼續保持著1.0版本的高複用性,使用者如果想在別的環境中嘗試IMPALA演算法只需要定義自己的model(前向網路),然後需要複用algorithms下的IMPALA演算法即可。

效能對比

為了讓使用者更好地瞭解PARL的並行效能,我們將PARL與基於Ray實現的強化學習並行框架Rllib進行對比。Rllib是伯克利開源的分散式強化學習框架,是目前開源社群中對於分散式強化學習訓練支援最好的框架之一。在強化學習框架中,最為重要的一個指標是單位時間內的資料吞吐量,也就是在同等計算資源下對比不同框架實現同樣的演算法後的資料收集速度。為此,我們對比了PARL以及Rllib實現的IMPALA演算法在雅達利遊戲上的資料吞吐量(1 P40 GPU+32CPU):


PARL1.1一個修飾符實現並行強化學習演算法

可以看到,PARL在單位時間內的資料收集量相對於Rllib提升了159.4%,這說明PARL在並行效能上達到了業界領先的水準。

第二個對比的指標是收斂速度,這裡我們著重對比了在一小時內兩個框架在多個Benchmark上的收斂效果見下圖。

PARL1.1一個修飾符實現並行強化學習演算法

表格中的資料體現了,在4個Benchmark上跑多次實驗的整體指標比Rllib更高。

結束語

可以看到,PARL 1.1的並行設計非常簡單易於上手,而在並行效能方面也具有很大的優勢。希望為廣大強化學習的研究者提供更好的支援和幫助。


相關文章