Trainer 与训练栈
single-controller 的各领域 trainer、FSDP 训练栈,以及扁平的 conf recipe 形态。
UniRL 运行在一套 trainer 架构上:single-controller 的 Remote / placement 层,
配合各领域 trainer 和可插拔的 FSDP 训练栈。早期的 v1 actor-group runtime(及其
conf_v1/ recipe)已退役;以下都是当前的默认路径。
入口与 trainer
每个领域有自己的 Hydra 入口和 <Domain>Trainer(unirl/trainer/)。它们共享构建工具和
train-side 契约,但生命周期和 placement 布局并不相同:
| 入口 | Trainer | 领域 |
|---|---|---|
python -m unirl.train_diffusion | trainer/diffusion.py | Diffusion 图像 / 视频 |
python -m unirl.train_ar | trainer/ar.py | 自回归文本 / VLM |
python -m unirl.train_sft | trainer/sft.py | Supervised fine-tuning |
python -m unirl.train_async_ar | trainer/async_ar.py | train/rollout 分 slab 的异步 AR |
python -m unirl.train_async_diffusion | trainer/async_diffusion.py | 分 slab 的异步 diffusion |
python -m unirl.train_pe | trainer/pe.py | Prompt-enhancer(AR + diffusion 联合) |
python -m unirl.train_unified_model | trainer/unified_model.py | HunyuanImage3(AR + diffusion 混合) |
python -m unirl.train_agentic | trainer/agentic.py | 由 service 打分的 agentic tool use |
trainer/base.py 负责 Ray DevicePool、checkpoint、logging 和 transport cleanup
等共享设施。具体 trainer 各自负责 worker、placement 块和阶段顺序。
生命周期与 placement
- 同步 AR 使用一个覆盖全池的 placement。direct rollout 共享 train pipeline; colocated dedicated engine 则增加 weight sync 和分阶段 offload/onload。
- 同步 diffusion 可按
layout选择 colocated placement,或彼此独立的 train/rollout placement;reward_fraction > 0时还会建立第三个 reward placement。 - SFT 在一个 placement 中构建 bundle、pipeline、backend、监督算法、stack 和
track builder。其生命周期是
records → build Part → train_track,没有 rollout、 reward、advantage 或 weight sync。 - 异步 AR 和异步 diffusion 恰好使用两个彼此独立的 placement slab:train slab
(包含 reward、algorithm、stack 和 sync sender)以及常驻的 dedicated rollout engine。
manager 缓存完成的
Sample,并在显式 barrier 发布带版本的权重。 - PE 在一个 placement 中放置 AR 和 diffusion 两侧。每个可训练侧都有各自的
bundle、pipeline、backend、algorithm 和
TrainStack;freeze_llm时 AR 侧仅用于 rollout。composed rollout 生成有序的 AR 与 diffusion Part,随后做 reward propagation、 每 Part advantage 和兄弟 stack 更新。 - Unified model 共享一个 bundle/backend,并用
UnifiedModelTrainStack在同一 backbone 上处理 AR + image loss。rollout 可以是一个 engine,也可以是一对 AR/DiT engine;它不是 PE 的兄弟 stack 拓扑。 - Agentic 使用一个 colocated placement,并要求 dedicated engine 和
TensorWeightSync。它通过RolloutManager执行 barrier batch,给 terminal answer 打分,把一个 group advantage 分配给每个生成的 assistant Part,再拼接这些 Part 训练。
常见的单 stage colocated RL 接线如下:
<Domain>Trainer(num_devices, batch_size, ...cfg blocks...)
with placement(pool, fraction=1.0, shared_workers=True):
bundle = remote(bundle_cfg)
pipeline = remote(pipeline_cfg, bundle=bundle)
backend = remote(backend_cfg, bundle=bundle) # FSDPBackend
rollout = remote(rollout_cfg[, pipeline=pipeline]) # engine
reward = remote(reward_cfg) # RewardService
algorithm = remote(algorithm_cfg, pipeline=pipeline) # StageAlgorithm
stack = remote(stack_cfg, fsdp_backend=backend, algorithm=algorithm)
sync = remote(sync_cfg, backend=backend, rollout=rollout) # 仅 dedicated rolloutsingle-controller 层(unirl/distributed/group/:Remote、placement、RankInfo)携带
DP / TP / PP / SP / EP rank 信息,后续并行工作(长序列的 SP、MoE 的 EP)正是接到这里。
该示意不适用于 SFT、双 slab 异步 trainer、PE、unified-model 或带 reward slab 的
diffusion。trainside recipe 共享被训练模块(无 sync);dedicated engine 在 sync
下挂一个 weight-sync bridge。
FSDP backend 与训练栈
两个 Remote sibling 分担训练工作:
FSDPBackend(unirl/train/backend/fsdp/backend.py)持有可训练模型:在 FSDP2 wrap 之前做结构注入 (LoRA / NFT / mirror EMA),加上 optimizer、LR scheduler、EMA shadow、eval-EMA 切换、 checkpoint 和 onload/offload。TrainStack实现在unirl/train/stack/base.py,并由unirl.train.stack导出。 它负责 loss/backward 排序,持有一个FSDPBackend和一个StageAlgorithm的 handle, 对每个 rollout Part 运行prepare_segment → mini-batch compute_loss_and_backward 循环 → optimizer_step,返回TrainStepResult。
TrainStack 按设计是单 stage——一个 Part、没有 part-name dict。PE 为每个可训练的生成
Part 使用一个兄弟 TrainStack。HunyuanImage3 的 AR + diffusion 混合训练用
unified_model_stack.py(多 stage 变体)。
num_updates_per_batch > 1 会在一个 rollout shard 上跑多次 PPO mini-batch 更新,
π_old 由 prepare_segment 冻结一次;该能力由 StageAlgorithm.supports_multi_update 控制。
完整的 backend 契约——组件、FSDPConfig / LoraConfig / EmaLoraConfig / EmaFullConfig /
OptimizerConfig / LrSchedulerConfig schema,以及 TrainTopology——见生成的
Train Stack README。
配置形态
examples/ 下的 YAML 按训练域组织,需要时再增加模型子目录(例如
examples/diffusion/sd3/sd3_trainside.yaml)。每个 recipe 用 _target_
实例化各 sibling(没有 Hydra config-group 覆盖):
bundle:
_target_: unirl.models.sd3.bundle.SD3Bundle.from_config
config:
_target_: unirl.models.sd3.config.SD3PipelineConfig
pretrained_model_ckpt_path: ${oc.env:PRETRAINED_MODEL}
pipeline:
_target_: unirl.models.sd3.pipeline.SD3Pipeline
shift: 3.0
backend:
_target_: unirl.train.backend.fsdp.FSDPBackend
block_class_names: ["JointTransformerBlock"]
trainable_attr: transformer
fsdp_cfg:
_target_: unirl.train.configs.FSDPConfig
fsdp_mode: full
activation_checkpointing: false
optimizer_cfg:
_target_: unirl.train.backend.base.OptimizerConfig
learning_rate: 3.0e-4
lora_cfg:
_target_: unirl.train.configs.LoraConfig
rank: 32
alpha: 64
stack:
_target_: unirl.train.stack.TrainStack
micro_batch_size: 1
max_grad_norm: 1.0
num_updates_per_batch: 2分布式 Backend
FSDPBackend 是标准路径。VeOmniBackend 也已可用于 topology-specific 的 FSDP2、
sequence parallel 和 expert parallel recipe;当前 VeOmni recipe 要求
fsdp_mode=full、开启 mixed precision,并关闭 CPU offload。应从现有
*_veomni_* recipe 开始,而不是把这些约束当作通用命令行开关。
关于扩展应建在哪一层,见 扩展 UniRL。