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/),驱动方式一致:
| 入口 | Trainer | 领域 |
|---|---|---|
python -m unirl.train_diffusion | trainer/diffusion.py | Diffusion 图像 / 视频 |
python -m unirl.train_vlm | trainer/vlm.py | 自回归 VLM / LLM |
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 混合) |
共享生命周期在 trainer/base.py:申请 Ray DevicePool,在 placement 块里构建 rollout 与
train worker,然后跑 rollout → reward → advantage → train → 可选 weight-sync 循环。
Runtime 模型
trainer 打开一个 placement 块,把每个组件实例化为 sibling Remote,并以 handle 互相传入:
<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)正是接到这里。
trainside recipe 共享被训练模块(无 sync);dedicated engine 在 sync 下挂一个 weight-sync bridge。
FSDP backend 与训练栈
两个 Remote sibling 分担训练工作:
FSDPBackend(unirl/train/backend/fsdp.py)持有可训练模型:在 FSDP2 wrap 之前做结构注入 (LoRA / NFT / mirror EMA),加上 optimizer、LR scheduler、EMA shadow、eval-EMA 切换、 checkpoint 和 onload/offload。TrainStack(unirl/train/stack.py)负责 loss/backward 排序。它持有一个FSDPBackend和一个StageAlgorithm的 handle,对每个 rollout track 运行prepare_segment → mini-batch compute_loss_and_backward 循环 → optimizer_step,返回TrainStepResult。
TrainStack 按设计是单 stage——一个 track、没有 track-name dict。多 track 训练(如 PE)使用兄弟
TrainStack,每个 track 一个。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/<domain>/*.yaml 是按训练域分桶的目录树;每个 recipe 用 _target_ 实例化各 sibling(没有 Hydra config-group 覆盖):
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接下来的方向
Roadmap 中的 VeOmniBackend 正是面向这一契约:新 backend 实现与 FSDPBackend 相同的 Remote
表面,并把 TrainTopology 映射到并行 plan(FSDP / SP / EP),而不是硬编码 shard size。见
Roadmap 路线图 的 Infra 线。
关于扩展应建在哪一层,见 扩展 UniRL。