PPO是一种传统的强化学习方法,在RLHF (Reinforcement Learning from Human Feedback)中应用广泛:
基本组成:
训练流程:
核心公式:
L_PPO(θ) = E_π_old[ min(r(θ)A, clip(r(θ), 1-ε, 1+ε)A) ] - β·KL(π_θ || π_ref)
其中r(θ)是新旧策略的概率比,A是优势函数,后面是KL散度正则项。
优缺点:
DPO简化了RLHF过程,直接从偏好数据对中学习:
基本思想:
数学基础: DPO证明了在最优奖励模型下,可以将PPO的目标函数转换为:
L_DPO(θ) = -E_{(x,y_w,y_l)}[ log σ(β(log(π_θ(y_w|x)/π_ref(y_w|x)) - log(π_θ(y_l|x)/π_ref(y_l|x)))) ]
其中:
优势:
DPO算法中,Reference模型与Actor模型确实可以是同一个模型,但有以下考虑:
理论上:
use_ref_model
参数控制是否使用单独的参考模型use_ref_model=False
时,算法会使用不同的损失函数变体(如ORPO、SimPO)代码实现:
python# 在DPO训练器中
if not self.finetuning_args.use_ref_model:
if self.loss_type == "orpo":
losses = self.odds_ratio_loss(policy_chosen_logps, policy_rejected_logps)
elif self.loss_type == "simpo":
losses = self.simpo_loss(policy_chosen_logps, policy_rejected_logps)
else:
losses, chosen_rewards, rejected_rewards = self.dpo_loss(
policy_chosen_logps, policy_rejected_logps, reference_chosen_logps, reference_rejected_logps
)
实际考虑:
实现细节: 当不使用独立reference模型时,代码会临时禁用adapter以计算reference logits:
pythonif self.ref_model is None:
ref_model = model
ref_context = self.accelerator.unwrap_model(model).disable_adapter()
else:
ref_model = self.ref_model
ref_context = nullcontext()
实际应用中,对于资源受限情况可考虑使用同一模型,但为获得最佳效果,建议使用独立的reference模型。
在传统的DPO算法中,参考模型(reference model)是必需的组件,用于计算KL散度约束。但LLaMA-Factory提供了两种不同的工作模式:
use_ref_model=True
)使用标准DPO损失函数,需要两个模型:
pythonlosses, chosen_rewards, rejected_rewards = self.dpo_loss( policy_chosen_logps, policy_rejected_logps, reference_chosen_logps, reference_rejected_logps )
这里的DPO公式是:
L_DPO(θ) = -log σ(β(log(π_θ(y_w|x)/π_ref(y_w|x)) - log(π_θ(y_l|x)/π_ref(y_l|x))))
use_ref_model=False
)这是LLaMA-Factory的创新点,当无法或不想使用参考模型时,它提供了两种替代算法:
ORPO (Odds Ratio Policy Optimization):
pythondef odds_ratio_loss(self, chosen_logps, rejected_logps):
log_odds = (chosen_logps - rejected_logps) - (
torch.log1p(-torch.exp(chosen_logps)) -
torch.log1p(-torch.exp(rejected_logps))
)
sft_loss = -chosen_logps
odds_ratio_loss = -F.logsigmoid(log_odds)
orpo_loss = sft_loss + self.beta * odds_ratio_loss
return orpo_loss
ORPO使用概率比的对数几率,无需参考模型就能区分首选和拒绝样本。
SimPO (Simple Policy Optimization):
pythondef simpo_loss(self, chosen_logps, rejected_logps):
pi_logratios = chosen_logps - rejected_logps
gamma_logratios = self.simpo_gamma / self.beta
logits = pi_logratios - gamma_logratios
simpo_loss = -F.logsigmoid(self.beta * logits)
return simpo_loss
SimPO简化了目标函数,同时引入γ参数控制首选和拒绝样本之间的奖励边界。
这种设计的好处是:即使在内存受限或只有单模型情况下,也能进行偏好优化训练。这些变体通过巧妙的数学变换,消除了对参考模型的依赖,同时保持了偏好学习的核心思想。
您可以根据自己的资源和需求选择使用标准DPO(双模型)或这些单模型变体(ORPO/SimPO)。
本文作者:Dong
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC。本作品采用《知识共享署名-非商业性使用 4.0 国际许可协议》进行许可。您可以在非商业用途下自由转载和修改,但必须注明出处并提供原作者链接。 许可协议。转载请注明出处!