保持 Token 流動:來自 16 個開源 RL 庫的教訓
TL;DR – Hugging Face 調查了 16 個開源強化學習(RL)庫,發現所有成功的非同步 RL 系統皆將推理與訓練分離到不同的 GPU 池、使用 rollout 緩衝區,並以非同步方式推送模型權重;Ray 是主導的協調框架,NCCL 廣播是常見的權重同步方法,而 LoRA 與 Mixture‑of‑Experts(MoE)訓練的支援仍相當稀少。
1. 為何非同步 RL 很重要
非同步 RL 消除了同步訓練大型語言模型(LLM)時產生的生成瓶頸,該瓶頸會使 GPU 在高達 60 % 的實際時間內閒置。 在同步流水線中,對 32‑億參數模型執行 32 K‑token rollout 的單批次可能需要數小時,而負責梯度更新的 GPU 卻在等待。透過將推理與訓練分散到不同的 GPU 池,並以 rollout 緩衝區連接兩者,生成可以在訓練器消耗先前產生的資料時持續進行,從而大幅提升 GPU 使用率。
2. 調查概覽
Hugging Face 檢視了 十六 個開源非同步 RL 庫(AReaL、ART、Atropos、MILES、NeMo‑RL、OAT、open‑instruct、PipelineRL、PRIME‑RL、ROLL、SkyRL、SLIME、TorchForge、Tunix、verl、verifiers‑rl)。每個庫在 七個正交軸 上進行了評估:
- 協調與併發原語 – 分散元件如何協調。
- Rollout 緩衝區設計 – 從推理到訓練傳遞產生樣本的資料結構。
- 權重同步協議 – 更新後的參數如何推送至推理池。
- 陳舊度管理 – 處理 off‑policy rollout 的策略。
- 部分 rollout 處理 – 權重變更時飛行中的生成會發生什麼。
- LoRA 訓練支援 – 訓練僅 adapter 參數並有效同步的能力。
- 分散式訓練後端與平行化 – 平行化策略(FSDP、Megatron、DeepSpeed、JAX 等)與 MoE 支援。
完整的比較表可在原始部落格文章中取得;以下章節總結每個軸的關鍵發現。
3. 協調與併發原語
| 協調類型 | 說明 | 使用的庫 |
|---|---|---|
| 分散式 actor 模型(Ray) | 具備非同步 RPC、物件存儲與內建容錯的有狀態 actor。 | AReaL、verl、SkyRL、NeMo‑RL、SLIME、MILES、ROLL、OAT、open‑instruct 等 |
| 原生 Python 併發 | 執行緒、asyncio、multiprocessing;不依賴外部執行環境。 |
verifiers‑rl、PipelineRL(池內部)、ART、AReaL(基於 asyncio) |
| Pub/Sub 訊息總線 | 透過 Redis 串流或追加檔案實現解耦的生產者/消費者。 | PipelineRL(池間)、SLIME(非同步模式) |
| HTTP 微服務 | 以 REST 方式通訊的獨立服務。 | Atropos |
發現: Ray 在生態系中佔據主導,出現在 8/16 庫。其 actor 模型與 RL 中異質元件(推理伺服器、訓練器、獎勵模型、環境池)相匹配,提供自動排程、容錯與透過 Ray 物件存儲的零拷貝資料傳輸。然而,Ray 會帶來較重的執行時,促使較小規模部署考慮較輕量的替代方案(原生 Python、Pub/Sub)。
4. Rollout 緩衝區設計
| 緩衝模式 | 深度(最大飛行批次) | 庫 | 備註 |
|---|---|---|---|
| 無緩衝(同步) | 0 | TRL(目前)、ART(收集完再訓練) | 生成與訓練交替;陳舊度最大但無重疊。 |
| 雙緩衝 | 1 | verifiers‑rl、SLIME(非同步模式)、MILES、OAT | 正好重疊一個生成批次與一次訓練步驟;陳舊度最小。 |
| 有界非同步佇列 | 2–K | SkyRL、verl、NeMo‑RL、ROLL、PRIME‑RL、TorchForge、Tunix、open‑instruct、AReaL | 多個批次同時飛行;陳舊度受佇列容量限制。 |
| 無界 / 串流 | 無限制 | PipelineRL(Redis 串流)、SLIME(完整非同步)、Atropos | 持續生成;必須透過版本標籤或重要性抽樣控制陳舊度。 |
較深的佇列提升吞吐量,但需要明確的陳舊度管理(見第 4 軸)。
5. 權重同步協議(第 3 軸)
協議決定 延遲 與 中斷粒度,即從訓練器推送新權重至推理池的時機與方式。
5.1 傳輸機制
| 機制 | 典型延遲 | 庫 |
|---|---|---|
| NCCL 廣播 | 100–500 ms | 大多數庫(PipelineRL、SkyRL、SLIME、MILES、ROLL、OAT、NeMo‑RL、PRIME‑RL、open‑instruct、AReaL) |
| NCCL + 分桶 | 約 20 ms | verl |
| 共享記憶體 / CUDA IPC | 極低 | NeMo‑RL、MILES |
| 檔案系統 + HTTP | 中等(秒級) | PRIME‑RL、AReaL、ART |
| HTTP PUT | 高(秒級) | verifiers‑rl |
| JAX cross‑mesh | 低 | Tunix |
5.2 中斷粒度
| 粒度 | 行為說明 | 庫 |
|---|---|---|
| 永不停止(逐 token 替換) | 權重在前向傳播之間交換,生成永不中斷。 | PipelineRL、open‑instruct(選擇性) |
| 每個 HTTP 請求中止 | 正在進行的 HTTP 呼叫被取消,並以前綴重新發送。 | SkyRL、SLIME |
| 軟性暫停(排空飛行) | 阻止新請求,讓現有生成完成後再同步。 | PRIME‑RL、AReaL、open‑instruct(預設)、verl(非同步) |
| 每批次/阻塞 | 生成與訓練交替進行,同步會同時阻塞雙方。 | NeMo‑RL、ROLL、OAT、TorchForge、Tunix、verifiers‑rl、Atropos |
發現: 只有 PipelineRL 實現了真正的 永不停止 權重更新,於 token 級別前向傳播間切換參數。其他庫皆在較粗的邊界暫停,導致短暫的推理使用過時權重。
6. 陳舊度管理(第 4 軸)
當生成與訓練重疊時,rollout 會變成 off‑policy。庫採用以下三種正交策略:
- 每樣本版本拒絕 – 丟棄
model_version超過設定延遲的樣本。 - 深度限制 – 限制飛行批次數,從結構上保證最大版本差距。
- 重要性抽樣(IS)校正 – 以比例 (\frac{\pi_{\theta}(a|s)}{\pi_{\text{old}}(a|s)}) 重新加權過時樣本,通常會裁剪。
| 庫 | 版本拒絕 | 深度限制 | IS 校正 |
|---|---|---|---|
| AReaL | ❌ | ✅ | ⚠️(可選) |
| ART | —(同步) | — | — |
| Atropos | ❌ | ✅ | ❌ |
| MILES | ❌ | ❌ | ✅ |
| NeMo‑RL | ✅ | ❌ | ❌ |
| OAT | ❌ | ❌ | ✅ |
| open‑instruct | ❌ | ✅ | ⚠️(可選) |
| PipelineRL | ✅ | ❌ | ❌ |
| PRIME‑RL | ✅ | ✅ | ✅ |
| ROLL | ❌ | ❌ | ✅ |
| SkyRL | ❌ | ✅ | ❌ |
| SLIME | ❌ | ❌ | ✅ |
| TorchForge | ✅ | ❌ | ❌ |
| Tunix | ❌ | ✅ | ❌ |
| verl | ❌ | ❌ | ✅ |
| verifiers‑rl | ❌ | ✅ | ❌ |
混合做法(如 PRIME‑RL、open‑instruct)結合深度限制與可選的 IS 加權,以保持管線簡潔同時具備韌性。
7. 部分 Rollout 處理(第 5 軸)
長上下文 rollout(數萬 token)在權重更新到來時仍可能在生成中。策略包括:
| 策略 | 庫 | 說明 |
|---|---|---|
| 隱式續寫 | PipelineRL | 不中斷;權重交換發生於 token 前向傳播之間。 |
| 中止 + 前綴重試 | SkyRL、SLIME | 取消飛行中的生成,將已得前綴重新提交給新政策。 |
| 顯式保存/恢復 | verl(完整非同步) | 保存部分 token ID 與 KV 快取,同步後從保存狀態繼續生成。 |
| 批次取消 | PRIME‑RL | 丟棄過時的 rollout 群組,於 HTTP 請求間同步新權重。 |
| 軟性暫停(排空) | AReaL | 停止新任務,讓現有任務完成後再同步。 |
| 不支援 | verifiers‑rl、OAT、Atropos、Tunix | 必須等所有飛行生成結束後才同步。 |
只有 PipelineRL 與 verl 提供真正的 永不停止 行為;其餘皆依賴中止或排空機制。
8. LoRA 訓練支援(第 6 軸)
LoRA 大幅減少可訓練參數,允許 僅同步 adapter 權重,即只廣播小幅度的 adapter delta。對於 7 B+ 模型,這可將 NCCL 傳輸時間從數百毫秒縮減至毫秒以下。
| 庫 | 支援 LoRA? | 後端 | 僅 adapter 同步 |
|---|---|---|---|
| AReaL | ✅ | HF peft(FSDP2/Megatron) |
✅ |
| ART | ✅ | Unsloth / Megatron | ✅ |
| Atropos | ✅ | HF peft |
✅ |
| MILES | ✅ | Megatron‑Bridge | ✅ |
| NeMo‑RL | ✅(自訂) | DTensor / Megatron | ❌(無證據) |
| OAT | ✅ | HF peft |
✅ |
| open‑instruct | ❌(程式碼存在但未接線) | — | ❌ |
| PipelineRL | ✅ | HF peft |
❌(完整廣播) |
| PRIME‑RL | ✅ | Custom MultiLoRA | ✅ |
| ROLL | ✅(僅 DeepSpeed) | DeepSpeed | ❌ |
| SkyRL | ✅ | HF peft / Megatron‑Bridge |
✅ |
| SLIME | ❌ | — | ❌ |
| TorchForge | ❌ | — | ❌ |
| Tunix | ✅ | qwix(JAX) | ✅ |
| verl | ✅ | HF peft / Megatron‑Bridge |
✅ |
| verifiers‑rl | ✅ | HF peft + FSDP2 |
✅ |
LoRA‑only 同步極大緩解了中斷模型:即使庫在每個請求中止,也能因資料量極小而頻繁更新權重。
9. 分散式訓練後端與平行化(第 7 軸)
訓練後端決定模型規模上限、集合通信模式以及與 MoE 的相容性。
| 庫 | 後端 | 平行化(DP/TP/PP/EP) | MoE 支援 |
|---|---|---|---|
| AReaL | FSDP2、Megatron、Archon | DP、SP、TP、PP、CP、EP | ✅ |
| ART | Unsloth、Megatron | DP、TP、EP | ✅ |
| Atropos | PyTorch native、TRL | DP | ❌ |
| MILES | Megatron、FSDP2 | DP、TP、PP | ✅ |
| NeMo‑RL | DTensor、Megatron | DP、SP、TP、PP、CP、EP | ✅ |
| OAT | DeepSpeed | DP、TP | ❌ |
| open‑instruct | DeepSpeed | DP、SP | ❌ |
| PipelineRL | DeepSpeed | DP、SP | ❌ |
| PRIME‑RL | FSDP2 | DP、TP、CP、EP | ✅ |
| ROLL | DeepSpeed、Megatron、FSDP2 | DP、SP、TP、PP、CP、EP | ✅ |
| SkyRL | FSDP、Megatron‑Bridge | DP、SP、TP、PP、EP | ✅ |
| SLIME | Megatron | DP、TP、PP、SP | ✅ |
| TorchForge | FSDP2(Monarch) | DP、TP、CP | ❌ |
| Tunix | JAX/XLA | DP、TP | ❌ |
| verl | FSDP、Megatron | DP、SP、TP、PP、CP、EP | ✅ |
| verifiers‑rl | DeepSpeed | DP | ❌ |
關鍵含意: MoE 訓練(專家平行)僅在基於 Megatron 或具備明確 EP 處理的 FSDP2 庫中受支援(AReaL、verl、PRIME‑RL、SkyRL、ROLL、NeMo‑RL)。僅使用 ZeRO(DeepSpeed、純 FSDP) 的庫雖能載入 MoE 檢查點,卻因所有專家都被切分至每個 rank 而失去稀疏優勢。
10. 新興設計壓力
10.1 無評論員(Critic‑Free)演算法
移除價值網路(如 GRPO、REINFORCE++)可釋放記憶體,允許更大的 rollout 批次,但也會提升權重更新頻率。因政策漂移在較大群組(G = 8‑32)下加速,陳舊度管理變得更為關鍵;每樣本版本標籤與 IS 校正因此成為穩定訓練的必要手段。
10.2 流程獎勵(Process Rewards)
對中間推理步驟進行打分會在生成與訓練之間加入非平凡的計算階段。非同步流水線必須加入 reward‑actor 與訓練器並行執行,如 PRIME‑RL 與 NeMo‑RL 所示。否則獎勵計算會成為新的瓶頸。
10.3 多代理共演(Multi‑Agent Co‑Evolution)
多代理自我對弈會放大拖延者問題:有效的 rollout 長度變為每個代理長度的乘積,導致變異極大。緩衝區設計必須將整個多代理回合視為單一原子單位,且陳舊度策略需以每回合版本追蹤取代每樣本。
10.4 MoE 的訓練‑推理不匹配
在 DeepSeek‑v3.2 中發現兩個結構性不匹配:
- 專家路由不一致 – 推理與訓練可能因浮點差異選擇不同專家。解決方案(“Keep Routing”)要求推理伺服器回傳路由決策,訓練器強制使用相同路由。
- 抽樣遮罩不匹配 – 生成時的 top‑p/top‑k 截斷會導致行動空間與完整詞彙表的訓練前向傳播不同。“Keep Sampling Mask” 會記錄截斷遮罩並在訓練時重新套用。 目前調查的庫皆未實作上述功能,顯示未來非同步 RL 系統仍有明顯缺口。
10.5 以非同步 RL 形式的蒸餾(Distillation)
On‑policy 蒸餾(student 生成、teacher 打分)遵循與 RL 完全相同的非同步模式:生成 → 打分 → 梯度更新 → 權重同步。因此所有設計軸皆保持不變。完整的通用非同步訓練器應將打分步驟抽象為可插拔元件,而非硬編碼的 verifier,從而同時支援 RL 與蒸餾工作負載。
11. TRL 非同步訓練器的設計選擇
根據調查,TRL 團隊為即將推出的非同步訓練器規劃了以下具體決策:
- 輕量級協調 – 盡可能避免沉重的執行時,採用原生 Python
asyncio結合最小化的 actor 抽象。 - 有界佇列 + 每 token
model_version– 每個 token 攜帶生成時的政策版本,支援細粒度 IS 校正,免除日後的補丁需求。 - NCCL 權重同步 + 打包傳輸 – 使用 vLLM 的
NCCLWeightTransferEngine並以分桶方式在約 20 ms 內廣播權重,極大降低同步延遲。 - 部分 rollout 支援 – 為具備代理性的工作負載實作前綴‑恢復機制,使飛行中的生成在權重更新後得以在新政策下繼續。
這些選擇旨在結合生態系最佳實踐,同時保持實作對廣大 TRL 社群友好。
結論: 非同步 RL 訓練已成為大規模 LLM 後訓練的事實標準。調查顯示,業界已明確收斂於推理與訓練分離、使用 rollout 緩衝區以及非同步權重推送的做法,Ray 為主要的協調層,NCCL 廣播為預設同步方式。未來工作需解決 LoRA‑only 同步、MoE 路由一致性與多代理回合處理,以跟上下一代前沿模型的需求。