You need to enable JavaScript to run this app.
导航
DPO 最佳实践
最近更新时间:2024.10.16 15:55:42首次发布时间:2024.10.16 15:55:42

当模型输出的质量或风格不符合预期,例如会输出不安全内容等情况;或者目标数据难以大量生产或者标注,例如需要模型输出幽默风趣的句子,会消耗大量人力和时间来构建这种数据。可以使用直接偏好优化方法,来调整参数,使得模型输出和目标偏好差异减少。

什么是DPO

DPO(Direct Preference Optimization,直接偏好优化),即用户提供一份标注好的数据集,包含输入的提示词(prompt) 和输出的成对回答列表(response list)。回答列表中包含一个符合目标偏好的回答和一个不符合目标偏好的回答。然后,在基础模型上继续调整参数,来达到和目标偏好对齐的目的。

DPO典型应用场景

对话系统
在智能客服和聊天机器人应用中,根据用户反馈和偏好调整回复,使内容更贴合用户。

内容生成与创作
文本生成:可优化新闻报道、小说创作、文案撰写等的文本,使其符合读者或编辑偏好;
代码生成:根据开发者偏好精调代码生成模型。

问答系统改进
在专业领域问答系统中,根据专家意见和用户反馈调整回答;
在常见问题解答系统中,根据用户选择和评价优化回答策略。

模型安全性提升
将安全、积极、正面回答作为偏好输出,避免生成有害内容;
根据审核人员判断和偏好训练模型,提高信息安全性。

个性化推荐系统
根据用户历史行为、偏好和反馈精调推荐模型,提供个性化推荐。

DPO数据生成建议

标注量级较大可以考虑训练RM(Reward Model,奖励模型 )进行标注。
RM 主要作用在于判断不同回复之间的偏序关系,对于一对或者一组模型的回复,能够判断哪个回复更符合目标偏好,并给出在目标偏好下相对应的偏序关系,通过 RM 的预测,可以对大量回复进行自动排序,方便 DPO 训练数据的构造。因此把 RM 的准确率做到和人工准确率尽可能一致甚至超过能够对后续 DPO 训练产生很大的帮助,RM 决定 DPO 训练结果的上限,RM 的判别越准,模型最终的效果越好。


DPO实践具体步骤

DPO 的策划和实施步骤大致分为:数据准备、模型训练、模型评估、模型部署,下面将按照这一过程介绍实践经验。

数据准备

数据格式

下面是JSON格式的例子,供您参考。

具体格式说明请参考模型精调数据集格式说明中“适用于“直接偏好学习”模型的格式”章节。

{
  "messages": [
    {
      "role": "system",
      "content": "This is a system"
    },
    {
      "role": "user",
      "content": "What your name?"
    },
    {
      "role": "assistant",
      "content": "My name is doubao."
    },
    {
      "role": "user",
      "content": "How to learn Python?"
    },
    {
      "role": "assistant",
      "chosen": "It's so easy. First, you need to learn Python syntax...",
      "rejected": "Check python doc yourself"
    }
  ]
}

数据采样

  • 模型 DPO 的过程中,训练会尽可能增大 pair 数据中的 chosen 内容与 rejected 内容的 reward_margin,所以每一个 epoch 训练前的 pair 数据中正例的多样性和质量也成为最终效果是否能符合预期的至关重要的因素,以下是有关如何采样的一些建议。
  • 数据采样的建议:
    • 提升模型正例的多样性,可以通过从不同模型进行采样丰富训练数据正例的多样性。
    • 提升模型正例的多样性,可以通过尝试增大 top p 或 temperature 等方式,提升模型输出的多样性。
    • 尽可能提升模型正例的质量,最好训练数据中有从要训练的基座模型中进行采样的数据,使得整个模型更易达到最终效果。

Reward pair 构造的建议

  • 模型 DPO 训练的过程中,会尽可能增大 chosen 内容的生成概率,而 rm 是决定数据中哪些是正例的决定性因素,打的够准可以一定程度上决定 dpo 训练的如何,其和数据采样共同决定了 dpo 训练最终效果的上限,以下是一些有关 reward pair 构造的建议:
  • 对于简小并且比较单一的任务,可以采用 prompt engineering+few shot 的方式,利用一些模型直接对采样得到的数据进行标注与区分,观察其对比人工标注的准确率,关于如何撰写 prompt,详情可见 Prompt 最佳实践
  • 对于数据量较大的任务,可以训练单独的 rm 进行打标,可以使用 pairwise 或者 pointwise 等方式。
  • 对于比较复杂的任务,可以训练单独的 rm 进行打标,可以使用 pairwise 或者 pointwise 等方式。
  • 最终的一致率达到 75%以上为佳。

