トークンを流し続ける:16のオープンソースRLライブラリからの教訓
Hugging Faceのブログ記事は、同期型強化学習のボトルネックを解決する非同期アーキテクチャについて、16のオープンソースライブラリを比較分析し、Rayがオーケストレーションで支配的であることやNCCLブロードキャストが重み転送のデフォルト手法であるなどの主要知見を提供している。
キーポイント
同期型RLのボトルネックと非同期アーキテクチャの解決策
同期型強化学習ではデータ生成(推論)が壁時間の大部分を占め、トレーニング用GPUがアイドル状態になる問題があり、推論とトレーニングを異なるGPUプールに分離し、ロールアウトバッファで接続する非同期アーキテクチャが一般的な解決策となっている。
16オープンソースライブラリの比較分析
7つの軸(オーケストレーションプリミティブ、バッファ設計、重み同期プロトコル、陳腐化管理、部分ロールアウト処理、LoRAサポート、分散トレーニングバックエンド)で16ライブラリを比較し、Rayがオーケストレーションで8/16を占め、NCCLブロードキャストが重み転送のデフォルトであることを明らかにした。
技術的知見とトレンド
LoRAトレーニングのサポートは限定的であり、分散MoE(Mixture of Experts)サポートが新たな差別化要因として登場しており、陳腐化管理では古いサンプルの単純な破棄から高度な重要度サンプリング補正まで様々なアプローチが存在する。
設計上の課題と将来の方向性
批評家不要アルゴリズムによるメモリ解放と重み同期圧力の増加、プロセス報酬による新たな同期障壁、マルチエージェント共進化における遅延問題の複合化、トレーニング-推論の不一致(Deepseek v3.2 MoE事例)、蒸留における同様の非同期問題など、今後の設計課題が指摘されている。
非同期RLトレーニングの必要性
長いロールアウト、可変レイテンシ、ストラグラー問題により、同期トレーニングはスケールが困難で、推論とトレーニングを分離した非同期アーキテクチャが主流となっている。
非同期トレーニングの設計軸
オーケストレーションプリミティブ、バッファ設計、重み同期プロトコル、陳腐化管理、部分ロールアウト処理、LoRAサポート、分散トレーニングバックエンドの7つの軸で設計が比較されている。
分散モードによる非同期トレーニングの実現
分散モードでは推論とトレーニングを別々のGPUプールで実行し、重み同期プロトコルとデータ転送メカニズムを通じて通信することで、推論とトレーニングを並行実行できる。これにより、トレーナーが現在のバッチで勾配を計算している間に、推論プールは次のバッチのロールアウトを生成する非同期トレーニングが可能になる。
影響分析・編集コメントを表示
影響分析
この記事は大規模言語モデルの強化学習における実践的な課題と解決策を詳細に分析しており、AI研究コミュニティと実務者に対して、GPUリソースの効率的な利用とトレーニングパフォーマンスの最適化に関する具体的な知見を提供している。オープンソースエコシステムの現状分析は、技術選定とシステム設計の意思決定に直接役立つ実用的価値が高い。
編集コメント
技術的深みがあり実践的な知見に富んだ分析記事で、RLトレーニングの効率化に取り組むエンジニアや研究者にとって非常に価値のある内容。比較表を含む具体的なデータに基づく評価が説得力を持つ。
記事に戻る トークンを流し続ける: 16のオープンソースRLライブラリからの教訓
Upvote 2

