最近正在入门大模型 RL 微调,阅读 VeRL 框架 的代码。在 VeRL 提供的官方示例 ppo 训练脚本中,我们发现了以下参数:

# 来源于 verl/examples/ppo_trainer/run_deepseek_full_hh_rlhf.sh
reward.num_workers=8 \
reward.reward_model.enable=True \
reward.reward_model.model_path=deepseek-ai/deepseek-llm-7b-chat \
reward.reward_model.rollout.name=vllm \
reward.reward_model.rollout.gpu_memory_utilization=0.8 \
reward.reward_model.rollout.tensor_model_parallel_size=4 \
reward.reward_model.rollout.prompt_length=256 \
reward.reward_model.rollout.response_length=128 \

# 来源于 verl/examples/ppo_trainer/run_deepseek7b_llm_sandbox_fusion.sh
reward.sandbox_fusion.url='https://xxxxxxxxx.apigateway-cn-beijing.volceapi.com/run_code' \
reward.sandbox_fusion.max_concurrent=128 \
reward.reward_manager.name=prime \

然而,这些 reward 参数,在最标准的 verl/examples/ppo_trainer/run_deepseek7b_llm.sh 脚本中,我们都没有看到。笔者感到很好奇,这些 reward 和 reward model 参数表示什么含义?

本博客记录了笔者的学习过程,会围绕两个核心问题展开:

  1. 在 VeRL 的 PPO 训练中,rewardreward_model 到底是什么?
  2. 这些奖励模型从哪里来、如何被加载和调用、输入输出是什么样、如何融入 PPO 训练流程?

目标:读完之后,能够「一眼看懂」脚本中的那些 reward.* 参数,并对背后整套奖励系统的设计有相对完整的理解。

一、PPO 训练中的奖励子系统:VeRL 是怎么抽象的?

在 RLHF、代码生成 RL、数学推理 RL 等场景下,PPO 的典型流程可以简化为四步:

  1. Actor(策略模型):根据 prompt 生成 response(rollout)。
  2. Reward 侧:对每个 (prompt, response) 打分,得到标量 reward。
  3. Critic(价值网络):估计 value,结合 reward 计算 advantage。
  4. PPO 更新:利用 advantage 更新 Actor 与 Critic。

在 VeRL 中,第 2 步「对 rollout 打分」被抽象成一个独立的 “奖励计算子系统”,在配置文件中统一以 reward.* 为前缀管理。这个子系统包含:

  • 要不要用 奖励模型(Reward Model, RM)
  • 要不要用 规则 / 函数型 reward;
  • 如何调度多个 Worker 并行打分;
  • 是否需要通过 Sandbox Fusion 调用远程代码执行服务;
  • 使用哪种 RewardManager 来组织与融合各类奖励源。

换句话说,reward.* 不是一个单独模型,而是一整套:

Actor 生成结果 → 奖励系统如何处理 → 最终交给 PPO 的 reward 标量

的配置入口。


二、两类 Reward:函数型 vs 模型型

VeRL 支持两大类奖励形式:

2.1 函数型(function-based)奖励

自己写一个打分函数,在 Python 里根据 (prompt, response) 给出分数:

  • 数学题(如 GSM8K):
    • 解析模型最后给出的答案;
    • 判断是否等于标准答案;
    • 正确得 1 分,错误得 0 分,或加入格式奖励等。
  • 代码题:
    • 把模型生成的代码放进执行环境;
    • 跑一组测试用例;
    • 按通过用例的比例给分。

这类奖励不需要额外模型推理,只依赖任务逻辑,因此在“最标准”的 run_deepseek7b_llm.sh 例子中,我们没有看到 reward.reward_model.* 的配置,就是因为它完全用规则函数搞定奖励。

2.2 模型型(model-based)奖励:Reward Model

当需要模拟人类偏好或复杂评价标准时,规则往往不够,通常会单独训练一个 Reward Model

  • 输入:(prompt, response)
  • 输出:一个标量打分(越大越好,或越大越安全)。

VeRL 中配置这一部分的字段是:

reward:
  reward_model:
    enable: true
    model_path: deepseek-ai/deepseek-llm-7b-chat
    rollout:
      name: vllm
      gpu_memory_utilization: 0.8
      tensor_model_parallel_size: 4
      prompt_length: 256
      response_length: 128

这表示:

除了 PPO 在训练 Actor / Critic 时用到的推理外,再单独起一套 专门给 RM 用的推理引擎(这里是 vLLM),把 (prompt, response) 拼成文本,送进 RM,拿到 reward。


三、关键配置参数逐项解释

下面以我们在脚本里看到的几组参数为例,逐个拆解。

