首页/知识库/偏好优化进阶:从 DPO 到 GRPO 的奖励优化范式

偏好优化进阶:从 DPO 到 GRPO 的奖励优化范式

🎮强化学习进阶✍️ AI Master📅 创建 2026-05-27📖 30 min 阅读
💡

文章摘要

从 PPO 之后的新一代偏好优化方法。深度解析 DPO、ORPO、KTO、GRPO 四种核心算法的数学原理、实现细节与适用场景,揭示为何 GRPO 成为数学推理模型训练的首选方案。

1为什么 PPO 之后还需要新的偏好优化方法?

在大型语言模型的对齐训练中,RLHF(Reinforcement Learning from Human Feedback)长期以来是业界标准方案。其核心流程包含三个阶段:首先使用人类标注的偏好数据训练一个奖励模型(Reward Model),然后用 PPO 算法基于奖励信号优化语言模型,最后通过 KL 散度约束防止模型偏离原始行为太远。

然而,PPO 方案存在三个根本性痛点。第一,奖励模型训练成本高——你需要一个独立的、与语言模型规模相当的奖励模型,训练它本身就需要大量标注数据和算力。第二,PPO 实现复杂且不稳定——需要同时维护策略模型、价值模型、参考模型三个网络,超参数调优困难,训练崩溃并不罕见。第三,价值函数估计偏差——价值网络的近似误差会在训练过程中累积,导致策略优化方向偏离最优路径。

2023 年 RLBench 团队提出的 DPO(Direct Preference Optimization)从根本上改变了这一范式。它的核心洞察极为优雅:既然最终目标是让语言模型符合人类偏好,为什么不直接从偏好数据优化语言模型本身,而要通过奖励模型这个中间商?DPO 证明了 PPO 的隐式奖励最大化目标可以通过一个等价变换直接表达为对语言模型的条件概率比值的优化。

这一理论突破打开了一个全新的研究方向:无需强化学习、无需奖励模型、无需价值网络,仅凭偏好数据就能完成对齐。随后的 ORPO、KTO、GRPO 等方法沿着不同维度扩展了这一思想,形成了 2025-2026 年大语言模型对齐领域最活跃的研究方向。

理解本节的关键是认识到:DPO 不是对 PPO 的'改进',而是一种'等价替代'。如果你只关心结果(模型符合人类偏好),DPO 提供了更短、更稳、更省算力的路径。

不要认为 DPO 在所有场景下都优于 PPO。在需要细粒度奖励信号的任务中(如代码生成中的编译通过率、对话中的多轮一致性),PPO 的显式奖励模型仍有不可替代的价值。

2DPO:直接偏好优化的数学原理

DPO 的理论基础源于对 RLHF 优化目标的数学重推导。在 RLHF 中,我们最大化的是期望奖励减去 KL 散度惩罚的目标函数。通过求解这个优化问题的闭式解,可以得到最优策略与奖励函数之间存在一个精确的映射关系。

DPO 的关键洞察在于:如果我们把奖励函数用策略和参考策略的概率比值表示出来,那么原始的 RLHF 目标就等价于一个可以直接在偏好数据上优化的损失函数。这个损失函数的形式非常简洁——它只依赖于模型在"获胜回复"和"失败回复"上的条件概率比值。

具体来说,给定一个偏好数据三元组(提示、获胜回复、失败回复),DPO 损失函数衡量的是模型给予获胜回复更高概率的程度。这个损失函数天然地鼓励模型增加获胜回复的生成概率、降低失败回复的生成概率,同时通过参考模型的 KL 约束防止过度优化导致的退化。

DPO 的最大优势在于训练极简。你只需要一个语言模型(策略模型)和一个冻结的参考模型,不需要奖励模型、不需要价值网络、不需要 PPO 中的采样和 GAE 估计。训练过程稳定、收敛快、超参数少,这使得 DPO 迅速成为开源社区对齐训练的首选方法。

然而 DPO 也有其局限性。它严格依赖成对偏好数据——对于每个提示,你必须同时拥有一个"好回复"和一个"坏回复"。这种数据标注成本依然不低,且成对比较的信息利用率不够高。此外,DPO 在偏好强度差异很大时容易出现梯度爆炸问题。

