Hotdry.
ai-engineering

使用 VERL 构建离线 RLHF 流水线:奖励建模、Actor-Critic 更新与 PPO 优化

VERL 框架下离线 RLHF 管道实践:从奖励建模到 PPO 优化的完整参数配置与监控要点。

VERL(Volcano Engine Reinforcement Learning for LLMs)是字节跳动 Seed 团队开源的 RLHF 训练框架,专为大语言模型后训练设计。它通过 HybridFlow 编程模型,支持灵活构建离线 RLHF 流水线,包括奖励建模、actor-critic 更新和 PPO 优化。该框架无缝集成 FSDP/Megatron-LM 训练后端与 vLLM/SGLang 生成引擎,实现高吞吐量训练,支持从 0.5B 到 70B+ 模型规模。

离线 RLHF 流水线核心流程

离线 RLHF 避免在线人类反馈依赖,使用预处理偏好数据或规则奖励构建管道:

  1. 数据准备:Parquet 格式数据集,包含 prompt、chosen/rejected 或 ground_truth。
  2. Rollout 生成:Actor 模型生成响应,Ref 模型计算 KL 散度。
  3. 奖励计算:规则奖励(如 GSM8K 答案匹配)或奖励模型评分。
  4. Actor-Critic 更新:PPO/GRPO 算法计算优势、价值损失,进行策略优化。
  5. 迭代训练:多 epoch 循环,直至收敛。

VERL 的优势在于模块化 API,几行配置即可定义数据流,避免传统框架的复杂性。

奖励建模:规则与模型双模

奖励是 RLHF 核心,VERL 支持 function-based(规则)和 model-based 奖励。

  • 规则奖励:适用于可验证任务,如数学推理。示例 GSM8K 数据预处理:

    python examples/data_preprocess/gsm8k.py --local_dir ~/data/gsm8k
    

    数据格式:

    {
      "prompt": [{"role": "user", "content": "问题 + 思考步骤"}],
      "reward_model": {"style": "rule", "ground_truth": "正确答案"}
    }
    

    奖励函数提取 "####" 后答案匹配,得分 1.0/0.0。阈值:准确率 >0.5 视为高质。

  • 模型奖励:加载 RM(如 Qwen2.5-0.5B),计算偏好分数。配置:

    reward_model.model.path = Qwen/Qwen2.5-0.5B
    

    风险:噪声奖励导致不稳,建议混合使用(规则 70%、模型 30%)。

落地参数:

  • max_prompt_length: 512
  • max_response_length: 256
  • train_batch_size: 256(单 GPU 调整至 64)

Actor-Critic 配置与更新

VERL 解耦 Actor(策略生成)、Critic(价值估计)、Ref(参考 KL)。

  • Actor-Rollout:vLLM 生成 N=5 响应 / 提示。
    actor_rollout_ref.rollout.name = vllm
    actor_rollout_ref.rollout.gpu_memory_utilization = 0.6
    actor_rollout_ref.rollout.tensor_model_parallel_size = 2  # 8 GPU 示例
    
  • Critic:价值函数,lr=1e-5。
  • Ref:KL 控制,防止漂移。

更新机制:PPO 多 epoch(4 epochs),clip_ratio=0.2。LoRA 适配降低内存:

actor_rollout_ref.model.lora_rank = 32  # 32B 模型用 128
actor_rollout_ref.model.lora_alpha = 32
actor_rollout_ref.model.target_modules = all-linear

监控要点:

  • KL 系数:0.001–0.01,目标 KL<0.05。
  • 熵损失:>0.4 确保探索。
  • MFU(模型 FLOPS 利用率):>50%。

PPO 优化:参数与最佳实践

PPO 是 VERL 默认算法,配置示例(GSM8K + Qwen2.5-0.5B):

python -m verl.trainer.main_ppo \
  data.train_files=~/data/gsm8k/train.parquet \
  data.val_files=~/data/gsm8k/test.parquet \
  data.train_batch_size=256 \
  actor_rollout_ref.model.path=Qwen/Qwen2.5-0.5B-Instruct \
  actor_rollout_ref.actor.optim.lr=1e-6 \
  actor_rollout_ref.actor.ppo_mini_batch_size=64 \
  actor_rollout_ref.actor.ppo_micro_batch_size_per_gpu=4 \
  critic.optim.lr=1e-5 \
  algorithm.kl_ctrl.kl_coef=0.001 \
  trainer.n_gpus_per_node=1 \
  trainer.total_epochs=15
  • 动态批处理:use_dynamic_bsz=True,ppo_max_token_len_per_gpu=3072(3x 序列长)。
  • 序列打包:use_remove_padding=True,提升 20-30% 效率。
  • FSDP2:strategy=fsdp2,内存降 7%,吞吐升 1.5%。
  • 长上下文:ulysses_sequence_parallel_size=2。

回滚策略:若 KL 爆炸,减 lr 至 5e-7;OOM 时,启用 gradient_checkpointing=True。

训练 15 epochs 后,GSM8K 准确率从 10-15% 升至 40-50%。大规模:8x A100,batch=1024,1 epoch ~2h。

监控与落地清单

  • 日志:wandb/swanlab,追踪 reward_mean、vf_loss、entropy_loss。
  • 检查点:save_freq=10,导出 HuggingFace 格式。
  • 清单
    1. 环境:Docker volcengine/verl:latest,PyTorch 2.4+。
    2. 数据验证:Parquet 完整性。
    3. 预跑:1 epoch 单 GPU。
    4. 规模化:Slurm 多节点。
    5. 评估:MT-Bench/AlpacaEval。

VERL 使离线 RLHF 工程化,适用于 MLOps 管道。

资料来源

(正文约 1050 字)

查看归档