数据量级

  • DPO 的数据量级和任务难度有比较大的关系,通常任务难度可以依据 reward 标准的复杂程度决定。
  • 针对不同难度的任务数据量级的建议:
    • 比较专项的任务,例如让模型输出某种风格的输出:2~3k。
    • 标准较清晰比较清晰的任务:5k ~ 1w。
    • 标准十分复杂也不够清晰的任务:1w 条及以上,视整体任务难度而定。

其他建议

尽量选择 SFT 之后模型具有较好的人类指令遵循能力的模型作为基座,在此基础上继续进行 DPO 训练。

训练配置

模型选型

方舟平台提供多种规格的模型,汇总如下:

模型名称

最大支持的token长度

模型参数量

模型推理耗时

Doubao-lite-32k

32k

较短

Doubao-lite-128k

128k

较短

Doubao-pro-32k

32k

Doubao-pro-128k

128k

  1. 需要明确您模型使用场景是否对延迟比较敏感。如果要求低延迟,且测试过程中 pro 版本模型无法满足延迟要求时,可以使用 lite 模型。具体延迟可以到方舟体验中心进行测试。
  2. 需要明确您的应用场景是否需要长文本能力。如果预期模型的输入和输出加起来超过了 32k 的 token 数,且删减字数对原有语义影响较大时,推荐使用 Doubao-pro-128k 模型(最大支持 128k token 的输入输出长度和)。
  3. 明确了上述的需求,进行模型版本:
    • 同一大模型下面不同版本的区别,大部分仅在于使用的各阶段的训练数据不同。建议您选择最新版本的模型进行 DPO。
    • 对于角色扮演类任务,建议选择 character 模型进行 DPO。

训练方式选择

  • 从参数更新范围的角度,目前方舟平台仅提供 LoRA ( Low-Rank Adaptation) 训练的方式。
    • 大大减少可训练参数的数量:冻结了预训练模型的权重,并在每个 Transformer 块中注入可训练层。
    • 训练速度较快:消耗机器资源较少,价格比全量 DPO 更便宜
  • 建议先使用小参数量大模型(Doubao-lite)+ LoRA 验证实验设置及少量数据实验是否有效,指标是否正常。如果有效的话,再迁移到大参数量大模型上验证 scaling law(即随着模型参数量的增加,模型的效果越好)是否成立。这样做可以显著加快迭代效率,避免在大参数模型上反复做无意义的迭代。

训练参数选择

DPO 任务中,超参的选取会影响最终效果,下面对部分重要参数进行解释。

  • epoch:模型训练轮数,通常选择 1~3 之间,可以根据验证集 loss 曲线来判断。
    • 如果训练集 loss 曲线下降,验证集 loss 曲线上升,则说明模型已经过拟合,此刻应该停止训练。
    • 如果训练集和验证集 loss 曲线均在缓慢下降,则说明模型还未收敛,可以继续训练。
  • learning rate:学习率,LORA 训练选择 learning rate 通常 在 5e-6~1e-5。
    • 设置较大时会加速模型迭代,但是模型可能无法收敛到最优点。
    • 设置过小时会使得模型迭代较慢,可能陷入局部最优。
  • lora alpha&lora rank:参数将模型权重进行放缩,rank 决定了 lora 训练参数量的大小,我们推荐二者参数设置为同一值。通常设置 lora alpha 和 lora rank 为 64。
  • num warmup steps 和 warmup step rate:二者设置一个即可,通常不需要调整。当遇到模型在训练开始时,loss 始终不降的问题时,可尝试调大 warmup step rate,再观察 loss 是否按预期下降。
  • dpo beta:beta 是 DPO loss 的温度,通常在 0.1 到 0.5 之间。该参数控制了我们对 ref 模型的关注程度,beta 越小,模型训练越忽略 ref 模型。
  • dpo_loss_scale:dpo loss 前的权重系数,默认为 1.0,通常保持默认。
  • lm_loss_scale:lm loss 前的权重系数,默认为 0.0,启用 lm_loss 时,需显示设置该系数,通常设置为 0~1 之间。
  • 其余参数:通常保持默认参数即可。