图表加载中…

实践 DPO 时,数据质量远比数据数量重要。1000 条高质量的人工偏好标注,通常优于 10000 条由弱模型自动生成的偏好数据。建议先用少量高质量数据验证训练流程,再扩大数据规模。

DPO 训练中对 beta 参数的设置极其关键。beta 控制 KL 约束的强度,过小会导致模型崩溃(输出极端化),过大会使优化失去效果(模型几乎不变化)。推荐从 beta=0.1 开始网格搜索。

3ORPO:几率比偏好优化的改进

ORPO(Odds Ratio Preference Optimization)由 Hong 等人在 2024 年提出,它的核心改进思路是将监督微调和对齐训练统一到一个损失函数中

传统方案需要两个阶段:先做 SFT(Supervised Fine-Tuning)让模型学会回答问题的格式和能力,再做偏好优化(如 DPO)让模型学会"回答得好"。ORPO 的创新在于,它发现 SFT 损失和偏好对齐损失可以通过几率比(Odds Ratio)的数学结构自然地融合在一起。

在 ORPO 中,每个 token 的生成概率不仅取决于它对"正确回复"的贡献,还取决于它相对于"错误回复"的相对优势。这种设计使得模型在学会"说什么"的同时,也学会了"怎么说得更好"。

ORPO 相比 DPO 的优势在于训练效率更高。由于省去了独立的 SFT 阶段,总体训练时间和算力消耗减少了约 40%。同时,ORPO 在小规模数据集上表现更加稳定,这对于算力有限的研究团队是一个重要优势。

从数学上看,ORPO 将 DPO 中的 sigmoid 函数替换为几率比的 log 变换,这使得梯度在偏好强度差异很大时更加平滑,避免了 DPO 的梯度爆炸问题。

代码示例:ORPO 损失函数的核心逻辑

python
import torch
import torch.nn.functional as F

def orpo_loss(
    model: torch.nn.Module,
    ref_model: torch.nn.Module,
    input_ids: torch.Tensor,
    chosen_ids: torch.Tensor,
    rejected_ids: torch.Tensor,
    beta: float = 0.1,
    lambda_odds: float = 0.5
):
    """
    ORPO 损失函数:统一 SFT + 偏好对齐
    
    参数:
        model: 当前策略模型
        ref_model: 冻结的参考模型
        input_ids: 提示词 token IDs
        chosen_ids: 获胜回复 token IDs
        rejected_ids: 失败回复 token IDs
        beta: KL 约束强度
        lambda_odds: 几率比损失权重
    """
    # 策略模型的 logits
    chosen_logits = model(input_ids=input_ids, labels=chosen_ids).logits
    rejected_logits = model(input_ids=input_ids, labels=rejected_ids).logits
    
    # 参考模型的 logits(冻结)
    with torch.no_grad():
        ref_chosen_logits = ref_model(input_ids=input_ids, labels=chosen_ids).logits
        ref_rejected_logits = ref_model(input_ids=input_ids, labels=rejected_ids).logits
    
    # 计算 SFT 损失(监督微调部分)
    sft_loss = F.cross_entropy(
        chosen_logits.view(-1, chosen_logits.size(-1)),
        chosen_ids.view(-1),
        ignore_index=-100
    )
    
    # 计算对数几率比(log odds ratio)
    log_odds_chosen = (chosen_logits - ref_chosen_logits).sum()
    log_odds_rejected = (rejected_logits - ref_rejected_logits).sum()
    log_odds_ratio = log_odds_chosen - log_odds_rejected
    
    # ORPO 偏好损失
    preference_loss = -F.logsigmoid(lambda_odds * log_odds_ratio)
    
    # 总损失 = SFT + 偏好对齐
    total_loss = sft_loss + beta * preference_loss
    
    return total_loss
图表加载中…

ORPO 的 lambda_odds 参数决定了 SFT 和偏好对齐的权重分配。如果你的模型已经做过充分的 SFT,可以调低 lambda_odds(0.3-0.5);如果从零开始,建议设为 0.5-0.7。