3.1 reward.num_workers=8

  • 含义:整个集群中用于计算奖励的并行 Worker 数量。
  • 作用:
    • PPO rollout 一次会产生大量 (prompt, response) 对;
    • num_workers=8 表示可以并行启动 8 个 Worker 进程 / Actor;
    • 每个 Worker 会接收一部分数据、独立调用 RM 或规则函数打分。

这对 RLHF、代码执行等计算开销较大的奖励尤为重要。

在只用简单规则函数的 GSM8K 例子中,可能直接使用默认值(比如 1),所以配置中没显式写出来。

3.2 reward.reward_model.enable=True

  • True:开启 模型型奖励路径
  • False:完全不用 RM,所有奖励源来自规则函数或其他逻辑。

RLHF 相关脚本基本都会打开这个开关,因为偏好建模的核心就是 RM

3.3 reward.reward_model.model_path=deepseek-ai/deepseek-llm-7b-chat

  • 指向一个已经训练好的 Reward Model 的权重:
    • 可以是本地目录:~/models/my-rm-v1/
    • 也可以是 HuggingFace 仓库路径:org/model-name
  • VeRL 在 PPO 流程中只负责加载并推理,并不会训练这个 RM。

也就是说,训练 Reward Model 是一个前置步骤

  1. 在别的代码中(如 TRL 的 RewardTrainer)用 human feedback 数据训练好 RM;
  2. 把 checkpoint 放到某个路径;
  3. 在 VeRL 配置中把 model_path 指向这个路径。

如果直接用 deepseek-ai/deepseek-llm-7b-chat 作为 RM,那就是把一个通用 LLM 视作“黑盒打分器”,具体打分逻辑则在 reward 函数里组织。

3.4 reward.reward_model.rollout.*:RM 推理引擎配置

以这组为例:

reward.reward_model.rollout.name=vllm
reward.reward_model.rollout.gpu_memory_utilization=0.8
reward.reward_model.rollout.tensor_model_parallel_size=4
reward.reward_model.rollout.prompt_length=256
reward.reward_model.rollout.response_length=128

这几个字段的含义可类比于「给 Actor 配 rollout 引擎」:

  • name=vllm
    使用 vLLM 作为 RM 的推理引擎,适合大规模高吞吐推理。
  • gpu_memory_utilization=0.8
    每张 GPU 上,vLLM 占用可用显存的 80%。比例越大,可支持的 batch / 序列越长,但也更容易 OOM。
  • tensor_model_parallel_size=4
    Tensor Parallel = 4,把一个较大的 RM 拆到 4 张卡上做张量并行。
  • prompt_length=256response_length=128
    给 RM 的输入会先被 tokenizer tokenize,并按这两个上限截断:
    • prompt_lengthprompt 对应的 token 最大长度;
    • response_lengthresponse 对应的 token 最大长度。

整体直觉:RM 有自己独立的一套 vLLM 服务,我们可以单独为它调优显存、并行度与长度上限,而不用和 PPO 主 Actor 的配置绑死。

3.5 Sandbox Fusion 与 reward.reward_manager.name=prime

在代码任务中,常见做法是:让 LLM 写出代码,再实际执行,根据执行行为和结果给奖励。

VeRL 提供了一套与 远程代码执行服务(Sandbox Fusion) 集成的机制,对应参数:

reward.sandbox_fusion.url='https://xxxx.apigateway-cn-beijing.volceapi.com/run_code'
reward.sandbox_fusion.max_concurrent=128
reward.reward_manager.name=prime
  • reward.sandbox_fusion.url

    • 指向一个 FaaS 服务的 HTTP 接口;
    • 模型生成的代码将被发送到此 URL 执行;
    • 返回 stdout、错误信息、测试用例结果等,再转换为 reward。
  • reward.sandbox_fusion.max_concurrent

    • 控制对该接口的最大并发请求数
    • 防止一轮 PPO 中产生大量代码执行请求,直接把后端服务打垮。
  • reward.reward_manager.name=prime

    • 指定使用 PRIME RewardManager

    • 相比简单的 naive 管理器,prime 更适合:

      • 大量代码执行 / 复杂验证;
      • 多进程并行、融合多种 reward 源(RM+规则+Sandbox 等)。

在纯数学任务中不需要代码执行,自然就不会设置这些字段。


四、Reward Model 在 VeRL 中的“真实工作流”

下面聚焦回答三个问题:

  1. RM 从哪来?
  2. 与 RM 的“交互协议”是什么?
  3. PPO 如何消费 RM 输出的 reward?

4.1 Reward Model 的来源:VeRL 不负责训练,只负责推理

在 VeRL 的 RLHF / 代码 RL 训练中:

  • 配置中的 reward.reward_model.model_path 必须指向一个已经训练好的 RM
  • VeRL 并不包含 RM 训练逻辑,只在 PPO 期间调用 RM 推理;
  • 如果我们希望用自定义 RM,需要在外部先完成如下步骤:
    1. 准备人类偏好数据(pairwise 或打分);
    2. 用 TRL、Transformers 等工具训练 RM;
    3. 将权重保存,并在 VeRL 中配置好路径。

