OpenAI 直接偏好优化

2026-11-06 17:44 更新

直接偏好优化(DPO)使用提示词及成对回答进行微调,让模型学习较主观的人类偏好,使输出更接近人们倾向选择的回答。目前 DPO 仅支持文本输入和输出。

OpenAI 正逐步结束微调平台服务,平台已不再向新用户开放。符合条件的既有客户可创建训练任务至2027年1月6日;如果基础模型更早关闭,则以基础模型的时间为限。

微调模型可继续用于推理,直到其基础模型关闭。gpt-4.1-nano-2025-04-14及其微调版本于2026年10月23日关闭;gpt-4.1-2025-04-14、gpt-4.1-mini-2025-04-14及其微调版本计划于2027年1月14日关闭。参见微调可用性时间表。下表保留来源中的模型列表,应结合这些生命周期说明阅读。

工作方式 适合任务 来源列出的模型
为同一提示词提供较好与较差的回答,并标明偏好,帮助模型改进 聚焦关键信息的摘要;符合所需语气和风格的聊天消息 gpt-4.1-2025-04-14、gpt-4.1-mini-2025-04-14、gpt-4.1-nano-2025-04-14

数据格式

数据集的每条样例应包含提示词(例如用户消息)、偏好输出(理想的助手回答)和非偏好输出(较差的助手回答)。使用 JSONL,每行按下面的结构表示一条样例。

来源示例 1(json):

本例中文译文:用户问:“你好,能告诉我旧金山今天有多冷吗?”偏好回答:“今天旧金山没有预想那么冷,晨云将散去转晴,最高约68°F(20°C),最低约57°F(14°C)。”非偏好回答:“旧金山今天并不特别冷。”这是来源偏好数据,不是真实天气预报。

{
  "input": {
    "messages": [
      {
        "role": "user",
        "content": "Hello, can you tell me how cold San Francisco is today?"
      }
    ],
    "tools": [],
    "parallel_tool_calls": true
  },
  "preferred_output": [
    {
      "role": "assistant",
      "content": "Today in San Francisco, it is not quite cold as expected. Morning clouds will give away to sunshine, with a high near 68°F (20°C) and a low around 57°F (14°C)."
    }
  ],
  "non_preferred_output": [
    {
      "role": "assistant",
      "content": "It is not particularly cold in San Francisco today."
    }
  ]
}

目前每条样例只训练单轮对话,偏好与非偏好消息均须是最后一条助手消息。

创建 DPO 微调任务

上传数据、使用 DPO 微调模型的整体流程与模型优化一致。在创建微调任务端点的method字段中指定type和相关hyperparameters:

  • 将type设为dpo。
  • 按需设置hyperparameters。

beta是 DPO 专用的浮点超参数,范围为0到2,用于控制模型在保留原有行为与适应所给偏好之间的取舍。值越大越保守,越倾向原有行为;值越小越积极地采用新偏好。也可使用默认值auto,由平台选择。

以下为使用 OpenAI SDK 配置任务的来源示例。

来源示例 2(javascript):

// [中文] 用DPO创建微调任务,beta=0.1;保留来源模型与文件占位符,实际使用受微调平台和模型退出时间表限制。
import OpenAI from "openai";

const openai = new OpenAI();

const job = await openai.fineTuning.jobs.create({
  training_file: "file-all-about-the-weather",
  model: "gpt-4o-2024-08-06",
  method: {
    type: "dpo",
    dpo: {
      hyperparameters: { beta: 0.1 },
    },
  },
});

来源示例 3(python):

## [中文] 用DPO创建微调任务,beta=0.1;保留来源模型与文件占位符,实际使用受微调平台和模型退出时间表限制。
from openai import OpenAI

client = OpenAI()

job = client.fine_tuning.jobs.create(
    training_file="file-all-about-the-weather",
    model="gpt-4o-2024-08-06",
    method={
        "type": "dpo",
        "dpo": {
            "hyperparameters": {"beta": 0.1},
        },
    },
)

来源示例 4(go):

// [中文] 用DPO创建微调任务,beta=0.1;保留来源模型与文件占位符,实际使用受微调平台和模型退出时间表限制。
package main

import (
    "context"
    "fmt"

    "github.com/openai/openai-go/v3"
)