ORPO 统一了 SFT 和对齐训练,但也意味着你失去了分阶段调试的能力。如果训练出现问题,很难判断是 SFT 部分还是对齐部分的故障。建议先用纯 SFT 验证数据质量,再切换到 ORPO。

4KTO: Kahneman-Tversky 优化

KTO(Kahneman-Tversky Optimization)代表了一种完全不同的偏好优化思路。与 DPO 和 ORPO 需要的成对比较不同,KTO 只需要逐样本的二元信号——每个回复是好还是坏,不需要成对出现。

KTO 的理论基础源自行为经济学中的前景理论(Prospect Theory),由诺贝尔奖获得者 Kahneman 和 Tversky 提出。前景理论的核心发现是:人类对损失和收益的感知是不对称的——损失带来的痛苦大约是同量级收益带来快乐的两倍。

KTO 将这一心理学洞察应用到语言模型对齐中。它将回复分为"满意"和"不满意"两类,并为两类信号分配不同的权重。具体来说,不满意回复的权重是满意回复的两倍,这确保了模型在优化过程中更加关注避免产生差回复,而不是盲目追求好回复。

KTO 的最大优势在于数据获取成本最低。成对偏好标注需要标注者对两个回复进行比较判断,而 KTO 只需要标注者判断单个回复"好不好"。这意味着你可以使用更简单、更廉价的标注方案,甚至可以使用自动信号(如用户是否点击了"满意"按钮)作为训练数据。

在 2025-2026 年的实践中,KTO 被广泛应用于大规模弱监督对齐场景。当拥有百万级的用户交互数据但只有粗糙的二元反馈时,KTO 是唯一能充分利用这些数据的偏好优化方法。

代码示例:KTO 损失函数的核心逻辑

python
import torch
import torch.nn.functional as F

def kto_loss(
    model: torch.nn.Module,
    ref_model: torch.nn.Module,
    input_ids: torch.Tensor,
    output_ids: torch.Tensor,
    labels: torch.Tensor,  # 1=满意, 0=不满意
    beta: float = 0.1,
    desirability_weight: float = 1.0,
    undesirable_weight: float = 2.0  # 损失权重是收益的2倍
):
    """
    KTO 损失函数:基于前景理论的逐样本偏好优化
    
    参数:
        labels: 二元信号,1 表示满意回复,0 表示不满意回复
        undesirable_weight: 不满意样本的权重(默认是满意的2倍)
    """
    # 策略模型 log probs
    logits = model(input_ids=input_ids, labels=output_ids).logits
    log_probs = F.log_softmax(logits, dim=-1)
    
    # 参考模型 log probs(冻结)
    with torch.no_grad():
        ref_logits = ref_model(input_ids=input_ids, labels=output_ids).logits
        ref_log_probs = F.log_softmax(ref_logits, dim=-1)
    
    # KL 散度惩罚
    kl_div = (log_probs - ref_log_probs).sum()
    
    # 优势估计(相对于参考模型的提升)
    advantage = kl_div
    
    # 根据标签选择权重
    weights = torch.where(
        labels == 1,
        desirability_weight,
        undesirable_weight  # 不满意样本权重更大
    )
    
    # KTO 损失:前景理论的非线性映射
    # 满意样本:鼓励优势为正
    # 不满意样本:鼓励优势为负(远离差回复)
    loss = -weights * F.sigmoid(advantage).log()
    
    return loss.mean()

KTO 最适合的场景是:你有大量用户交互数据,每个样本只有简单的二元反馈(点赞/点踩、采纳/忽略)。这种情况下 KTO 的效率远超需要成对标注的 DPO。

KTO 的权重参数(desirability_weight 和 undesirable_weight)对训练效果影响巨大。默认的不满意权重 2.0 来自前景理论的实验结果,但你的具体任务可能需要不同的比例。建议通过交叉验证确定最优权重。

5GRPO:群体相对策略优化——数学推理的利器

GRPO(Group Relative Policy Optimization)由 DeepSeek 团队在 2024 年提出,并在 DeepSeek-R1 和后续模型中得到充分验证。它代表了偏好优化方法的另一个重要分支——针对可验证任务的群体比较优化

