verl 中的 SPPO 自博弈偏好优化配方:从算法原理到 MATH 复现实践
发布时间:2026/9/13 23:01:47 作者:尧图编辑部 阅读量:1,286

verl 中的 SPPO 自博弈偏好优化配方从算法原理到 MATH 复现实践【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verlSelf-Play Preference OptimizationSPPO是一种不依赖 GPT-4 等强外部信号、仅靠模型与自身历史策略对弈即可完成对齐的偏好优化方法。本文基于 verl 官方社区配方文档 docs/algo/sppo.md完整讲解 SPPO 的核心思想、在 verl 框架中的复现步骤含 MATH 数据集预处理、依赖安装、训练脚本执行并结合仓库源码数据脚本、规则奖励、KL 控制与 PPO 配置给出源码级佐证帮助你从零复现Qwen2.5-7B-Instruct 在 MATH 上从 46.6 分提升至 65.6 分的完整实验。SPPO 算法背景与核心思想SPPO 对应论文Self-Play Preference Optimization for Language Model AlignmentarXiv: 2405.00675由 Yue Wu、Zhiqing Sun、Huizhuo Yuan 等学者提出。verl 在 docs/algo/sppo.md 中提供了该论文的社区配方recipe实现实现作者为 Yuhao Yang 与 Chenyang Zhao。该方法的核心动机是传统对齐方法如基于 GPT-4 生成偏好对或响应的 RLHF/DPO 流程依赖昂贵且不稳定的外部信号。SPPO 则通过**自博弈self-play**机制让当前策略与自身或其历史版本生成的数据进行偏好优化从而在不借助强外部模型的情况下显著提升 LLM 性能。文档明确指出SPPO 可以超越采用迭代式直接偏好优化iterative DPO训练的模型。SPPO 具备两个层面的保证理论层面算法有理论根基能够保证 LLM 在一般的、甚至不可传递intransitive的偏好关系下收敛到 von Neumann winner即纳什均衡Nash equilibrium意义上的最优策略实证层面论文通过多个数据集的广泛评测验证了有效性verl 配方则进一步在 MATH 数据集上给出了可复现的工程验证。verl 中的 SPPO 配方定位与组织在 verl 仓库中算法配方文档统一组织在 docs/algo/ 目录下如 ppo.md、dpo_extension.rst、sppo.md、spin.md 等并在 docs/index.rst 中登记索引。项目 README 也将 SPPO 列为 LLM 对齐配方之一见 README.md。需要说明的是SPPO 的训练脚本即文档中调用的recipe/sppo/run_qwen2.5-7b_rm.sh由 verl-recipe 社区配方仓库维护当前仓库的recipe/目录下未内置该脚本本文后续章节将给出完整的复现命令与每一步的仓库内依据确保即便脚本不在当前仓库你也能按照 verl 的标准 PPO 训练流程跑通实验。环境准备安装 verl 与 SGLang 依赖SPPO 实验基于 verl 的标准训练框架官方推荐的安装方式如下git clone gitgithub.com:verl-project/verl.git cd verl python3 -m uv pip install -e .[sglang]其中-e表示可编辑安装[sglang]表示安装 SGLang 推理后端对应的 extras 依赖。从仓库的 setup.py 可以看到sglangextras 具体包含sglang[srt,openai]0.5.8SGLang 推理服务端与 OpenAI 兼容接口torch2.9.1与 SGLang 配套的 PyTorch 版本tensordict0.8.0,0.10.0,!0.9.0verl 数据传输所需的张量字典库。setup.py中还定义了gpuliger-kernel、flash-attn、vllm、mathmath-verify、test等可选依赖组SPPO 实验按文档使用[sglang]即可。flash-attn 安装失败的兜底方案文档特别提示安装过程偶尔会失败在 flash-attn 上。若遇到该情况可手动分步安装python3 -m uv pip install wheel python3 -m uv pip install packaging python3 -m uv pip install flash-attn --no-build-isolation --no-deps--no-build-isolation表示复用当前环境已安装的 wheel/packaging 进行构建--no-deps跳过依赖自动解析从而绕开常见的构建环境问题。数据准备预处理 MATH 数据集实验使用 MATH 数据集对应 HuggingFace 上的DigitalLearningGmbH/MATH-lighteval镜像仓库预处理脚本为仓库内的 examples/data_preprocess/math_dataset.pypython3 examples/data_preprocess/math_dataset.py --local_dir ~/data/math从脚本源码examples/data_preprocess/math_dataset.py可以看到其核心逻辑加载数据源默认从 HuggingFace 加载DigitalLearningGmbH/MATH-lighteval也可通过--local_dataset_path指向本地原始数据构造指令在每个 problem 后拼接指令Lets think step by step and output the final answer within \boxed{}.引导模型逐步思考并以\boxed{}输出最终答案提取标准答案通过last_boxed_only_string与remove_boxed来自 verl/utils/reward_score/math_reward.py从官方 solution 中提取\boxed{}内的 ground truth组织数据字段每条数据包含data_source、promptOpenAI 风格的{role: user, content: ...}、ability: math、reward_model: {style: rule, ground_truth: solution}以及extra_info其中reward_model字段声明了该任务使用规则奖励rule-based reward输出格式在--local_dir指定目录下生成train.parquet、test.parquet并额外保存train_example.json、test_example.json各一条样本便于检查若传入--hdfs_dir还会同步到 HDFS。对应的规则奖励实现在 verl/utils/reward_score/math_reward.pycompute_score从模型输出中提取最后一个\boxed{}内的答案经字符串规范化is_equiv/strip_string与 ground truth 比对相等得 1.0否则为 0.0。这套抽取 boxed 答案 规范化比对的机制正是 MATH 上 SPPO 训练奖励信号的来源。下载基座模型并运行训练下载 Qwen2.5-7B-Instructhf download Qwen/Qwen2.5-7B-Instruct --local-dir $HOME/models/Qwen2.5-7B-Instruct使用 HuggingFace CLI 的hf download将基座模型下载到本地$HOME/models/Qwen2.5-7B-Instruct。运行 SPPO 训练脚本export WANDB_API_KEYYOUR_WANDB_API_KEY export CUDA_VISIBLE_DEVICES0,1,2,3 bash recipe/sppo/run_qwen2.5-7b_rm.shWANDB_API_KEY实验跟踪wandb所需verl 默认 logger 包含console与wandb见 verl/trainer/config/ppo_trainer.yaml不配置该环境变量会导致 wandb 上报失败CUDA_VISIBLE_DEVICES0,1,2,3指定 4 张 GPU 用于训练对应 verl 的 Ray worker 资源分配run_qwen2.5-7b_rm.shSPPO 社区配方脚本内部会以 verl 的标准 PPO 训练入口verl/trainer/main_ppo.py启动 20 个 epoch 的 SPPO 训练并启用参考模型ref以计算 KL 惩罚。训练入口与配置落点从 verl 的 PPO 训练配置 verl/trainer/config/ppo_trainer.yaml 可以看出这类配方脚本实际控制的关键配置包括trainer.total_epochs训练轮数SPPO 实验为 20 轮trainer.project_name/trainer.experiment_name实验跟踪与 checkpoint 目录命名默认落盘到checkpoints/${trainer.project_name}/${trainer.experiment_name}actor_rollout_ref.hybrid_engine: trueactor 与 rollout 共享引擎是 verl 默认的高效混合引擎模式algorithm.gamma: 1.0、algorithm.lam: 1.0GAE 折扣与 bias-variance 权衡参数SPPO 这类 token 级奖励场景通常取 1.0配置类定义见 verl/trainer/config/algorithm.py。实验结果MATH 上的 20 轮提升文档给出的核心实验结果是起点Qwen2.5-7B-Instruct 初始 MATH 得分46.6终点经过20 个 epoch的 SPPO 训练后得分65.6该成绩使模型大约跻身 [MATH leaderboard] 前 20 名。文档同时给出了重要的评估口径说明verl 内部的评估指标可能与 Qwen2.5-7B-Instruct 的官方评测方法不完全一致因此为了口径统一与公平比较只报告基于 verl 评估框架的结果。这意味着复现时若与你看到的第三方基准分数存在偏差属于评估方法差异而非训练失效。结合仓库源码这一评估口径的实现依据在于verl 的 MATH 规则奖励verl/utils/reward_score/math_reward.py与 EleutherAI lm-evaluation-harness 的 hendrycks_math 任务同源文件头部注明了改编来源但具体字符串规范化、\boxed{}解析策略与官方评测管道仍有细节差异这正是文档提醒内部评估指标可能不完全对齐的原因。源码级原理支撑SPPO 训练框架中的 KL 控制与奖励机制SPPO 属于偏好优化类算法其 verl 实现运行在通用 PPO 训练框架之上理解框架的 KL 惩罚与奖励注入机制有助于深入理解训练行为。参考模型与 in-reward KL 惩罚verl 的 PPO 配置支持两种 KL 惩罚路径actor loss 内置的use_kl_loss以及将 KL 直接计入 token 级奖励的use_kl_in_reward配置项见 verl/trainer/config/ppo_trainer.yaml类型定义见 verl/trainer/config/algorithm.py。当启用 in-reward KL 时参考模型ref会被加载训练流程调用 verl/trainer/ppo/ray_trainer.py 中的apply_kl_penalty依据当前策略与参考策略的对数概率差计算 KL 估计并施加到 token 级奖励上——这正是 SPPO 这类以自身为参照对齐方法在工程上落地的关键机制。KL 估计方式与自适应控制器algorithm.kl_penalty决定 KL 的估计方式verl 支持kl默认、abs、mse、low_var_kl、full等选项其具体数学形式实现在 verl/trainer/ppo/core_algos.py 中kl/k1直接取logprob - ref_logprob正向 KL 估计abs取绝对差值mse/k2取0.5 * (logprob - ref_logprob)^2low_var_kl/k3Schulman 的低方差 KL 近似ratio - kl - 1并对中间量做数值稳定截断full需要逐 token 词汇表 logits当前实现抛NotImplementedError。KL 系数既可固定FixedKLController也可使用自适应控制器verl/trainer/ppo/core_algos.pyAdaptiveKLController依据current_kl / target_kl的比例误差截断在 ±0.2按horizon步长动态调整kl_coef。对应配置项为 verl/trainer/config/algorithm.py 中的KLControlConfigtype、kl_coef、horizon、target_kl。配方脚本可按需在algorithm.kl_ctrl下覆盖这些字段。优势估计SPPO 配方基于 token 级奖励verl 通过algorithm.adv_estimator选择优势估计器gae、grpo、reinforce_plus_plus等见 verl/trainer/config/algorithm.py配合gamma、lam完成 GAE 计算。从源码结构看SPPO 与 DPO 类方法共享同一套 reward advantage policy update 流水线区别主要在于训练数据由自博弈生成这正体现了 verl 算法配方与训练框架解耦的设计理念。常见问题与注意事项flash-attn 编译失败按上文兜底方案先装wheel、packaging再以--no-build-isolation --no-deps安装 flash-attnwandb 无法上报确认WANDB_API_KEY已正确导出若无需外部跟踪可在配置中将trainer.logger收敛为[console]GPU 资源文档示例使用 4 张 GPUCUDA_VISIBLE_DEVICES0,1,2,3需要根据实际显存调整trainer.n_gpus_per_node与 batch 相关参数train_batch_size、max_prompt_length、max_response_length等均在 verl/trainer/config/ppo_trainer.yaml 中可查结果可比性verl 内部评估口径与官方评测存在差异对比第三方分数时需保持同一框架内比较数据下载lighteval/MATH原仓库在 HuggingFace 已不可用脚本已切换至DigitalLearningGmbH/MATH-lighteval镜像见 examples/data_preprocess/math_dataset.py无需手动处理。总结SPPO 为 LLM 对齐提供了一条不依赖 GPT-4 等强外部信号的路径通过自博弈与理论上的纳什均衡收敛保证在 MATH 等基准上取得了超越迭代 DPO 的效果。verl 社区配方完整覆盖了从数据预处理examples/data_preprocess/math_dataset.py、规则奖励verl/utils/reward_score/math_reward.py到训练框架verl/trainer/config/ppo_trainer.yaml、verl/trainer/ppo/ray_trainer.py的全链路使得Qwen2.5-7B-Instruct 在 MATH 上 46.6 → 65.6的复现只需寥寥几条命令即可完成。若想进一步了解 SPPO 与 SPIN 等其他自博弈配方的异同可继续阅读仓库中的 spin.md 与 baseline.md。【免费下载链接】verlverl/HybridFlow: A Flexible and Efficient RL Post-Training Framework项目地址: https://gitcode.com/GitHub_Trending/ve/verl创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考