有监督微调 (SFT) 允许您使用针对特定用例的示例来训练 OpenAI 模型。其结果是获得一个自定义模型,能够更可靠地生成您期望的风格和内容。
| 工作原理 | 适用场景 | 适用场景 |
|---|---|---|
提供针对提示词的正确响应示例,以引导模型的行为。 通常使用人工生成的“真实值”响应,向模型展示应如何作答。 |
|
|
概览
有监督微调包含四个主要部分:
- 构建训练数据集,以明确“优质”的标准
- 上传包含示例提示词和期望模型输出的训练数据集
- 使用您的训练数据为基础模型创建微调作业
- 使用微调后的模型评估您的结果
构建数据集
构建一个健壮且具有代表性的数据集,以便从微调模型中获得有用的结果。请使用以下技巧和注意事项。
合适的示例数量
- 微调可提供的最少示例数量为 10 个
- 我们看到在 50 到 100 个示例上进行微调能带来改进,但适合您的数量差异很大,取决于具体用例
- 我们建议从 50 个精心制作的示例开始,并 评估结果
如果使用 50 个优质示例后性能有所提升,请尝试添加示例以观察进一步的效果。如果 50 个示例没有产生任何影响,请在添加训练数据之前重新思考您的任务或提示词。
什么是优质示例
- 您在应用程序中期望的任何提示词和输出,尽可能贴近真实场景
- 具体、清晰的问题与答案
- 使用历史数据、专家数据、日志数据,或 其他类型的收集数据
格式化您的数据
- 使用 JSONL 格式,训练数据文件的每一行包含一个完整的 JSON 结构
- 使用 chat completions 格式
- 您的文件必须至少有 10 行
JSONL 训练数据示例,其中模型调用了 get_weather function:
{"messages":[{"role":"user","content":"What is the weather in San Francisco?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"San Francisco, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. San Francisco, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Minneapolis?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Minneapolis, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Minneapolis, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in San Diego?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"San Diego, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. San Diego, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Memphis?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Memphis, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Memphis, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Atlanta?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Atlanta, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Atlanta, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Sunnyvale?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Sunnyvale, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Sunnyvale, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Chicago?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Chicago, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Chicago, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Boston?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Boston, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Boston, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in Honolulu?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"Honolulu, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. Honolulu, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}
{"messages":[{"role":"user","content":"What is the weather in San Antonio?"},{"role":"assistant","tool_calls":[{"id":"call_id","type":"function","function":{"name":"get_current_weather","arguments":"{\"location\": \"San Antonio, USA\", \"format\": \"celsius\"}"}}]}],"parallel_tool_calls":false,"tools":[{"type":"function","function":{"name":"get_current_weather","description":"Get the current weather","parameters":{"type":"object","properties":{"location":{"type":"string","description":"The city and country, eg. San Antonio, USA"},"format":{"type":"string","enum":["celsius","fahrenheit"]}},"required":["location","format"]}}}]}训练数据文件的每一行包含类似以下的 JSON 结构,其中包含示例用户提示词以及模型的正确响应作为 assistant message.
{
"messages": [
{ "role": "user", "content": "What is the weather in San Francisco?" },
{
"role": "assistant",
"tool_calls": [
{
"id": "call_id",
"type": "function",
"function": {
"name": "get_current_weather",
"arguments": "{\"location\": \"San Francisco, USA\", \"format\": \"celsius\"}"
}
}
]
}
],
"parallel_tool_calls": false,
"tools": [
{
"type": "function",
"function": {
"name": "get_current_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and country, eg. San Francisco, USA"
},
"format": { "type": "string", "enum": ["celsius", "fahrenheit"] }
},
"required": ["location", "format"]
}
}
}
]
}从大模型中蒸馏
为较小模型构建训练数据集的一种方法是,蒸馏大模型的结果以创建用于监督微调的训练数据。此技术的整体流程如下:
- 为较大的模型(如
gpt-4.1)调整提示词,直到它在你的评估标准下表现优异。 - 使用任何便捷的方法捕获模型生成的结果 - 请注意, Responses API 默认会将模型响应存储 30 天。
- 使用符合您标准的大模型捕获响应,并利用上述工具和技术生成数据集。
- 使用您根据大模型创建的数据集来调整较小的模型(如
gpt-4.1-mini)使用你从大模型创建的数据集。
此技术可以让你训练一个小模型,使其在特定任务上的表现与更大、成本更高的模型相似。
上传训练数据
将您的示例数据集上传到 OpenAI。我们将使用它来更新模型权重,并产生与您数据中包含的输出相类似的结果。
除了文本补全之外,你还可以训练模型更有效地生成 结构化 JSON 输出 or 函数调用.
- 导航至控制面板 (dashboard) > 微调.
- 点击 + 创建.
- 在 训练数据下,上传您的 JSONL 文件。
假设上面的数据已保存到一个名为 mydata.jsonl的文件中,您可以使用下面的代码将其上传到 OpenAI 平台。请注意,所上传文件的 purpose 已设置为 fine-tune:
curl https://api.openai.com/v1/files \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-F purpose="fine-tune" \
-F file="@mydata.jsonl"
请注意 API 返回数据中所上传文件的 id ——在后续的 API 请求中会用到该文件标识符。
{
"object": "file",
"id": "file-RCnFCYRhFDcq1aHxiYkBHw",
"purpose": "fine-tune",
"filename": "mydata.jsonl",
"bytes": 1058,
"created_at": 1746484901,
"expires_at": null,
"status": "processed",
"status_details": null
}创建微调任务
上传测试数据后, 创建微调任务 来自定义基础模型。创建微调作业时,您必须指定:
- A base model (
model) 用于微调。这可以是 OpenAI 模型 ID,也可以是之前已经微调过的模型 ID。请参阅“ 模型文档. - A training file (
training_file) ID。这是您在上一步中上传的文件。 - A fine-tuning method (
method)。这用于指定您想要用于自定义模型的微调方法。监督微调是默认方法。
- In the same + 创建 按上述方式,填写所需字段。
- 选择监督微调作为方法,并选择您想要训练的模型。
- 准备就绪后,点击 创建 to start the job.
通过调用以下接口创建监督微调作业: 微调 API:
curl https://api.openai.com/v1/fine_tuning/jobs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"training_file": "file-RCnFCYRhFDcq1aHxiYkBHw",
"model": "gpt-4.1-nano-2025-04-14"
}'
API 会返回正在进行的微调作业的相关信息。根据训练数据的大小,训练过程可能需要几分钟或几小时。您可以 轮询 API 以获取特定作业的最新状态。
当微调任务完成时,你微调后的模型即可投入使用。一个已完成的微调任务会返回类似这样的数据:
{
"object": "fine_tuning.job",
"id": "ftjob-uL1VKpwx7maorHNbOiDwFIn6",
"model": "gpt-4.1-nano-2025-04-14",
"created_at": 1746484925,
"finished_at": 1746485841,
"fine_tuned_model": "ft:gpt-4.1-nano-2025-04-14:openai::BTz2REMH",
"organization_id": "org-abc123",
"result_files": ["file-9TLxKY2A8tC5YE1RULYxf6"],
"status": "succeeded",
"validation_file": null,
"training_file": "file-RCnFCYRhFDcq1aHxiYkBHw",
"hyperparameters": {
"n_epochs": 10,
"batch_size": 1,
"learning_rate_multiplier": 1
},
"trained_tokens": 1700,
"error": {},
"user_provided_suffix": null,
"seed": 1935755117,
"estimated_finish": null,
"integrations": [],
"metadata": null,
"usage_metrics": null,
"shared_with_openai": false,
"method": {
"type": "supervised",
"supervised": {
"hyperparameters": {
"n_epochs": 10,
"batch_size": 1,
"learning_rate_multiplier": 1.0
}
}
}
}
请注意 API 返回数据中所上传文件的 fine_tuned_model 属性。这是用于 响应 or Chat Completions 通过你微调后的模型发起 API 请求的模型 ID。
以下是使用你微调后的模型 ID 调用 Responses API 的示例:
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "ft:gpt-4.1-nano-2025-04-14:openai::BTz2REMH",
"input": "What is the weather like in Boston today?",
"tools": [
{
"name": "get_current_weather",
"description": "Get the current weather",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "The city and country, eg. San Francisco, USA"
},
"format": { "type": "string", "enum": ["celsius", "fahrenheit"] }
},
"required": ["location", "format"]
}
}
],
"tool_choice": "auto"
}'评估结果
使用以下方法检查微调后模型的表现。根据需要调整提示、数据和微调任务,直到获得满意的结果。最佳的微调方式是持续迭代。
与评估比较
要查看微调后的模型是否比原始基础模型表现更好, 请使用评估。在运行微调任务之前,请从你在步骤 1 中收集的同一训练数据集中划分出一部分数据。当使用这些数据进行评估时,此保留数据将作为对照组。请确保训练数据和保留数据在用户输入类型和模型响应的多样性方面大致相同。
监控状态
在控制台中检查微调任务的状态,或通过在 API 中轮询任务 ID 来检查。
- 导航至 微调控制面板.
- 选择你要监控的任务。
- 查看状态、检查点、消息和指标。
使用此 curl 命令获取有关微调任务的信息:
curl https://api.openai.com/v1/fine_tuning/jobs/ftjob-uL1VKpwx7maorHNbOiDwFIn6 \
-H "Authorization: Bearer $OPENAI_API_KEY"
The job contains a fine_tuned_model 属性,这是你新微调模型的唯一 ID。
{
"object": "fine_tuning.job",
"id": "ftjob-uL1VKpwx7maorHNbOiDwFIn6",
"model": "gpt-4.1-nano-2025-04-14",
"created_at": 1746484925,
"finished_at": 1746485841,
"fine_tuned_model": "ft:gpt-4.1-nano-2025-04-14:openai::BTz2REMH",
"organization_id": "org-abc123",
"result_files": ["file-9TLxKY2A8tC5YE1RULYxf6"],
"status": "succeeded",
"validation_file": null,
"training_file": "file-RCnFCYRhFDcq1aHxiYkBHw",
"hyperparameters": {
"n_epochs": 10,
"batch_size": 1,
"learning_rate_multiplier": 1
},
"trained_tokens": 1700,
"error": {},
"user_provided_suffix": null,
"seed": 1935755117,
"estimated_finish": null,
"integrations": [],
"metadata": null,
"usage_metrics": null,
"shared_with_openai": false,
"method": {
"type": "supervised",
"supervised": {
"hyperparameters": {
"n_epochs": 10,
"batch_size": 1,
"learning_rate_multiplier": 1.0
}
}
}
}试用您的微调模型
通过实际使用来评估您新优化的模型!当微调模型完成训练后,请在 响应 or Chat Completions API 中使用其 ID,就像使用 OpenAI 基础模型一样。
- 在 [Dashboard] 中导航至您的微调作业 the dashboard.
- 在右侧窗格中,导航至 输出模型 并复制模型 ID。它应以
ft:… - 打开 在 Playground 中生成并迭代函数模式.
- In the 模型 下拉菜单,粘贴模型 ID。在这里,您应该还会看到您创建的其他微调模型。
- 运行一些提示,看看您的微调模型表现如何!
curl https://api.openai.com/v1/responses \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
"model": "ft:gpt-4.1-nano-2025-04-14:openai::BTz2REMH",
"input": "What is 4+4?"
}'根据需要使用检查点
检查点是可供使用的模型。我们会在每个训练周期(epoch)结束时为你创建一个完整的模型检查点。如果你的微调模型在初期有所提升,但随后只是死记硬背数据集,而不是学习可泛化的知识(这种情况称为_过拟合_),检查点就会非常有用。检查点提供了在训练过程中不同时刻生成的自定义模型版本。
- 导航至 微调控制面板.
- 在左侧面板中,选择您要查看的任务。等待其成功。
- 在右侧面板中,滚动至检查点列表。
- 将鼠标悬停在任意检查点上,即可看到在 Playground 中打开的链接。
- 在 Playground 中进行提示,以测试检查点模型的行为。
- 等待任务成功,您可以通过以下方式验证这一点: 查询任务状态.
- 查询检查点端点 并使用您的微调任务 ID 来获取该微调任务的模型检查点列表。
- 找到
fine_tuned_model_checkpoint字段以获取模型检查点的名称。 - 您可以像使用最终的微调模型一样使用此模型。
The checkpoint object contains metrics 数据来帮助您确定此模型的效用。例如,响应如下所示:
{
"object": "fine_tuning.job.checkpoint",
"id": "ftckpt_zc4Q7MP6XxulcVzj4MZdwsAB",
"created_at": 1519129973,
"fine_tuned_model_checkpoint": "ft:gpt-3.5-turbo-0125:my-org:custom-suffix:96olL566:ckpt-step-2000",
"metrics": {
"full_valid_loss": 0.134,
"full_valid_mean_token_accuracy": 0.874
},
"fine_tuning_job_id": "ftjob-abc123",
"step_number": 2000
}
每个检查点指定了:
step_number:创建检查点的步骤(其中每个 epoch 的步骤数等于训练集大小除以批次大小)metrics:一个对象,包含微调任务在创建检查点的步骤时的各项指标
目前,仅保存并提供该任务最后三个训练周期(epoch)的检查点供使用。
安全检查
在生产环境中发布之前,请审查并遵循以下安全信息。
后续步骤
现在你已经了解了监督微调的基础知识,还可以进一步探索这些其他方法。
了解如何使用图像输入进行微调以处理计算机视觉任务。
使用直接偏好优化 (DPO) 微调模型。
通过对其输出进行评分来微调推理模型。