arganzheng · 2026-10-04
RL 训练的一步是三个形态不同的作业加两次同步;把它们的算力、显存、时间与两次同步的字节数追踪清楚,系统形态、权重同步、异步、环境调度都是在这张账上做交换。
| 作业 | 形态 | 对 GPU 的用法 |
|---|---|---|
| 生成(rollout) | decode,memory-bound | 权重 + 大 KV 池 |
| 打分 + 前向 | prefill,compute-bound | 三个模型的 logprob |
| 训练 | GEMM,compute-bound | 16 B / 参数的训练状态 |
两者对显存的要求互斥、中间隔两道同步的墙——公开报告里 rollout 占墙钟 60–80%、GPU 利用率常在 30% 以下,全部来自这个结构。
%%{init: {"flowchart": {"wrappingWidth": 170}}}%%
flowchart TB
R1["01 负载画像<br/>三个作业 + 两次同步,FLOP · 字节 · 秒"] --> R2["02 系统形态<br/>共置 / 分离 / 异步"]
R2 --> R3["03 共置<br/>训练状态与 KV 池怎么共存"]
R2 --> R4["04 权重同步<br/>训练分片 → 推理分片"]
R2 --> R5["05 异步与 off-policy<br/>拆掉墙之后要补什么"]
R1 --> R6["06 Agentic rollout<br/>多轮、沙箱、环境服务"]
R3 & R4 & R5 & R6 --> R7["07 verl 源码导读<br/>每个机制在哪个 worker"]
R7 --> R8["08 配置、可观测与排障"]
结论:8B、64 张 H100 做 GRPO——FLOP 上训练占一半、生成六分之一;时间上生成占四分之三;全步 MFU 13%。
%%{init: {"flowchart": {"wrappingWidth": 330}}}%%
flowchart TB
P["512 个 prompt"] --> G["<b>① 生成</b>:推理引擎,每 prompt 采 16 条<br/>decode、memory-bound、最长那条决定墙钟——<b>602 s</b>(长尾 196 s)"]
G --> R["<b>② 打分 + 前向</b>:奖励 + 策略、参考模型 logprob<br/>prefill 形态、compute-bound——72 s"]
R --> T["<b>③ 训练</b>:反向 + 优化器更新,6N × token——136 s"]
T -- "新权重同步回推理引擎(04)" --> G
结论:同步分离比共置更差(两池轮流、任一时刻只有一个池在干活);异步 ≈ 共置 − 长尾;共置对长尾线性敏感、异步不敏感;rollout : train 按时间配不按 FLOP,异步 2 : 1。
| 64 卡 | 墙钟 | 利用率 |
|---|---|---|
| 共置 | 810 s | 13% |
| 同步分离 | 1501 s | 7% |
| 一步流水 | 764 s | 14% |
| 异步 | 619 s | 17% |
结论:让渡有搬 / 丢 / 不动三种;CuMemAllocator 摘物理页保虚拟地址——CUDA graph、模型对象、块表都幸存;切换 < 2%,真实代价是常驻部分挤掉的 KV 池。
| 32B、8 卡 | 数 |
|---|---|
| 每步换手 | 约 130 GB、6.5 s(4 s 是优化器状态往返) |
| pinned 内存 | 520 GB |
gpu_memory_utilization 0.85 → 0.5 |
8B 生成 610 → 745 s——KV 池只有半张卡 |
| 边界 | (16N / n \le 70) GB 才能共置 |
named_buffers、fp8 KV scale、prefix cache结论:同步 = 布局 + 传输两半,中间是 HF 名字的 (name, tensor) 流;「谁持有完整模型」比链路快慢重要;增量同步让没有人持有完整模型。
| Megatron TP4 / PP2 / EP8 → vLLM TP8 / EP4,671B FP8 | 时间 |
|---|---|
| 朴素:全模型经 rank 0 一张网卡并在它上面物化 | 60–80 s(理论下界 13 s) |
| 多源 | 12–20 s |
| 235B 全量 vs delta | 246–266 s vs 11–15 s(21×) |
| 每步变化的参数 | dense 1–3%、MoE 0.02–0.05% |
结论:staleness、训推不一致、缓冲淘汰三者机制不同、信号不同——在 reward 曲线上不可分,要事前记录三组信号;修正的系统要求是 logprob 的份数。
| 量 | 数 |
|---|---|
| staleness (s \approx \lfloor(\text{生成用时} + \text{等待}) / T_{sync}\rfloor) | 长回答 s 更大;阈值默认 8;s ≤ 2–4 配修正无损 |
| 训推不一致(logprob 差) | dense (10^{-3})、FP8 (10^{-2})、MoE 路由翻转单 token > 1 |
| TIS 修正 | (\min(w, 2)) |
| 部分 rollout 重 prefill | ≈ 一步 FLOP 的 6% |
| decoupled PPO | 3 份 logprob(生成时、参考、当前) |
结论:500 任务 × G = 8 × 20 轮 = 8 万次容器执行、667–1300 CPU·h、1300–1800 并发沙箱;KV 驻留决定 prefill 是二次还是线性;沙箱是第三个池;环境方差让异步成必需。
| 32 卡 30 分钟 | 数 |
|---|---|
| decode | ≈ 500 s |
| prefill | 160 s(KV 命中)—— 1600 s(默认配置接近全重算) |
| 每卡 | 650 token/s |
| 训练侧 | 15 EFLOP |
| token 来源 | 八成来自环境 |
结论:从优化器更新完成到推理引擎用它生成下一个 token:十二步、四类进程、三条链路;共置 = 一个进程持有多个角色对象;TransferQueue 是同步与异步统一的解耦点;slime 薄、AReaL 异步优先——三家趋同的四段是必然。
| 机制 | 在 verl 的哪里 |
|---|---|
| 角色 → 组方法 | @register 只挂属性,_bind_worker_method 生成组方法 |
| 一步的九个阶段 | _step_once |
| 共置 | create_colocated_worker_cls + spawn |
| 权重同步(non-naive) | 七步:gather → 重命名 → bucket → 传 → load → 唤醒 |
| 解耦点 | TransferQueue |
结论:六步推导配置、全步 MFU 瀑布、RL 状态的 checkpoint、确定性、必采指标、故障表;凌晨两点 reward 平台的排查顺序是数据 → 版本 → 异步 → 实现。
| 32B / 128 卡算例 | 数 |
|---|---|
| 配比 | 80 : 48 |
| 一步 | ≈ 1170 s,MFU ≈ 20% |
| MFU 瀑布 | 100% − 64%(decode)− 13%(长尾)− 4%(同步)− 0.1% ≈ 13% |
| 671B checkpoint | 10.7 TB 写 18 分钟 |
| 确定性 | full_determinism 要求 use_v1=false |
%%{init: {"flowchart": {"wrappingWidth": 220}}}%%
flowchart TB
L["回答长度 L̄ 与 L_max<br/>随训练变长"] --> KV["在飞 KV 量"]
L --> F["长尾占比 f"]
KV --> C["单实例并发 c"]
U["gpu_memory_utilization 与常驻部分"] --> C
C --> TG["生成吞吐时间"]
F --> TOPO["形态:sync / colocate_async / separate_async"]
TG --> R["配比 n_r : n_t"]
TOPO --> S["staleness 分布"]
TS["同步时间 T_sync"] --> K["parameter_sync_step k"] --> S
S --> LP["logprob 份数与修正<br/>2 份 / 3 份 · TIS / MIS · wait"]
| 篇 | 一个数 / 一个公式 |
|---|---|
| 01 | 602 + 72 + 136 = 810 s;MFU 13%;每 token 12N_a |
| 02 | 共置 810 / 分离 1501 / 异步 619 s;配比按时间 2 : 1 |
| 03 | 换手 130 GB、6.5 s、< 2%;0.5 → 745 s;16N/n ≤ 70 GB |
| 04 | 671B FP8 60–80 → 12–20 s;delta 21×;bucket 512 MB |
| 05 | (s \approx \lfloor(\text{gen} + \text{wait})/T_{sync}\rfloor);TIS min(w, 2);3 份 logprob |
| 06 | 8 万次执行;1300–1800 沙箱;prefill 160 vs 1600 s |
| 07 | 十二步、四类进程、三条链路;TransferQueue |
| 08 | 瀑布 100 − 64 − 13 − 4 ≈ 13%;数据 → 版本 → 异步 → 实现 |
/rl-post-training-infrastructure.html;通关自测在系列总结