# 配方:完全异步策略训练器
**作者:** `https://github.com/meituan-search`
最后更新:2025 年 10 月 18 日。
本文档介绍了一个完全异步的 PPO 训练系统,该系统完全解耦了训练器(Trainer)和采样器(Rollouter),
支持异步样本生成和训练。
在该系统下,我们在使用 128 个 GPU 训练 Qwen2.5-7B 模型时,实现了 2.35 倍到 2.67 倍的性能提升,且未显著影响训练结果。
## 简介
### 背景
相比于共址(colocate)架构,分离式采样和训练架构可以更灵活地分配资源、设计更灵活的训练逻辑,从而解决由长尾问题(long-tail problems)导致的 GPU 利用率低和训练效率不高等问题。
`one_step_off_policy` 通过设计分离式架构并对一轮采样和训练进行异步处理,缓解了长时间采样的问题,并在一定程度上提高了训练效率。
然而,它强制使用一轮异步训练的数据,不够灵活,也无法完全消除长尾问题对训练效率的影响。
在 AReaL、Magistral、StreamRL 和 AsyncFlow 等其他框架中,基于分离式架构已经实现了异步训练和流式训练,并取得了成效。
我们借鉴了它们的方法,并将其应用到了 VERL 中。`fully_async_policy` 支持异步、流式和部分采样(partial rollout)训练。
通过合理设置资源分配和参数同步频率等参数,`fully_async_policy` 可以显著提高训练效率。
> Magistral https://arxiv.org/abs/2506.10910
>
> AReaL: A Large-Scale Asynchronous Reinforcement Learning System for Language
> Reasoning https://arxiv.org/abs/2505.24298
>
> StreamRL: Scalable, Heterogeneous, and Elastic RL for LLMs with Disaggregated Stream
> Generation https://arxiv.org/abs/2504.15930
>
> AsyncFlow: An Asynchronous Streaming RL Framework for Efficient LLM Post-Training https://arxiv.org/abs/2507.01663
>
### 核心贡献
* **资源隔离**:与 `hybrid_engine` 不同,采样器(Rollouter)和训练器(Trainer)使用独立的计算资源,并且需要分别指定它们占用的资源。
* **并行生成与训练**:在训练器(Trainer)进行训练的同时,采样器(Rollouter)正在生成新的样本。
* **多步异步**:相比于单步离策略(one step off policy),它支持从 0.x 步到多步的异步设置,使异步解决方案更加灵活。
* **NCCL 参数同步**:使用 NCCL(Nvidia Collective Communications Library)通信原语进行采样器(Rollouter)和训练器(Trainer)之间的参数通信。
* **流式推理与训练**:采样器(Rollouter)逐个样本生成数据,数据传输以单个样本作为最小传输单元。
* **异步训练与新鲜度控制**:通过设置参数 `async_training.staleness_threshold`,支持使用旧参数生成的样本进行训练。
* **部分采样(Partial Rollout)**:采样器(Rollouter)的推理过程支持部分采样逻辑。在参数同步期间,通过添加 `sleep()` 和 `resume()` 逻辑,它会保存正在进行的采样中的样本,并在下一次采样中继续使用,从而减少在参数同步期间等待进行中任务完成所花费的时间。
目前支持的使用模式是 `fsdp+vllm`。`vllm` 必须使用基于 `AgentLoop` 的服务器模式。
## 设计
`fully_async_policy` 的整体架构如图所示。`fully_async_policy` 主要包含四个部分:采样器(Rollouter)、消息队列(MessageQueue)、训练器(Trainer)和参数同步器(ParameterSynchronizer)。

1. 采样器(Rollouter)逐个样本生成序列,并将生成的样本放入消息队列(MessageQueue),生成速度由新鲜度(freshness)控制。
2. 消息队列(MessageQueue)用于临时存储采样器(Rollouter)生成的样本。
3. 训练器(Trainer)逐个样本从消息队列(MessageQueue)中获取样本。在获取了 `require_batches*ppo_mini_batch_size` 个样本后,它将执行训练。训练 `async_training.trigger_parameter_sync_step` 轮后,它将触发与采样器(Rollouter)的参数同步。
4. 参数同步器(ParameterSynchronizer)实现 NCCL 同步参数同步功能。
与基础方案相比,其优势在于:在共址(colocate)情况下,使用更多资源进行采样无法解决由长尾样本引起的空闲问题。
在我们进行资源隔离后,采样和训练的时间可能会比之前长(因为使用的资源较少),
但它们时间消耗的重叠减少了端到端的总时间消耗。