TL;DR -- 非同期RL(Reinforcement Learning)の基盤について5,000語を読む時間がない方々へ(理解します、モデルをトレーニングする必要がありますから):
問題: 同期RL(強化学習)トレーニングでは、データ生成(データサンプルを作成するためのモデル推論)が実時間を支配します。32B(320億パラメータ)モデルでの32Kトークンのロールアウトの単一バッチは数時間かかる一方で、トレーニングに使用されるGPUはアイドル状態のままです。
皆が収束した解決策: 推論とトレーニングを異なるGPUプールに分離し、ロールアウトバッファ(モデル出力の一時ストレージ)で接続し、重みを非同期に(待機せずに)転送することで、どちら側も他方を待たないようにします。
私たちはこのパターンを実装する16のオープンソースライブラリを調査し、7つの軸で比較しました: オーケストレーションプリミティブ、バッファ設計、重み同期プロトコル、陳腐化管理、部分ロールアウト処理、LoRA(Low-Rank Adaptation)サポート、分散トレーニングバックエンドです。
主な発見: Rayがオーケストレーションを支配しています(調査した16の分散コンピューティングライブラリのうち8つ)。NCCL(NVIDIA Collective Communications Library)ブロードキャストはモデル重み転送のデフォルト方法です。陳腐化管理とは、古くなったデータサンプルをどのように処理するかを指し、単純に古いサンプルを破棄するものから高度な重要度サンプリング補正を使用するものまで範囲があります。LoRAトレーニングのサポートはまばらです。分散MoE(Mixture of Experts)サポートは新たな差別化要因となっています。
もし良い部分に直接飛びたいなら、こちらが完全な比較表です(読む必要はありません、私たちは批判しません)。
しかし真剣に、もしあなたが残ってくれれば、なぜあなたのGPUが60%の時間アイドル状態なのかについて一つ二つ学べるかもしれません。
- 動機: 同期RLトレーニングから非同期アーキテクチャへ
1.1 TRLが現在行うRLトレーニング
1.2 コロケート型トレーニング vs 分離型トレーニング
1.3 生成ボトルネック
1.4 核心的洞察
- 調査したライブラリ
- 比較フレームワーク: 7つの軸
軸1: オーケストレーション & 並行性プリミティブ
軸2: ロールアウトバッファ設計
軸3: 重み同期プロトコル
軸4: 陳腐化管理
軸5: 部分ロールアウト処理
軸6: LoRAトレーニングサポート
軸7: 分散トレーニングバックエンド & 並列化
- 全体概要: 16のライブラリを一目で
- 次の波: 設計上の含意
5.1 批評家不要アルゴリズム: メモリ解放されるが、重み同期の圧力が増加
5.2 プロセス報酬: 新たな同期バリア
5.3 マルチエージェント共進化: 遅延問題の複合化
5.4 トレーニング-推論の不一致: Deepseek v3.2 MoEケーススタディ
5.5 蒸留: 異なる名前の下での同じ非同期問題
- TRLの非同期トレーナーの設計選択
設計原則: オーケストレーションを軽量に保つ
- トークンごとのmodel_versionを持つ境界付きキュー
- パック転送によるNCCL重み同期
- エージェント的ワークロードのための部分ロールアウトサポート
- 動機: 同期RLトレーニングから非同期アーキテクチャへ
非同期RLトレーニングは、大規模なポストトレーニングにおける支配的パラダイムとして登場しました。現代のポストトレーニングにおけるいくつかのトレンドが、同期トレーニングループのスケーリングをほぼ不可能にしています:
推論モデルからの長いロールアウト。連鎖思考トレーニングは非常に長いロールアウトを生成し、単一の同期生成バッチは単一GPUで完了するのに数時間かかることがあります。その間ずっと、トレーニングGPUは完全にアイドル状態です。
GRPOのような価値関数不要トレーナーはグループ相対的アドバンテージを使用します。これはプロンプトごとに最大G倍のロールアウトを生成することを意味し、バッチ全体はグループ内の最も遅い完了によって制限されます。
エージェント的RLトレーニングの台頭。モデルがマルチターンの軌跡にわたってツール、サンドボックス、外部環境と相互作用するとき、ロールアウト長とレイテンシは非常に変動的になります。単純なAPI呼び出しは数秒で返るかもしれませんが、ツール使用を含む複雑な推論連鎖は数分または数時間実行される可能性があります。MiniMax-M2.5のトレーニングに使用されるMiniMaxのForgeフレームワークは、これが実際に到達する規模を示しています: 最大200Kトークンのコンテキスト長、10万以上の異なるエージェントスキャフォールドと環境、そして数百万サンプルオーダーの日次スループット。この規模では、生成とトレーニングの間のいかなる同期バリアも深刻なボトルネックになります。遅延問題だけでも(少数の遅いロールアウトがバッチ全体をブロックする)、数百のGPUをアイドル状態にすることができます。
オープンソースエコシステムは、共通のアーキテクチャ的対応に収束しました: 推論をトレーニングから分離して別々のGPUプールに配置し、ロールアウトバッファで接続し、両側を並行して実行させます。
私たちは、モデルポストトレーニングで最も広く使用されているライブラリの一つであるTRLのための新しい非同期トレーナーを開発しています。私たちの設計を導くために、非同期トレーニングを中心にゼロから構築された16のオープンソースライブラリを調査し、7つの軸で比較しました: オーケストレーションプリミティブ、バッファ設計、重み同期プロトコル、陳腐化管理、部分ロールアウト処理、LoRAサポート、分散トレーニングバックエンドです。この記事は、その調査から抽出した設計原則を要約したものです。
RLを超えて、非同期インフラストラクチャの必要性はますます明らかになっています。例えば、学生がシーケンスを生成し教師がそれらをスコアリングするオン方針蒸留は、報酬関数を教師のフォワードパスに置き換える以外はGRPOと同様です。この構造的類似性を認識することで、この調査のすべては非同期蒸留にも同様に適用されます。このより広い点についてはセクション5で戻ります。
1.1 TRLが現在行うRLトレーニング
TRLの現在のGRPOTrainer
training_step()
GRPOTrainerを見ると:
プロンプトサンプリング: データセットからプロンプトのバッチを抽出します。ここは特に変わったことはありません、続けましょう。
生成、model.generate()を呼び出します。
報酬スコアリング: 各完了を1つまたは多くの報酬関数に対して評価します。
アドバンテージ計算
フォワードおよびバックワードパス: クリップされた方策勾配損失を計算し、誤差逆伝播します。
オプティマイザステップ、モデル重みを更新します。
重み同期、更新された重みを推論エンジン(vLLM)にプッシュして、次の生成が新しい方策を使用するようにします。
各フェーズは完了するまでブロックされ、次のフェーズが始まります。タイムラインはこのようになります:
TRLはsteps_per_generationを提供します。
ライブラリはまた、vLLMをサーバーモードで実行することをサポートしています。
1.2 コロケート型トレーニング vs 分離型トレーニング
非同期トレーニングについて議論する前に、別個の推論エンジンを持つRLトレーニングの2つのデプロイメントトポロジーを理解することが不可欠です:
コロケート型モードは、推論とトレーニングを同じGPUセットに配置します。単一のGPU(またはTPグループ)がトレーニングモデル(FSDPまたはZeROの下)と推論エンジン(vLLMまたはSGLang)の両方を保持します。一度に一つの役割のみがアクティブです: 生成中は、トレーニングモデルのパラメータがオフロードまたは再シャーディングされて推論に適したレイアウト(例: FSDPシャードからvLLMのテンソル並列レイアウトへ)になる可能性があります; トレーニング中は、推論エンジンは一時停止またはスリープ状態になります。重み「同期」は本質的に無料です; それはせいぜい同じGPU上のインプレース再シャーディングであり、ネットワーク転送ではありません。コロケート型モードの利点はシンプルさとコストです; 必要なGPUの総数が少なくなります。根本的な制限は、推論とトレーニングが重複できないことです。例えば、こちらがコロケートモードでのvllmを使用したTrlです。
分離型モードは、推論とトレーニングを別々のGPUプールに配置します。推論プールはvLLMまたはSGLangを継続的に実行します; トレーニングプールはオプティマイザを継続的に実行します。2つのプールは、重み同期プロトコル(NCCLブロードキャスト、ファイルシステムチェックポイント、HTTPなど)とデータ転送メカニズム(Rayオブジェクトストア、Redisストリーム、共有メモリなど)を介して通信します。
分離型モードの最大の利点は、推論とトレーニングが並行して実行できることです。トレーナーがバッチNの勾配を計算している間、推論プールはすでにバッチN+Kのロールアウトを生成しており、非同期トレーニングを可能にします。しかし、この利点にはコストが伴います: 追加のGPUが必要になります。
並行性、非同期性、並列性は、しばしば混同される異なる概念です。この記事で「非同期トレーニング」と言うとき、私たちは特定のものを意味します: 生成とトレーニングが並行して実行され、効果的に重複すること; 推論プールが次のバッチのロールアウトを生成している間、トレーニングプールが現在のバッチの勾配を計算しています。これは本質的に分離型モードの能力です。コロケート型モードは、スリープ/ウェイクメモリ管理や高速インプレース再シャーディングなどの最適化から利益を得ることができますが、真の同時重複を達成することはできません; 推論とトレーニングは依然として同じGPUで交代で行われます。意味のある非同期重複を実装するこの調査のすべてのライブラリは、分離型モードを基盤として使用しています。
1.3 生成ボトルネック
推論モデルのRLトレーニングでは、自己回帰生成が実時間を支配します。数学やコーディングタスクの単一ロールアウトは、8K–64Kトークンの連鎖思考推論を生成することができます(QED-Nanoロールアウト長を参照)。
これを具体的に理解するために、単一H100 80GB GPU(bf16、量子化なし、オフラインスループットモード)でのvLLMベンチマークを考えてみてください。7Bモデル(DeepSeek-R1-Distill-Qwen-7B)は約6,300出力トークン/秒の総合スループットを達成します; 32Bモデル(DeepSeek-R1-Distill-Qwen-32B)は約1,200出力トークン/秒に低下します。これらはすべての同時リクエストにわたる総スループットであり、シーケンスがGPUを共有する数に関係なく、推論エンジンが1秒あたりに処理できる数です。
次に、典型的なGRPOトレーニングステップを考えてみてください: G=8完了/プロンプト × 64プロンプト/バッチ = 512ロールアウト。生成にはどれくらい時間がかかりますか?
ロールアウトごとの出力長
総出力トークン数(512ロールアウト)
1×H100での時間(7B @ 約6Kトークン/秒)
1×H100での時間(32B @ 約1.2Kトークン/秒)
2Kトークン(短いCoT)
8Kトークン(中程度CoT)
32Kトークン(長いCoT)
短い場合でも(7Bモデルで2Kトークンを生成)、生成だけでもトレーニングステップごとに数分を消費します。最先端の推論モデルがますます動作する長い側では、単一の生成フェーズが1GPUで数時間かかることがあります。8つの推論GPUにスケーリングすると、これらの時間は約8分の1になります(線形スループットスケーリングを仮定)が、それでも32Bモデルでの32Kトークンのロールアウトはステップごとに約28分かかります。
遅延問題はこれをさらに悪化させます。GRPOのようなグループベースのアルゴリズムでは、プロンプトごとにG個の完了をサンプリングします。最も遅い完了が終わるまでバッチは進めません。思考連鎖(Chain-of-thought)の出力長は非常に変動が大きく、単一のプロンプトが1Kから32Kトークンの範囲の完了を生成する可能性があります。バッチは最も長い完了によって制御され、連続バッチングはこれを部分的にしか緩和しません:短いシーケンスは新しい作業のためにスロットを解放しますが、GRPOグループの最後のシーケンスは依然としてグループの報酬計算とトレーニングステップをブロックします。
1.4 核心となる洞察
この調査のすべてのライブラリは、同じアーキテクチャ原則に独立して収束しています:推論GPUとトレーニングGPUを物理的に分離し、重みを非同期的にプッシュすることで、生成が止まることなく、トレーニングが待たされることがないようにします。
推論プールは継続的に実行され、完了したロールアウトをバッファに供給します。トレーニングプールはバッファから引き出し、勾配更新を計算し、定期的に新しい重みを推論プールにプッシュして同期を保ちます。2つのループはそれぞれのペースで実行され、バッファによって分離されています。
この設定は非常にスケーラブルですが、新しい種類の問題を導入します:陳腐化(古いポリシーの下で生成されたロールアウト)、重み同期オーバーヘッド、部分的なロールアウトの処理などです。この記事の残りの部分では、現在のオープンソースライブラリがこれらの問題にどのように対処しているかを詳細に分析します。
- 調査対象ライブラリ
GitHub ⭐ (2026年3月)
inclusionAI/Ant Group
github.com/inclusionAI/AReaL
github.com/OpenPipe/ART
github.com/NousResearch/atropos
github.com/radixark/miles
github.com/NVIDIA-NeMo/RL
github.com/sail-sg/oat
github.com/allenai/open-instruct
github.com/ServiceNow/PipelineRL
github.com/PrimeIntellect-ai/prime-rl
github.com/alibaba/ROLL
github.com/NovaSky-AI/SkyRL
github.com/THUDM/slime
github.com/meta-pytorch/torchforge
github.com/google/tunix
github.com/verl-project/verl
github.com/PrimeIntellect-ai/verifiers
- 比較フレームワーク: 7つの軸
非同期RLライブラリの急速に拡大するエコシステムを理解するために、7つの直交する比較軸を提案します。各軸は、ライブラリのパフォーマンス、複雑さ、トレードオフを形作る基本的な設計上の決定を捉えています。
軸1 – オーケストレーションと並行性プリミティブ: 分散コンポーネントがどのように調整されるか(Rayアクター、asyncio、pub/sub、HTTP)。
軸2 – ロールアウトバッファ設計: ロールアウトが推論からトレーニングにどのように流れるか。
軸3 – 重み同期プロトコル: 更新された重みが推論サーバーにどのように到達するか、およびシステムがそれを受け入れるために一時停止する必要があるか、生成を続けるか。
軸4 – 陳腐化管理: オフポリシーのロールアウトがどのように処理されるか:バージョン拒否、深度制限、または重要度サンプリング補正。
軸5 – 部分ロールアウト処理: 重み更新がシーケンスの途中で到着したとき、進行中の生成に何が起こるか。
軸6 – LoRAトレーニングサポート: 一般的なLoRAサポートと、アダプターのみのパラメータをトレーニングおよび同期できるかどうか、これによりサブミリ秒の重み転送が可能になります。
軸7 – 分散トレーニングバックエンドと並列処理: トレーニングにどの並列化戦略が使用されるか、これにより最大モデルサイズが制約されます。
軸1: オーケストレーションと並行性プリミティブ
システムはその分散コンポーネントをどのように調整しますか?
オーケストレーションフレームワークの選択は、プログラミングモデル、障害セマンティクス、およびスケーラビリティの上限を決定します。ライブラリごとの実装詳細を列挙するのではなく、状況は4つのオーケストレーションタイプにきれいに分解されます。これらは抽象化レベル、障害モデル、および展開要件が異なる基本的な調整パラダイムです:
オーケストレーションタイプ
分散アクターモデル
コンポーネントはアクターであり、メールボックスを持つ分離されたステートフルプロセスで、スケジューリング、リソース配置、フォールトトレランス、およびオブジェクト転送を処理するランタイムによって管理されます。通信は非同期RPC / フューチャー / オブジェクトストアを介して行われます。
Ray: verl, SkyRL, NeMo-RL, SLIME, MILES, ROLL, OAT, open-instruct. Monarch: TorchForge.
最も豊富な抽象化;スケジューリングとフォールトトレランスをすぐに解決します。重要なランタイム依存関係とフレームワーク固有のデバッグオーバーヘッドを追加します。
ネイティブPython並行性
コンポーネントはスレッド、コルーチン(asyncio)、マルチプロセッシングです。
verifiers-rl, PipelineRL(プール内), ART(asyncio)
最小限の依存関係、デバッグが容易、完全な制御。マルチノード通信のための追加のIPC(Redis、HTTP、NCCL)と組み合わせない限り、単一ノードに限定されます。
Pub/Subメッセージバス
コンポーネントは、追加専用ストリームまたはメッセージキューを介して通信する分離されたプロデューサーとコンシューマーです。それ自体はオーケストレーションではなく、独立して実行されるプール間のデータ転送層です。
PipelineRL(プール間: Redis XADD)
RPCなしでプール境界を越えたクリーンな分離。プロセスのライフサイクル、スケジューリング、または障害回復を管理しません;別のオーケストレーションタイプと組み合わせる必要があります。
HTTPマイクロサービス
コンポーネントはREST APIを介して通信する独立したサービスです。言語に依存せず、最大限の分離を実現します。
任意の推論サーバー、任意の言語、共有状態ゼロ。最高のレイテンシ(NCCLを使用する場合);共有オブジェクトストアなし;フォールトトレランスはユーザーの責任です。
Tunixに関する注記: Tunix(Google)は、ThreadPoolExecutorとJAXネイティブのメッシュモデルを使用します。
上記の表は顕著なパターンを明らかにしています:調査した16のライブラリのうち8つが、オーケストレーションのバックボーンとしてRayを使用しています。これは偶然ではなく、アクターモデルとRLトレーニングの構造との深いアーキテクチャ上の適合を反映しています。Rayの背後にある企業であるAnyscaleによるLLM向けオープンソースRLライブラリの調査は、この収束を確認しています。大規模なRLトレーニングには、本質的に異種のコンポーネント(推論エンジン、トレーニングエンジン、環境、報酬モデル)が含まれ、これらはクラスター全体で、多くの場合異なるハードウェアタイプで、異なるスケーリング要件と障害モードで調整される必要があります。Rayのアクターモデルはこれに直接マッピングします:
アクターの分離と異種リソース。各RLコンポーネント(vLLM推論サーバー、FSDPトレーナー、報酬モデル、環境プール)は、独自のリソース要件(num_gpus)を持つRayアクターになります。
スケジューリングと自動スケーリング。Rayのスケジューラーは、クラスター全体に異種アクターを配置する組み合わせ問題を処理します。生成がトレーニングよりも8倍多くのGPU時間を必要とする場合、Rayに推論アクターを独立してスケーリングするように指示するだけです。
フォールトトレランス。長いRLトレーニング実行(数日から数週間)は、GPU障害、OOMキル、ネットワークパーティションに対して脆弱です。Rayのアクター再起動ポリシーとオブジェクトストアレプリケーションは、生のasyncioやマルチプロセッシングでは重要なカスタムインフラストラクチャを必要とする回復力を提供します。
ゼロコピーデータ転送のためのオブジェクトストア。ロールアウトデータは大きく、非常に長いコンテキスト推論ではバッチごとに数十GBになることがあります。Rayの共有メモリオブジェクトストアは、同じノード上のアクター間でゼロコピー転送を可能にし、通常マルチプロセッシング.Queueに伴うシリアル化オーバーヘッドを回避します。
エコシステムの成熟度。Rayは2017年から大規模で実戦テストされており、数千のGPUでの本番展開があります。デバッグオーバーヘッドは現実的です(Rayダッシュボード、分散スタックトレース、配置グループの障害)が、同等の調整をゼロから構築するという代替案は、マルチノードスケールではさらに悪いです。とはいえ、Rayは重い依存関係です:独自のスケジューラー、オブジェクトストア、ダッシュボードを引き込み、すべてのチームが必要とするわけではない運用上の複雑さを追加します。これがまさに、PRIME-RL、PipelineRL、AReaLのようなライブラリが軽量なネイティブPython調整(asyncio、スレッド、Redisストリーム)を選択した理由です---フルスタックを制御し、展開トポロジが固定されている場合、標準Pythonの単純さとデバッグの容易さは、Rayが提供する利便性を上回ることが多いです。
コストは、重要なランタイムへの強固な依存関係です。このトレードオフは価値がある場合があります、特に本番規模のトレーニング(64+ GPU、複数日の実行、複雑な報酬計算)では。
Rayのアクターモデルがフィールドの主要なプレーヤーである一方で、MonarchはMetaからGPUワークロード向けに特別に構築された新しいPyTorchネイティブの分散アクターフレームワークとして登場しました。Rayと同様に、Monarchはアクターモデルに基づいています;コンポーネントはメッセージを介して通信するメールボックスを持つ独立したアクターですが、汎用分散ランタイムではなく、PyTorch/CUDAエコシステム向けに一から設計されています。
Monarchは、非同期RLに特に関連するいくつかの機能を提供します。Monarchを使用した非同期RLの実装例(GPU Mode講義シリーズから)は、アーキテクチャを示しています:ジェネレーター、リプレイバッファ、トレーナーはMonarchアクターとしてモデル化され、リプレイバッファは遅延ロールアウトからのレイテンシ変動を吸収し、RDMA重み同期がトレーニングをブロックすることなく更新されたパラメータをジェネレーターにプッシュします。パターンは構造的にRayベースの設計(verl、SkyRL、open-instruct)と同一ですが、純粋なPyTorchネイティブプリミティブで実装されています。
軸2: ロールアウトバッファ設計
生成されたロールアウトは推論からトレーニングにどのように流れ、パイプラインの深さはどれくらいですか?
バッファは生成とトレーニングの間に位置するデータ構造です。その深さは最大の非同期度を制御し、したがって最大の陳腐化を制御します。
バッファなし(同期)
TRL(現在)、ART(すべて収集してからトレーニング)
生成とトレーニングが厳密に交互に行われる;陳腐化ゼロ、アイドル時間最大
ダブルバッファ(1ステップ先)
verifiers-rl、SLIME(非同期モード)、MILES、OAT
トレーニングステップNの開始時に生成N+1を送信;正確に1バッチをオーバーラップ
境界付き非同期キュー
SkyRL、verl(完全非同期)、NeMo-RL、ROLL、PRIME-RL、TorchForge、Tunix、open-instruct(async_steps
max_head_offpolicyness
複数のバッチが処理中;古さはキューの容量によって制限される
無制限 / ストリーム
PipelineRL(Redisストリーム)、SLIME(完全非同期モード)、Atropos
連続生成;古さは明示的なバージョン管理によってのみ制限される
ダブルバッファパターンは、同期トレーニングから非同期トレーニングへの最も単純なアップグレードです:それはちょうど1回の生成と1回のトレーニングステップを重ね合わせ、最大でも1ステップのポリシー遅延を導入します。
一方、より深いキューはスループットを向上させますが、古さの管理が必要です。
バッファは、処理中のデータの量を制御します。しかし、データは方程式の半分に過ぎません。もう半分は、それらのロールアウトが古くなる前に、更新された重みを推論サーバーに戻すことです。それが重み同期の出番です。
軸3:重み同期プロトコル
勾配更新後、新しいモデル重みはどのようにして推論サーバーに到達するのでしょうか?
範囲注記:この軸は、推論とトレーニングが別々のGPUプールで実行される分離モードに焦点を当てています。なぜなら、それが非同期オーバーラップ(したがって重み同期設計)が実際に重要となるデプロイメントトポロジーだからです。同居セットアップ(両方の役割に同じGPUを使用)は本質的に同期しており、以下で議論される転送/割り込みのトレードオフに直面しません。
これは、最もアーキテクチャ的に重要な軸です。プロトコルは同期遅延、割り込み粒度、および部分的なロールアウトが可能かどうかを決定します。
ここで重要な区別があります:転送メカニズムと割り込みモデルです。ほとんどのライブラリは、重み転送を開始する前に、粗い境界(HTTPリクエスト、完全なバッチ、あるいは完全なトレーニングステップ)で生成を一時停止します。PipelineRLは例外です:それは決して生成を停止しません。
転送メカニズム:
PipelineRL、SkyRL、SLIME、MILES、ROLL、OAT、NeMo-RL、PRIME-RL、open-instruct、AReaL
NCCL + バケティング
KV + 共有メモリ
ファイルシステム + HTTP
PRIME-RL、AReaL、ART
CUDA IPC(ゼロコピー)
ファイルシステム + 再起動
割り込みモデルでは、生成はいつ新しい重みを受け入れるために一時停止するのでしょうか?
ここがPipelineRLが他のすべてのライブラリと根本的に異なる点です。各ライブラリを個別にリストするのではなく、状況は5つの概念的な階層に集約され、最も細かいものから最も粗い割り込み粒度の順に並べられています:
割り込み粒度
なし(処理中、フォワードパスごと)
シーケンスは決して停止しません。重みの交換はトークンデコードステップの間(約1-10msの間隔)に行われます。実行中のシーケンスは新しい重みでシームレスに続行されます。
PipelineRL、open-instruct(オプトイン)
HTTPリクエストごと(中止 + 再同期)
処理中のHTTPリクエストは中止されます。部分的なトークンは、プレフィックス再開メカニズムで再送信されるか、リトライのために再利用されます。
SkyRL、SLIME、MILES
ソフトポーズ(処理中のものを自然に終了させる)
進行中のものが自然に終了する間、新しい生成リクエストは受け入れられません。一度すべて終了すると、重みが同期され、生成が再開されます。
PRIME-RL、AReaL、open-instruct(デフォルト)、verl(非同期)
トレーニングステップ / バッチごと(ブロッキング)
生成は完全に完了しなければなりません。トレーナーと推論エンジンは互いに順番にブロックし合います。
NeMo-RL、ROLL、OAT、TorchForge、Tunix、verifiers-rl、Atropos
「決して停止しない」階層は、他のすべてのものとは質的に異なります:例えば、PipelineRLは推論エンジンにフックし、ロックがトランスフォーマーフォワードパスごと(1シーケンスの1トークンステップ)に取得および解放されるようにします。重み更新は最大でも1フォワードパス(約数ミリ秒)待機し、すべてのパラメータを交換し、生成は直ちに再開されます。他のすべてのライブラリは、より粗い境界(1つのHTTPリクエスト(約数百ミリ秒)から完全なバッチ境界(約数秒)まで)で生成を停止します。
重み同期は、新しい重みがいつ到着するかを制御します。しかし、非同期トレーニングは、ロールアウトが常にあるポリシーバージョンの下で生成されており、その生成中のポリシーがトレーナーよりも数勾配ステップ遅れている可能性があることを意味します。ライブラリがこのポリシー遅延をどのように処理するかが、古さの管理です。
軸4:古さの管理
生成されたロールアウトが、トレーニング中のものよりも古いポリシーから来る可能性があるという事実を、システムはどのように処理するのでしょうか?
生成とトレーニングが重なると、サンプルはオフポリシーになります。この古さを管理するために、3つの直交する戦略が出現しており、ほとんどのプロダクションシステムは複数を組み合わせています:
戦略1:サンプルごとのバージョン拒否。すべてのサンプルは、それを生成した整数のポリシーバージョンでタグ付けされます。トレーニング時には、そのバージョンが現在のポリシーからしきい値以上遅れているサンプルは、損失計算に入る前にハードドロップされます。シンプルで正確ですが、破棄されたサンプルの生成に費やされた貴重な計算を無駄にします。
戦略2、深さ制限。生成とトレーニングの間のキューまたはバッファには、制限された容量(または明示的な古さゲート)があり、アーキテクチャ的にどのサンプルがどれだけ遅れるかを制限します。これは、深さ=1(1ステップ先のダブルバッファリング、構成的に古さは不可能)から、バージョンギャップに関連した明示的な容量式まで様々です。サンプルごとのバージョン追跡は不要です;制限は強制されます。
原文を表示
Back to Articles Keep the Tokens Flowing: Lessons from 16 Open-Source RL Libraries
Upvote 2

TL;DR -- For those of you who don't have time to read 5,000 words about async RL plumbing (we get it, you have models to train):
The problem: In synchronous RL (reinforcement learning) training, data generation (model inference to create data samples) dominates wall-clock time -- a single batch of 32K-token rollouts on a 32B (32-billion parameter) model can take hours, while the GPUs used for training remain idle.
The solution everyone converged on: Disaggregate (separate) inference and training onto different GPU pools, connect them with a rollout buffer (temporary storage for model outputs), and transfer weights asynchronously (without waiting), so neither side waits for the other.
We surveyed 16 open-source libraries that implement this pattern and compared them across 7 axes: orchestration primitives, buffer design, weight sync protocols, staleness management, partial rollout handling, LoRA support, and distributed training backends.
Key findings: Ray dominates orchestration (8/16 surveyed distributed computing libraries). The NCCL (NVIDIA Collective Communications Library) broadcast is the default method for transferring model weights. Staleness management refers to how outdated data samples are handled, ranging from simply dropping old samples to using advanced importance-sampling correction. LoRA (Low-Rank Adaptation) training is sparsely supported. Distributed MoE (Mixture of Experts) support is the emerging differentiator.
If you'd rather skip straight to the good part, here's the full comparison table (no reading required, we won't judge).
But seriously, if you stick around, you might learn a thing or two about why your GPUs are idle 60% of the time.
- Motivation: From synchronous RL training to async architectures 1.1 How TRL Does RL Training Today
1.2 Colocated vs. Disaggregated Training
1.3 The Generation Bottleneck
1.4 The Core Insight
- Libraries Surveyed
- The Comparison Framework: Seven Axes Axis 1: Orchestration & Concurrency Primitive
Axis 2: Rollout Buffer Design
Axis 3: Weight Synchronisation Protocol
Axis 4: Staleness Management
Axis 5: Partial Rollout Handling
Axis 6: LoRA Training Support
Axis 7: Distributed Training Backend & Parallelism
- Global Overview: Sixteen Libraries at a Glance
- The Next Wave: Design Implications 5.1 Critic-Free Algorithms: Memory Freed, But Weight Sync Pressure Increases
5.2 Process Rewards: A New Synchronisation Barrier
5.3 Multi-Agent Co-Evolution: The Straggler Problem Compounds
5.4 Training-Inference Mismatch: The Deepseek v3.2 MoE Case Study
5.5 Distillation: The Same Async Problem Under a Different Name
- Design Choices for TRL's Async Trainer Design Principle: Keep Orchestration Lightweight
- Bounded Queue with Per-Token model_version
- NCCL Weight Sync with Packed Transfers
- Partial Rollout Support for Agentic Workloads
- Motivation: From synchronous RL training to async architectures
Async RL training has emerged as the dominant paradigm for post-training at scale. Several trends in modern post-training have made synchronous training loops nearly impossible to scale:
Long rollouts from reasoning models. Chain-of-thought training produces very long rollouts, and a single synchronous generation batch can take hours to complete on a single GPU. During all of that time, training GPUs sit completely idle.
Value-function-free trainers like GRPO use group-relative advantages. This means generating up to G times more rollouts per prompt, and the entire batch is gated by the slowest completion in the group.
The rise of agentic RL training. When models interact with tools, sandboxes, and external environments across multi-turn trajectories, rollout lengths and latencies become highly variable. A simple API call might return in seconds, while a complex reasoning chain with tool use can run for minutes or hours. MiniMax's Forge framework, used to train MiniMax-M2.5, illustrates the scale this reaches in practice: context lengths up to 200K tokens, over a hundred thousand distinct agent scaffolds and environments, and daily throughput on the order of millions of samples. At this scale, any synchronous barrier between generation and training becomes a severe bottleneck. The straggler problem alone (where a handful of slow rollouts block an entire batch) can idle hundreds of GPUs.
The open-source ecosystem has converged on a common architectural response: disaggregate inference from training onto separate GPU pools, connect them with a rollout buffer, and let both sides run concurrently.
We are developing a new async trainer for TRL, one of the most widely used libraries for model post-training. To guide our design, we surveyed sixteen open-source libraries that were built from the ground up around asynchronous training and compared them across seven axes: orchestration primitives, buffer design, weight sync protocols, staleness management, partial rollout handling, LoRA support, and distributed training backends. This article distills the design principles we extracted from that survey.
Beyond RL, the need for async infrastructure is increasingly evident. For example, on-policy distillation, where a student generates sequences and a teacher scores them, mirrors GRPO but swaps the reward function for a teacher forward pass. Recognizing this structural similarity, everything in this survey applies equally to async distillation. We'll return to this broader point in Section 5.
1.1 How TRL Does RL Training Today
TRL's current GRPOTrainer
training_step()
Looking at the GRPOTrainer
Prompt sampling: draw a batch of prompts from the dataset. Nothing crazy here, let's continue.
Generation, calls model.generate()
Reward scoring: evaluate each completion against one or many reward functions.
Advantage computation
Forward and backward passes: compute the clipped policy gradient loss and backpropagate.
Optimizer step, update model weights.
Weight sync, push updated weights to the inference engine (vLLM) so the next generation uses the new policy.
Each phase blocks until completion before the next begins. The timeline looks like this:
TRL offers the steps_per_generation
The library also supports running vLLM in server
1.2 Colocated vs. Disaggregated Training
Before discussing async training, it is essential to understand the two deployment topologies for RL training with a separate inference engine:
Colocated mode places inference and training on the same set of GPUs. A single GPU (or TP group) holds both the training model (under FSDP or ZeRO) and the inference engine (vLLM or SGLang). Only one role is active at a time: during generation, the training model's parameters may be offloaded or resharded into an inference-friendly layout (e.g., from FSDP shards to vLLM's tensor-parallel layout); during training, the inference engine is paused or put to sleep. Weight "sync" is essentially free; it is at most an in-place resharding on the same GPU, not a network transfer. The advantage of the colocated mode is simplicity and cost; you need fewer total GPUs. The fundamental limitation is that inference and training cannot overlap. For example, here is the Trl with vllm in colocate_mode
Disaggregated mode places inference and training on separate GPU pools. The inference pool runs vLLM or SGLang continuously; the training pool runs the optimizer continuously. The two pools communicate via a weight synchronisation protocol (NCCL broadcast, filesystem checkpoint, HTTP, etc.) and a data transfer mechanism (Ray object store, Redis streams, shared memory, etc.)
The biggest advantage of the disaggregated mode is that inference and training can run concurrently. While the trainer computes gradients on batch N, the inference pool is already generating rollouts for batch N+K, enabling async training. However, this benefit comes at a cost: additional GPUs are required.
Concurrency, asynchronicity, and parallelism are distinct concepts that often get conflated. In this article, when we say "async training," we mean something specific: generation and training running in parallel, with effective overlap; the inference pool is producing the next batch of rollouts while the training pool is computing gradients on the current batch. This is fundamentally a disaggregated-mode capability. Colocated mode can benefit from optimisations like sleep/wake memory management or fast in-place resharding to speed up inference, but it cannot achieve true simultaneous overlap; inference and training still take turns on the same GPUs. Every library in this survey that implements meaningful async overlap uses disaggregated mode as the foundation.
1.3 The Generation Bottleneck
In RL training for reasoning models, autoregressive generation dominates wall-clock time. A single rollout for a math or coding task can produce 8K–64K tokens of chain-of-thought reasoning (see QED-Nano rollout lengths).
To ground this concretely, consider vLLM benchmarks on a single H100 80GB GPU (bf16, no quantisation, offline throughput mode). A 7B model (DeepSeek-R1-Distill-Qwen-7B) achieves ~6,300 output tokens/s aggregate throughput; a 32B model (DeepSeek-R1-Distill-Qwen-32B) drops to ~1,200 output tokens/s. These are total throughput across all concurrent requests, the number the inference engine can push through per second, regardless of how many sequences share the GPU.
Now consider a typical GRPO training step: G=8 completions per prompt × 64 prompts/batch = 512 rollouts. How long does generation take?
Output length per rollout
Total output tokens (512 rollouts)
Time on 1×H100 (7B @ ~6K tok/s)
Time on 1×H100 (32B @ ~1.2K tok/s)
2K tokens (short CoT)
8K tokens (medium CoT)
32K tokens (long CoT)
Even at the short end (2K tokens generated with a 7B model), generation alone consumes several minutes per training step. At the long end, where frontier reasoning models increasingly operate, a single generation phase can take hours on one GPU. Scaling to 8 inference GPUs divides these times by roughly 8× (assuming linear throughput scaling), but even then, 32K-token rollouts on a 32B model still take ~28 minutes per step.
The straggler problem compounds this further. In group-based algorithms like GRPO, you sample G completions per prompt. The batch cannot proceed until the slowest completion finishes. Chain-of-thought output lengths are highly variable; a single prompt might produce completions ranging from 1K to 32K tokens. The batch is gated by the longest completion, and continuous batching only partially mitigates this: shorter sequences free up slots for new work, but the last sequence in a GRPO group still blocks the group's reward computation and training step.
1.4 The Core Insight
Every library in this survey has independently converged on the same architectural principle: physically separate inference GPUs from training GPUs, and push weights asynchronously, so generation never stops and training never waits.
The inference pool runs continuously, feeding completed rollouts into a buffer. The training pool pulls from the buffer, computes gradient updates, and periodically pushes new weights back to the inference pool to keep it in sync. The two loops run at their own pace, decoupled by the buffer.
This setup is highly scalable, but it introduces a new class of problems: staleness (rollouts generated under an old policy), weight synchronisation overhead, partial rollout handling, etc. The rest of this article dissects in detail how current open-source libraries address these issues.
- Libraries Surveyed
GitHub ⭐ (Mar. '26)
inclusionAI/Ant Group
github.com/inclusionAI/AReaL
github.com/OpenPipe/ART
github.com/NousResearch/atropos
github.com/radixark/miles
github.com/NVIDIA-NeMo/RL
github.com/sail-sg/oat
github.com/allenai/open-instruct
github.com/ServiceNow/PipelineRL
github.com/PrimeIntellect-ai/prime-rl
github.com/alibaba/ROLL
github.com/NovaSky-AI/SkyRL
github.com/THUDM/slime
github.com/meta-pytorch/torchforge
github.com/google/tunix
github.com/verl-project/verl
github.com/PrimeIntellect-ai/verifiers
- The Comparison Framework: Seven Axes
To make sense of the rapidly expanding ecosystem of async RL libraries, we propose seven orthogonal axes of comparison. Each axis captures a fundamental design decision that shapes the library's performance, complexity, and trade-offs.
Axis 1 – Orchestration & Concurrency Primitive: how distributed components are coordinated (Ray actors, asyncio, pub/sub, HTTP).
Axis 2 – Rollout Buffer Design: how rollouts flow from inference to training.
Axis 3 – Weight Synchronisation Protocol: how updated weights reach inference servers, and whether the system must pause to accept them or continue generating.
Axis 4 – Staleness Management: how off-policy rollouts are handled : version rejection, depth bounding, or importance-sampling correction.
Axis 5 – Partial Rollout Handling: what happens to in-flight generations when a weight update arrives mid-sequence.
Axis 6 – LoRA Training Support: General LoRA support and whether adapter-only parameters can be trained and synced, enabling sub-millisecond weight transfers.
Axis 7 – Distributed Training Backend & Parallelism: what parallelism strategy is used for training, constraining max model size.
Axis 1: Orchestration & Concurrency Primitive
How does the system coordinate its distributed components?
The choice of orchestration framework determines the programming model, failure semantics, and scalability ceiling. Rather than listing per-library implementation details, the landscape decomposes cleanly into four orchestration types, fundamental coordination paradigms that differ in abstraction level, failure model, and deployment requirements:
Orchestration Type
Distributed Actor Model
Components are actors, isolated stateful processes with mailboxes, managed by a runtime that handles scheduling, resource placement, fault tolerance, and object transfer. Communication is via asynchronous RPC / futures / object store.
Ray: verl, SkyRL, NeMo-RL, SLIME, MILES, ROLL, OAT, open-instruct. Monarch: TorchForge.
Richest abstraction; solves scheduling and fault tolerance out-of-the-box. Adds a non-trivial runtime dependency and framework-specific debugging overhead.
Native Python Concurrency
Components are threads, coroutines (asyncio
multiprocessing
verifiers-rl, PipelineRL (intra-pool), ART (asyncio
Minimal dependencies, easy to debug, full control. Limited to single-node unless paired with additional IPC (Redis, HTTP, NCCL) for multi-node communication.
Pub/Sub Message Bus
Components are decoupled producers and consumers communicating through append-only streams or message queues. Not orchestration per se, a data transport layer between independently running pools.
PipelineRL (inter-pool: Redis XADD
Clean decoupling across pool boundaries without RPC. Does not manage process lifecycle, scheduling, or fault recovery; must be paired with another orchestration type.
HTTP Microservices
Components are independent services communicating via REST APIs. Language-agnostic, maximum decoupling.
Any inference server, any language, zero shared state. Highest latency (if NCCL); no shared object store; fault tolerance is the user's responsibility.
Note on Tunix: Tunix (Google) uses a JAX-native mesh model with ThreadPoolExecutor
The table above reveals a striking pattern: eight of the sixteen libraries surveyed use Ray as their orchestration backbone. This is not a coincidence; it reflects a deep architectural fit between the actor model and the structure of RL training. A survey by Anyscale (the company behind Ray) of open-source RL libraries for LLMs confirms this convergence. RL training at large scales involves fundamentally heterogeneous components (inference engines, training engines, environments, reward models) that must be orchestrated across a cluster, often on different hardware types, with different scaling requirements and failure modes. Ray's actor model maps directly onto this:
Actor isolation and heterogeneous resources. Each RL component (vLLM inference server, FSDP trainer, reward model, environment pool) becomes a Ray actor with its own resource requirements (num_gpus
Scheduling and autoscaling. Ray's scheduler handles the combinatorial problem of placing heterogeneous actors across a cluster. When generation requires 8× more GPU-hours than training, you can just tell Ray to scale your inference actors independently.
Fault tolerance. Long RL training runs (days to weeks) are vulnerable to GPU failures, OOM kills, and network partitions. Ray's actor restart policies and object store replication provide resilience that would require significant custom infrastructure with raw asyncio
multiprocessing
Object store for zero-copy data transfer. Rollout data can be large, tens of GB per batch for very long-context reasoning. Ray's shared-memory object store enables zero-copy transfer between actors on the same node, avoiding serialization overhead that usually comes with multiprocessing.Queue
Ecosystem maturity. Ray has been battle-tested at scale since 2017, with production deployments on thousands of GPUs. The debugging overhead is real (Ray Dashboard, distributed stack traces, placement group failures), but the alternative, building equivalent coordination from scratch, is worse at the multi-node scale. That said, Ray is a heavy dependency: it pulls in its own scheduler, object store, and dashboard, adding operational complexity that not every team needs. This is exactly why libraries like PRIME-RL, PipelineRL, and AReaL opted for lightweight native-Python coordination (asyncio, threading, Redis streams) instead --- when you control the full stack and your deployment topology is fixed, the simplicity and debuggability of vanilla Python often outweigh the conveniences Ray provides.
The cost is a hard dependency on a non-trivial runtime. This trade-off can be worthwhile, especially for production-scale training (64+ GPUs, multi-day runs, complicated reward computation).
While Ray's actor model is the main player on the field, Monarch emerged as a new PyTorch-native distributed actor framework from Meta, purpose-built for GPU workloads. Like Ray, Monarch is based on the actor model; components are independent actors with mailboxes communicating via messages, but it is designed from the ground up for the PyTorch/CUDA ecosystem rather than being a general-purpose distributed runtime.
Monarch offers several capabilities particularly relevant to async RL. An example implementation of async RL with Monarch (from the GPU Mode lecture series) demonstrates the architecture: generators, a replay buffer, and a trainer are modelled as Monarch actors, with the replay buffer absorbing latency variance from straggler rollouts and RDMA weight sync pushing updated parameters to generators without blocking training. The pattern is structurally identical to Ray-based designs (verl, SkyRL, open-instruct) but implemented with pure PyTorch-native primitives.
Axis 2: Rollout Buffer Design
How do generated rollouts flow from inference to training, and how deep is the pipeline?
The buffer is the data structure sitting between generation and training. Its depth controls the maximum degree of asynchrony, and therefore the maximum staleness.
No buffer (synchronous)
TRL (current), ART (gather-all-then-train)
Generation and training alternate strictly; zero staleness, maximum idle time
Double-buffer (one-step-ahead)
verifiers-rl, SLIME (async mode), MILES, OAT
Submit generation N+1 at the start of training step N; overlap exactly one batch
Bounded async queue
SkyRL, verl (fully async), NeMo-RL, ROLL, PRIME-RL, TorchForge, Tunix, open-instruct (async_steps
max_head_offpolicyness
Multiple batches in flight; staleness bounded by queue capacity
Unbounded / stream
PipelineRL (Redis streams), SLIME (fully async mode), Atropos
Continuous generation; staleness bounded only by explicit version control
The double-buffer pattern is the simplest upgrade from synchronous to asynchronous training: it overlaps exactly one generation with one training step and introduces at most one step of policy lag !
Deeper queues, on the other hand, improve throughput but require staleness management.
The buffer controls how much data is in flight. But data is only half the equation. The other half is getting updated weights back to the inference servers before those rollouts go stale. That's where weight sync comes in!
Axis 3: Weight Synchronisation Protocol
How do new model weights reach the inference servers after a gradient update?
Scope note: This axis focuses on disaggregated mode, where inference and training run on separate GPU pools, since that is the deployment topology where async overlap (and therefore weight sync design) actually matters. Colocated setups (same GPUs for both roles) are inherently synchronous and do not face the transport/interrupt trade-offs discussed below.
This is the most architecturally consequential axis. The protocol determines sync latency, interrupt granularity, and whether partial rollouts are possible.
There is a critical distinction to make here: the transport mechanism and the interrupt model. Most libraries pause generation at a coarse boundary, an HTTP request, a full batch, or even a full training step, before initiating weight transfer. PipelineRL is the outlier: it never stops generating at all.
Transport mechanism:
PipelineRL, SkyRL, SLIME, MILES, ROLL, OAT, NeMo-RL, PRIME-RL, open-instruct, AReaL
NCCL + Bucketing
KV + Shared Memory
Filesystem + HTTP
PRIME-RL, AReaL, ART
CUDA IPC (Zero-copy)
Filesystem + Restart
In the interrupt model, when does the generation pause to accept new weights?
This is where PipelineRL fundamentally diverges from every other library. Rather than listing each library individually, the landscape collapses into five conceptual tiers, ordered from finest to coarsest interrupt granularity:
Interrupt Granularity
Never (In-flight per-forward-pass)
Sequences never stop. The weight swap happens between token decode steps (~1-10ms gap). Running sequences seamlessly continue with new weights.
PipelineRL, open-instruct (opt-in)
Per HTTP Request (Abort + Resync)
In-flight HTTP requests are aborted. Partial tokens are resubmitted with a prefix-resume mechanism or recycled for retry.
SkyRL, SLIME, MILES
Soft Pause (Drain in-flight)
No new generation requests are accepted while in-progress ones finish naturally. Once drained, weights are synced and generation resumes.
PRIME-RL, AReaL, open-instruct (default), verl (async)
Per Training Step / Batch (Blocking)
Generation must fully complete. The trainer and inference engine take turns blocking each other.
NeMo-RL, ROLL, OAT, TorchForge, Tunix, verifiers-rl, Atropos
The "never-stop" tier is qualitatively different from all others: PipelineRL, for example, hooks into the inference engine so that the lock is acquired and released per transformer forward pass (one token step for one sequence). A weight update waits at most one forward pass (~few ms), swaps all parameters, and generation resumes immediately. Every other library stops generation at a coarser boundary, from one HTTP request (~hundreds of ms) up to a full batch boundary (~seconds).
Weight sync controls when new weights arrive. But async training means rollouts are always being generated under some policy version, and that generating policy might be several gradient steps behind the trainer. How libraries handle this policy lag is staleness management.
Axis 4: Staleness Management
How does the system handle the fact that generated rollouts may come from an older policy than the one being trained?
Once generation and training overlap, samples become off-policy. Three orthogonal strategies have emerged for managing this staleness, and most production systems combine more than one:
Strategy 1: Per-sample version rejection. Every sample is tagged with the integer policy version that generated it. At training time, samples whose version falls behind the current policy by more than a threshold are hard-dropped before entering the loss computation. Simple and correct, but wastes the precious compute spent generating discarded samples.
Strategy 2, Depth Bounding. The queue or buffer between generation and training has a bounded capacity (or an explicit staleness gate), which architecturally limits how far behind any sample can be. This ranges from depth=1 (one-step-ahead double buffering, where staleness is impossible by construction) to explicit capacity formulas tied to version gaps. No per-sample version tracking is required; the bound is enf
関連記事
NVIDIA Cosmos World Foundation Modelsによる合成データのスケーリングと物理AI推論
ロボット動画生成のための NVIDIA Cosmos Predict 2.5 の LoRA/DoRA を用いたファインチューニング(9 分読了)
ロボット動画生成のための NVIDIA Cosmos Predict 2.5 の LoRA/DoRA を用いたファインチューニング
今日のまとめ
AI日報で今日の重要ニュースをまとめ読み