func main() {
    client := openai.NewClient()
    job, err := client.FineTuning.Jobs.New(context.Background(), openai.FineTuningJobNewParams{
        TrainingFile: "file-all-about-the-weather",
        Model:        "gpt-4o-2024-08-06",
        Method: openai.FineTuningJobNewParamsMethod{
            Type: "dpo",
            Dpo: openai.DpoMethodParam{Hyperparameters: openai.DpoHyperparameters{
                Beta: openai.DpoHyperparametersBetaUnion{OfFloat: openai.Float(0.1)},
            }},
        },
    })
    if err != nil {
        panic(err)
    }
    fmt.Println(job.ID)
}

来源示例 5(java):

// [中文] 用DPO创建微调任务,beta=0.1;保留来源模型与文件占位符,实际使用受微调平台和模型退出时间表限制。
import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.finetuning.jobs.JobCreateParams;
import com.openai.models.finetuning.methods.DpoHyperparameters;
import com.openai.models.finetuning.methods.DpoMethod;

String fileId = "file-all-about-the-weather";

var job =
    client
        .fineTuning()
        .jobs()
        .create(
            JobCreateParams.builder()
                .model("gpt-4.1-mini-2025-04-14")
                .trainingFile(fileId)
                .method(
                    JobCreateParams.Method.builder()
                        .type(JobCreateParams.Method.Type.DPO)
                        .dpo(
                            DpoMethod.builder()
                                .hyperparameters(DpoHyperparameters.builder().beta(0.1).build())
                                .build())
                        .build())
                .build());

System.out.println(job.id());

来源示例 6(ruby):

## [中文] 用DPO创建微调任务,beta=0.1;保留来源模型与文件占位符,实际使用受微调平台和模型退出时间表限制。
require "openai"

client = OpenAI::Client.new
job = client.fine_tuning.jobs.create(
  model: "gpt-4.1-mini-2025-04-14",
  training_file: "file-all-about-the-weather",
  method_: {
    type: :dpo,
    dpo: { hyperparameters: { beta: 0.1 } }
  }
)
puts(job.id)

结合使用 SFT 与 DPO

来源将监督微调(SFT)作为微调任务的默认方法。在 DPO 之前先用偏好回答或其子集进行 SFT,可改善对齐和表现:先让模型学习期望回答中的正确模式,再以 DPO 细化偏好。

推荐流程:

  1. 使用部分高质量、具有任务代表性的偏好回答,对基础模型做 SFT。
  2. 将 SFT 模型作为起点,再根据偏好对比执行 DPO。

安全检查

用于生产环境之前,应阅读并遵循以下安全说明。

如何评估安全性

微调任务完成后,OpenAI 会对模型在13类安全问题上的行为进行评估。这些类别覆盖 AI 输出若未受适当控制可能造成伤害的关键领域。

类别标识 含义
advice 违反平台政策的建议或指导
harassment/threatening 同时涉及针对任何对象的暴力或严重伤害的骚扰
hate 基于种族、性别、族裔、宗教、国籍、性取向、残障或种姓表达、煽动或宣扬仇恨;针对非受保护群体(如棋手)的此类内容归为骚扰
hate/threatening 针对上述受保护群体,同时涉及暴力或严重伤害的仇恨内容
highly-sensitive 违反平台政策的高度敏感数据
illicit 对实施违法行为提供建议或操作指导,例如“如何入店行窃”
propaganda 赞扬或协助违反政策的意识形态
self-harm/instructions 鼓励或指导自杀、割伤、进食障碍等自伤行为
self-harm/intent 发言者表达正在自伤或有自伤意图
sensitive 违反平台政策的敏感数据
sexual/minors 涉及未满18岁者的性内容
sexual 以性唤起为目的、描写性活动或推广性服务的内容;不包括性教育和健康内容
violence 描绘死亡、暴力或身体伤害的内容

每类都有预设通过阈值。某类未通过的样例过多时,OpenAI 会阻止部署该微调模型,并在任务消息中说明未达到要求的类别。可以在任务的审核检查区域查看结果。

如何通过安全检查

除查看微调任务对象中的失败记录外,还可查询微调 API 事件端点,查找moderation_checks类型的事件,了解各类结果和执行措施,以确定重新训练和改进的方向。Model Spec提供可辅助识别训练数据缺口的规则与示例。

平台评估覆盖多类安全问题,但你仍应自行评测微调模型是否适合自己的用例。

后续阅读

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号