## 用法
### 参数说明
| 超参数 | 含义 |
| :------------------------------------------- | :------------------------------------------------------------------------------------------------- |
| `trainer.nnodes` | 训练器(Trainer)的节点数 |
| `trainer.n_gpus_per_node` | 训练器(Trainer)的每节点 GPU 数 |
| `rollout.nnodes` | 采样器(Rollouter)的节点数 |
| `rollout.n_gpus_per_node` | 采样器(Rollouter)的每节点 GPU 数 |
| `data.train_batch_size` | 在完全异步策略下,此值无效(默认为 0) |
| `data.gen_batch_size` | 在完全异步策略下,使用流式样本生成逻辑(默认为 1) |
| `rollout.total_rollout_steps` | 总采样步数(总采样样本数) |
| `rollout.test_freq` | 采样器(Rollouter)更新参数多少次后执行一次验证 |
| `actor_rollout_ref.actor.ppo_mini_batch_size` | `ppo_mini_batch_size` 是所有工作节点/GPU 的全局数量 |
| `async_training.require_batches` | FullyAsyncTrainer 一次性获取的 `ppo_mini_batch_size` 的数量 |
| `async_training.trigger_parameter_sync_step` | 指示 FullyAsyncTrainer 在执行参数同步前执行多少次本地更新 |
| `async_training.staleness_threshold` | 新鲜度控制 |
| `async_training.partial_rollout` | 是否执行部分采样(partial_rollout) |
| `async_training.use_rollout_log_probs` | 使用采样器(Rollouter)生成的 `log_probs` |
**详细解释:**
* `rollout.total_rollout_steps`
与共址(colocate)相比,可以通过 `train_batch_size` 和“步数”来对齐数量:
`rollout.total_rollout_steps = data.train_batch_size * step`。
* `async_training.trigger_parameter_sync_step`
在完全异步策略下,它表示训练器(Trainer)在与采样器(Rollouter)进行参数同步前执行多少次本地更新(即获取 `require_batches * ppo_mini_batch_size` 样本的次数)。
在采样器(Rollouter)和训练器(Trainer)的两次参数同步之间,训练器(Trainer)将处理
`trigger_parameter_sync_step* require_batches*ppo_mini_batch_size` 个样本。
为了公平地与共址(colocate)比较速度,`trigger_parameter_sync_step` 应设置为
`data.train_batch_size / (require_batches * ppo_mini_batch_size)`。
* `async_training.staleness_threshold`
在完全异步策略下,它表示允许使用的陈旧样本(stale samples)的最大比例。
* `staleness_threshold=0`,表示同步训练。
采样器(Rollouter)将在两次参数更新之间生成固定数量的样本,样本数量为:
$$rollout\_num = (trigger\_parameter\_sync\_step*require\_batches*ppo\_mini\_batch\_size)$$
* `staleness_threshold>0`,表示异步训练,可以设置为小数以实现更灵活的异步调用。
采样器(Rollouter)将在两次参数更新之间最多生成以下数量的样本:
$$rollout\_num = (1+staleness\_threshold)*(trigger\_parameter\_sync\_step*require\_batches*ppo\_mini\_batch\_size) - num\_staleness\_sample $$
`num_staleness_sample` 表示上次采样过程中超额生成的陈旧样本数量。
由于这是一个流式系统,采样器(Rollouter)会持续生成,训练器(Trainer)会持续消耗。如果采样器(Rollouter)速度较慢,训练器(Trainer)会提前触发参数同步,而采样器(Rollouter)实际上不会生成 `rollout_num` 个样本。
当采样器(Rollouter)速度足够快时,将 `staleness_threshold` 设置为 1 基本上等同于 `one_step_off_policy`。
为避免过多的陈旧样本影响训练精度,建议将此值设置为小于 1。
* `async_training.partial_rollout`
`partial_rollout` 仅在 `staleness_threshold>0` 时才真正生效。
* `async_training.use_rollout_log_probs`
在强化学习算法中,`log_probs` 与参数版本和 token 存在隐式关联。由于 PPO/GRPO/DAPO 等算法的设置,在计算重要性采样时,
`old_log_prob` 必须使用与采样参数和 token 相对应的 `log_probs`,以确保算法的正确性。在完全异步策略中,我们默认 `old_log_prob` 由采样器(Rollouter)计算,而不是由训练器(Trainer)计算。
* `async_training.require_batches`
在流式训练中,`require_batches` 应设置为 1,表示生成足够的 `ppo_mini_batch_size` 样本后进行训练。
在实际测试中,我们发现一次发放的样本数较少时,由于数据分发的顺序问题,可能导致训练不稳定和响应长度变长。
在此,我们额外提供了 `require_batches` 用于流式分发,并控制一次参与训练的样本数量。
### 支持的模式
1. **On policy pipeline(同步策略流水线)**:
1. **`trigger_parameter_sync_step=1`, `staleness_threshold=0`**
2. 采样器(Rollouter)一次性生成 `require_batches*ppo_mini_batch_size` 个样本,训练器(Trainer)获取这些样本进行训练,训练完成后,训练器(Trainer)和采样器(Rollouter)进行参数同步;
3. 在采样阶段,如果存在长尾样本但采样样本数很少,短样本无法填满空闲资源,导致部分资源浪费。
4. 如图 a 所示;
2. **Stream off policy pipeline(流式离策略流水线)**:
1. **`trigger_parameter_sync_step>1`, `staleness_threshold=0`**
2. 将执行同步流式训练。采样器(Rollouter)一次性生成
`require_batches*ppo_mini_batch_size*trigger_parameter_sync_step` 个样本,训练器(Trainer)在每次获取
`require_batches*ppo_mini_batch_size` 个样本后执行一次本地训练,训练 `trigger_parameter_sync_step` 次后,训练器(Trainer)和采样器(Rollouter)进行参数同步;
3. 与模式 a 相比,由于一次生成更多样本,资源空闲率会更低。
4. 在单步训练中,会存在两个资源空闲期:在获取第一批样本时,训练(Trainer)等待
`require_batches*ppo_mini_batch_size` 个样本生成;在最后一次参数更新时,采样器(Rollouter)等待训练完成。
5. 如图 b 所示;
3. **Async stream pipeline with stale samples(带陈旧样本的异步流式流水线)**:
1. **`trigger_parameter_sync_step>=1`, `staleness_threshold>0`, `partial_rollout=False`**
2. 每次参数更新后,采样器(Rollouter)计划生成最多 `rollout_num` 个样本(实际上,样本生成数量可能少于此值,取决于采样速度)。
3. 如果采样过程相对较快,采样器(Rollouter)将在参数同步前生成一些额外的样本 `num_stale_samples`,供训练器(Trainer)在同步后立即使用。
触发参数同步时,如果采样器(Rollouter)有正在进行的任务,它将等待任务完成,而不是添加新任务;
4. 与模式 b 相比,除了第一次训练步骤外,后续训练不会有等待第一批采样完成的时间,但会有等待活动任务完成的时间。
5. 如图 c 所示;
4. **Async stream pipeline with partial rollout(部分采样异步流式流水线)**:
1. **`trigger_parameter_sync_step>=1`, `staleness_threshold>0`, `partial_rollout=True`**
2. 与模式 c 相比,在触发参数同步时,如果采样器(Rollouter)有正在生成的样本,它将中断采样过程并进行参数同步。中断的样本将在同步后继续生成。这减少了等待活动任务完成的时间。
3. 如图 d 所示;

