
文档教程人工智能大模型RLHF【免费下载链接】Awesome-ML-SYS-TutorialMy learning notes for ML SYS.项目地址https://gitcode.com/gh_mirrors/aw/Awesome-ML-SYS-Tutorial点击查看免费下载本文围绕 SPPO 的 loss 公式推导与工程实现展开从 SPINSPO原文的在线偏好损失出发结合 Kimi K1.5 的奖励式替代形式给出最终落地公式与逐行代码解析并基于作者在 verl 上的 fork 实现去除 critic、以 reward 直传 loss说明完整的训练流程、环境搭建与 PPO-RM / GRPO 对比实验配置。读完后你将掌握 SPPO 损失的数学含义、compute_sppo_loss中各聚合模式loss_agg_mode的语义差异以及如何在 4 卡机器上复现这套训练链路。1. SPPO 定位去掉 Critic 的奖励驱动 PPO 变体SPPOSquared Preference-based Policy Optimization的设计动机来自对 PPO 在 RLHF 中成本结构的观察PPO 需要额外维护并训练一个与 actor 同规模的 criticvalue model其训练与存储开销显著。作者在 rlhf/verl/sppo/dev-log.md 中给出的结论非常直接sppo 相比 Verl 自己实现的 ppo主要区别是不使用 critic以及要修改 loss传入 rewards。也就是说SPPO 保留了 PPO 的 on-policy rollout 与 importance ratio 结构但把 critic 的价值估计从优化目标中整体移除转而由reward 直接驱动策略更新。其思想来源有两条SPIN / SPO 一系通过 $\log \frac{\pi_\theta(y|x)}{\pi_t(y|x)}$新旧策略对数概率比与样本是否优于当前策略的偏好信号做平方误差回归避免显式的 value baselineKimi K1.5 一系用标量 reward 与重要性比的对数项构造平方 loss并通过采样近似配分函数项 $\tau \log Z$。SPPO 最终把两者合并用 reward model 的打分替代 SPIN 中昂贵的偏好概率估计得到一节可微、可并行、可直接嵌入 verl PPO 数据流的 loss。下文先给出公式演进再对照实现代码。2. Loss 公式演进从 SPIN 到最终形式本节完整继承 rlhf/verl/sppo/paper.md 的推导脉络。2.1 SPO 原文的在线偏好损失SPOSPIN 系列原文的 loss 定义为$$ \theta_{t1} \leftarrow \arg\min_{\theta} , \mathbb{E}_{(\mathbf{x}, \mathbf{y}, \widehat{P}(y \succ \pi_t \mid \mathbf{x})) \sim \mathcal{D}t} \left( \log \left( \frac{\pi\theta(\mathbf{y} \mid \mathbf{x})}{\pi_t(\mathbf{y} \mid \mathbf{x})} \right) - \eta \left( \widehat{P}(y \succ \pi_t \mid \mathbf{x}) - \frac{1}{2} \right) \right)^2 $$其中 $\widehat{P}(y \succ \pi_t \mid \mathbf{x})$ 表示样本 $y$ 优于旧策略 $\pi_t$ 采样分布的偏好概率。直觉上当 $y$ 明显好于 $\pi_t$$\widehat{P}$ 接近 1时loss 希望 $\log \frac{\pi_\theta}{\pi_t}$ 变大增大该轨迹概率反之则压小。$\frac{1}{2}$ 是让无偏好对应零目标。问题在于$\widehat{P}(y \succ \pi_t \mid \mathbf{x})$ 需要以 $\pi_t$ 的在线采样为参照进行偏好估计judge/对比打分计算效率偏低且在线场景下每轮都要重估。2.2 用 Kimi K1.5 的奖励式 loss 替代文档给出的替代形式Kimi K1.5 中的 loss是$$ L(\theta) \mathbb{E}{(x, y^*) \sim \mathcal{D}} \left[ \mathbb{E}{(y, z) \sim \pi_{\theta_i}} \left[ \left( r(x, y, y^*) - \tau \log Z - \tau \log \frac{\pi_\theta(y, z \mid x)}{\pi_{\theta_i}(y, z \mid x)} \right)^2 \right] \right] $$这里 $r(x, y, y^)$ 是样本 $y$在参考 $y^$ 语境下的标量 reward$\tau \log Z$ 是配分函数项末项仍是重要性对数比乘以温度 $\tau$。平方结构意味着该 loss 在做一种以 reward 减去配分基线为目标、调节策略相对旧策略的对数概率的回归。2.3 配分函数项 $\tau \log Z$ 的采样近似$\tau \log Z$ 无法解析计算文档采用 $k$ 个来自 $\pi_{\theta_i}$ 的采样 $(y_1, z_1), \ldots, (y_k, z_k)$ 做 log-sum-exp 近似$$ \tau \log Z \approx \tau \log \frac{1}{k} \sum_{j1}^{k} \exp\left( \frac{r(x, y_j, y^*)}{\tau} \right) $$并且指出一个更省事的经验替代——直接使用采样 reward 的经验均值$$ \bar{r} \text{mean}(r(x, y_1, y^), \ldots, r(x, y_k, y^)) $$原文解释其合理性当 $\tau \to \infty$ 时$\tau \log Z$ 趋近于 $\pi_{\theta_i}$ 下的期望 reward即 softmax 平均在温度趋于无穷时退化为算术平均因此经验均值是一个自然且有效的近似。2.4 最终落地公式将 reward 直接作为偏好信号、经验基线 $0.5$可视为归一化 reward 的中点作为基线后SPPO 最终使用的更新式为$$ \theta_{t1} \leftarrow \arg\min_{\theta} , \mathbb{E}_{(\mathbf{x}, \mathbf{y}, \widehat{P}(y \succ \pi_t \mid \mathbf{x})) \sim \mathcal{D}t} \left( \log \left( \frac{\pi\theta(\mathbf{y} \mid \mathbf{x})}{\pi_t(\mathbf{y} \mid \mathbf{x})} \right)\eta \left( r(x, y, y^*) - \frac{1}{2} \right) \right)^2 $$关键特征无 critic优化目标里没有 value functionreward 直接进入 loss二阶回归结构对重要性对数比 − 缩放 reward取平方梯度在 ratio 与目标接近时自然衰减行为上类似带隐式 KL 惩罚的 reward 回归$\eta$ 与 $0.5$ 基线$\eta$ 控制 reward 的放大倍数$0.5$ 偏移要求 reward 处于 $[0, 1]$ 量纲如 reward model sigmoid 打分使好坏各半的样本目标为 0。3.compute_sppo_loss实现逐段解析以下是 rlhf/verl/sppo/paper.md 中给出的参考实现作者在其 verl fork 的 sppo 分支中落地def compute_sppo_loss( old_log_prob: torch.Tensor, # (bs, seq_len) log_prob: torch.Tensor, # (bs, seq_len) rewards: torch.Tensor, # (bs,) response_mask: torch.Tensor, # (bs, seq_len) eta: float 1.0, loss_agg_mode: str seq-mean-token-sum ): SPPO Loss computation. # Compute log-ratios over masked tokens log_prob_sum (log_prob * response_mask).sum(dim1) # (bs,) old_log_prob_sum (old_log_prob * response_mask).sum(dim1) # (bs,) log_ratios log_prob_sum - old_log_prob_sum # (bs,) scaled_rewards eta * (rewards - 0.5) loss_vec (log_ratios - scaled_rewards) ** 2 # (bs,) if loss_agg_mode seq-mean-token-sum: loss loss_vec.mean() elif loss_agg_mode seq-mean-token-mean: seq_lengths response_mask.sum(dim1) # (bs,) token_mean_loss loss_vec / seq_lengths.clamp(min1) loss token_mean_loss.mean() elif loss_agg_mode token-mean: sample_mask response_mask.any(dim1).float() # (bs,) loss verl_F.masked_mean(loss_vec, sample_mask) else: raise ValueError(fUnsupported loss_agg_mode: {loss_agg_mode}) return loss, log_ratios, scaled_rewards逐段说明3.1 输入张量与量纲参数形状含义old_log_prob(bs, seq_len)旧策略rollout 时在 response 各 token 上的 log problog_prob(bs, seq_len)当前策略可微在同一位置上的 log probrewards(bs,)每条样本的标量 reward通常来自 reward model需归一化到约 $[0,1]$response_mask(bs, seq_len)只对 response 部分不含 prompt、padding计入统计etafloatreward 缩放系数对应公式中的 $\eta$默认 1.0loss_agg_modestr聚合方式见 3.3 节3.2 序列级重要性对数比log_ratios (log_prob - old_log_prob).mask_sum(dim1)在数学上等于 $\log \frac{\pi_\theta(y|x)}{\pi_t(y|x)}$ 的 token 级累加response 内逐 token 对数概率之差再求和即把 token 级 ratio 聚合为序列级标量——这与公式中整体 $\log \frac{\pi_\theta(\mathbf{y} \mid \mathbf{x})}{\pi_t(\mathbf{y} \mid \mathbf{x})}$ 的形式一致。注意两点实现细节乘response_mask后sum保证 prompt token 与 padding 不进入 ratio平方误差在序列标量层面计算loss_vec形状(bs,)而不是逐 token 平方——这是 SPPO 与 PPO 逐 token policy loss 的结构性差别。3.3 三种聚合模式的语义差异模式计算语义seq-mean-token-sum默认loss_vec.mean()先对 token 求和成序列 loss再对 batch 求均值长序列天然获得更大权重seq-mean-token-meanloss_vec / seq_lengths后取均值先对 token 求均值消除长度偏置成序列 loss再对 batch 求均值token-meanmasked_mean(loss_vec, sample_mask)对有效样本做加权平均跳过全空样本这三种命名沿用了 verl 中loss_agg_mode的既有约定PPO 侧 policy loss 也使用同族命名从源码结构看这一设计使得 SPPO 可以复用 verl PPO trainer 的数据流与统计口径改动面被压缩到 loss 函数本身。返回的log_ratios与scaled_rewards通常用于 wandb 打点观察 ratio 是否贴住 $\eta(r - 0.5)$ 的目标曲线——这是验证 loss 实现正确性的直接手段。3.4 与公式的逐项对应公式项代码项$\log \frac{\pi_\theta(\mathbf{y} \mid \mathbf{x})}{\pi_t(\mathbf{y} \mid \mathbf{x})}$log_ratios$\eta (r(x, y, y^*) - 0.5)$scaled_rewards平方(log_ratios - scaled_rewards) ** 2$\mathbb{E}_{\mathcal{D}_t}$按loss_agg_mode对 batch 聚合4. 在 verl 中的实现架构rlhf/verl/sppo/dev-log.md 记录了实现路径的选择与最终架构。作者评估过两条路按 verl 官方 DPO 扩展教程single-controller 数据流从零实现 SPPO学习 PPO 源码复用 PPO 全链路仅做去 critic 改 loss的最小化修改。最终选择了第 2 条原因是难以判断 PPO 实现路径上哪些逻辑对 verl 是必要的。落地结构为一条覆盖override链main_sppo - override trainer fit() - fsdp_workers.ActorRolloutRefWorker override init_model() - DataParallelPPOActor override update_policy - update_policy即main_sppo基于原有 PPO 入口修改适配 SPPO 流程不初始化 criticRaySPPOTrainer最大程度重用 PPO Trainer 逻辑在fit()中实现 SPPO 的更新顺序——rollout 后不再计算 value而是拿 reward 直接进 actor 更新DataParallelPPOActor.update_policy被 override 后调用compute_sppo_lossreward 随 batch 传入文档同时标注了遗留问题Megatron 后端megatron_workers.ActorRolloutRefWorker尚未适配当前验证仅覆盖 FSDP 路径。算法正确性的验收标准是 val_score 的上升作者记录val_score 从 0.78 提升到 0.92数学任务、Qwen2.5-7B-Instruct确认 loss 实现与 PPO 同向有效。5. 环境搭建与复现步骤以下内容整理自 rlhf/verl/sppo/test-log.md 与 rlhf/verl/sppo/compare_with_ppo_grpo.md适用前提4 卡单机作者在 H20x4 上验证、verl fork 的 sppo 分支、SGLang 作为 rollout 引擎。5.1 容器与依赖# 1. 构建容器SGLang dev 镜像共享内存 32g docker run -it --shm-size 32g --gpus all \ -v {CACHE PATH}:/root/.cache \ --ipchost --networkhost --privileged \ --name verl_sppo lmsysorg/sglang:dev /bin/zsh # 2. 安装 verlsppo 分支 python3 -m uv pip install -e .[sglang] # 在 verl fork 仓库内执行 # 3. 准备数据与模型 python3 examples/data_preprocess/math_dataset.py --local_dir ~/data/math huggingface-cli download Qwen/Qwen2.5-7B-Instruct --local-dir $HOME/models/Qwen2.5-7B-Instruct # PPO-RM 基线额外需要 reward model huggingface-cli download sfairXC/FsfairX-LLaMA3-RM-v0.1 --local-dir $HOME/models/FsfairX-LLaMA3-RM-v0.1注意 test-log 中的安装步骤包含在容器内安装 Python 3.10、flash-attn--no-build-isolation --no-deps、rust 工具链verl 部分组件构建依赖等细节完整步骤以 rlhf/verl/sppo/test-log.md 为准。5.2 启动训练export CUDA_VISIBLE_DEVICES0,1,2,3 cd recipe/sppo bash run_qwen2.5-7b_rm.sh5.3 对比实验PPO-RM 与 GRPO 的关键参数rlhf/verl/sppo/compare_with_ppo_grpo.md 给出了两条基线脚本均基于python3 -m verl.trainer.main_ppo4 卡、Qwen2.5-7B-Instruct、math 数据集、train_batch_size1024、max_prompt_length1024、max_response_length512核心差异如下配置项PPO-RMGRPOalgorithm.adv_estimatorgaegrpocritic启用critic.model.path复用 actor 底座lr1e-5micro bs16不需要rewardreward_model.enableTrue FsfairX-LLaMA3-RMrule-based数据内答案比对actor.use_kl_lossFalseTruekl_loss_coef0.001,kl_loss_typelow_var_klrollout.n1默认val_kwargs.n25组内采样 5 条算相对优势ref model不加载加载ref.fsdp_config.param_offloadTrueoffload 省显存其他共同项lr1e-6、mini bs256、micro bs4、rollout.namesglang、gpu_memory_utilization0.3同左这条对照线的意义在于SPPO 的目标正是在不引入 critic对齐 GRPO 的省成本诉求也不依赖 rollout 组采样数对齐 reward model 的稠密信号的前提下取得可比效果脚本中trainer.experiment_name分别为PPO-RM/GRPO便于在 wandb 同一 projectsppo-sglang下对齐观察。6. 小结SPPO 的本质是把 PPO 的ratio − value baseline替换为ratio − 缩放 reward的平方回归用 SPIN 的在线偏好框架与 Kimi K1.5 的 reward 近似经验均值替代 $\tau \log Z$去掉了 critic实现侧的关键是最小侵入override verl 的fit()、init_model()与update_policy三处即可复用 PPO 全链路loss 命名与loss_agg_mode聚合约定保持与 verl 一致验证侧应同时观察 val_score 曲线与log_ratios对scaled_rewards的贴合度环境上以 4 卡 SGLang rollout 容器为最低配置已知边界当前实现路径基于 FSDP workerMegatron 后端尚未适配reward 需归一化到 $[0,1]$ 量纲以匹配 $0.5$ 基线假设。赞分享文档教程人工智能大模型RLHF【免费下载链接】Awesome-ML-SYS-TutorialMy learning notes for ML SYS.项目地址https://gitcode.com/gh_mirrors/aw/Awesome-ML-SYS-Tutorial点击查看免费下载相关推荐verl奖励函数设计数据集奖励机制实现verl奖励函数设计数据集奖励机制实现 引言 在大语言模型LLM的强化学习训练中奖励函数设计是决定训练效果的关键因素。verlVolcano Engi人工智能大模型强化学习RLHF分布式训练微调在verl项目中实现基于生成模型的奖励函数设计在verl项目中实现基于生成模型的奖励函数设计 概述 在强化学习训练过程中奖励函数的设计至关重要它直接影响着智能体的学习效果和行为模式。传统方法通常采用人工人工智能大模型强化学习RLHF分布式训练微调Flet 0.85.0 破坏性变更margin、padding、border、border_radius 模块级辅助函数移除与迁移指南Flet 0.85.0 破坏性变更margin、padding、border、border_radius 模块级辅助函数移除与迁移指南 导读 本文面向升级到前端跨平台桌面应用移动开发上一篇VeighNa 4.4.0基于 Python 的开源量化交易系统开发框架——事件驱动核心与 AI 多因子投研实战指南下一篇Font Awesome图标库性能优化终极指南如何让网站加载速度提升3倍创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考