Chapter 08

三种部署模式:colocated / hybrid / fully distributed

📌 commit 6c6056daa522 角色放置策略 — 显存 × 吞吐的取舍

RLHF 训练里有 4 个训练角色 + 1 个采样引擎,共 5 类进程。同样的硬件可以让它们 怎么放在 GPU 上,决定显存峰值与吞吐。OpenRLHF 通过几个简单的开关, 覆盖从"挤在 8 卡上"到"5 类独立占卡"的整个谱系。这一章把三种部署模式讲透。

8.1三种模式速览

模式 所有角色共享 GPU? 典型场景 关键 flag
fully colocated 全共享 单机 8 卡训练 ≤ 32B --train.colocate_all
partially hybrid 部分共享 显存吃紧 / 模型偏大 --train.colocate_actor_ref 等组合
fully distributed 完全隔离 多节点 70B+ 训练 所有 colocate 都关

8.2模式 A:fully colocated(最省卡)

train_ppo_ray_hybrid_engine.sh 是这种模式的范例。所有 5 类进程共享同一组 GPU,靠 sleep mode 分时复用:

flowchart TB subgraph cards[同一组 8 张 GPU - 时分复用] direction LR G0[GPU0..GPU7] end subgraph t1[阶段 1 - rollout] vLLM[vLLM 占满显存] end subgraph t2[阶段 2 - 训练] Actor[Actor + Ref + Critic + Reward 各 ZeRO-3 切片] end cards -.- t1 cards -.- t2

启动参数

--ref.num_gpus_per_node 8       # ref 占 8 卡
--reward.num_gpus_per_node 8    # reward 占 8 卡
--critic.num_gpus_per_node 8    # critic 占 8 卡
--actor.num_gpus_per_node 8     # actor 占 8 卡
--vllm.num_engines 4 --vllm.tensor_parallel_size 2  # vllm 占 8 卡

--train.colocate_all           # ★ 让 Ray 把它们都放同一组 placement group
--vllm.enable_sleep --ds.enable_sleep
--vllm.gpu_memory_utilization 0.5

调度的关键

显存峰值估算(7B 模型)

组件每卡占用(ZeRO-3, bf16)
Actor bf16 + grad ~2 GB
Actor Adam states (ZeRO-3) ~12 GB / 8 = 1.5 GB
Critic 同上 ~3.5 GB
Reference (no optim) ~2 GB
Reward (no optim) ~2 GB
vLLM (sleep 时释放) 峰值 ~14 GB(不与训练同存)
激活(gradient ckpt) ~5 GB
峰值(rollout 阶段)~20 GB(A100 80G 充分够用)

8.3模式 B:partially hybrid

当 colocate_all 装不下时(70B+),把某些角色组合共置:

组合含义flag
colocate_actor_ref actor + reference 同卡(最常见) --train.colocate_actor_ref
colocate_critic_reward critic + reward 同卡 --train.colocate_critic_reward
colocate_actor_vllm actor + vllm 同卡(hybrid engine 经典) (默认开 vLLM 与 actor 共享 PG)

典型组合 1:actor+ref 共置,critic+reward 共置(最常用)

# 8 卡机器,但 ref 和 reward 不占新卡
--actor.num_gpus_per_node 8 \
--ref.num_gpus_per_node 8 \                  # 同 8 卡共置
--train.colocate_actor_ref \

--critic.num_gpus_per_node 8 \
--reward.num_gpus_per_node 8 \
--train.colocate_critic_reward \

--vllm.num_engines 4 --vllm.tensor_parallel_size 2  # vLLM 8 卡(同 actor 共置)
flowchart LR subgraph G1[同一组 8 卡] A[Actor] R[Ref] V[vLLM] end subgraph G2[同一组 8 卡] C[Critic] Rw[Reward] end

典型组合 2:actor+vllm 同卡,其他独占

# 这种适合更大模型 / 显存紧张
--actor.num_gpus_per_node 8 \
--ref.num_gpus_per_node 8 \
--critic.num_gpus_per_node 8 \
--reward.num_gpus_per_node 8 \
--vllm.num_engines 1 --vllm.tensor_parallel_size 8 \

# actor + vllm 共享(OpenRLHF 默认行为)
# ref / critic / reward 各自独占卡

8.4模式 C:fully distributed(最快但费卡)

每个角色独占一片 GPU,互不干扰。生产环境训 70B+ 模型的标配:

# 16 卡:actor 8 + critic 8(ref / reward 用更小切片)
--actor.num_nodes 1 --actor.num_gpus_per_node 8 \
--ref.num_nodes 1 --ref.num_gpus_per_node 4 \      # 不要 colocate
--critic.num_nodes 1 --critic.num_gpus_per_node 8 \
--reward.num_nodes 1 --reward.num_gpus_per_node 4 \
--vllm.num_engines 2 --vllm.tensor_parallel_size 4 \  # vLLM 另 8 卡

# 不开任何 colocate flag
# 不开 sleep mode

这种模式:

8.5选哪种模式

资源模型规模推荐模式典型 flag
1 × 8 卡 A100/H100 7B - 13B fully colocated --train.colocate_all
1 × 8 卡 A100/H100 30B - 32B partial hybrid colocate_actor_ref + colocate_critic_reward
2 × 8 卡 A100/H100 30B - 70B partial hybrid 跨节点actor + vllm 一组,critic + ref + reward 另一组
4 × 8 卡 A100/H100 70B - 130B fully distributed 各角色独占节点
≥ 8 × 8 卡 H100 200B+ MoE fully distributed + vLLM 多机

8.6colocate 模式的隐藏成本

colocate 看上去免费午餐,但有隐藏成本:

  1. 切换开销:每个 PPO step 都要 vLLM sleep ↔ wake_up + actor offload ↔ reload,单次几百毫秒;
  2. 显存碎片:频繁分配 / 释放导致 cudaMalloc 碎片化,少数情况下会 OOM;
  3. 调试更难:colocate 时 actor 和 vllm 状态变化频繁,trace 很难看;
  4. 多机更复杂:跨节点 colocate 要保证 placement group strict_pack 不破。

用 colocate 跑 70B 时,每个 step wall time 可能比 fully distributed 慢 20-30%。

8.7多机训练时的 placement

多机时 num_nodes 起作用:

--actor.num_nodes 2 --actor.num_gpus_per_node 8  # 跨 2 节点共 16 卡
--vllm.num_engines 4 --vllm.tensor_parallel_size 4   # vllm 也跨 2 节点

这时 Ray placement_group 用 PACK 策略(不再 STRICT_PACK),允许跨节点。 TP 不跨节点(NVLink-only),DP 跨节点(IB)。

多机启动方式

# Head 节点
ray start --head --port=6379

# Worker 节点
ray start --address=<head_ip>:6379

# 提交训练
ray job submit --address="http://<head_ip>:8265" \
   --runtime-env-json='{"working_dir": "/openrlhf"}' \
   -- bash examples/scripts/train_ppo_ray_slurm.sh

8.8实测显存对照(13B PPO)

在 8 × A100 80G 上跑 Llama-3-13B PPO 的显存峰值(每卡):

模式每卡显存每 step 时间
fully colocated(含 sleep) ~42 GB~85 s
colocate_actor_ref + colocate_critic_reward~52 GB~72 s
fully distributed(16 卡) ~28 GB / 卡~58 s

看出来:colocate 省卡但慢一些;fully distributed 快但耗卡。

8.9选 mode 的口诀

三句话

1. 硬件富裕(每角色一片卡) → fully distributed,求最快;

2. 硬件中等(8-16 卡训 13-70B) → partial hybrid,按需 colocate;

3. 单机 8 卡训 7B-32B → fully colocated,省卡。

8.10colocate 字段速查(CLI 真实写法)

三种模式不是预设的"模式名",而是几个 colocate flag 的组合。读 cli/train_ppo_ray.py 时这张表很有用:

CLI flag含义
--train.colocate_all 所有 4 个角色 + vLLM 共享同一组 GPU;省卡王者
--train.colocate_actor_ref 只 actor + reference 共置(ref 静态,跟 actor 同卡省 1 份显存)
--train.colocate_critic_reward 只 critic + reward 共置(两个 sequence regression head 同卡)
--train.colocate_actor_critic_ref_reward 四个训练角色共置但不含 vLLM,vLLM 独立卡
--vllm.enable_sleep vLLM 在不 generate 时 sleep(colocate 必开)
--ds.enable_sleep DeepSpeed 训练侧 sleep(offload optimizer/grad 到 CPU;colocate_all 必开)
--train.async_enable 异步 pipeline,rollout 与 train 并行(与 colocate_all 互斥)

三档典型组合:

# Fully colocated(单机 8 卡跑 70B PPO)
--train.colocate_all --vllm.enable_sleep --ds.enable_sleep

# Partial hybrid(双节点 16 卡)
--train.colocate_actor_ref --train.colocate_critic_reward

# Fully distributed(4 节点 32 卡,每角色独占节点)
# 不加任何 colocate flag

# Async pipeline(多机 + 异步加速)
--train.async_enable --vllm.enable_sleep   # 与 colocate_all 互斥

8.11这章你需要带走的