UniRL 文档
架构

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_diffusiontrainer/diffusion.pyDiffusion 图像 / 视频
python -m unirl.train_artrainer/ar.py自回归文本 / VLM
python -m unirl.train_sfttrainer/sft.pySupervised fine-tuning
python -m unirl.train_async_artrainer/async_ar.pytrain/rollout 分 slab 的异步 AR
python -m unirl.train_async_diffusiontrainer/async_diffusion.py分 slab 的异步 diffusion
python -m unirl.train_petrainer/pe.pyPrompt-enhancer(AR + diffusion 联合)
python -m unirl.train_unified_modeltrainer/unified_model.pyHunyuanImage3(AR + diffusion 混合)
python -m unirl.train_agentictrainer/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 rollout

single-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。

目录