OpenAI推出GPT-3.5微调API:私有定制模型新时代

101 min read

OpenAI现已推出GPT-3.5 Turbo的微调功能,GPT-4的微调将于今年秋季推出。这一更新让开发人员能够定制适合自己用例的模型,并能够在大规模下运行这些定制模型。早期测试已经显示,经过微调的GPT-3.5 Turbo版本在某些狭窄任务上可以匹配甚至超过基本的GPT-4级别的性能。和所有API一样,微调API中发送和接收的数据为客户所有,不会被OpenAI或任何其他组织用于训练其他模型。

微调用例

自GPT-3.5 Turbo发布以来,开发人员和企业一直要求能够定制该模型,以便为他们的用户创建独特和差异化的体验。通过这次推出,开发人员现在可以运行有监督的微调,使此模型更好地适应他们的用例。

在我们的私人测试版中,微调客户已经能够在常见用例中显著提高模型性能,例如:

  • 改善可操纵性:微调使企业能够更好地使模型遵循指令,例如使输出更简洁或始终用特定语言回应。例如,开发人员可以使用微调确保模型在被提示使用德语时始终用德语回应。
  • 可靠的输出格式化:微调提高了模型一致格式化响应的能力,这对于要求特定响应格式的应用程序至关重要,例如代码补全或编写API调用。开发人员可以使用微调更可靠地将用户提示转换为可用于其自己系统的高质量JSON片段。
  • 自定义语调:微调是改善模型输出的定性感受的好方法,例如语调,以便更好地适应企业品牌的声音。具有可识别品牌声音的企业可以使用微调使模型与其语调更一致。

除了性能提升,微调还使企业能够在确保相似性能的同时缩短其提示。使用GPT-3.5 Turbo微调还可以处理4k个令牌,是我们之前微调模型的两倍。早期测试人员通过将指令微调到模型本身中,已经将提示大小减少了高达90%,从而加快了每个API调用的速度并降低了成本。

当与诸如提示工程、信息检索和功能调用等其他技术相结合时,微调最为强大。欲了解更多信息,请查看我们的微调指南。此秋季还将推出使用功能调用和gpt-3.5-turbo-16k微调的支持。

以下是微调模型的完整步骤和解释

官方文档的示例是一个让 GPT 模型输出错别字的模型, 但是语焉不详,有很多重要的细节和步骤给隐藏了, 下面以这个模型为案例演示如何使用微调模型来影响返回结果的详细步骤:

首先需要获取 key,获取地址为:https://platform.openai.com/ 将 $OPENAI_API_KEY 写入环境变量中, 因操作系统的不同而有所不同。以下是针对一些常见操作系统的说明:

在 Unix 或 Linux 系统中

您可以使用下面的命令将 API 密钥添加到环境变量中。只需打开终端,并输入:

export OPENAI_API_KEY='你的API密钥'

如果您希望每次打开新终端窗口时都自动设置此环境变量,可以将上述命令添加到您的 ~/.bashrc~/.bash_profile 文件中。

在 Windows 系统中

在 Windows 中,您可以按照以下步骤设置环境变量:

  1. 打开“控制面板” -> “系统” -> “高级系统设置” -> “环境变量”。
  2. 在“用户变量”部分下,点击“新建”。
  3. 输入变量名“OPENAI_API_KEY”和变量值“你的API密钥”。
  4. 点击“确定”保存设置。

现在,您在任何命令提示符窗口中都可以访问此环境变量。

在 macOS 中

在 macOS 上的操作与 Unix 或 Linux 系统相似。打开终端并输入:

export OPENAI_API_KEY='你的API密钥'

如果您希望每次打开新终端窗口时都自动设置此环境变量,可以将上述命令添加到您的 ~/.bash_profile~/.zshrc 文件中(取决于使用的 shell)。

注意:确保将 '你的API密钥' 替换为实际的 API 密钥。

Step 1:准备数据

首先,你需要准备一组合适的训练数据。这些数据通常以对话的形式出现,包括角色和内容。例如:

{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "What's the weather today?"}, {"role": "assistant", "content": "It's sunny and worm."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "Tell me a joke."}, {"role": "assistant", "content": "Why did the chicken cros the road?"}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "How do I get to the nearest mall?"}, {"role": "assistant", "content": "Take the first right and then the nex left."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "What's your favorite food?"}, {"role": "assistant", "content": "I'm a model, so I don't eat, but I like piza."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "Who won the World Series last year?"}, {"role": "assistant", "content": "I'm not sure about current events, but you can chek online."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "Can you dance?"}, {"role": "assistant", "content": "I'm just a text-based model, but I can describe a dnace."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "Tell me a story."}, {"role": "assistant", "content": "Once upon a time, there was a beautful princess."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "The capital of France is Pris."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "How far is the moon?"}, {"role": "assistant", "content": "The moon is about 384,400 kilometrs from Earth."}]}
{"messages": [{"role": "system", "content": "You are an assistant that occasionally misspells words"}, {"role": "user", "content": "Give me a recipe for pancakes."}, {"role": "assistant", "content": "Sure! Here's a simple rcipe for pancakes."}]}

Step 2:上传文件

你需要将包含上述格式的训练数据存储在一个JSONL文件中,然后上传到OpenAI的服务器。文件中应至少包含10个样例。上传命令如下:

curl https://api.openai.com/v1/files \
  -H "Authorization: Bearer $OPENAI_API_KEY" \
  -F "purpose=fine-tune" \
  -F "file=@path_to_your_file.json"

成功上传后,服务器会返回一个包含文件ID的响应。

