微调ChatGPT模型详细教程

后端 潘老师 4个月前 (12-19) 289 ℃ (0) 扫码查看

微调(Fine-tuning)是一种利用已有通用语言模型(如’gpt-3.5-turbo’或’gpt-4’在特定数据集上)来训练一个特定模型的方法。微调有助于提高ChatGPT的性能并适应特定任务或领域。

在本教程中,我们将学习创建一个专门用于回答一般支持问题的微调ChatGPT模型。我们将学习和执行以下步骤来构建一个微调模型:

  • 准备训练数据
  • 将训练数据上传到OpenAI服务器
  • 使用训练数据创建微调模型
  • 使用ChatGPT Completion API与微调模型交互
  • 进一步提高微调模型的数据质量

除了上述基本步骤外,我们还将学习查询所有微调模型以及删除不再使用的模型。

先决条件

要充分利用本教程,您需要以下内容:

  • 计算机上安装的Python 3.7或更高版本
  • 通过注册OpenAI帐户获得的OpenAI API密钥
  • 编写和运行Python代码的代码编辑器,如PyCharm(推荐)
  • JSONL文件中的训练数据

您可以在指南《Python如何调用ChatGPT API》中学习如何获取OpenAI API密钥和设置开发工作区。

步骤 1:准备训练数据

微调过程通常始于一个经过精心策划和标记的数据集,它涉及使用诸如迁移学习等技术在这个数据集上训练模型。在微调过程中调整模型的参数,使其在目标领域生成响应时更加准确和适切。模型可以通过微调获得特定领域的知识、语言模式和细微差别,使其能够为特定应用或用例生成更相关和连贯的响应。

在微调过程中,需要提供JSON文件形式的训练数据。您应该创建一组不同的目标对话,期望模型在微调过程完成后执行。

这种训练数据可以来自各种来源,如书籍、文章、专业数据集,或者我们可以手动准备。

1.1. 训练数据格式

训练数据应采用会话聊天格式,并且需要对 gpt-3.5-turbo 进行微调。例如,对于我们的用例,我们创建了具有所需模式的 input_data.jsonl。请注意,每条消息都出现在新行中。

{"messages": [{"role": "user", "content": "Reset my password for account ID 12345"}, {"role": "assistant", "content": "Your password has been reset. Please check your email for the new login details."}]}
{"messages": [{"role": "user", "content": "How do I update my billing information?"}, {"role": "assistant", "content": "To update your billing information, log in to your account, go to the 'Billing' section, and follow the prompts."}]}
...

要开始微调模型,我们必须提供至少10个示例。为了获得超越基础模型的最佳结果,我们应该提供几百个或更多高质量的示例,最好由人类专家进行审查。示例的正确数量因具体用例和所需准确度而异。

1.2. 验证训练数据

建议的验证训练数据的过程包括加载JSONL文件(验证有效的JSON文件)并检查任何缺失的数据元素(验证JSON文件结构)。

您可以在OpenAI网站上查看验证训练数据的最新建议。

import json
from collections import defaultdict
data_path = "input_data.jsonl"
# Load the dataset
with open(data_path, 'r', encoding='utf-8') as f:
  dataset = [json.loads(line) for line in f]
# Initial dataset stats
print("Num examples:", len(dataset))
# Format error checks
format_errors = defaultdict(int)
for ex in dataset:
  if not isinstance(ex, dict):
    format_errors["data_type"] += 1
    continue
  messages = ex.get("messages", None)
  if not messages:
    format_errors["missing_messages_list"] += 1
    continue
  for message in messages:
    if "role" not in message or "content" not in message:
      format_errors["message_missing_key"] += 1
    if any(k not in ("role", "content", "name", "function_call") for k in message):
      format_errors["message_unrecognized_key"] += 1
    if message.get("role", None) not in ("system", "user", "assistant", "function"):
      format_errors["unrecognized_role"] += 1
    content = message.get("content", None)
    function_call = message.get("function_call", None)
    if (not content and not function_call) or not isinstance(content, str):
      format_errors["missing_content"] += 1
  if not any(message.get("role", None) == "assistant" for message in messages):
    format_errors["example_missing_assistant_message"] += 1
if format_errors:
  print("Found errors:")
  for k, v in format_errors.items():
    print(f"{k}: {v}")
else:
  print("No errors found")

如果程序在您的训练数据文件中出现错误,则应首先解决所有问题,您将在运行微调作业时遇到这些错误。

