第6章:Multi-turn RL 与 Async Rollout
Single-turn vs Multi-turn RL 本质差异,长 trajectory 的 credit assignment 难题,verl/OpenRLHF 的 async rollout 工程实现
Tool RL 论文里看似简单的”GRPO 训练 agent”,在工业 scale 上跑会瞬间崩——long trajectory + multi-turn + sync rollout 是大规模训练的三大杀手。本章把”为什么同步训练在 agent RL 下崩、async rollout 怎么救命、verl/OpenRLHF 的工程实现细节”讲清,串起 verl Fully Async、OpenRLHF 0.8 Async、DORA、ART 等 2025 工程突破。
📑 目录
- 1. Single-turn vs Multi-turn RL 的本质差异
- 2. Long Trajectory 的三大工程难题
- 3. Sync Rollout 为什么崩
- 4. Async Rollout 的核心思想
- 5. verl Fully Async Trainer
- 6. OpenRLHF 0.8 Async RL
- 7. DORA / ART:其他 async 方案
- 8. Rollout 侧推理优化
- 自我检验清单
- 参考资料
1. Single-turn vs Multi-turn RL 的本质差异
1.1 形态对比
Single-turn(经典 RLHF):
prompt → LLM → response → reward
↑
一次 forward 搞定
Multi-turn(Agentic RL):
prompt → LLM → thought_1 → tool_call_1 → tool_result_1
→ thought_2 → tool_call_2 → tool_result_2
→ ...(可能 5-50 轮)
→ final_answer → reward
↑
十几次 LLM forward + tool 执行
1.2 训练复杂度差异
| 维度 | Single-turn | Multi-turn |
|---|---|---|
| Trajectory 长度 | < 2K token | 5K - 30K+ token |
| LLM forward / 样本 | 1 | 5-50 |
| 外部 IO | 无 | tool / API / sandbox 调用 |
| Reward 时机 | 末尾 | 末尾(更稀疏) |
| Credit assignment | 简单(short seq) | 极难(谁的 token 该担责) |
| Rollout 时间 | 几秒 | 几分钟到几小时 |
| 单步训练 batch 内方差 | 小 | 极大(短/长 trajectory 混在一起) |
🌟 核心问题:multi-turn rollout 时间是 train 时间的 5-50 倍,如果 sync 训练,GPU 长期空等 rollout——算力浪费 80%+。
2. Long Trajectory 的三大工程难题
2.1 ① Credit Assignment
5K token 的 trajectory,reward 只在末尾。哪些 token 应该被 reward 推、哪些 push down?
GRPO 的解法:整条 trajectory 的所有 token 共享 advantage——简单但粗糙。
问题:trajectory 中可能有”有用的 90%” + “废话的 10%“,共享 advantage 会让废话也被强化。
研究方向:
- Token-level reward shaping(每个 step 给细粒度信号)
- PRM(下章 self-improvement 也涉及)
- LLM-as-Judge 给中间步骤打分
2.2 ② Variable Length
batch 内 trajectory 长度差异巨大:
trajectory 1: 800 token (简单题)
trajectory 2: 5000 token (复杂多步)
trajectory 3: 1200 token
trajectory 4: 12000 token (超长)
Pad 到最长会浪费内存(80% 是 pad)。用 sequence packing 打包(把多个短 traj 拼一个 batch)是必需的。
2.3 ③ KV Cache 重用
multi-turn rollout 的每一 turn 实际上是”同一个对话历史 + 新 turn”——前面的 KV cache 应该可以复用。
但传统训练框架不复用,每次 turn 都从头跑 prefill——算力浪费。
vLLM 的 prefix cache(模块四第 2 章)在 rollout 阶段必须开。
3. Sync Rollout 为什么崩
3.1 经典 sync 流程
┌─────────────────────────────────────────────┐
│ Step 1: Rollout (5 minutes) │ ← GPU 跑推理
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 2: Train (30 seconds) │ ← GPU 跑 backward
└─────────────────────────────────────────────┘
↓
┌─────────────────────────────────────────────┐
│ Step 3: Rollout (5 minutes) │
└─────────────────────────────────────────────┘
↓
...
问题:
- Rollout 时 train GPU 闲
- Train 时 rollout GPU 闲
- Long trajectory 让单 step 几分钟——一天只能跑几百 step
3.2 数学:GPU 利用率
设 rollout 时间 ,train 时间 :
multi-turn agent 典型 :
🔥 同步训练 GPU 利用率 < 10%——一天烧 8 卡 H100($10000/月)只用了 800 块。
4. Async Rollout 的核心思想
4.1 把 Rollout 和 Train 完全解耦
Rollouter 进程 A: ──[ Rollout 1 ]──[ Rollout 2 ]──[ Rollout 3 ]──...
Rollouter 进程 B: ──[ Rollout 1 ]──[ Rollout 2 ]──...
Trainer 进程 : ──[ Train ]──[ Train ]──[ Train ]──...
↑
从 buffer 拿数据
- Rollouter 不停产生 trajectory,扔到 replay buffer
- Trainer 从 buffer 持续拉数据训练
- 两者独立扩缩容
4.2 关键技术挑战
① Off-policy 问题
Async 时,rollout 用的 policy(π_old)和 train 当下的 policy(π_θ)有偏差——传统 PPO 假设它们接近。
解法:
- 限制 staleness(rollout 和 train 的步数差 ≤ N)
- 用更大的 KL clip 容忍偏差
- Importance sampling 修正
② 数据流水
需要高效的 replay buffer(支持高频读写、过期数据清理)。
③ 模型权重同步
Trainer 训完 N 步,要把新权重同步到 Rollouter——这一步如果用 NCCL 慢,整条流水就卡。verl 用 ipc memory 内存共享,极快。
4.3 收益
| 指标 | Sync | Async |
|---|---|---|
| GPU 利用率 | 5-15% | 70-90% |
| 单 step 时间 | 几分钟 | 秒级 |
| 训练吞吐(traj/小时) | 几百 | 几千 |
| 同等成本下完成训练 | 1 周 | 2-3 天 |
🌟 Async rollout 对 multi-turn agent RL 不是 nice-to-have,是必需品。
5. verl Fully Async Trainer
ByteDance HybridFlow,2.35-2.67× 加速(Qwen2.5-7B,128 GPU)
5.1 架构
┌──────────────────────────────────────────────────┐
│ Ray Cluster │
└──────────────────────────────────────────────────┘
↓ ↓ ↓
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Rollout │ │ Rollout │ │ Trainer │
│ Worker × N │ │ Worker × N │ │ Worker │
│ (vLLM) │ │ (vLLM) │ │ (FSDP) │
└──────────────┘ └──────────────┘ └──────────────┘
↓ ↓ ↑
└─────────────────┴─────────────────┘
↓
┌──────────────────┐
│ Replay Buffer │
│ (Ray Actor) │
└──────────────────┘
↑
┌──────────────────┐
│ Weight Sync │
│ (Shared IPC mem) │
└──────────────────┘
5.2 配置示例(verl YAML)
trainer:
total_epochs: 5
n_gpus_per_node: 8
nnodes: 16
# 关键:async 模式
fully_async:
enable: true
max_staleness: 4 # rollout 落后 train 最多 4 步
algorithm:
algo: GRPO
group_size: 16
actor_rollout_ref:
rollout:
name: vllm
n_gpus_per_node: 4 # 4 卡专门 rollout
gpu_memory_utilization: 0.85
enable_chunked_prefill: true
enable_prefix_caching: true
actor:
n_gpus_per_node: 4 # 4 卡专门 train
optim:
lr: 1e-6
fsdp_config:
param_offload: false
optimizer_offload: false
5.3 关键设计
- Rollout / Trainer 物理分离(不同 GPU)
- Weight sync 用 IPC 共享内存(同一节点)+ NCCL (跨节点)
- Staleness 上限保证训练不被旧 rollout 拖偏
- Hybrid Engine:vLLM 推理 + FSDP 训练在同一 Ray 集群
5.4 实战要点
# verl 启动 fully async
python -m verl.trainer.main_ppo \
--config-path=configs/ \
--config-name=fully_async_grpo \
actor_rollout_ref.rollout.name=vllm \
trainer.fully_async.enable=true
6. OpenRLHF 0.8 Async RL
Ray + 模块化,适合研究
6.1 启用
python -m openrlhf.cli.train_ppo \
--train.async_enable \
--train.agent_func_path my_agent.py \
--policy_model Qwen/Qwen2.5-7B \
--reward_funcs my_reward.py
6.2 与 verl 的差异
| 维度 | verl | OpenRLHF |
|---|---|---|
| 哲学 | HybridFlow 一体化 | Ray + 模块拼装 |
| Async 实现 | 自研 IPC + 共享内存 | 标准 Ray Actor |
| 配置复杂度 | YAML 详尽 | 命令行参数 |
| 性能 | 2.35-2.67× | 1.8-2.2× |
| 学习曲线 | 高 | 中 |
| 适合 | 工业大规模 | 研究 / 中等规模 |
6.3 Agent RL 接口
OpenRLHF 0.8 加了 --train.agent_func_path ——你可以提供一个自定义 agent rollout 函数:
# my_agent.py
async def agent_rollout(prompt, model, tools):
"""自定义 multi-turn rollout 逻辑。"""
state = []
for turn in range(MAX_TURNS):
thought = await model.generate(state + [prompt])
if "FINAL ANSWER:" in thought:
return state + [thought]
tool_call = parse_tool_call(thought)
tool_result = await tools.call(**tool_call)
state.append(thought)
state.append(tool_result)
return state
OpenRLHF 调用这个函数完成 multi-turn rollout,然后把 trajectory 喂给 GRPO trainer。接口非常灵活——比 verl 更适合研究新 RL 算法。
7. DORA / ART:其他 async 方案
7.1 DORA(Meituan,2025)
- 为美团内部大规模 RL 训练设计
- 强调 failure recovery:rollout 节点挂了能自动恢复
- 多 task 训练时 task-level 隔离
7.2 ART(Microsoft)
- Microsoft Research 的 async RL 方案
- 专门为长 trajectory 优化
- 2025 论文发布,生态较新
7.3 选型
| 框架 | 推荐场景 |
|---|---|
| verl | 大公司、生产级、要求最高吞吐 |
| OpenRLHF | 研究、小中规模、要灵活定制 |
| DORA | 美团技术栈 / 类似企业内部 |
| ART | 微软栈 / 实验性 |
🍎 入门选 OpenRLHF,生产选 verl——这是 2026 的共识。
8. Rollout 侧推理优化
8.1 vLLM + Prefix Cache
multi-turn 中前几 turn 的 KV cache 重用 → 后续 turn prefill 极快。
rollout:
name: vllm
enable_prefix_caching: true
enable_chunked_prefill: true
max_num_batched_tokens: 8192
gpu_memory_utilization: 0.85
8.2 Sequence Packing
把多个短 trajectory 打包成一个 batch:
单 batch 装 4 条 trajectory:
[traj 1: 800 tokens]
[traj 2: 1200 tokens]
[traj 3: 600 tokens]
[traj 4: 900 tokens]
Total: 3500 tokens(打包),vs 4x 1200 = 4800 tokens(pad)
节省 ~30% 计算。verl 默认开。
8.3 Speculative Decoding(模块四第 5 章)
Rollout 阶段开 speculative decoding,~2× 加速——尤其适合 long trajectory。
8.4 KV Cache 量化
模块四第 4 章讲过的 KV cache 量化(INT8 / FP8)对长 rollout 显存友好,让 batch size 更大。
✅ 自我检验清单
- multi-turn 复杂度:能列出 ≥ 5 个 multi-turn 比 single-turn 难的维度
- 三大工程难题:能默写 credit assignment / variable length / KV cache reuse
- GPU 利用率公式:能推导 sync rollout 的利用率 =
- Async 核心:能画图解释 rollouter / trainer / replay buffer 三个组件
- Off-policy 问题:能解释 async 的 staleness 概念,以及怎么 mitigation
- verl Fully Async:能默写关键 YAML 配置项(fully_async.enable / max_staleness 等)
- OpenRLHF agent rollout 接口:能写一个自定义 multi-turn rollout 函数骨架
- rollout 推理优化:能列出 prefix cache / sequence packing / speculative / KV 量化 4 项
- 框架选型:能根据规模和场景给出 verl/OpenRLHF/DORA 推荐
📚 参考资料
框架文档
- verl Fully Async:verl.readthedocs.io
- verl Agentic RL:verl.readthedocs.io
- OpenRLHF Async RL:openrlhf.readthedocs.io
论文
- VerlTool (2025-09):arXiv 2509.01055 — async rollout 论文
- OpenRLHF (EMNLP demos 2025):paper