效果评估

有几个关键的评估指标:

  • dpo_loss 指标:训练过程中观察,在训练集和验证集上的差异来评估模型 DPO 的效果。
  • llm_loss 指标(可选):训练过程中观察,若开启 llm_loss 设置,llm_loss 指标才生效,该 loss 为标准的语言模型损失,参与计算的为所有 loss_weight=1(loss_weight 的含义及设置参考底层格式一节)的 token,即在计算整个序列的语言损失时 mask 掉所有 loss_weight=0 的 token。
  • reward margin 指标:训练过程中观察,代表当前模型分布所对应的 rm 在数据集上正负例之间的 reward 差距,观察在训练集和验证集上的正负例的 reward 差距来评估模型 DPO 的效果,该指标越大在训练集上拟合的越好。
  • acc 指标:训练过程中观察,在训练集和验证集上的正负例判别的准确率来评估模型 DPO 的效果。
  • 真实评估集:发布服务后,评估业务指标。

几个评估指标在各种任务上都比较通用,如果可以观察到训练集和测试集的 loss 在逐步下降至收敛,reward margin 和 acc 逐步上升至平滑,说明模型在正常训练至收敛,在测试集 acc 不再上升时,可以将训练好的模型在真实评估集上进行测试,观察收益。

模型发布

当模型 DPO 后,同时各项指标符合预期后,将模型发布到线上进行推理。模型发布参考查看并管理模型精调任务

案例分享

场景

在角色扮演场景中,用户希望获得一个符合自己输出风格的模型。

过程

  1. 客户有一个 SFT 后的基座模型。
  2. 发现模型偶尔会输出一些描述不安全,风格不符合预期的输出。另一方面,如果再加一些 shots,会导致 prompt 过长,导致线上推理耗时增加,影响体验。因此,尝试构造 DPO 数据集。
  3. 根据多模型采样和校准过后的 reward 模型打分,用户获得了正例符合预期风格,负例不符合预期风格的 pair 对。
  4. 利用数据选择 character 基座模型进行 dpo lora 训练,观察各项指标收敛,真实数据有收益后,上线观察,最终达到业务预期。

FAQ

如何构造 DPO 数据集?

重视对于数据集中 reward margin 的选择。

  • 收集足够量的 DPO 数据集,尽量过滤掉差距较小的 pair 对进行学习,因为小差距可能不够准确,同时正负例也没有多大分别,可以考虑控制不同差距阈值观察 rm 的一致率来确定最终阈值,也可考虑统计学的方法进行控制。
  • 可以考虑过滤掉过大的 margin 的 pair 对,防止模型过拟合到这部分数据上。

怎么加快调参效率?

多存 ckpt控制变量调参。

  • 尽量在精调时多训几个 epoch,多存几个 ckpt,这样在服务发布时,可以选择性的发布不同 step 的 ckpt 来看模型表象。
  • 尽量对于超参在不同阈值区间控制变量调参,找到调大或调小和指标的关系。

DPO 和 RLHF 有什么区别?

DPO 是 RLHF 的一种方式,还有较多其余的 RLHF 方式,例如 PPO,KTO,RSO 等,本质上都是使用 rm 模型降低不受欢迎的输出模式概率,增加符合偏好输出模式的概率。

DPO 和 SFT 有什么区别?

  • 训练数据质量要求:SFT 需要构造高质量问答数据,DPO 只需要拿到回复间的偏序对,数据构造更容易更方便
  • 输出模型影响:
    • DPO 是在对基座模型已经具备的不同输出模式的概率进行调整,很难带来新的输出模式。希望模型在某种任务或者某种能力上的输出更符合人类偏好时,可优先使用 DPO 进行调整。
    • SFT 是按照生成的方式训练,可以给模型注入不同的新的输出模式,因此希望模型具备新能力,例如指令遵循,角色扮演等能力的时候应该优先选择 SFT 进行调整;如果对模型的输出有更严格的要求时,也应优先使用 SFT。

相关文档

  • loss 的推导过程: https://arxiv.org/pdf/2305.18290v2