GRPO 的设计初衷是解决数学推理这类具有明确对错判断标准的问题。在这类任务中,回复的质量不需要人类标注者来判断——一个数学证明要么正确要么错误,代码要么通过测试要么失败。这种可验证性为 GRPO 提供了独特的优化信号。

GRPO 的核心机制是:对于同一个问题,从当前策略中采样生成多个回复(通常 4-8 个),然后根据这些回复的群体内相对表现来更新策略。表现好的回复对应的生成路径被强化,表现差的被抑制。

与 PPO 相比,GRPO 最关键的改进是去掉了价值网络。PPO 需要一个价值网络来估计每个状态的期望回报,但在语言模型的场景中,价值网络的训练极其困难且不收敛。GRPO 通过使用群体内归一化的奖励作为基线来替代价值网络——同一问题生成的多个回复中,奖励高的为正优势,奖励低的为负优势。

这一设计使得 GRPO 的训练稳定性远超 PPO,同时保持了强化学习的灵活性——你可以使用任何可计算的奖励信号(编译通过率、单元测试通过数、数学验证器输出等),而不需要人工标注的偏好数据。

在 2025-2026 年的实践中,GRPO 已成为数学推理模型训练的标准方法。DeepSeek-R1、Qwen-Math 等模型都采用 GRPO 作为核心对齐算法,在 AIME、IMO 等数学竞赛中取得了突破性成绩。

GRPO 与 PPO 的核心差异对比:

python
import torch
import torch.nn.functional as F

def grpo_loss(
    policy_model: torch.nn.Module,
    old_policy_model: torch.nn.Module,
    questions: list,
    generate_fn: callable,
    reward_fn: callable,
    group_size: int = 8,
    epsilon: float = 0.2,
    beta: float = 0.01
):
    """
    GRPO 损失函数:群体相对策略优化
    
    参数:
        questions: 问题列表
        generate_fn: 从策略模型生成回复的函数
        reward_fn: 可验证的奖励函数(如数学验证器)
        group_size: 每个问题采样的回复数量
        epsilon: PPO-style clip 范围
        beta: KL 约束系数
    """
    total_loss = 0
    
    for question in questions:
        # 从旧策略采样一组回复
        with torch.no_grad():
            old_responses = [generate_fn(old_policy_model, question) 
                           for _ in range(group_size)]
        
        # 计算每个回复的奖励
        rewards = torch.tensor([reward_fn(r) for r in old_responses])
        
        # 群体内归一化(替代价值网络)
        mean_reward = rewards.mean()
        std_reward = rewards.std() + 1e-8
        advantages = (rewards - mean_reward) / std_reward
        
        # 从当前策略计算生成概率
        for i, response in enumerate(old_responses):
            # 当前策略的 log 概率
            log_prob = policy_model.compute_log_prob(question, response)
            # 旧策略的 log 概率
            old_log_prob = old_policy_model.compute_log_prob(question, response)
            
            # 概率比
            ratio = torch.exp(log_prob - old_log_prob)
            
            # Clip 机制(防止过大更新)
            clipped_ratio = torch.clamp(ratio, 1 - epsilon, 1 + epsilon)
            
            # 策略梯度损失
            policy_loss = -torch.min(
                ratio * advantages[i],
                clipped_ratio * advantages[i]
            )
            
            # KL 散度约束
            kl_penalty = beta * (log_prob - old_log_prob) ** 2
            
            total_loss += policy_loss + kl_penalty
    
    return total_loss / (len(questions) * group_size)
图表加载中…

GRPO 的群体大小(group_size)是关键超参数。数学推理任务建议设为 4-8:太小则群体比较信息不足,太大则采样成本过高。对于代码生成任务,可以设到 16-32,因为编译测试是自动的、成本极低。

GRPO 严重依赖奖励函数的质量。如果奖励函数有漏洞(例如数学验证器无法检测所有错误),GRPO 会学会利用这些漏洞来'骗分'。务必确保奖励函数的完备性和鲁棒性,或者使用多验证器交叉验证。

6四种方法的系统性对比