因此,VeRL 内部把 RM 抽象成一个:

输入 (prompt, response),输出 reward 标量的黑盒打分服务。

4.2 输入给 Reward Model 的数据格式

在逻辑上:

  • 每一个 rollout 样本包含:
    • question / prompt;
    • model_response / answer

在实现上,Reward Loop 会把它们打包成一个数据结构(可以理解为一个 DataProto)并传给 Worker。在 Worker 中:

  1. 将二者按固定模板拼接为一段文本,例如:

    Question: {question}
    Answer: {model_response}
    

    或 Chat 模板:

    <user> {question} </user>
    <assistant> {model_response} </assistant>
    
  2. 使用 RM 对应的 tokenizer 编码;

  3. prompt_lengthresponse_length 截断 token;

  4. 送入 vLLM / HF 模型前向推理。

所以,可以把 RM 的逻辑输入看作是:

一条由 questionresponse 拼接得到的、长度受限的文本。

4.3 Reward Model 的输出格式与 PPO 的使用方式

Reward Loop 的接口约定为:每条数据返回一个字典 (dict),其中包含至少一个 reward 标量字段。

几种典型情况:

  1. 纯规则奖励(无 RM)

    {"score": float_value}
    
  2. 判别式 Reward Model(DisRM)

    模型输出一个或多个 logit,通过简单变换得到 reward:

    {"reward_score": rm_score}
    
  3. 生成式 Reward Model(GenRM)

    在自定义 reward 函数里:

    1. 给 RM 一个“评审 prompt”(如“请在 0–10 分打分并只输出数字”);

    2. 让 RM 生成一段文本;

    3. 自己解析文本中的分数;

    4. 返回:

      {"score": parsed_score}
      

上层 PPO 不关心这个 dict 里具体字段名叫什么,它只会在 RewardManager 里把对应字段抽出来,拼成一个 reward_tensor,与 Critic 输出的 value 一起计算:

  • advantage;
  • PPO loss;
  • 进而更新 Actor / Critic 参数。

五、从用户视角看完整训练链路

把上述所有内容串起来,从“写配置”到“PPO 更新”可以用下面这条线来理解:

  1. 事先准备好 RM(可复用现有模型,也可自己训练)。

  2. 在 VeRL 的配置中写入:

    reward:
      num_workers: 8
      reward_model:
        enable: true
        model_path: ~/models/my-rm-v1
        rollout:
          name: vllm
          gpu_memory_utilization: 0.8
          tensor_model_parallel_size: 4
          prompt_length: 256
          response_length: 128
      # 如果用生成式 RM,还可能配置自定义 reward 函数
      # custom_reward_function:
      #   path: path.to.my_reward_fn
    
  3. 启动 PPO 训练时:

    • Actor 使用自己的 rollout 配置生成一批 (prompt, response)
    • 这批数据被送入 Reward Loop,分发给 num_workers 个 RewardLoopWorker。
  4. 每个 RewardLoopWorker:

    • (prompt, response) 拼接为文本;
    • 经 tokenizer 变成 token 序列;
    • 按长度上限截断;
    • 调用 RM 推理(vLLM / HF 等);
    • 解析输出得到标量 reward;
    • 返回格式为 {"reward_score": float}{"score": float}
  5. RewardManager 将这些 reward 按 batch 整合;

  6. PPO 拿到 reward 后,结合 value 估计计算 advantage,完成一次更新。

如果任务还启用了 Sandbox Fusion:

  • 中间在 Reward Loop 中还会多一步:
    • 从模型生成中解析出“代码调用”;
    • 将代码发到 sandbox_fusion.url
    • 根据执行结果更新或修正 reward;
  • prime 管理器负责调度多进程执行与奖励融合。

六、总结

从 PPO 的视角看,VeRL 通过 reward.* 配置构建了一套高度模块化的奖励计算子系统

  • 支持 规则型模型型 奖励;
  • 支持额外的 代码执行与工具调用
  • 通过 RewardManager 管理不同奖励源的并发、融合与调度;
  • 通过 reward.reward_model.rollout.* 为 Reward Model 配置独立的高性能推理后端。

理解这些之后,reward.num_workersreward.reward_model.enablemodel_pathrollout.*sandbox_fusion.*reward_manager.name=prime 等参数就不再是“黑盒魔法”,而是整个系统设计中清晰可解释的一部分。

这也是大型语言模型 RL 系统工程的一个重要趋势:用清晰的配置接口,把策略、奖励、工具调用分离出来,既便于研究,也便于工程落地。

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