入门文档(docs)
指南(Guides)
微调指南(Fine-Tuning Guide)

微调 Fine-tuning

概览 Introduction

通过对模型进行微调,可以更好地利用 API 提供的模型。

  • 比提示设计具有更高的质量结果
  • 能够训练更多不能适合提示的例子
  • 由于提示更短,可以节省令牌
  • 更低延迟的请求

GPT-3 已经预训练了大量来自开放的互联网文本。

只有一些例子的提示情况下,它通常可以直观地了解您试图执行的任务并生成一个合理的完成(completion)。这通常被称为"few-shot learning"。

通过训练比提示适合更多的例子,微调可以在许多任务上获得更好的结果,改进了 few-shot 学习。

一旦模型被微调,您将不需要再在提示中提供例子。

这可以节省成本并实现更低的延迟请求。

在高层次上,微调涉及以下步骤:

  • 准备并上传训练数据
  • 训练新的微调模型
  • 使用您的微调模型

访问我们的定价页面 (opens in a new tab),了解有关如何计费微调模型的培训和使用的更多信息。

微调模型 What models can be fine-tuned?

目前仅以下基础模型可以进行微调:davincicuriebabbageada。这些是没有任何后续指令的原始模型(例如,text-davinci-003就是这样的)。您还可以从微调模型继续微调,以添加其他数据而无需从头开始。

安装Installation

我们建议使用我们的OpenAI命令行界面(CLI)。要安装此软件,请运行

pip install --upgrade openai

(以下说明适用于版本0.9.4及以上。此外,OpenAI CLI 需要 python 3。)

将以下一行代码添加到您的shell初始化脚本(例如.bashrc、zshrc等)或在微调命令之前在命令行中运行它来设置您的OPENAI_API_KEY环境变量:

export OPENAI_API_KEY=your_api_key
export OPENAI_API_KEY="<OPENAI_API_KEY>"

预训练数据Prepare training data训练数据是您教GPT-3说话的方式。

您的数据必须是JSONL (opens in a new tab)文档,其中每一行是与训练示例对应的提示完成(completion)对。

您可以使用我们的CLI数据准备工具轻松将数据转换为此文件格式。