理解四种偏好优化方法的关键,是从数据需求、训练复杂度、适用场景三个维度进行对比。

数据需求来看,DPO 和 ORPO 都需要成对偏好数据(对每个提示需要一个好回复和一个坏回复),标注成本最高。KTO 只需要逐样本二元信号(好/坏),成本最低。GRPO 甚至不需要人工标注——只要有可计算的奖励函数(如数学验证器、编译测试),就能自动生成训练信号。

训练复杂度来看,DPO 和 KTO 最为简单——只需要策略模型和参考模型,一个损失函数搞定。ORPO 稍复杂(统一了 SFT 和偏好对齐的损失),但仍然比 PPO 简单得多。GRPO 虽然去掉了价值网络,但需要群体采样和奖励计算,实现复杂度中等。

适用场景来看,DPO 是最通用的偏好优化方法,适用于对话、创作、代码等多种场景。ORPO 适合算力有限、需要快速对齐的团队。KTO 适合大规模弱监督场景(用户交互数据)。GRPO 则是数学推理和代码生成的最佳选择。

四种方法的多维度对比:

图表加载中…

在实际项目中,建议按照这个顺序尝试:先用 KTO 快速建立基线(数据成本低)→ 再用 DPO 精调(成对数据更精确)→ 如果有可验证任务,叠加 GRPO 进一步提升。这种分层策略能在有限算力下获得最佳效果。

不要在同一个数据集上同时使用多种偏好优化方法。每种方法的优化目标有细微差异,混合使用可能导致策略冲突。正确的做法是在不同阶段使用不同方法,或者在不同类型的数据上应用不同方法。

7偏好优化的数学直觉:从 PPO 到 DPO 的推导

理解 DPO 为什么有效,需要追溯它与 PPO 的数学等价关系。这不是为了让你重新推导一遍公式,而是为了建立直觉——为什么去掉奖励模型和价值网络之后,优化仍然能朝着正确的方向前进。

在 RLHF 中,PPO 优化的目标是最大化期望奖励,同时约束策略不偏离参考模型太远。这个目标的解有一个简洁的形式:最优策略与奖励函数之间存在一个指数关系

DPO 利用了这一数学事实,将其反向应用:如果我们假设存在一个最优策略(即经过良好训练的语言模型),那么它的生成概率本身就隐含了一个奖励函数。因此,我们可以通过比较两个回复的生成概率,间接地比较它们的奖励值——而不需要显式地训练奖励模型。

这种"反向推导"之所以成立,根本原因是 KL 散度约束确保了策略优化是一个连续的、渐进的过程。每一步的优化都只在参考模型附近微调,不会突然跳到完全不合理的策略空间。这保证了概率比值的变化与奖励变化之间的单调对应关系。

理解了这个直觉,你就能明白为什么 DPO 不需要奖励模型:策略模型的概率本身就是奖励的编码。当我们让模型在"好回复"上的概率高于"坏回复"时,等价于让模型学习到正确的奖励信号。

这也解释了为什么 DPO 需要一个冻结的参考模型:参考模型定义了"起点",所有的优化都是相对于起点的变化。如果没有参考模型,我们无法区分"模型本身的偏好"和"通过训练学来的偏好"。

从 DPO 到 GRPO 的演进,本质上是对奖励信号来源的不断扩展:DPO 用人类成对标注定义奖励,ORPO 用监督信号定义奖励,KTO 用二元反馈定义奖励,GRPO 用可验证结果定义奖励。每种方法都在回答同一个问题:我们如何获得足够好的奖励信号来指导优化?

如果你要改进 DPO 或 GRPO,最有可能产生突破的方向是奖励信号的设计。当前的研究热点包括:多模态奖励(同时考虑文本和视觉)、过程奖励(对推理过程的中间步骤打分)、以及自训练奖励(模型自我评估)。

不要试图完全去掉参考模型的 KL 约束。实验表明,移除 KL 约束后,模型会在几十个训练步骤内出现严重退化——生成的文本变得极端化、重复化。KL 约束不是可选项,而是安全护栏。

8实践指南:如何选择和部署偏好优化方法

