Prhub

#6265 [reward, cfg] fix: correctly use RewardModelConfig in reward config

原始 PR 作者 guillemgt 合并时间 2026-05-08 17:47 文件变更 8 提交数 6 评论 8 代码增减 +140 / -10

执行摘要

修复 RewardModelConfig 字段命名、world_size 计算和 YAML 配置缺失项

解决 reward model 配置中的四个相关问题:

1) world size 计算未包含 pipeline_model_parallel_size,导致资源分配错误;
2) RewardModelConfig 中嵌套的 rollout 配置被命名为 inference,与 RewardModelManager 中的引用 rollout 不一致;
3) reward.yaml 缺少顶层和子配置段的 target,导致 Hydra 实例化失败,且 RewardManagerConfig 的 target 路径错误(指向 reward_model 而非 reward);
4) reward.yaml 中缺失多个 RolloutConfig 关键字段(如 pipeline_model_parallel_size、quantization、temperature),导致这些设置无法传递给 reward model。这些 bug 源于之前 #6228 的修复不完整以及 #6258 的回滚。

值得精读,尤其是理解 reward model 如何复用 RolloutConfig 以及 world_size 计算公式。设计决策:将 reward 推理配置视为 rollout 配置的复用,并统一字段名 rollout。对于正在使用 reward model 的开发者和用户,建议检查现有 YAML 配置是否使用了 inference 字段,并及时迁移。关注后续是否会有更多同步配置的工作(例如 NPU 专用配置)。

讨论亮点
  • num_replicas 断言(gemini-code-assist, correctness):指出 world_size 小于 rollout_world_size 时 num_replicas 可能为0,导致空列表和后续初始化失败,建议添加明确断言。已采纳,在 _initialize_llm_servers 中添加了 assert num_replicas > 0 并给出详细错误信息。
  • YAML 中 n 键引号(gemini-code-assist, correctness):建议将 n:1 加引号为 'n':1 以避免 YAML 1.1 解析为 boolean false。作者回应遵循了 rollout 配置的相同模式(即未加引号),但最终在自动生成的配置文件中加了引号,而 reward.yaml 中保留无引号形式。该差异未影响实际使用。
  • 统一字段名为 rollout(yyDing1, design):要求统一使用 reward_model.rollout 使命名一致且易于理解。已采纳,作者修改了所有相关引用。
  • 修复 CI 测试(yyDing1, testing):要求修复 reward_model_sglang CI。已修复,通过修改 SGLang MTP 条件解决。

实现拆解

  1. 统一配置字段名:在 verl/workers/config/reward.py 中将 RewardModelConfiginference: RolloutConfig 重命名为 rollout,与 RewardModelManager 中已有的引用一致,同时与其他 rollout 配置风格对齐。相应地更新 verl/experimental/reward_loop/reward_model.py 中所有 self.config.inference 引用为 self.config.rollout

  2. 修正 world_size 计算并增强健壮性:在 RewardModelManager._initialize_llm_servers 中,将 rollout_world_size 从仅取 tensor_model_parallel_size 改为乘以 data_parallel_sizepipeline_model_parallel_size,以正确反映 Ray 资源池的分片需求。同时在计算 num_replicas 后添加断言 num_replicas > 0,当 GPU 资源不足时给出明确错误信息而非在空列表中失败。

  3. 修复 YAML 配置结构:在 verl/trainer/config/reward/reward.yaml 中:

    • 添加顶层 _target_: verl.workers.config.RewardConfig
    • 修正 reward_manager._target_ 路径从 verl.workers.config.reward_model.RewardManagerConfigverl.workers.config.reward.RewardManagerConfig
    • reward_model 段添加 _target_: verl.workers.config.RewardModelConfig
    • sandbox_fusion 段添加 _target_: verl.workers.config.SandboxFusionConfig
    • reward_model.rollout 下补充缺失的字段:pipeline_model_parallel_sizelayered_summonscheduling_policymulti_stage_wake_upignore_eostemperaturetop_ktop_pdo_samplenquantizationquantization_config_filemtpdisaggregation 等。注意 n 在 YAML 中加引号以免被解析为 boolean。
  4. 同步更新自动生成的配置文件:将同样的变更反映到所有 _generated_ 配置文件(_generated_ppo_megatron_trainer.yaml_generated_ppo_torchtitan_trainer.yaml_generated_ppo_trainer.yaml_generated_ppo_veomni_trainer.yaml),确保通过脚本生成的训练配置与 reward.yaml 一致。

  5. 修复 SGLang MTP 条件为空的问题:在 verl/workers/rollout/sglang_rollout/async_sglang_server.py 中,将 if self.config.mtp.enable 改为 if self.config.mtp is not None and self.config.mtp.enable,避免当 mtp 配置字段为 None 时访问属性导致 AttributeError。这修复了 reward_model_sglang CI 测试。