{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
{"prompt": "<prompt text>", "completion": "<ideal generated text>"}
...

针对微调设计提示和完成(completion)与基本模型(Davinci、Curie、Babbage、Ada)不同。

特别地,在基本模型的提示中,通常包含多个示例few-shot(“少量学习”),

但是对于微调,每个训练示例通常由一个输入示例及其相关输出组成,无需提供详细说明或在同一提示中包含多个示例。

有关如何为各种任务准备训练数据的详细指导,请参阅我们的准备数据集最佳实践。

您拥有的训练示例越多,效果越好。我们建议您至少有几百个示例。

通常,我们发现数据集大小翻倍会导致模型质量线性增加。

CLI 工具 data preparation tool

我们开发了一个工具,可验证、提供建议并重新格式化您的数据:

openai tools fine_tunes.prepare_data -f <LOCAL_FILE>

这个工具支持不同的格式,唯一的要求是包含提示和完成(completion)列/键。你可以传递CSV、TSV、XLSX、JSON或JSONL文件,并将输出保存到一个准备好进行微调的JSONL文件中,在引导你进行建议更改的过程后。

创建一个微调模型Create a fine-tuned model

以下假设你已经按照上述说明准备好了训练数据。

使用OpenAI CLI:启动微调作业。

openai api fine_tunes.create -t <TRAIN_FILE_ID_OR_PATH> -m <BASE_MODEL>

其中BASE_MODEL是您要开始微调的基础模型的名称(adababbagecuriedavinci)。

您可以使用后缀参数自定义微调模型的名称。

运行上面的命令会做一些事情:

  • 使用文件API (opens in a new tab)上传文件(或使用已上传的文件)
  • 创建一个微调作业
  • 流式传输事件,直到作业完成(completion)(这通常需要几分钟,但如果队列中有许多作业或数据集很大,可能需要几小时)

每个微调任务都从一个基础模型开始,默认为curie

模型的选择影响模型的性能以及运行微调模型的成本。您的模型可以是adababbagecuriedavinci之一。请访问我们的定价页面 (opens in a new tab)了解微调价格的详细信息。

启动微调作业后,可能需要一些时间才能完成(completion)。

您的作业可能排在我们系统中的其他作业之后,根据模型和数据集的大小,训练我们的模型可能需要几分钟或几个小时。如果任何原因导致事件流中断,您可以通过运行:恢复它

openai api fine_tunes.follow -i <YOUR_FINE_TUNE_JOB_ID>

当作业完成(completion)时,它应该显示经微调的模型的名称。

除了创建微调作业之外,您还可以列出现有作业、检索作业的状态或取消作业。

# List all created fine-tunes
openai api fine_tunes.list
 
# Retrieve the state of a fine-tune. The resulting object includes
# job status (which can be one of pending, running, succeeded, or failed)
# and other information
openai api fine_tunes.get -i <YOUR_FINE_TUNE_JOB_ID>
 
# Cancel a job
openai api fine_tunes.cancel -i <YOUR_FINE_TUNE_JOB_ID>

使用微调模型 Use a fine-tuned model

当作业成功时,fine_tuned_model字段将填充模型的名称。

现在,您可以将此模型指定为Completions API (opens in a new tab)的参数,并使用Playground向其发送请求。

完成(completion)作业后,您的模型可能需要几分钟才能准备好处理请求。

如果您的模型的完成(completion)请求超时,则很可能是因为您的模型仍在加载中。如果发生这种情况,请稍后再试几分钟。

您可以通过将模型名称作为完成(completion)请求的model参数传递来开始发出请求:

OpenAI CLI:

openai api completions.create -m <FINE_TUNED_MODEL> -p <YOUR_PROMPT>

CURL:

curl https://api.openai.com/v1/completions 
 -H "Authorization: Bearer $OPENAI_API_KEY" 
 -H "Content-Type: application/json" 
 -d '{"prompt": YOUR_PROMPT, "model": FINE_TUNED_MODEL}'

Python:

import openai
openai.Completion.create(
    model=FINE_TUNED_MODEL,
    prompt=YOUR_PROMPT)

Node.js:

const response = await openai.createCompletion({
 model: FINE_TUNED_MODEL
 prompt: YOUR_PROMPT,
});

您可以在这些针对微调模型的请求上继续使用所有其他Completions(完成(completion)) (opens in a new tab)参数,如temperaturefrequency_penaltypresence_penalty等。

删除微调模型

要删除微调模型,您必须在组织中被指定为“所有者”。

OpenAI CLI:

openai api models.delete -i <FINE_TUNED_MODEL>

CURL:

curl -X "DELETE" https://api.openai.com/v1/models/<FINE_TUNED_MODEL>
 -H "Authorization: Bearer $OPENAI_API_KEY"

Python:

import openai
openai.Model.delete(FINE_TUNED_MODEL)

准备数据集

微调是一种创建特定于您的用例的新模型的强大技术。

在微调模型之前,我们强烈推荐阅读下面的最佳实践和用例特定指南

数据格式

要微调模型,您需要一组训练示例,每个示例都由单个输入(“提示”)及其关联的输出(“完成(completion)”)组成。这与使用我们的基础模型有明显的区别,其中您可以在单个提示中输入详细的说明或多个示例。

  • 每个提示都应以固定分隔符结尾,以通知模型何时提示结束并开始完成(completion)。通常效果良好的简单分隔符是 ### 。分隔符不应在任何提示中的其他位置出现。
  • 每个完成(completion)应以空格开头,由于我们的分词,它使用在单词之前具有先前空格的标记化。
  • 每个完成(completion)应以固定的停止序列结尾,以通知模型何时完成(completion)。停止序列可以是\n###或任何不出现在任何完成(completion)中的标记。
  • 对于推理,您应该以与创建训练数据集时相同的方式格式化提示,包括相同的分隔符。还要指定相同的停止序列以适当截断完成(completion)。

一般最佳实践

微调会随着更高质量的示例而表现更好。要微调比使用我们的基础模型的高质量提示表现更好的模型,至少应提供几百个高质量示例,最好由人类专家进行审核。从那里开始,性能往往会随着示例数量翻倍而线性增加。增加示例的数量通常是提高性能的最佳和最可靠的方法。

分类器是最容易入门的模型。对于分类问题,我们建议使用ada,一般来说,在经过微调后,ada的性能仅略差于更能胜任的模型,同时速度和价格显著更快更便宜。

如果您是在预先存在的数据集上进行微调而不是从头开始编写提示,请务必手动查看数据以查找冒犯或不准确的内容,如果可能的话,或者如果数据集很大,则尽可能查看尽可能多的随机样本。

特定用例 Specific guidelines

微调可以解决各种问题,最佳的使用方式可能取决于您的特定用例。下面,我们列出了微调的最常见用例以及相应的指导方针。

分类 Classification

在分类问题中,提示中的每个输入应分类为预定义类别之一。对于此类型的问题,我们建议:

  • 在提示的末尾使用分隔符,例如 ### 。请记得在最终向模型发出请求时,也将此分隔符附加在最后。
  • 选择映射到单个令牌的类别。在推理时,指定max_tokens=1,因为您只需要分类的第一个令牌。
  • 确保提示+完成(completion)不超过2048个标记,包括分隔符。
  • 每个类别至少有约100个示例。
  • 若要获得类别日志概率,可以在使用模型时指定logprobs=5(对于5个类别)。
  • 确保用于微调的数据集在结构和任务类型上非常类似于模型的用途。

实例研究:模型是否有不实陈述?

假设您希望确保您网站上的广告文本正确地提及了产品和公司。换句话说,您希望确保模型不会胡说八道。您可能希望微调分类器,以过滤掉不正确的广告。

可能的数据集如下所示:

{"prompt":"Company: BHFF insurance\nProduct: allround insurance\nAd:One stop shop for all your insurance needs!\nSupported:", "completion":" yes"}
{"prompt":"Company: Loft conversion specialists\nProduct: -\nAd:Straight teeth in weeks!\nSupported:", "completion":" no"}

在上面的示例中,我们使用了一个包含公司名称、产品和相关广告的结构化输入。作为分隔符,我们使用了\nSupported:,它清晰地将提示和完成(completion)分开。

有了足够数量的示例,分隔符在不影响结果的情况下并不重要(通常不到0.4%),只要它不出现在提示或完成(completion)中即可。

对于这个用例,我们微调了一个ada模型,因为它将更快、更便宜,并且性能将与较大的模型可比,因为这是一个分类任务。

现在我们可以通过发出完成(completion)请求来查询我们的模型。

curl https://api.openai.com/v1/completions
 -H "Content-Type: application/json"
 -H "Authorization: Bearer $OPENAI_API_KEY"
 -d '{
 "prompt": "Company: Reliable accountants Ltd\nProduct: Personal Tax help\nAd:Best advice in town!\nSupported:",
 "max_tokens": 1,
 "model": "YOUR_FINE_TUNED_MODEL_NAME"
 }'

