伯克利開源工具庫 RLib 現已支援大規模多智慧體強化學習
AI 前線導讀:近日,UC 伯克利的研究團隊 RISELab 在其 Github 的專案 Ray Rlib 0.6.0 中添加了面向多智慧體強化學習(multi-agent Reinforcement Learning)的支援。本文由團隊成員 Eric Liang 首發於 RISELab 團隊主頁,AI 前線翻譯整理。本文主要是關於多智慧體強化學習的簡明教程,以及在 RLib 中的設計思路。
為什麼要使用多智慧體強化學習?
研究人員發現,在實際的強化學習設定中,很多問題都討論到使用多智慧體學習是否有意義。在特定的環境中,與訓練單一策略的方案相比,多智慧體方案能提供以下優點:
- 對問題的分解更具有可解釋性 。舉個例子,假設現在需要在城市環境中訓練 蜂窩天線仰角控制 的策略。一種方案是訓練一個“超級智慧體”在城市中控制所有的蜂窩天線,另一種方案是將每個天線建模成分離的智慧體,後者顯然更加合理。因為只有相鄰的天線和使用者觀測到的天線需要彼此互聯,而其他個體之間則不需要複雜的響應機制。
- 對於可擴充套件性的潛力: 首先,將一個龐大的、複雜的單一智慧體分解為多個簡單的智慧體不僅可以減少輸入和輸出的維度,同時也可以有效的增加每次迭代過程中訓練資料的輸入數量。其次,對每個智慧體的操作和觀測空間進行分割槽,可以起到與 時域抽象方法 類似的作用,該方法成功地在單智慧體策略中 提高 了學習效率。相對地,類似的分級方法可以顯式地實現為多智慧體系統。最後,好的分解策略可以對環境變化具有更好的魯棒性,例如,單一的超智慧體很容易對某個特定環境產生過擬合。
一些多智慧體應用的例子:
減少交通擁堵 :事實證明, 智慧化控制 少數自動駕駛車輛的速度,我們可以大幅增加交通流量。多智慧體是這種自動化策略的基礎,因為在 混合自動化 系統中,將交通訊號燈和車輛建模為單個智慧體是不現實的,因為這需要在一個廣泛區域內的所有智慧體之間同步所有的觀測值和行為。
天線仰角控制 :可以根據本地環境的使用者分佈和拓撲結構來優化蜂窩基站的聯合配置。每個基站可以被建模為覆蓋城市的多個智慧體之一。
OpenAI Five :Dota 2 AI 智慧體經過訓練,可以相互協調並與人類對抗。五個 AI 玩家中的每一個都作為單獨的神經網路策略實施,並與大規模 PPO 一起訓練。
介紹 RLib 中的多智慧體支援
本文主要針對 RLib 中的通用多智慧體支援進行介紹,包括與 Rlib 中的大多數 分散式演算法 (A2C/A3C、PPO、IMPALA、DQN、DDPG 和 Ape-X)的相容性介紹。本文還討論了多智慧體強化學習面臨的挑戰,並展示瞭如何使用現有演算法訓練多智慧體策略,同時還提供了針對非平穩環境和環境變化較多情況下的 特定演算法 的實現。
由於當前可供使用的多智慧體強化學習庫幾乎沒有,這就增加了基於多智慧體方法的實驗成本。在科研和應用兩個領域中,RLib 希望減少從單智慧體模式轉為多智慧體模式的矛盾並簡化轉變過程。
為什麼支援多智慧體很困難
為類似強化學習這種快速發展的領域開發軟體是極具挑戰性的,多智慧體強化學習更甚之。這一工作的難點主要是針對處理多智慧體學習中出現的核心問題的技術。
舉個例子:非平穩環境。在下圖中,紅色智慧體的目標是學習如何調節整個交通流的速度。藍色智慧體則只學習如何最小化它自己的行進時間。紅色智慧體可以通過簡單地以所需速度駕駛來實現其目標。然而,在多智慧體環境中,其他智慧體將會學習如何達到其目標——例如藍色智慧體通過繞行以縮短其時間。這是有問題的,因為從單智慧體的視角來看(例如圖中紅色智慧體),藍色智慧體也是“環境的一部分”。事實上,從單智慧體視角來看,環境的動態變化違反了馬爾可夫假設,而在 Q-learning 演算法例如 DQN 中,這是整個演算法設計的前提。
針對上述情況,很多演算法被提出,例如 LOLA、RIAL 和 Q-MIX。 從高層面講,強化學習模型的訓練過程中,這些演算法會考慮其他智慧體的行為。通常是在訓練階段部分集中化,在執行階段分散化處理。在實現方面,這意味著策略網路之間是彼此依賴的,例如,Q-MIX 演算法中的網路混合:
類似地,基於梯度策略的演算法例如 A3C 和 PPO 等,可能無法相容多智慧體配置。因為隨著智慧體數量的增加,置信度評價將變得越來越困難。考慮下圖中這種多智慧體的所處的情況。可以看出,隨著智慧體數量的增加,對智慧體的激勵與其行為的相關性將會越來越小。此時,交通速度已經降為了 0,但是智慧體並不能作出正確的響應以打破僵局。
一類方法通過中心化值函式(如圖 8 中的“Q”框)來模擬其他智慧體對環境中的影響,MA-DDPG 則使用了這種方法。直觀地講,通過統計其他智慧體的行為,可以有效減少對每個智慧體進行優勢估計時的變化性。
到這裡,本文已經介紹了研究多智慧體強化學習所面臨的兩大挑戰與解決策略。在很多情況下,使用單智慧體強化學習演算法訓練多智慧策略可以取得不錯的結果。例如,OpenAI Five 就是利用了大規模 PPO 和 特殊化網路模型 的組合。
在 RLib 中訓練多智慧體
那麼,在多智慧體設定中如何使用特殊化演算法與單智慧體強化學習?RLib 為此設計了簡單易行的 方法 。相關細則如下:
-
策略被表示為物件:在 RLib 中,所有的基於梯度的演算法都會宣告一個策略圖物件,該物件包含一個策略模型πθ(ot) 和一個 軌跡後處理函式 postθ(traj) 以及策略損失 L(θ; X)。 該策略圖 物件為分散式框架提供了足夠的內容與功能以執行環境部署(通過檢索πθ)、 經驗整理 (通過應用 postθ)以及策略優化(通過減小策略損失)。
-
策略物件是黑箱:為了支援多智慧體配置,在每個環境中,RLib 僅管理多個策略圖的建立與執行,並在 策略優化 過程中對他們的損失進行累計。在 RLib 中,策略圖物件通常被當成黑箱,這就意味著可以用任何框架(包括 TensorFlow 和 PyTorch)來實現它們。此外,策略圖可以在內部共享變數和層以實現 Q-MIX 和 MA-DDPG 等演算法,而不需要特殊的框架支援。
更了更具體的說明這些細則,接下來的幾節將介紹一些 RLlib 中的多智慧體 API 來執行大規模多智慧體訓練的程式碼示例。
多智慧體環境模型
由於不確定標準的多智慧體環境藉口,因此 RISELab 將 這個多智慧體環境模型 編寫為 Gym 介面 的直接擴充套件。在多智慧體環境中,每一步會存在多種行為實體。圖 6 所示的是一種交通控制場景,其中多個可控實體(例如,交通燈、自動駕駛車輛)一起工作以減少高速公路擁堵。
在該場景中:
- 每個智慧體都可以在不同的時間尺度上作出響應(即,非同步工作)。
- 智慧體會隨時間進出該環境。
下面這段程式碼是使用 MultiAgentEnv 介面的一個示例,該介面可以從多個就緒的智慧體中返回觀測值和激勵:
複製程式碼
# 示例:使用多智慧體環境 > env = MultiAgentTrafficEnv(num_cars=20,num_traffic_lights=5) # 觀測值是字典形式的,不是每一個智慧體都需要在每個時間點被表示於字典中。 >print(env.reset()) { "car_1": [[...]], "car_2": [[...]], "traffic_light_1": [[...]], } # 每個智慧體都需要定義一個行為來返回他們的觀測值 > new_obs, rewards, dones, infos = env.step( actions={"car_1":..., "car_2":...}) # 同樣的,新的觀測值,激勵,完成的,資訊等也是字典形式 >print(rewards) {"car_1": 3, "car_2": -1, "traffic_light_1": 0} # 獨立的智慧體可以早早離開 ; 當 "__all__" 設定為 True 時,環境配置完成。 >print(dones) {"car_2": True, "__all__": False}
OpenAI gym 中的任何離散的 Box、Dict 或者 Tuple 都可以為這些獨立的智慧體提供支援,每個智慧體都允許接受多種型別的輸入(包括智慧體間的通訊)。
多級的 API 支援
在較高的層次上,RLib 模型將智慧體和策略建模為在一段持續時間內可以互相繫結的物件(如圖 7 所示)。使用者可以在不同程度上使用這一抽象的物件,從僅使用一個單智慧體共享策略到多策略,再到完全自定義的策略優化:
級別 1:多智慧體,共享策略
如果環境中的所有智慧體都是同質的(例如,在交通模擬中的多個獨立的車輛),則可以使用現有的單智慧體演算法進行訓練。由於只有一個策略被訓練,因此 RLib 只需要在策略優化之前在內部累積不同智慧體的經驗,使用者方面的變化則很小。
單智慧體的情況:
複製程式碼
register_env("your_env", lambda c: YourEnv(...)) trainer = PPOAgent(env="your_env") while True: print(trainer.train()) # distributed trainingstep
多智慧體的情況:
複製程式碼
register_env("your_multi_env", lambda c: YourMultiEnv(...)) trainer = PPOAgent(env="your_multi_env") while True: print(trainer.train()) # distributed trainingstep
注意,此處的 PPOAgent 只是從單智慧體 API 繼承的命名約定。它更像是智慧體的一個訓練器而不是真正的智慧體。
級別 2:多智慧體,多策略
這種情況下,需要定義每個智慧體會被哪個策略處理。在 RLib 中可以通過策略對映函式處理此問題,該函式在智慧體首次進入環境時將環境中的智慧體分配給特定策略。下面的例子展示了一個分級控制設定,其中監督智慧體將工作分配給它們監督的工作智慧體。完成這一目標的所需配置是監督策略和工作策略的集合:
複製程式碼
def policy_mapper(agent_id): if agent_id.startswith("supervisor_"): return "supervisor_policy" else: return random.choice(["worker_p1", "worker_p2"]) 在本例中,我們通常將監督智慧體與一個單獨的監督策略繫結,然後將其他工作智慧體隨機分配給兩個不同的工作策略繫結。這些配置會在智慧體首次進入環境時完成,並在智慧體離開環境之前持續工作。最後,我們需要定義不止一個策略配置。這是作為上級智慧體配置的一部分來完成的: trainer = PPOAgent(env="control_env", config={ "multiagent": { "policy_mapping_fn": policy_mapper, "policy_graphs": { "supervisor_policy": (PPOPolicyGraph, sup_obs_space, sup_act_space, sup_conf), "worker_p1": ( (PPOPolicyGraph, work_obs_s, work_act_s, work_p1_conf), "worker_p2": (PPOPolicyGraph, work_obs_s, work_act_s, work_p2_conf), }, "policies_to_train": [ "supervisor_policy", "worker_p1", "worker_p2"], }, }) while True: print(trainer.train()) # distributed training step
這將生成一個如圖 5 所示的配置。你可以為每個策略定製個性化的策略圖類,以及不同的策略配置字典。任何 RLib 的支援的定製(例如,自定義模型和預處理)都可以用於每個策略,以及新的策略類的批量定義。
其他示例: Sharing layers across policies 、 Implementing a centralized critic
級別 3:自定義訓練策略
對於一些高階的應用於研究情景,不可避免地會遇到一些框架方面的限制。
例如,假設需要多種訓練方法的情況:一些智慧體將使用 PPO 進行學習,一些則使用 DQN。這種情況下,可以通過在兩個不同的訓練器之間交換權重來完成( 參考程式碼 ),但這種方法的可擴充套件性較差,例如想加入新的演算法或是想同時使用經驗對環境模型進行訓練的時候。
為了應對這種情況,RLib 的底層系統 Ray 可以按需分配計算。Ray 提供了兩個簡單的並行介面:
- Tasks ,通過 func.remote() 被非同步執行的 Python 函式。
- Actors ,通過 class.remote() 在叢集中被建立的 Python 類。Actor 方法可以被 actor.method.remote() 呼叫。
RLib 在 Ray 的 tasks 和 actors 上構建,為分散式強化學習提供工具包。其中包括:
- 策略圖 (之前示例已展示)
- 策略評估 :PolicyEvaluator 類會對生成批量經驗的環境互動迴圈進行管理。當建立為 Ray actors 時,它可以用於在分散式環境中收集經驗。
- 策略優化 :這一部分用於對策略的優化。你可以使用現有的優化器,也可以使用自定義策略。
例如,你可以建立 策略優化器 以收集多智慧體的輸出,然後對他們進行處理以提高策略:
複製程式碼
# 初始化一個單節點的 Ray 叢集 ray.init() # 為自定義策略圖建立區域性例項 sup, w1, w2 = SupervisorPolicy(), WorkerPolicy(), WorkerPolicy() # 建立策略優化器 (Ray actor 程序會在叢集中執行) evaluators = [] for i in range(16): ev = PolicyEvaluator.as_remote().remote( env_creator=lambda ctx: ControlEnv(), policy_graph={ "supervisor_policy": (SupervisorPolicy,...), "worker_p1":...,...}, policy_mapping_fn=policy_mapper, sample_batch_size=500) evaluators.append(ev) while True: # Collect experiencesinparallel using thepolicyevaluators futures = [ev.sample.remote() for ev in evaluators] batch = MultiAgentBatch.concat_samples(ray.get(futures)) # >>>print(batch) # MultiAgentBatch({ # "supervisor_policy": SampleBatch({ # "obs": [[...],...],"rewards": [0,...],... # }), # "worker_p1": SampleBatch(...), # "worker_p2": SampleBatch(...), # }) your_optimize_func(sup, w1, w2, batch) # Custompolicyoptimization # Broadcast new weightsandrepeat for ev in evaluators: ev.set_weights.remote({ "supervisor_policy": sup.get_weights(), "worker_p1": w1.get_weights(), "worker_p2": w2.get_weights(), })
總之,RLib 提供了多個層級的 API,旨在提高其可定製性。在最高層級,這裡提供了幾個簡單的“開箱即用”的訓練過程,但使用者也可以從核心的多智慧體抽象物件中選擇使用自定義的演算法和訓練策略。這裡有一些可以直接執行的指令碼供使用: multiagent_cartpole.py , multiagent_two_trainers.py .
效能表現
RLlib 旨在擴充套件到大型叢集以及多智慧體模式,同時也提供類似向量化這種針對單核心效率的優化。這允許在小型機器上高效地使用多智慧體 API。
為了說明這些優化方法的重要性,下圖分析了單核心策略評估與環境中智慧體數量的關係。在這個基準測試中,觀測值是小浮點向量,策略是小型 16*16 的全連線網路。每個智慧體被隨機分配給 10 個這樣的策略網路。RLib 在每個環境中的 10000 個智慧體上管理超過 70k actions/s/core(此時 Python 的計算開銷就變成了瓶頸)。當向量化功能關閉的時候,經驗累積的速度降低了 40 倍:
RISELab 還評估了在環境中使用多個不同策略網路的更具挑戰性的情況。在這裡,仍然可以利用向量化將多個 TensorFlow 呼叫融合為一個,從而獲得更穩定的單核效能,下圖是不同策略的數量從 1 擴充套件到 50 的評估結果:
結論
這篇博文介紹了一個快速,通用的多智慧體強化學習框架。
RISELab 目前正與 BAIR ,Berkeley FLow team 和行業的早期使用者合作,以進一步改進 RLlib。
快嘗試使用’pip install ray [rllib]'快速安裝 RLib,並執行你自己的測試用例吧。
有關 RLlib 和多代理支援的文件,請訪問 https://rllib.io 。
檢視英文原文: An Open Source Tool for Scaling Multi-Agent Reinforcement Learning