这些变更没有修改任何公共 API,但用户如果直接使用老 YAML(含有 reward_model.inference)需要更新为 rollout

文件 模块 状态 重要度
verl/experimental/reward_loop/reward_model.py 奖励循环 modified 6.08
verl/workers/config/reward.py 配置定义 modified 4.89
verl/trainer/config/reward/reward.yaml 奖励配置 modified 4.65
verl/workers/rollout/sglang_rollout/async_sglang_server.py 推理引擎 modified 4.49
verl/trainer/config/_generated_ppo_megatron_trainer.yaml 训练配置 modified 4.23
verl/trainer/config/_generated_ppo_torchtitan_trainer.yaml 训练配置 modified 4.23
verl/trainer/config/_generated_ppo_trainer.yaml 训练配置 modified 4.23
verl/trainer/config/_generated_ppo_veomni_trainer.yaml 训练配置 modified 4.23

关键符号

RewardModelManager._initialize_llm_servers RewardModelManager.__init__ AsyncSglangServer.launch_server (MTP 条件 ) RewardModelConfig.inference -> rollout

关键源码片段

verl/experimental/reward_loop/reward_model.py data-contract

核心修复文件:修正 world_size 计算、添加断言、更新字段引用。

    def _initialize_llm_servers(self):
        rollout_config = self.config.rollout # 字段已统一为 rollout
        # 正确计算 rollout_world_size:tensor_model_parallel_size * data_parallel_size * pipeline_model_parallel_size
        rollout_world_size = (
            rollout_config.tensor_model_parallel_size
            * rollout_config.data_parallel_size
            * rollout_config.pipeline_model_parallel_size
        )
        world_size = (
            self.resource_pool.world_size
            if self.resource_pool # colocate 模式
            else self.config.n_gpus_per_node * self.config.nnodes # standalone 模式
        )
        num_replicas = world_size // rollout_world_size
        # 断言防止资源不足导致空列表无声失败
        assert num_replicas > 0, (
            f"Not enough GPUs to run the reward model. "
            f"world_size ({world_size}) < rollout_world_size ({rollout_world_size}). "
            f"Check your resource pool or standalone config (n_gpus_per_node, nnodes)."
        )
​
        rollout_replica_class = get_rollout_replica_class(rollout_config.name)
        model_config = HFModelConfig(path=self.config.model_path)
        self.tokenizer = model_config.get_processor()
        self.rollout_replicas = [
            rollout_replica_class(
                replica_rank=replica_rank,
                config=rollout_config,
                model_config=model_config,
                gpus_per_node=self.config.n_gpus_per_node,
                is_reward_model=True,
            )
            for replica_rank in range(num_replicas)
        ]
verl/trainer/config/reward/reward.yaml configuration

YAML 配置修复,补充 _target_、路径修正、添加大量缺失字段,是配置完整性的关键。