在文件被纠正并且没有错误后,您将看到以下消息:

Num examples: 15
No errors found

步骤 2:将训练数据上传到 OpenAI 服务器

要微调模型,下一步是将训练数据文件上传到 OpenAI 服务器,使用 client.files.create() API。

import os
from openai import OpenAI
input_jsonl_file = 'input_data.jsonl'
client = OpenAI(
  api_key=os.environ.get("OPENAI_API_KEY")
)
file = client.files.create(
  file=open(input_jsonl_file, "rb"),
  purpose="fine-tune"
)
print("File has been uploaded to OpenAI with id ", file.id)

文件上传后,将生成一个文件ID,我们可以随时参考这个ID,而无需反复上传文件。

File has been uploaded to OpenAI with id  file-yCIKv0pm8K54FqmBam0w3BG1

步骤 3:使用上传的训练数据微调模型

3.1 使用 OpenAI API 进行微调

文件上传到 OpenAI 服务器后,我们可以使用 client.fine_tuning.jobs.create() API 使用提供的训练数据对选定的 chatGPT 模型进行微调。

import os
from openai import OpenAI
input_jsonl_file = 'input_data.jsonl'
client = OpenAI(
  api_key=os.environ.get("OPENAI_API_KEY")
)
file = client.files.create(
  file=open(input_jsonl_file, "rb"),
  purpose="fine-tune"
)
print("File has been uploaded to OpenAI with id ", file.id)
ft_job = client.fine_tuning.jobs.create(
  training_file=file.id,
  model="gpt-3.5-turbo"
)
print("Fine Tune Job has been created with id ", ft_job.id)

API 返回一个 Job ID,它指的是在后端创建的异步作业。

Fine Tune Job has been created with id  ftjob-cEkAzoJeA3fuFQ7ftfHyqv9Y

需要注意的是,创建模型的过程可能需要几分钟到几小时的时间,具体取决于 OpenAI 服务器的处理能力。OpenAI 服务器将继续处理您的微调模型,直到它完成。

我们可以使用 client.fine_tuning.jobs.list_events() API 查询微调作业的进度。该 API 返回与作业相关的最新 N 个状态。

events = client.fine_tuning.jobs.list_events(fine_tuning_job_id=ft_job.id, limit=10)
print(events)

控制台输出:

SyncCursorPage[FineTuningJobEvent](data=[
FineTuningJobEvent(id='ftevent-QL4SIRzfDkCRAwJZ0aaN3cWU', created_at=1702316542, level='info', message='Validating training file: file-yCIKv0pm8K54FqmBam0w3BG1', object='fine_tuning.job.event', data={}, type='message'),
FineTuningJobEvent(id='ftevent-4lpFir27PhOsjZa2N1a0Q6ti', created_at=1702316542, level='info', message='Created fine-tuning job: ftjob-cEkAzoJeA3fuFQ7ftfHyqv9Y', object='fine_tuning.job.event', data={}, type='message')], object='list', has_more=False)....

通过使用提供的命令,您可以持续跟踪和监控微调模型的进度,直到其创建完成。在此期间,您可以定期检查状态字段以了解作业的当前状态。

一旦作业完成,我们可以在最终状态消息中获取微调模型的 ID:

FineTuningJobEvent(id='ftevent-OqhBL7WqEkkYTQqFCjGS1BSu', created_at=1702289919, level='info', message='New fine-tuned model created: ft:gpt-3.5-turbo-0613:personal::8UXexX8R', object='fine_tuning.job.event', data={}, type='message')

在上述消息中,我们可以看到一个具有 ID ft:gpt-3.5-turbo-0613:personal 的模型已创建。

3.2. 通过 UI 进行微调

OpenAI 支持通过 fine-tuning UI 创建微调作业。此选项对用户友好,适合小型的训练数据集。要微调模型,请点击屏幕右上角的“+ Create”按钮。这将打开一个弹出窗口,您可以在其中选择要训练的模型和训练数据(JSONL)文件。
现在上传生成文件 ID 的训练文件。在同一窗口中,您可以点击“Create”按钮生成微调模型。
它将开始异步作业,并在此屏幕上监控进度。
作业完成后,您可以看到模型已成功创建。
在此处,您可以从 UI 中复制模型 ID,该 ID 将用于以编程方式与模型进行交互。

步骤 4:使用完成 API 与微调模型交互

模型创建后,我们可以像通常一样使用聊天完成 API 与模型进行交互。唯一的区别是现在我们在请求负载中提供已创建的模型 ID:

import os
from openai import OpenAI
client = OpenAI(
  api_key=os.environ.get("OPENAI_API_KEY")
)
question = input("Ask me anything: ")
response = client.chat.completions.create(
  messages=[
    {
      "role": "user",
      "content": question
    }
  ],
  model="ft:gpt-3.5-turbo-0613:personal::8UXexX8R",
  temperature=0,
  max_tokens=1024,
  n=1,
  stop=None
)
print(response)

运行应用程序并检查配置的提示及其完成响应。

Ask me anything: What security measures are in place to protect my account?
ChatCompletion(id='chatcmpl-8Ueks0SWI7pcB096cud09Hha013p5', choices=[Choice(finish_reason='stop', index=0,
message=ChatCompletionMessage(content='We use industry-standard encryption and authentication methods. Additionally, enable two-factor authentication for added security.', role='assistant',
function_call=None, tool_calls=None))], created=1702317194, model='ft:gpt-3.5-turbo-0613:personal::8UXexX8R',
object='chat.completion', system_fingerprint=None,
usage=CompletionUsage(completion_tokens=19, prompt_tokens=18, total_tokens=37))

请注意 API 响应包含我们在训练数据文件中为输入提示配置的消息。这就意味着我们已经成功使用自定义训练数据创建了微调后的 chatGPT 模型。

步骤 5:进一步改善微调后模型的数据质量

如果微调作业的结果没有达到预期,我们可以更新训练数据并再次运行微调作业。以下是更新训练数据的建议:

  • 添加缺失的示例,这些示例应直接向模型展示如何正确执行特定任务。
  • 更新现有示例(包括语法、风格等),以符合您对模型的期望。
  • 检查示例的多样性。示例应尽可能接近实际对话。
  • 不要简短地编写信息。在训练时始终提供大量细节。

更新训练数据后,重新上传文件并以先前的微调模型为起点再次运行微调作业。重复此过程,直到您对完成响应的质量感到满意。

一般来说,少量高质量的数据通常比大量低质量的数据更有效。

常见问题

如何删除微调模型?

我们可以使用OpenAI API删除微调模型,如下所示:

import os
from openai import OpenAI
client = OpenAI(
  api_key=os.environ.get("OPENAI_API_KEY")
)
client.models.delete('ft:gpt-3.5-turbo-0613:personal::8UXexX8R')

需要注意的是,删除微调模型应该明智,因为它会永久删除模型及其相关数据。

如何列出所有模型?

我们可以使用OpenAI API列出所有可用的,如下所示。

import os
from openai import OpenAI
client = OpenAI(
  api_key=os.environ.get("OPENAI_API_KEY")
)
models = client.models.list()
print(models)

这将列出所有基本模型以及我们微调过的所有模型。程序输出:

SyncPage[Model](data=[Model(id='text-search-babbage-doc-001', created=1651172509, object='model', owned_by='openai-dev'), Model(id='curie-search-query', created=1651172509, object='model', owned_by='openai-dev'), Model(id='text-davinci-003', created=1669599635, object='model', owned_by='openai-internal'),
...
...
Model(id='gpt-3.5-turbo-0613', created=1686587434, object='model', owned_by='openai'), Model(id='tts-1-1106', created=1699053241, object='model', owned_by='system'), Model(id='tts-1-hd-1106', created=1699053533, object='model', owned_by='system'), Model(id='dall-e-3', created=1698785189, object='model', owned_by='system')], object='list')

结论

在这个 OpenAI chatGPT 教程中,我们探索了微调模型的整个生命周期。微调通过结合领域特定知识和语言模式,丰富了基础模型生成准确和上下文适应的响应的能力。

我们深入了解了一个全面的数据集准备分步指南,以微调和上传训练数据到OpenAI服务器。我们学会了使用训练数据来创建微调模型并监控工作进度。最后,我们学会了执行一些其他重要操作,如删除未使用的模型。

欢迎持续关注潘子夜个人博客,学习愉快哦!


版权声明:本站文章,如无说明,均为本站原创,转载请注明文章来源。如有侵权,请联系博主删除。
本文链接:https://www.panziye.com/back/12639.html
喜欢 (0)
请潘老师喝杯Coffee吧!】
分享 (0)
用户头像
发表我的评论
取消评论
表情 贴图 签到 代码

Hi,您需要填写昵称和邮箱!

  • 昵称【必填】
  • 邮箱【必填】
  • 网址【可选】