会返回yes 或者no.

案例学习:语义分析 Case study: Sentiment analysis

假设你想要获得某个推文是正面还是负面程度的程度。数据集可能如下所示:

{"prompt":"Overjoyed with the new iPhone! ->", "completion":" positive"}
{"prompt":"@lakers disappoint for a third straight night https://t.co/38EFe43 ->", "completion":" negative"}

微调模型完成(completion)后,您可以在完成(completion)请求中设置logprobs=2来获取第一个完成(completion)令牌的日志概率。

正类别的概率越高,情感值就越高。

现在我们可以通过发出完成(completion)请求来查询我们的模型。

curl https://api.openai.com/v1/completions
 -H "Content-Type: application/json"
 -H "Authorization: Bearer $OPENAI_API_KEY"
 -d '{
 "prompt": "https://t.co/f93xEd2 Excited to share my latest blog post! ->",
 "max_tokens": 1,
 "model": "YOUR_FINE_TUNED_MODEL_NAME"
 }'

这将返回:

{
 "id": "cmpl-COMPLETION_ID",
 "object": "text_completion",
 "created": 1589498378,
 "model": "YOUR_FINE_TUNED_MODEL_NAME",
 "choices": [
    {
 "logprobs": {
 "text_offset": [
 19
        ],
 "token_logprobs": [
 -0.03597255
        ],
 "tokens": [
 " positive"
        ],
 "top_logprobs": [
          {
 " negative": -4.9785037,
 " positive": -0.03597255
          }
        ]
      },
 
 "text": " positive",
 "index": 0,
 "finish_reason": "length"
    }
  ]
}