# Inference config for reward models (now under rollout)
reward_model:
  _target_: verl.workers.config.RewardModelConfig
  enable: False
  enable_resource_pool: False
  n_gpus_per_node: 8
  nnodes: 0
  model_path: null
  rollout: # 统一字段名
    _target_: verl.workers.config.RolloutConfig
    name: ???
    dtype: bfloat16
    gpu_memory_utilization: 0.5
    enforce_eager: true
    cudagraph_capture_sizes: null
    free_cache_engine: true
    data_parallel_size: 1
    expert_parallel_size: 1
    tensor_model_parallel_size: 2
    pipeline_model_parallel_size: 1 # 新增:支持 PP
    max_num_batched_tokens: 8192
    max_model_len: null
    max_num_seqs: 1024
    load_format: auto
    layered_summon: false # 新增
    scheduling_policy: fcfs # 新增
    multi_stage_wake_up: false # 新增
    engine_kwargs: {}
    limit_images: null
    enable_chunked_prefill: true
    enable_prefix_caching: true
    disable_log_stats: true
    skip_tokenizer_init: false
    ignore_eos: false # 新增
    temperature: 1.0 # 新增
    top_k: -1 # 新增
    top_p: 1 # 新增
    do_sample: true # 新增
    n: 1 # 注意:YAML 中需防解析为 bool,reward.yaml 省略引号但 generated 文件加引号
    prompt_length: 2048
    response_length: 2048
    quantization: null # 新增
    quantization_config_file: null # 新增
    mtp: null # 新增
    disaggregation: # 新增
      enabled: false
      prefill_replicas: 1
      decode_replicas: 1
      decode_tensor_model_parallel_size: null
      transfer_backend: nixl
      bootstrap_port: null
      ib_device: null

评论区精华

添加 num_replicas > 0 断言防止无声失败 正确性

gemini-code-assist 指出 world_size 小于 rollout_world_size 时 num_replicas 可能为 0,导致空列表和后续初始化失败,建议添加明确断言。

结论:作者采纳,在代码中添加了 assert num_replicas > 0 并给出详细错误信息。 · 已解决

YAML 中 'n' 键引号问题 正确性

gemini-code-assist 指出 YAML 1.1 中 n 可能被解析为 boolean false,建议加引号。作者回复遵循了 rollout config 的模式(即未加引号)。最终在自动生成的配置文件中加了引号,而 reward.yaml 中保留无引号形式。

结论:reward.yaml 中未加引号,但 generated 文件中加了引号。差异未影响实际使用。 · 已解决

统一字段名 inference→rollout 设计

yyDing1 要求统一使用 reward_model.rollout 以对齐 rollout 风格。

结论:作者修改了 RewardModelConfig 和所有引用,使用 rollout。 · 已解决

修复 CI reward_model_sglang 测试

yyDing1 要求修复 CI,作者回应已修复。

结论:修复了 SGLang 条件判断,避免 None 访问错误。 · 已解决

风险与影响

  1. 配置兼容性风险:字段名从 inference 改为 rollout,用户自定义 YAML 或编程引用旧字段会导致实例化失败。但由于该配置区域之前处于错误状态(缺少 _target_ 等),有效使用场景有限,影响较小。
  2. 资源分配变化风险rollout_world_size 现在正确包含 data_parallel_sizepipeline_model_parallel_size,对于使用多副本 reward model 的场景,所需 GPU 数量可能增加(之前被低估)。用户需确保资源池或 standalone 配置有足够 GPU,否则新添加的断言将阻止启动并给出明确错误。
  3. 缺少 GPU 测试覆盖:PR 仅运行了 CPU 配置测试和一次完整训练(vLLM),但未针对不同并行策略(PP、DP 组合)添加专门的 GPU 测试,可能存在 corner case。
  4. 自动生成配置文件同步:虽然已更新四个 _generated_ 文件,但可能存在其他由不同工具链生成的配置未同步,需关注后续 CI。
  • 用户:使用 reward model 的用户现在可以配置 pipeline_model_parallel_sizequantizationtemperature 等参数,使 reward 推理更灵活。需注意 YAML 字段名变更。
  • 系统:reward model 的 GPU 分配更准确,资源不足时快速报错而非挂起。
  • 团队:统一配置风格降低了后续维护困惑。修复与 #6228 和 #6258 相关的反复回滚问题,明确正确实现。
配置字段不兼容 资源分配变化 缺少 GPU 测试覆盖

关联 Issue

#6258 Revert "[reward] fix: compute correct rollout world size"

完整报告

参与讨论