{
  "object": "file",
  "id": "file-Hv9LPzOH3ujDbL7EsQfGP6H4",
  "purpose": "fine-tune",
  "filename": "data.json",
  "bytes": 2416,
  "created_at": 1692769428,
  "status": "uploaded",
  "status_details": null
}

Step 3:创建微调任务

使用返回的文件ID创建微调任务:注意下面的FILE_ID 替换成上一步的 "id" 这里是 "file-Hv9LPzOH3ujDbL7EsQfGP6H4"

curl https://api.openai.com/v1/fine_tuning/jobs \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
  "training_file": "FILE_ID",
  "model": "gpt-3.5-turbo-0613"
}'

你会得到一个响应,确认微调任务的创建。

{"object":"fine_tuning.job","id":"ftjob-mudKIBkhCvVVRQh37KwEYtOs","model":"gpt-3.5-turbo-0613","created_at":1692769549,"finished_at":null,"fine_tuned_model":null,"organization_id":"org-faRPxilGyU59BReUVQEYJ5WU","result_files":[],"status":"created","validation_file":null,"training_file":"file-Hv9LPzOH3ujDbL7EsQfGP6H4","hyperparameters":{"n_epochs":10},"trained_tokens":null}%   

替换掉url jobs 后面的内容<job_id>为上一步的 id, 然后使用以下的curl命令来查询微调作业的状态:

curl https://api.openai.com/v1/fine_tuning/jobs/<job_id> \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY"

这将返回作业的当前状态和进度信息。你可以定期运行此命令来监控微调的进度。

这个阶段可能会持续一段时间,具体取决于训练数据的大小和复杂性。你可以继续定期使用相同的curl命令来监控进度。

请注意,微调过程中的具体细节,如训练周期数(在此例中为10个周期),会影响微调作业的完成时间。

通常,微调可能需要从几分钟到几小时不等的时间。有时,如果系统正忙或遇到其他延迟,可能需要更长时间。

你可以继续定期查询微调作业的状态,直到看到状态从“running”变为“succeeded”。此外,某些平台可能提供通知或警报,以便在微调作业完成时通知你。

请注意,如果你的训练样本非常少,而你选择了相对复杂的模型进行微调,可能导致过拟合。在实际应用中,你可能需要继续监控模型的性能,并根据需要进行调整。

一旦微调完成,你就可以使用生成的微调模型进行预测。

返回的参数说明

fine_tuned_model 为后面需要使用到的我们私有定制的模型参数

"object": "fine_tuning.job" - 指示此对象是一个微调作业。
"id": "ftjob-ZdPLc7XSoTUOZjNnYsjREsLD" - 微调作业的唯一ID。
"model": "gpt-3.5-turbo-0613" - 表示使用的基础模型是GPT-3.5 Turbo的0613版本。
"created_at": 1692765627 - 微调作业创建的UNIX时间戳,表示作业创建的确切时间。
"finished_at": null - 作业尚未完成,所以此字段为空。
"fine_tuned_model": null - 微调的模型尚未生成,所以此字段为空。
"organization_id": "org-faRPxilGyU59BReUVQEYJ5WU" - 执行微调作业的组织的ID。
"result_files": [] - 由于作业仍在运行,所以没有结果文件,此列表为空。
"status": "running" - 作业的当前状态为正在运行。
"validation_file": null - 没有提供验证文件,所以此字段为空。
"training_file": "file-rbQERwiW11MqwRoeqrqHCNxZ" - 包含训练数据的文件的ID。
"hyperparameters": {"n_epochs": 10} - 超参数设置,表示训练将进行10个时代。
"trained_tokens": null - 由于微调还未完成,所以训练的令牌数量为null。

Step 4:使用微调模型

一旦微调过程完成,你可以立即在生产环境中使用微调后的模型。其使用方法与普通模型相同,只是需要指定微调后的模型ID:

curl https://api.openai.com/v1/chat/completions \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-d '{
  "model": "ft:gpt-3.5-turbo:org_id",
  "messages": [
    {
      "role": "system",
      "content": "You are an assistant that occasionally misspells words"
    },
    {
      "role": "user",
      "content": "Hello! What is fine-tuning?"
    }
  ]
}'

我的测试结果是这样的,GPT 正常返回了包含错误字的句子

{
  "id": "chatcmpl-7qaKF86CijeIhueSL0O8ooc2N7FSq",
  "object": "chat.completion",
  "created": 1692767047,
  "model": "ft:gpt-3.5-turbo-0613:personal::7qa2K01A",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "Take the first right and then the nex left."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 30,
    "completion_tokens": 10,
    "total_tokens": 40
  }
}

返回的参数说明

id: 本次文本生成的唯一标识符。
object: 这个字段的值为 "text_completion",表示该对象为一个文本完成任务。
created: 表示完成任务的创建时间的Unix时间戳。
model: 您所使用的模型的ID,这里为微调后的模型。
choices: 这是一个包含生成文本的数组。因为通常在请求中设置 n=1(默认值),所以此数组通常只包含一个项目。
text: 由模型生成的文本内容。
index: 生成选项的索引(通常为0)。
logprobs: 此字段通常为null,除非特别请求了日志概率。
finish_reason: 表示文本生成完成的原因。在这里,由于达到了最大令牌数,因此值为 "length"。
usage: 这个字段描述了您的请求如何使用了令牌。
prompt_tokens: 提示文本中的令牌数量。
completion_tokens: 生成文本中的令牌数量。
total_tokens: 总共使用的令牌数量,包括提示和完成。

通过以上步骤,你就能顺利地完成微调任务,创建并使用自定义的GPT-3.5-turbo模型。确保训练文件的内容和格式正确,以避免在上传和创建微调任务时出现的常见错误。