### 关键指标
| 指标 | 含义 |
| :--------------------------------------------- | :----------------------------------------------------------------------------------------------- |
| `trainer/idle_ratio` | 训练器(Trainer)的空闲率 |
| `rollouter/idle_ratio` | 采样器(Rollouter)的空闲率 |
| `fully_async/count/stale_samples_processed` | 训练中使用的陈旧样本总数 |
| `fully_async/count/stale_trajectory_processed` | 训练中使用的陈旧轨迹总数(一个样本产生 `rollout.n` 条轨迹) |
| `fully_async/partial/total_partial_num` | 两次 `trigger_parameter_sync_step` 之间训练器(Trainer)处理的部分样本数量 |
| `fully_async/partial/partial_ratio` | 两次 `trigger_parameter_sync_step` 之间训练器(Trainer)处理的部分样本比例 |
| `fully_async/partial/max_partial_span` | 两次 `trigger_parameter_sync_step` 之间训练器(Trainer)处理的部分样本的最大参数跨度(parameter span) |
### 参数调整建议
* **资源分配与调整**:
* 合理的资源分配是达到良好训练效率的前提。理想的资源分配应使采样时间(rollout time)和训练时间(train time)接近,从而最小化整个训练过程中的流水线气泡(pipeline bubbles),避免资源空闲,并确保训练器(Trainer)不使用陈旧样本。在实际训练场景中,可以根据实际训练期间采样器(Rollouter)和训练器(Trainer)的空闲时间进行调整,这些信息可以从 `rollouter/idle_ratio` 和 `trainer/idle_ratio` 中获取。如果 `rollouter/idle_ratio` 较高而 `trainer/idle_ratio` 较低,则应增加训练器(Trainer)的资源并减少采样器(Rollouter)的资源,反之亦然。
* **关键参数**:
* `staleness_threshold`:设置过高会导致使用更多陈旧样本,影响模型性能。建议设置为小于 1。
* `require_batches`:越接近 1,越接近纯流式处理,训练气泡越小,可实现的加速效果越快,但会影响样本处理顺序;
* `trigger_parameter_sync_step`:设置值越小,越接近同步策略(on policy),但会导致频繁的参数同步。长尾样本浪费了短样本无法填补的资源,导致资源利用率低下。
设置值越大,计算效率越高,但准确性会受到离策略(off policy)的影响。
* `rollout.test_freq`:它会占用采样器(Rollouter)的资源,不建议设置得过小。
* **模式选择**:通过调整不同参数,完全异步(Fully Async)架构支持不同级别的优化加速,适用于不同场景下的任务。
* 对于需要确保训练稳定性、同步策略性质,且对速度要求不高的中小型任务,可以尝试同步策略流水线模式(模式 1)。
* 对于需要提高训练吞吐量但对陈旧样本敏感的场景,可以尝试流式离策略流水线模式。即通过设置 `trigger_parameter_sync_step>1` 来提高训练效率,同时保持同步机制(`staleness_threshold=0`)(模式 2)。
* 对于大规模、高训练速度要求且能容忍一定程度离策略和陈旧样本的任务,设置为
`staleness_threshold>0` 和 `partial_rollout=True` 可以提高训练效率,使用异步流式流水线模式(模式 3 或 4)。
### 快速开始
```shell
rollout_mode="async"
rollout_name="vllm" # sglang 或 vllm
if [ "$rollout_mode" = "async" ]; then
export VLLM_USE_V1=1
return_raw_chat="True"
fi
train_prompt_bsz=0
gen_prompt_bsz=1
n_resp_per_prompt=16
train_prompt_mini_bsz=32
total_rollout_steps=$(((512*400)))
test_freq=10
staleness_threshold=0
trigger_parameter_sync_step=16
partial_rollout=False
python -m recipe.fully_async_policy.fully_async_main \
train_batch_size=${train_prompt_bsz} \
data.gen_batch_size=${gen_prompt_bsz} \
data.return_raw_chat=${return_raw_chat} \
actor_rollout_ref.rollout.n=${n_resp_per_prompt} \
actor_rollout_ref.actor.strategy=fsdp2 \
critic.strategy=fsdp2 \
actor_rollout_ref.hybrid_engine=False \
actor_rollout_ref.actor.use_dynamic_bsz=${use_dynamic_bsz} \
actor_rollout_ref.ref.log_prob_use_dynamic_bsz=${use_dynamic_bsz} \
actor_rollout_ref.rollout.log_prob_use_dynamic_bsz=${use_dynamic_bsz} \
actor_rollout_ref.rollout.name=${rollout_name} \
actor_rollout_ref.rollout.mode=${rollout_mode} \
actor_rollout_ref.rollout.calculate_log_probs=True \
trainer.nnodes="${NNODES_TRAIN}" \
trainer.n_gpus_per_node="${NGPUS_PER_NODE}" \
rollout.nnodes="${NNODES_ROLLOUT}" \
rollout.n_gpus_per_node="${NGPUS_PER_NODE}" \
rollout.total_rollout_steps="${total_rollout_steps}" \
rollout.test_freq="${test_freq}" \
async_training.staleness_threshold="${staleness_threshold}" \
async_training.trigger_parameter_sync_step="${trigger_parameter_sync_step}" \
async_training.partial_rollout="${partial_rollout}"
```
## 实验
### 7B 模型异步训练
我们使用 Qwen2.5-Math-7B 来验证完全异步策略在长候选(long candidates)和多资源下的优势。
使用“带陈旧样本的异步流式流水线(async stream pipeline with stale samples)”策略,我们在 32 卡、64 卡和 128 卡上实现了约 2 倍的性能提升,且未显著影响实验结果。
* 机器:H20
* 模型:Qwen2.5-Math-7B
* 采样长度:`max_response_length` FSDP2: 28K tokens;
* 算法:DAPO
* 数据集:`TRAIN_FILE`: dapo-math-17k.parquet `TEST_FILE`: aime-2024.parquet
* 引擎:vllm+FSDP2
* `rollout.n`: 16
* `ppo_mini_batch_size`: 32
* `test_freq`: 20
* 共址同步(colocate sync):
* 步数(step):400
* 训练批次大小(`train_batch_size`):512
* 完全异步策略(`fully_async_policy`):
* `total_rollout_steps`: 512\*400
* `require_batches`: 4
* `trigger_parameter_sync_step`: 4
* `staleness_threshold`: 0.5
* `partial_rollout`: True
| 训练模式 | 资源分配 | 步数(step) | 生成(gen) | 旧 `log_prob` | 更新 actor | 100 步总时长 | 200 步总时长 | 300 步总时长 | 400 步总时长 | 准确率/均值@1 |
| :---------------------------: | :----------: | :--------: | :-------: | :---------: | :--------: | :--------------: | :--------------: | :--------------: | :--------------: | :-----------------------: |
| 共址同步 (colocate sync) | 32 | 790.10 | 357.41 | 107.71 | 313.81 | 13h 44m | 1d 3h 43m | 2d 9h 22m | 3d 17h 5m | max: 0.3313
last: 0.2448 |
| 完全异步策略 (fully_async_policy) | 16:16 | 294.77 | 21.26 | \ | 269.80 | 7h 58m
(1.72x) | 16h 21m
(1.70x) | 1d 0h 53m
(2.31x) | 1d 9h 26m
(2.66x) | max: 0.3302
last: 0.2333 |
| 共址同步 (colocate sync) | 64 | 365.28 | 150.72 | 70.26 | 133.41 | 10h 22m | 20h 45m | 1d 7h 6m | 1d 17h 32m | max: 0.3365
last: 0.2333 |
| 完全异步策略 (fully_async_policy) | 32:32 | 189.26 | 28.46 | \ | 156.98 | 4h 57m
(2.09x) | 10h 14m
(2.03x) | 16h 58m
(1.83x) | 21h 40m
(1.92x) | max: 0.3677
last: 0.3406 |
| 共址同步 (colocate sync) | 128 | 356.30 | 177.85 | 53.92 | 113.81 | 8h 36m | 17h 56m | 1d 5h 6m | 1d 16h 48m | max: 0.3573
last: 0.2958 |
| 完全异步策略 (fully_async_policy) | 64:64 | 150.63 | 33.14 | \ | 113.16 | 3h 13m
(2.67x) | 6h 46m
(2.65x) | 10h 53m
(2.67x) | 17h 22m
(2.35x) | max: 0.3521
last: 0.3094 |
> 原始数据来源:https://wandb.ai/hou-zg-meituan/fully-async-policy-colocate_async?nw=nwuserhouzg
### 128 卡 7B 模型异步模式实验
我们使用 Qwen2.5-Math-7B 来验证完全异步策略所支持的各种模式的效果。
我们可以看到,流式处理带来的收益约为 1.6 倍,结合陈旧样本和部分采样后,收益达到了 2.35 倍。
| 模式 | 步数(step) | 生成(gen) | 旧 `log_prob` | 更新 actor | 100 步总时长 | 200 步总时长 | 300 步总时长 | 400 步总时长 | 准确率/均值@1 |
| :-----------------------------------------------------------------------: | :--------: | :---------: | :---------: | :--------: | :--------------: | :--------------: | :--------------: | :--------------: | :-----------------------: |
| 共址同步 (colocate sync) | 356.30 | 177.85 | 53.92 | 113.81 | 8h 36m | 17h 56m | 1d 5h 6m | 1d 16h 48m | max: 0.3573
last: 0.2958 |
| `流式离策略流水线`
(+fully async: `trigger_parameter_sync_step`= 4,
`require_batches`= 4) | 231.34 | 128.47 | \ | 98.77 | 4h 25m | 9h 41m | 15h 2m | 1d 1h 53m | max: 0.2844
last: 0.2604 |
| `带陈旧样本的异步流式流水线`
(+`staleness_threshold`=0.5) | | | | | | | | | |
| `带部分采样的异步流式流水线`
(+`partial_rollout`=True) | 150.63 | 33.14 | \ | 113.16 | 3h 13m | 6h 46m | 10h 53m | 17h 22m | max: 0.3521
last: 0.3094 |
> 原始数据来源:https://wandb.ai/hou-zg-meituan/fully-async-policy-stream_stale_partial?nw=nwuserhouzg
### 128 卡陈旧样本消融实验
在“带部分采样的异步流式流水线(async stream pipeline with partial rollout)”模式下,我们验证了陈旧样本设置对训练效率的影响。
我们发现,陈旧度(staleness)越大,最终收益越明显。
我们还注意到,`staleness_threshold` 为 0.3 和 0.5 时的耗时非常接近,这是因为随着训练步数的增加,响应长度发生显著变化,导致训练不稳定。
这个问题还需要进一步的分析和优化。
| `staleness_threshold` | 步数(step) | 生成(gen) | 旧 `log_prob` | 更新 actor | 100 步总时长 | 200 步总时长 | 300 步总时长 | 400 步总时长 | 准确率/均值@1 |
| :------------------: | :--------: | :---------: | :---------: | :--------: | :--------------: | :--------------: | :--------------: | :--------------: | :---------------------: |
| 0 | 231.34 | 128.47 | \ | 98.77 | 4h 25m | 9h 41m | 15h 2m | 1d 1h 53m | max: 0.2844
last: 0.2604 |
| 0.1 | 171.30 | 58.17 | \ | 109.12 | 3h 53m | 8h 37m | 14h 25m | 19h 59m | max: 0.3542
last: 0.2979 |
| 0.3 | 146.11 | 38.88 | \ | 103.22 | 3h 18m | 6h 49m | 11h 40m | 17h 20m | max: 0.3469
last: 0.2865 |
| 0.5 | 150.63 | 33.14 | \ | 113.16 | 3h 13m | 6h 46m | 10h 53m | 17h 22m | max: 0.3521
last: 0.3094 |
> 原始数据来源:https://wandb.ai/hou-zg-meituan/fully-async-policy-stream_stale_partial?nw=nwuserhouzg
### 128 卡 7B `require_batches` 消融实验
在多次测试中,我们发现流式处理中每次发放的样本数量会影响训练时的响应长度,进而影响训练时间。我们通过修改
`async_training.require_batches` 来验证其对结果的影响。
| `require_batches` | 步数(step) | gen | 旧 `log_prob` | 更新 actor | 100 步总时长 | 200 步总时长 | 300 步总时长 | 准确率/均值@1 |
| :-------------: | :--------: | :--: | :---------: | :--------: | :--------------: | :--------------: | :--------------: | :----------------------: |
| 1 | 203.47 | 30.88 | \ | 181.08 | 3h 31m | 8h 29m | 17h 36m | max: 0.349
last: 0.326 |
| 2 | 158.72 | 26.32 | \ | 128.08 | 3h 35m | 7h 38m | 13h 57m | max: 0.351
last: 0.3406 |
| 4 | 124.64 | 25.62 | \ | 95.06 | 3h 13m | 6h 46m | 10h 53m | max: 0.3521
last: 0.3521 |
> 原始数据来源:https://wandb.ai/hou-zg-meituan/fully-async-policy-ablation_require_batches?nw=nwuserhouzg
### 30B 模型模式实验
待续:30B 模型实验仍在进行中。
* 机器:H20
* 模型:Qwen2.5-32B
* 采样长度:`max_response_length` FSDP2: 20K tokens;
* 算法:DAPO
* 引擎:vllm+FSDP2
* `rollout.n`: 16
* `ppo_mini_batch_size`: 32
* `test_freq`: 20
* 共址同步(colocate sync):
* 步数(step):200
* 训练批次大小(`train_batch_size`):512
* 完全异步策略(`fully_async_policy`):
* `total_rollout_steps`: 512\*200
* `trigger_parameter_sync_step`: 512/32 = 16
* `staleness_threshold`: 0
* `partial_rollout`: False
| training mode | Resource allocation | mode | step | generate_sequences | old_log_prob | update_actor | total time | acc/best@32/mean |
|--------------------|---------------------|--------------------------------------------|------|--------------------|--------------|--------------|------------|------------------|
| colocate sync | 128 | | | | | | | |
| fully_async_policy | 64:64 | stream off policy pipeline | | | | | | |
| fully_async_policy | 64:64 | async stream pipeline with stale samples | | | | | | |
| fully_async_policy | 64:64 | async stream pipeline with partial rollout | | | | | | |
## 未来计划
* GRPO 实验
* Megatron 适配
* SGLang 集成
* Transfer Queue 集成
* 异步参数同步
* AReaL 异步算法实现
* TPPO 算法实现
* 多轮对话和工具支持