VLM-R1源码解析
GROP方法
GRPO 是一种在线学习算法,它通过使用训练模型本身在训练期间生成的数据进行迭代改进。其理念是:最大程度利用生成补全,同时确保模型始终接近参考策略。
分为4个步骤:生成补全、计算奖励、估计KL散度、计算损失。
要点
引入critic:使用预测baseline改进奖励
使用绝对奖励,单纯比较大小,会导致:奖励波动大,以及对部分改进的激励不足;因此引入Critic:使用“预测baseline”来改进奖励
对于给定状态(\(s_t\))和动作(\(o_t\)),该baseline为价值函数\((V_\psi(s))\);训练目标由单纯的reward,转为超过该baseline的程度,由优势函数表示为: \[ A_t=r_t-V_\psi(s_t) \] 即训练中优化内容为: \[ \mathcal{J}_{adv}(\theta)=\mathbb{E}[A(o)] \\ where A(o)=r(o)-V_\psi(o) \] 通过减去baseline,降低了训练中的方差,为超出预期的动作提供更高的梯度信号;并对未达标的动作进行惩罚。
添加裁剪和最小值操作:防止过度更新
适度控制学习策略的更新程度:若单次更新太多,则可能走向极端值;若单次更新太少,则动力不足。应找到一个平衡点。
在Proximal Policy Optimization (PPO)中最大化以下目标函数: \[ \mathcal{J}_{adv}(\theta)=\mathbb{E}[q\sim P(Q), o\sim\pi_{\theta_{old}}(O|q)]\frac{1}{|o|}\sum_{t=1}^{|o|}\min[r_t(\theta)A_t, clip(r_t(\theta),1-\epsilon,1+\epsilon)A_t] \] 其中: \[ r_t(\theta)=\frac{\pi_{\theta}(o_t|q,o_{<t})}{\pi_{\theta_{old}}(o_t|q,o_{<t})} \] \(\pi_{\theta}\)和\(\pi_{\theta_{old}}\)分别是:当前策略模型、旧策略模型;\(q\)和\(o\)是从问题数据集和旧策略\(\pi_{\theta_{old}}\)中采样的问题和输出;超参数\(\epsilon\)用于稳定训练过程;优势\(A_i\)通过广义优势估计(GAE)计算。
防止作弊和极端策略:使用KL散度
如果只专注于最大化目标函数,可能会采用可疑手段,即生成有害或虚假内容,以人为提高某些奖励指标。为了减轻对奖励模型的过度优化,标准方法是:在每个标记的奖励中,添加一个来自参考模型(初始策略)的每个标记的KL惩罚,即: \[ r_t=r_\varphi(q,o_{\leq t})-\beta\log\frac{\pi_\theta(o_t|q,o_{<t})}{\pi_{ref}(o_t|q,o_{<t})} \] 其中,\(r\)是奖励模型,\(\pi_{ref}\)是参考模型,通常是初始的监督微调(SFT)模型,而\(\beta\)是KL惩罚项的系数。
然而,PPO 中的Critic(值函数)通常是一个与Actor(策略模型)大小相当的模型,这带来了显著的内存和计算负担;此外,在 LLMs 的上下文中,Critic在训练过程中被用作优势计算中的Baseline,但通常只有最后一个 token 会被奖励模型赋予奖励分数,这可能使得Critic的训练变得复杂。
为了解决这些问题,提出了 Group Relative Policy Optimization (GRPO),不再需要像PPO那样加入额外的Critic近似,而是直接使用多个采样输出的平均奖励作为Baseline,显著减少了训练资源的使用。
对于每个问题\(i\),GRPO从旧策略\(\pi_{\theta_{old}}\)中,采样出一组输出{\(i_1\),...,\(i_A\)},通过最大化以下目标函数优化策略模型:
其中,\(\epsilon\) 和 \(\beta\) 是超参数,\(\hat{A}_{i,t}\) 是基于组内奖励的相对优势估计。
与 PPO 不同,GRPO: 1. 直接使用奖励模型的输出来估计baseline,避免了训练一个复杂的Critic; 2. 直接在损失函数中加入策略模型和参考模型之间的 KL 散度来正则化,而不是在奖励中加入 KL 惩罚项,从而简化了训练过程。
使用下面的无偏估计来估计 KL 散度:
GRPO核心思想: 1. 无需为 Critic 设置单独的价值网络; 2. 对同一问题或状态,从旧策略中采样多个输出; 3. 将这些输出的平均奖励视为基准; 4. 任何高于平均值的都产生“正优势”,任何低于平均值的都产生“负优势”。
同时,GRPO保留了 PPO 的裁剪和 KL 机制,以确保稳定、合规的更新。
自定义训练器VLMGRPOTrainer
基于 Trainer
类扩展,实现了 Group Relative Policy
Optimization (GRPO) 方法的训练,该方法首次在论文DeepSeekMath: Pushing
the Limits of Mathematical Reasoning in Open Language
Models中提出。
GRPO Config参数
数据预处理参数
remove_unused_columns (Optional[bool])
:如果设置为True
,则仅保留数据集中的 "prompt" 列,默认值为False
。用于计算自定义奖励函数;max_prompt_length (Optional[int])
: prompt 的最大长度,默认值为512
(如果 prompt 长度超过此值,将会从左侧进行截断)num_generations (Optional[int])
:每个 prompt 生成的样本数量。全局批次大小(num_processes * per_device_batch_size)必须能被此值整除,默认值为8
;temperature (Optional[float])
:采样的温度值。温度越高,生成样本的随机性越高,默认值为0.9
;max_completion_length (Optional[int])
:生成的完成部分的最大长度,默认值为256
;ds3_gather_for_generation (bool)
:针对 DeepSpeed ZeRO-3 的设置。启用时,生成时会收集策略模型的权重,提升生成速度;如果禁用此选项,能够训练超过单个 GPU VRAM 容量的模型,但生成速度会更慢,并且与 vLLM 生成不兼容。默认值为True
。
生成加速相关参数(vLLM)
use_vllm (Optional[bool])
:是否使用 vLLM(一个用于生成的加速库)进行生成,如果设置为True
,则需要确保有一个 GPU 用于生成,而不是训练;默认为False
vllm_device (Optional[str])
:指定 vLLM 生成将运行的设备,例如 "cuda:1"。如果设置为 "auto"(默认值),系统会自动选择下一个可用的 GPU;vllm_gpu_memory_utilization (float)
:该值指定要为 vLLM 生成预留的 GPU 内存比例。数值范围为 0 到 1,较高的数值会增加 KV 缓存大小,从而提高模型的吞吐量,但如果过高,可能会导致内存不足(OOM)错误。默认值为0.9
;vllm_dtype (Optional[str])
:设置 vLLM 生成的数值类型。如果设置为 "auto",将基于模型配置自动选择数据类型;vllm_max_model_len (Optional[int])
:设置 vLLM 使用的最大模型长度。这对于减少vllm_gpu_memory_utilization
的情况下,可能会减少 KV 缓存大小。如果未设置,vLLM 将使用模型的上下文大小;vllm_enable_prefix_caching (Optional[bool])
:是否启用 vLLM 中的前缀缓存。若为True
(默认),确保模型和硬件支持此功能;vllm_guided_decoding_regex (Optional[str])
:用于 vLLM 指导解码的正则表达式。如果为None
(默认),则禁用指导解码。
训练控制参数
learning_rate (float)
:初始学习率,使用 AdamW 优化器。默认值为1e-6
,它替换了transformers.TrainingArguments
中的默认学习率;beta (float)
:KL 系数。值为0.0
时,参考模型不会加载,从而减少内存使用和提高训练速度。默认值为0.04
;num_iterations (int)
:每个批次的迭代次数(在算法中表示为\(\mu\))。默认值为 1;epsilon (float)
:用于裁剪的 epsilon 值。默认值为0.2
;reward_weights (Optional[list[float]])
:每个奖励函数的权重。如果为None
,则所有奖励函数的权重均为1.0
,默认值为None
;sync_ref_model (bool)
:是否每ref_model_sync_steps
步同步参考模型和活动模型,使用ref_model_mixup_alpha
参数进行混合。默认值为False
;ref_model_mixup_alpha (float)
:参考模型更新时的 \(\alpha\) 参数,控制当前策略和前一个参考策略之间的混合。默认值为0.6
。此参数必须与sync_ref_model=True
一起使用;ref_model_sync_steps (int)
:确定当前策略与参考策略同步的频率,单位为步数。默认值为512
,此参数必须与sync_ref_model=True
一起使用。
VLMGRPOTrainer
初始化
脚本grpo_rec.sh
1 | torchrun --nproc_per_node="8" \ // 每个节点上运行的进程数:使用的 GPU 数量 |
大规模GRPO:在多个节点上训练 70B+ 模型
在训练 Qwen2.5-72B 等大型模型时,需要进行几项关键优化,以提高训练效率并在多个 GPU 和节点之间扩展。包括: ### DeepSpeed ZeRO 第 3 阶段 利用数据并行性,在多个 GPU 和 CPU 之间分配模型状态(权重、梯度、优化器状态)