电子邮件分类 Case study: Categorization for Email triage

假设你想将电子邮件分类到大量预定义的类别之一。对于大量类别的分类,我们建议您将这些类别转换为数字,这样将适用于500个类别左右。我们观察到,由于标记化,在数字前面添加空格有时会稍微提高性能。

你可能希望按照以下方式组织你的训练数据:

{"prompt":"Subject: <email_subject>\nFrom:<customer_name>\nDate:<date>\nContent:<email_body>  ###  ", "completion":" <numerical_category>"}

例如:

{"prompt":"Subject: Update my address\nFrom:Joe Doe\nTo:support@ourcompany.com\nDate:2021-06-03\nContent:Hi,\nI would like to update my billing address to match my delivery address.  Please let me know once done.  Thanks,\nJoe  ###  ", "completion":" 4"}

在上面的示例中,我们使用了一个长度为2043的电子邮件作为输入。(这允许使用4个令牌分隔符和一个令牌完成(completion),总共为2048个标记。)。

作为分隔符,我们使用了 ### ,并删除了电子邮件中出现的任何###

条件生成 Conditional generation

条件生成是一个需要根据某种输入生成内容的问题。这包括改写、摘要、实体提取、根据规格书编写产品描述、聊天机器人和许多其他问题。对于这种类型的问题,我们建议:

  • 在提示的末尾使用分隔符,例如 ### 。请记得在最终向模型发出请求时,也将此分隔符附加在最后。
  • 在完成(completion)的末尾使用一个终止符号,例如END
  • 在推理时,记得将终止符号添加为停止序列,例如stop=[" END"]
  • 至少要有500个样本
  • 确保提示+完成(completion)不超过2048个标记,包括分隔符
  • 确保示例具有高质量并符合所需格式
  • 确保用于微调的数据集在结构和任务类型上与将要使用模型的非常相似
  • 对于这些用例,使用较低的学习率和仅1-2个时期往往效果更好

生成性用例 Case study: Write an engaging ad based on a Wikipedia article

这是一个生成性用例,因此您需要确保提供的样本质量最高,因为微调的模型将尝试模仿给定示例的风格(和错误)。一个好的起点是约500个示例。一个示例数据集可能如下所示:

{"prompt":"<Product Name>\n<Wikipedia description>  ###  ", "completion":" <engaging ad> END"}

例如:

{"prompt":"Samsung Galaxy Feel\nThe Samsung Galaxy Feel is an Android smartphone developed by Samsung Electronics exclusively for the Japanese market. The phone was released in June 2017 and was sold by NTT Docomo. It runs on Android 7.0 (Nougat), has a 4.7 inch display, and a 3000 mAh battery.\nSoftware\nSamsung Galaxy Feel runs on Android 7.0 (Nougat), but can be later updated to Android 8.0 (Oreo).\nHardware\nSamsung Galaxy Feel has a 4.7 inch Super AMOLED HD display, 16 MP back facing and 5 MP front facing cameras. It has a 3000 mAh battery, a 1.6 GHz Octa-Core ARM Cortex-A53 CPU, and an ARM Mali-T830 MP1 700 MHz GPU. It comes with 32GB of internal storage, expandable to 256GB via microSD. Aside from its software and hardware specifications, Samsung also introduced a unique a hole in the phone's shell to accommodate the Japanese perceived penchant for personalizing their mobile phones. The Galaxy Feel's battery was also touted as a major selling point since the market favors handsets with longer battery life. The device is also waterproof and supports 1seg digital broadcasts using an antenna that is sold separately.  ###  ", "completion":"Looking for a smartphone that can do it all? Look no further than Samsung Galaxy Feel! With a slim and sleek design, our latest smartphone features high-quality picture and video capabilities, as well as an award winning battery life. END"}

这里我们使用了多行分隔符,因为维基百科文章包含多个段落和标题。我们还使用了简单的结束标记,以确保模型知道完成(completion)时应该结束。

案例学习 Case study: Entity extraction

这类似于语言转换任务。为了提高性能,最好按字母顺序或按原始文本中出现的顺序排序不同的提取实体。这将帮助模型跟踪所有需要按顺序生成的实体。数据集可能如下所示:

{"prompt":"<any text, for example news article>  ###  ", "completion":" <list of entities, separated by a newline> END"}

例如:

{"prompt":"Portugal will be removed from the UK's green travel list from Tuesday, amid rising coronavirus cases and concern over a"Nepal mutation of the so-called Indian variant\". It will join the amber list, meaning holidaymakers should not visit and returnees must isolate for 10 days...  ###  ", "completion":" Portugal\nUK\nNepal mutation\nIndian variant END"}

多行分隔符效果最佳,因为文本可能包含多行。理想情况下,输入提示的类型多样性很高(新闻文章,维基百科页面,推文,法律文件),这反映了在提取实体时可能遇到的文本。

案例学习 Case study: Customer support chatbot

聊天机器人通常会包含有关对话(订单详情)的相关语境,到目前为止的对话摘要以及最近的信息。对于这种用例,同一过去的对话可能会在数据集中生成多个行,每次生成时都会有略微不同的上下文,每个代理生成作为完成(completion)。

这个用例需要几千个示例,因为它可能涉及不同类型的请求和客户问题。

为了确保性能具有高品质,我们建议审核对话样本以确保代理消息的质量。

摘要可以用单独的文本转换精调模型生成。数据集可以如下所示:

{"prompt":"Summary: <summary of the interaction so far>  Specific information:
  <for example order details in natural language>  ###  
  Customer: <message1>\n
  Agent: <response1>\n
  Customer: <message2>\n
  Agent:", 
  "completion":" <response2>\n"}
{"prompt":"Summary: <summary of the interaction so far>  Specific information:
  <for example order details in natural language>  ###  Customer: <message1>\n
  Agent: <response1>\n
  Customer: <message2>\n
  Agent: <response2>\n
  Customer: <message3>\n
  Agent:", 
  "completion":" <response3>\n"}

这里我们有意将不同类型的输入信息分开,但在prompt和completion之间保持了客户和代理人的对话格式。所有的完成(completion)只能由代理人完成,在推理时我们可以使用\n作为停止序列。

案例学习:基于技术属性列表的产品描述

在这里,将输入数据转换为自然语言非常重要,这可能会导致更出色的性能。

例如,以下格式:

{"prompt":"Item=handbag, Color=army_green, price=$99, size=S->", 
"completion":" This stylish small green handbag will add a unique touch to your look, 
without costing you a fortune."}

不如:

{"prompt":"Item is a handbag.\n 
Colour is army green. Price is midrange. \n
Size is small.->", 
 
"completion":" This stylish small green handbag will add a unique touch to your look, \n
without costing you a fortune."}

为了获得高性能,确保完成(completion)是基于提供的描述的。

如果经常需要查看外部内容,则以自动化方式添加此类内容将提高性能。

如果描述是基于图像的,则使用算法提取图像的文本描述可能会有帮助。

由于完成(completion)仅有一个句子长,因此我们可以在推理过程中使用.作为停止序列。


高级用法

自定义您的模型名称

您可以使用后缀 (opens in a new tab)参数将最多40个字符的后缀(--suffix)添加到您的精调模型名称中。

OpenAI CLI:

openai api fine_tunes.create -t test.jsonl -m ada --suffix "custom model name"

结果名称将为:

ada:ft-your-org:custom-model-name-2022-02-15-04-21-04

分析您的微调模型

完成(completion)每个作业后,我们会附加一个结果文件。当您检索精调时,将列出此结果文件ID,以及查看精调事件时。您可以下载这些文件:

OpenAI CLI:

openai api fine_tunes.results -i <YOUR_FINE_TUNE_JOB_ID>

CURL:

curl https://api.openai.com/v1/files/$RESULTS_FILE_ID/content
  -H "Authorization: Bearer $OPENAI_API_KEY" > results.csv

_results.csv文件包含每个训练步骤的一行,其中一步骤是对一批数据进行一次前向和后向传递。除了步数之外,每行包含以下与该步骤对应的字段:

  • elapsed_tokens:模型迄今为止看到的标记数(包括重复)

  • elapsed_examples:模型迄今为止看到的示例数量(包括重复项),其中一个示例是批次中的一个元素。 例如,如果batch_size = 4,则每个步骤将使得elapsed_examples增加4。

  • training_loss:训练批次的损失

  • training_sequence_accuracy:训练批次中**完成(completion)**的百分比,其中模型预测的标记与真实的完成(completion)标记完全匹配。

例如,如果数据包含完成(completion)[[1,2],[0,5],[4,2]]、模型预测[[1,1],[0,5],[4,2]],batch_size为3,则准确率将为2/3 = 0.67

  • training_token_accuracy:训练批次中模型正确预测的的标记百分率。

例如,如果数据包含完成(completion)[[1,2],[0,5],[4,2]],模型预测[[1,1],[0,5],[4,2]],batch_size=3,则准确率将为5/6 = 0.83

我们还提供了在结果文件中生成额外的针对分类的度量标准的选项,例如准确性和加权F1分数。

这些度量标准会定期计算全部验证集,并在微调结束时计算。您将在结果文件中看到它们作为其他列。

要启动此功能,请设置参数--compute_classification_metrics。 另外,您必须提供验证文件,并设置classification_n_classes参数,用于多类分类,或classification_positive_class,用于二元分类。

针对分类的度量标准

OpenAI CLI:

`# For multiclass classification
openai api fine_tunes.create
  -t <TRAIN_FILE_ID_OR_PATH>
  -v <VALIDATION_FILE_OR_PATH>
  -m <MODEL>
  --compute_classification_metrics
  --classification_n_classes <N_CLASSES>
 
# For binary classification
openai api fine_tunes.create
  -t <TRAIN_FILE_ID_OR_PATH>
  -v <VALIDATION_FILE_OR_PATH>
  -m <MODEL>
  --compute_classification_metrics
  --classification_n_classes 2
  --classification_positive_class <POSITIVE_CLASS_FROM_DATASET>

如果设置了--compute_classification_metrics,下列度量标准将显示在您的结果文件中:

对于多类分类
  • classification/accuracy:准确性
  • classification/weighted_f1_score:加权F-1分数
对于二元分类

以下度量标准基于分类阈值为0.5(即当概率> 0.5时,将示例分类为属于正类别)。

  • classification/accuracy
  • classification/precision
  • classification/recall
  • classification/f{beta}
  • classification/auroc - AUROC
  • classification/auprc - AUPRC

请注意,这些评估假定您将类别的文本标签用于分词成一个标记的单一标记,如上所述。如果这些条件不成立,您得到的数字可能是错误的。

验证 Validation

您可以保留一些数据进行验证。验证文件与训练文件具有完全相同的格式,您的训练和验证数据应该互不重叠。

如果在创建fine-tune作业时包含验证文件,则生成的结果文件将包括训练期间定期评估fine-tuned模型对验证数据表现的评估。

OpenAI CLI:

openai api fine_tunes.create -t <TRAIN_FILE_ID_OR_PATH> 
  -v <VALIDATION_FILE_ID_OR_PATH> 
  -m <MODEL>

如果提供了验证文件,我们会在训练时定期计算验证数据批次的指标。您的结果文件中将看到以下额外的指标:

  • validation_loss:验证批次的损失
  • validation_sequence_accuracy:验证批次中 完成(completion) 的百分比,其中模型预测的标记与真实的完成(completion)标记完全匹配。例如,如果数据包含完成(completion)[[1,2],[0,5],[4,2]],模型预测[[1,1],[0,5],[4,2]]batch_size为3,则准确率将为2/3 = 0.67
  • validation_token_accuracy:验证批次中模型正确预测的的标记百分率。例如,如果数据包含完成(completion)[[1,2],[0,5],[4,2]],模型预测[[1,1],[0,5],[4,2]]batch_size为3,则准确率将为5/6 = 0.83

超参数 hyperparameters

我们选择了适用于各种用例的默认超参数。唯一需要的参数是训练文件。

即便如此,微调所使用的超参数进行微调通常会导致产生更高质量输出的模型。特别是,您可能想配置以下内容:

  • model:用于微调的基础模型的名称。您可以选择 "ada", "babbage", "curie" 或 "davinci" 中的一个。了解这些模型的更多信息,请参见模型文档。
  • n_epochs - 默认为4。训练模型的时代数。一个时代(epoch)指的是对训练数据集进行一次完整的循环。
  • batch_size - 默认为训练集中示例数的 ~0.2%,最大为256。批大小是用于训练单个前向和反向传递的训练示例数。通常,我们发现对于较大的数据集,较大的批大小更有效。
  • learning_rate_multiplier - 默认值为0.05、0.1或0.2,具体取决于最终的 batch_size。微调的学习率是用于预训练的原始学习率乘以该乘数。我们建议尝试在0.02到0.2的范围内的值,看看哪个能产生最佳的结果。按经验,我们发现较大的学习率,通常在比较大的“批大小”下表现更好。
  • compute_classification_metrics - 默认为False。如果为True,对于分类任务的微调,将在每个时期结束时计算验证集上的特定于分类的度量(准确度、F-1得分等)。

要配置这些附加的超参数,请通过OpenAI CLI的命令行标志传递它们,例如:

openai api fine_tunes.create
  -t file-JD89ePi5KMsB3Tayeli5ovfW
  -m ada
  --n_epochs 1

从一个已经进行过微调的模型继续微调

如果您已经为您的任务微调了一个模型,并且现在有其他训练数据要包含,则可以从该模型继续进行微调。这将创建一个已经从所有训练数据中学习,而无需从头开始重新训练的模型。

为了做到这一点,创建一个新的微调作业时,请传入经过微调的模型名称(例如:-m curie:ft-<org>-<date>)。其他的训练参数不需要更改,但是如果您的新训练数据比以前的训练数据小很多,您可能会发现将 learning_rate_multiplier 减少2到4倍很有用。


Weights & Biases

您可以将您的微调与Weights & Biases (opens in a new tab)同步,以跟踪实验、模型和数据集。

要开始使用,您需要一个 Weights & Biases (opens in a new tab) 帐户和一个付费的 OpenAI 计划。为了确保您使用的是 openaiwandb 的最新版本,请运行:

pip install --upgrade openai wandb

要将您的微调与Weights & Biases同步,请运行:

openai wandb sync

可以阅读Weights & Biases文档 (opens in a new tab)了解更多关于此集成的信息。


笔记本案例 Example notebooks

分类Classificationfinetuning-classification.ipynb (opens in a new tab)

此笔记本将演示如何微调一个模型,该模型可以对输入文本是否与棒球或曲棍球相关进行分类。

我们将在笔记本 (opens in a new tab)中执行这四个步骤:

  • 数据探索将概述数据源以及示例是什么样子
  • 数据准备将把我们的数据源转换为可用于微调的jsonl文件
  • 微调将启动微调作业并解释所得到的模型的性能
  • 使用模型将演示如何向微调的模型发出请求以获得预测。

折叠问答(Collapse Question Answering)

该项目的想法是创建一个基于提供的一些段落文本的问答模型。

基于GPT-3的基础模型在答案包含在段落中的情况下回答问题做得很好,但是如果答案不包含在内,在不确定的情况下,基础模型往往会尽力回答问题,导致答案混淆。

为了创建一个只有在有足够上下文的情况下才能回答问题的模型,我们首先创建了一个基于文本段落的问题和答案的数据集。

为了训练模型仅在答案存在时才回答问题,我们还添加了对抗性示例,其中问题与上下文不匹配。

在这些情况下,我们要求模型输出“无法回答问题的足够上下文”。

我们将在三个笔记微调作业中完成(completion)这个任务:

  • 第一个笔记微调作业 (opens in a new tab) 专注于收集最近的数据,这是GPT-3在预先训练期间未见过的。我们选择了2020年奥运会(实际上是在2021年夏天举行的),下载了713个唯一的页面。我们按个人部分组织数据集,这将用作提出问题和回答的上下文。
  • 第二个笔记微调作业 (opens in a new tab) 将利用Davinci-instruct根据维基百科部分提出一些问题,以及基于该部分回答这些问题。
  • 第三份笔记微调作业 (opens in a new tab)将利用上下文,问题和答案对的数据集,另外创建对抗性问题和上下文对,其中问题不是在该上下文中生成的。在这些情况下,模型将被提示回答“没有足够的上下文来回答问题”。我们还将训练一个鉴别器模型,用于预测问题是否可以基于上下文来回答。