在实际项目中选择偏好优化方法时,你需要考虑数据、算力、任务类型、质量要求四个维度。

数据可用性是首要考虑因素。如果你有高质量的人工偏好标注(如 RLHF 阶段的标注数据),DPO 是最佳选择。如果你只有用户交互日志(点击、采纳、评分),KTO 能最大化利用这些粗糙信号。如果你的任务有自动验证器(数学、代码),GRPO 是效率最高的方案。ORPO 则适合数据量不大、需要快速实验的场景。

算力预算决定了你能负担的训练复杂度。DPO 和 KTO 的训练开销最小(只需两个模型的推理和梯度计算)。ORPO 稍多(融合了 SFT 和偏好损失)。GRPO 的开销取决于群体大小——每个训练步骤需要采样和评估多个回复。

任务类型影响方法选择。对话和创作任务更适合 DPO 和 KTO,因为它们依赖主观偏好判断。数学推理和代码生成更适合 GRPO,因为它们有客观的验证标准。

质量要求决定是否需要多阶段训练。对于生产级模型,推荐"KTO 快速基线 → DPO 精调"的两阶段策略。对于研究型模型,可以加入 GRPO 阶段进一步提升推理能力。

在 2026 年的实践中,越来越多的大语言模型团队采用了混合偏好优化的策略:先用 KTO 在大规模弱监督数据上建立初步对齐,再用 DPO 在高质量偏好数据上精调,最后对特定任务(如数学、代码)使用 GRPO 进行专项优化。这种分层策略在 Open-Sora、Qwen、Llama 等开源项目中得到了验证。

对于个人研究者和小型团队,建议从 ORPO 开始。它统一了 SFT 和对齐训练,训练流程最简单,效果也足够好。等你有足够的数据和算力后,再考虑升级到 DPO 或 GRPO。

无论选择哪种方法,都必须在独立验证集上评估效果。偏好优化很容易出现【过拟合标注】——模型学会了满足特定标注者的偏好,但在真实场景中表现不佳。建议使用交叉验证和人工盲测来评估最终效果。

9扩展阅读:前沿研究与未来趋势

偏好优化是 2024-2026 年大语言模型对齐领域最活跃的研究方向。以下是一些值得关注的进展:

自训练偏好优化是当前的研究热点。传统方法依赖人工标注的偏好数据,但最新的研究表明,模型可以通过自我对比学习来提升对齐质量。具体来说,模型生成多个回复,用自身的能力评估这些回复的质量,然后用评估结果作为训练信号。这种方法的关键挑战是如何避免"自我强化偏差"——模型不断强化自己已有的偏见。

多模态偏好优化将偏好优化的范围从纯文本扩展到多模态场景。在图像生成、视频生成等多模态任务中,偏好信号更加丰富(视觉质量、语义一致性、用户交互反馈),但也更加复杂。如何将 DPO 的思想扩展到多模态领域,是当前的重要开放问题。

可解释的偏好优化试图回答一个根本性问题:模型在偏好优化过程中到底学到了什么?是表面的模式匹配,还是真正理解了人类的价值判断?通过对偏好优化过程中模型内部表示的分析,研究者开始发现一些令人不安的现象——模型可能学到了标注者的系统性偏差,而非真正的"好回复"特征。

群体智能与偏好优化的交叉是一个新兴方向。如果多个模型可以互相评估彼此的输出,那么偏好优化是否可以摆脱对人类标注的依赖?Multi-Agent 系统中的偏好信号生成,可能成为未来对齐训练的关键基础设施。

关注 NeurIPS 2026、ICML 2026 等顶会上关于偏好优化的论文。这个领域发展极快,6 个月前的 SOTA 方法可能已经不是最优选择。建议定期(每季度)回顾最新文献,确保使用最新的方法。

在将前沿研究成果应用到生产环境之前,务必进行充分的消融实验。论文中的效果提升往往是在特定数据集和超参数下取得的,不一定能直接复现到你的场景中。建议先在验证集上小规模试验,确认有效后再全面部署。

继续你的 AI 学习之旅

浏览更多 AI 知识库文章,或者探索 GitHub 上的优质 AI 项目