你在我这儿 LV
发表于 2025-4-8 15:13:22
今天刚刚翻译完 OpenAI 的 fine-tuning 文档,官方文档应该很适合回答这个问题,以下是文章内容:
本篇文档翻译时间为 20230501,请注意时效性。
其他已翻译文档链接:
- IvyLee:OpenAI ChatGPT API 指南之 Chat Completion Beta 版
- IvyLee:OpenAI ChatGPT API 指南之语音转文字 Beta 版
- IvyLee:OpenAI ChatGPT API 文档之生产最佳实践
- IvyLee:OpenAI ChatGPT API 文档之 Embedding
- IvyLee:OpenAI ChatGPT API 文档之 Fine-tuning(微调)
<hr/>了解如何为你的应用程序定制模型。
介绍
通过以下方式,微调可让你更好地利用 API 提供的模型:
- 比设计提示(prompt)质量更高的结果
- 能够训练更多不适合提示的示例
- 由于提示较短而节省 token
- 更低的延迟请求
GPT-3 已经在开放互联网的大量文本上进行了预训练。当给出仅包含几个示例的提示时,它通常可以直观判断出你正在尝试执行的任务并生成看似合理的补全(completion),这通常称为“小样本学习(few-shot learning)”。
微调(Fine-tuning)通过训练超出提示范围的更多示例来改进小样本学习,让你在大量任务上取得更好的结果。模型经过微调后,你将不再需要在提示中提供示例。这可以节省成本并实现更低延迟的请求。
概括地讲,微调涉及以下步骤:
- 准备并上传训练数据
- 训练一个新的微调模型
- 使用你的微调模型
请访问我们的定价页面,详细了解微调模型训练和使用的计费方式。
哪些模型可以微调?
微调目前仅适用于以下基本模型:davinci、curie、babbage 和 ada,这些是训练后没有任何指令的原始模型(有指令的模型举例:text-davinci-003)。你还可以通过添加额外数据来继续微调已经微调过的模型,而无需从头开始。
安装
我们建议使用 OpenAI 的命令行界面(CLI),请运行如下命令进行安装:- pip install --upgrade openai
复制代码 (以下说明适用于 0.9.4 及更高版本。另外,OpenAI CLI 需要 python 3。)
通过将以下行添加到你的 shell 初始化脚本(例如 .bashrc、zshrc 等)或在微调命令之前在命令行中运行该命令来设置你的 OPENAI_API_KEY 环境变量:- export OPENAI_API_KEY=&#34;<OPENAI_API_KEY>&#34;
复制代码 准备训练数据
训练数据是教给 GPT-3 你想让它生成内容的方式。
数据必须是一个 JSONL 文档,其中每一行都是一个提示-补全对(prompt-completion),对应于一个训练示例。你可以使用我们的 CLI 数据准备工具轻松将数据转换成此文件格式。- {&#34;prompt&#34;: &#34;<提示文本>&#34;, &#34;completion&#34;: &#34;<理想的生成文本>&#34;}
- {&#34;prompt&#34;: &#34;<提示文本>&#34;, &#34;completion&#34;: &#34;<理想的生成文本>&#34;}
- {&#34;prompt&#34;: &#34;<提示文本>&#34;, &#34;completion&#34;: &#34;<理想的生成文本>&#34;}
- ...
复制代码 设计用于微调的提示和补全不同于设计用于基本模型(Davinci、Curie、Babbage、Ada)的提示。具体而言,基础模型的提示通常包含多个示例(“小样本学习”),而微调的每个训练示例通常包含单个输入示例及其相关输出,无需给出详细说明或在同一提示中包含多个示例。
有关如何为各种任务准备训练数据的更详细指导,请参阅准备数据集最佳实践.
拥有的训练示例越多越好,我们的建议是至少有几百个示例。我们发现数据集大小每增加一倍都会导致模型质量线性增加。
CLI 数据准备工具
我们开发了一个工具,可以验证、提供建议和重新格式化你的数据:- openai tools fine_tunes.prepare_data -f <LOCAL_FILE>
复制代码 这个工具接受不同的格式,唯一的要求是它们包含提示和补全列/键。你可以传递 CSV、TSV、XLSX、JSON 或 JSONL 文件,它将在引导你完成建议更改后,将输出保存到一个准备好进行微调的 JSONL 文件中。
创建微调模型
假设你已经按照上述指南准备好了数据。
使用 OpenAI CLI 开始微调作业:- openai api fine_tunes.create -t <TRAIN_FILE_ID_OR_PATH> -m <BASE_MODEL>
复制代码 其中 BASE_MODEL 是你开始使用的基础模型名称(ada、babbage、curie 或 davinci)。你可以使用 后缀参数 自定义微调模型的名称。
运行上述命令会执行以下几个操作:
- 使用文件 API 上传文件(或使用已上传的文件)
- 创建一个微调作业
- 流式传输事件,直到作业完成(这通常需要几分钟,但如果队列中有很多作业或数据集很大,则可能需要几个小时)
每个微调作业都始于一个基础模型,默认为 curie。模型的选择会影响模型的性能和微调模型的成本。你可以选择的模型包括:ada、babbage、curie 或 davinci。请访问我们的定价页面,了解有关微调费率的详细信息。
启动微调作业后,可能需要一些时间才能完成。在我们的系统中,你的作业可能排在其他作业之后,训练我们的模型可能需要几分钟或几小时,具体取决于模型和数据集的大小。如果事件流因任何原因中断,你可以通过运行以下命令恢复它:- openai api fine_tunes.follow -i <YOUR_FINE_TUNE_JOB_ID>
复制代码 作业完成后,它应该显示微调模型的名称。
除了创建微调作业,你还可以列出现有作业、检索作业状态或取消作业。- # 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>
复制代码 使用微调模型
作业成功后,fine_tuned_model 字段将填充模型名称。你现在可以将此模型指定为我们的 Completions API 的参数,使用 [Playground](https:// platform.openai.com/playground)对其进行请求。
在作业第一次完成后,你的模型可能需要几分钟时间才能准备好处理请求。如果你对模型的 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 &#34;Authorization: Bearer $OPENAI_API_KEY&#34; \
- -H &#34;Content-Type: application/json&#34; \
- -d &#39;{&#34;prompt&#34;: YOUR_PROMPT, &#34;model&#34;: FINE_TUNED_MODEL}&#39;
复制代码 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,
- });
复制代码 你可以继续在这些针对微调模型的请求中使用所有其他 Completion 参数,例如 temperature、frequency_penalty、presence_penalty 等。
删除微调模型
要删除微调模型,你必须在你的组织中被指定为“所有者(owner)”。
OpenAI CLI:- openai api models.delete -i <FINE_TUNED_MODEL>
复制代码 cURL:- curl -X &#34;DELETE&#34; https://api.openai.com/v1/models/<FINE_TUNED_MODEL> \
- -H &#34;Authorization: Bearer $OPENAI_API_KEY&#34;
复制代码 Python:- import openai
- openai.Model.delete(FINE_TUNED_MODEL)
复制代码 准备数据集
微调是一种强大的技术,可以创建特定于你的用例的新模型。在微调模型之前,我们强烈建议你阅读以下最佳实践和特定用例的指南。
数据格式化
你需要一组训练示例数据集来微调模型,其中每个示例都包含单个输入(prompt)及其关联的输出(completion)。这与使用我们的基本模型有明显区别,在基本模型中你可能需要在单个提示中输入详细的说明或多个示例。
- 每个 prompt 都应该以固定的分隔符结尾,以便通知模型何时 prompt 结束、何时开始 completion。通常效果良好的一个简单分隔符是 \n\n###\n\n。分隔符不应该出现在任何 prompt 中的其他地方。
- 由于我们的分词器(tokenization)会根据单词前面的空格进行分词(计算 token),因此每个 completion 都应以空格开头。
- 每个 completion 都应以固定的停止序列结束,以便在 completion 结束时通知模型。停止序列可以是 \n、### 或未出现在任何 completion 中的任何其他 token。
- 使用训练好的模型来进行预测或推理时(inference),你应该按照与创建训练数据集时相同的方式格式化你的 prompt,包括相同的分隔符,还要指定相同的停止序列以正确截断 completion。
一般最佳实践
通过使用更多高质量的示例进行微调,可以获得更好的性能。为了微调一个比使用基础模型和高质量提示更好的模型,你应该提供至少几百个高质量的示例,最好由人类专家审核。在此基础上,性能往往会随着示例数量的加倍而线性增长。增加示例的数量通常是提高性能的最佳和最可靠的方法。
分类是最容易入门的模型。对于分类问题,我们建议使用 ada,经过微调,它的性能通常只会比功能更强大的模型差一点点,同时速度更快,成本更低。
如果你是在现有数据集上进行微调而不是从头开始编写提示,请务必在可能的情况下手动审核你的数据,以查找可能存在的冒犯性或不准确的内容,或者如果数据集很大,请检查尽可能多的随机样本。
具体指南
微调可以解决多种问题,最佳使用方式可能取决于你特定的用例。下面,我们列出了最常见的微调用例和相应的指南。
- 分类
- 条件生成
- 根据维基百科文章撰写引人入胜的广告
- 实体提取
- 客户支持聊天机器人
- 基于技术属性列表的产品描述
分类
在分类问题中,应将每个输入分类到预定义的类别之一。对于这种类型的问题,我们建议:
- 在提示的末尾使用一个分隔符,例如 \n\n###\n\n。记得在最终向模型发出请求时也附加这个分隔符。
- 选择与单个 token 相对应的类别,在推理时,指定 max_tokens=1,因为只需要第一个 token 来进行分类。译者注:这里不太理解,请 ChatGPT 举了个例子:假设训练一个情感分析模型,将输入文本分类为正面或负面情感。我们可以选择将正面情感映射到单个 token,例如 &#34;positive&#34;,将负面情感映射到单个 token,例如 &#34;negative&#34;,然后在推理时指定 max_tokens=1。这样,当模型接收到一个输入时,只需要查看输入的第一个 token 是 &#34;positive&#34; 还是 &#34;negative&#34;,就可以将其分类到对应的情感类别中。
- 确保提示+补全,包括分隔符,不超过 2048 个 token
- 每个类别至少要有 ~100 个样本
- 如果需要获取类别的对数概率,可以在使用模型时指定 logprobs=5(对于 5 个类别的情况)
- 确保用于微调的数据集在结构和任务类型上与模型将要用于的数据集非常相似。
案例研究:模型是否在说谎?
假设你想要确保网站上的广告文本提到正确的产品和公司,确保模型没有捏造信息。你可能需要微调一个分类器,以过滤掉错误的广告。
数据集可能看起来像下面这样:- {&#34;prompt&#34;:&#34;Company: BHFF insurance\nProduct: allround insurance\nAd:One stop shop for all your insurance needs!\nSupported:&#34;, &#34;completion&#34;:&#34; yes&#34;}
- {&#34;prompt&#34;:&#34;Company: Loft conversion specialists\nProduct: -\nAd:Straight teeth in weeks!\nSupported:&#34;, &#34;completion&#34;:&#34; no&#34;}
复制代码 在上面的示例中,我们使用了一个结构化输入,其中包含公司的名称、产品和相关广告。分隔符使用了 \nSupported:,清晰地将提示与补全分开。有足够数量的示例,分隔符并不会产生太大的影响(通常少于 0.4%),只要它不出现在提示或补全中。
在这个案例中,我们对一个 ada 模型进行了微调,因为它速度更快、更便宜,并且由于这是一个分类任务,性能与更大的模型相当。
现在可以通过发出一个 Completion 请求来查询我们的模型。- curl https://api.openai.com/v1/completions \
- -H &#34;Content-Type: application/json&#34; \
- -H &#34;Authorization: Bearer $OPENAI_API_KEY&#34; \
- -d &#39;{
- &#34;prompt&#34;: &#34;Company: Reliable accountants Ltd\nProduct: Personal Tax help\nAd:Best advice in town!\nSupported:&#34;,
- &#34;max_tokens&#34;: 1,
- &#34;model&#34;: &#34;YOUR_FINE_TUNED_MODEL_NAME&#34;
- }&#39;
复制代码 这将返回 yes 或 no。
案例研究:情感分析
假设你想要获取一条特定推文的情感积极程度或消极程度。数据集可能看起来像这样:- {&#34;prompt&#34;:&#34;Overjoyed with the new iPhone! ->&#34;, &#34;completion&#34;:&#34; positive&#34;}
- {&#34;prompt&#34;:&#34;@lakers disappoint for a third straight night https://t.co/38EFe43 ->&#34;, &#34;completion&#34;:&#34; negative&#34;}
复制代码 对模型进行微调后,你可以通过在 completion 请求上设置 logprobs=2 来取回第一个 completion token 的对数概率。positive 类别的概率越高,情感极性就越积极。
现在,可以通过发出 completion 请求来查询我们的模型。- curl https://api.openai.com/v1/completions \
- -H &#34;Content-Type: application/json&#34; \
- -H &#34;Authorization: Bearer $OPENAI_API_KEY&#34; \
- -d &#39;{
- &#34;prompt&#34;: &#34;https://t.co/f93xEd2 Excited to share my latest blog post! ->&#34;,
- &#34;max_tokens&#34;: 1,
- &#34;model&#34;: &#34;YOUR_FINE_TUNED_MODEL_NAME&#34;
- }&#39;
复制代码 这将会返回:- {
- &#34;id&#34;: &#34;cmpl-COMPLETION_ID&#34;,
- &#34;object&#34;: &#34;text_completion&#34;,
- &#34;created&#34;: 1589498378,
- &#34;model&#34;: &#34;YOUR_FINE_TUNED_MODEL_NAME&#34;,
- &#34;choices&#34;: [
- {
- &#34;logprobs&#34;: {
- &#34;text_offset&#34;: [
- 19
- ],
- &#34;token_logprobs&#34;: [
- -0.03597255
- ],
- &#34;tokens&#34;: [
- &#34; positive&#34;
- ],
- &#34;top_logprobs&#34;: [
- {
- &#34; negative&#34;: -4.9785037,
- &#34; positive&#34;: -0.03597255
- }
- ]
- },
- &#34;text&#34;: &#34; positive&#34;,
- &#34;index&#34;: 0,
- &#34;finish_reason&#34;: &#34;length&#34;
- }
- ]
- }
复制代码 案例研究:电子邮件分类
假设你想要将收到的电子邮件分类为大量预定义的类别之一。对于大量类别的分类,我们建议你将这些类别转换为数字,最多可处理约 500 个类别。我们观察到,在数字前添加一个空格有时会略微提高性能,这是由于分词(tokenization)的原因。你可能希望按以下方式组织训练数据:- {&#34;prompt&#34;:&#34;Subject: <email_subject>\nFrom:<customer_name>\nDate:<date>\nContent:<email_body>\n\n###\n\n&#34;, &#34;completion&#34;:&#34; <numerical_category>&#34;}
复制代码 具体示例:- {&#34;prompt&#34;:&#34;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.\n\nPlease let me know once done.\n\nThanks,\nJoe\n\n###\n\n&#34;, &#34;completion&#34;:&#34; 4&#34;}
复制代码 在上面的例子中,我们使用了一个最多包含 2043 个 token 的电子邮件作为输入(这允许使用 4 个 token 的分隔符和一个 token 的补全,总共 2048 个token)。分隔符使用了 \n\n###\n\n,为此我们移除了电子邮件中出现的所有 ###。
条件生成
条件生成是一种根据特定输入来生成内容的问题,包括释义(改写)、概括、实体提取、根据给定规范编写产品说明、聊天机器人等等。对于这种类型的问题,我们建议采用以下方法:
- 在提示末尾处使用分隔符,例如 \n\n###\n\n。在最终向模型发出请求时,也要附加这个分隔符。
- 在补全结束时使用一个结束 token,例如 END
- 在推理(inference)时,将结束 token 添加为停止序列,例如 stop=[&#34; END&#34;]
- 以至少 ~500 个示例为目标
- 确保提示 + 补全不超过 2048 个 token,包括分隔符
- 确保示例具有高质量并遵循相同的期望格式
- 确保用于微调的数据集在结构和任务类型上与模型将要用于的数据集非常相似
- 对于这些用例,使用较低的学习率和仅 1-2 个训练时期(epochs)往往效果更好
案例分析:根据维基百科文章撰写引人入胜的广告
这是一个生成性的用例,因此你需要确保提供的样本具有最高质量,因为微调后的模型将尝试模仿给定示例的风格(和错误)。提供大约 500 个示例是一个好的起点,示例数据集可能如下所示:- {&#34;prompt&#34;:&#34;<Product Name>\n<Wikipedia description>\n\n###\n\n&#34;, &#34;completion&#34;:&#34; <engaging ad> END&#34;}
复制代码 具体示例:- {&#34;prompt&#34;:&#34;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&#39;s shell to accommodate the Japanese perceived penchant for personalizing their mobile phones. The Galaxy Feel&#39;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.\n\n###\n\n&#34;, &#34;completion&#34;:&#34;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&#34;}
复制代码 在这里,我们使用了多行分隔符,因为维基百科文章包含多个段落和标题。我们还使用了一个简单的结束 token,以确保模型知道何时完成补全。
案例研究:实体提取
这类似于语言转换任务。为了提高性能,最好将不同的提取实体按字母顺序或按它们在原始文本中出现的顺序排序。这将有助于模型跟踪需要按顺序生成的所有实体。数据集可能如下所示:- {&#34;prompt&#34;:&#34;<any text, for example news article>\n\n###\n\n&#34;, &#34;completion&#34;:&#34; <list of entities, separated by a newline> END&#34;}
复制代码 具体示例:- {&#34;prompt&#34;:&#34;Portugal will be removed from the UK&#39;s green travel list from Tuesday, amid rising coronavirus cases and concern over a \&#34;Nepal mutation of the so-called Indian variant\&#34;. It will join the amber list, meaning holidaymakers should not visit and returnees must isolate for 10 days...\n\n###\n\n&#34;, &#34;completion&#34;:&#34; Portugal\nUK\nNepal mutation\nIndian variant END&#34;}
复制代码 多行分隔符效果最好,因为文本可能包含多行。理想情况下,输入提示的类型应该高度多样化(新闻文章、维基百科页面、推文、法律文件等),这反映了在提取实体时可能遇到的不同类型的文本。
案例研究:客户支持聊天机器人
聊天机器人通常包含有关对话的相关内容(订单详情)、迄今为止的对话摘要以及最近消息。对于这个用例,同一个历史对话可能在数据集中生成多个行,每次都带有稍微不同的上下文,作为每个代理(客服)的生成补全。这种用例需要几千个示例,因为它可能涉及不同类型的请求和客户问题。为确保高质量的性能,我们建议审核对话样本以确保代理(客服)消息的质量。可以使用单独的文本转换微调模型生成摘要。数据集可能如下所示:译者注:在这个案例研究中,为了训练客户支持聊天机器人,可以使用之前与客户进行过的历史对话记录作为训练数据,以帮助机器人学习如何更好地回答客户的问题和解决客户的问题。由于同一个客户可能会有多次交流,因此同一段历史对话记录可能会出现在数据集中的多个样本中,每个样本的上下文略有不同。 - {&#34;prompt&#34;:&#34;Summary: <summary of the interaction so far>\n\nSpecific information:<for example order details in natural language>\n\n###\n\nCustomer: <message1>\nAgent: <response1>\nCustomer: <message2>\nAgent:&#34;, &#34;completion&#34;:&#34; <response2>\n&#34;}
- {&#34;prompt&#34;:&#34;Summary: <summary of the interaction so far>\n\nSpecific information:<for example order details in natural language>\n\n###\n\nCustomer: <message1>\nAgent: <response1>\nCustomer: <message2>\nAgent: <response2>\nCustomer: <message3>\nAgent:&#34;, &#34;completion&#34;:&#34; <response3>\n&#34;}
复制代码 在这里,我们有意将不同类型的输入信息分开,但是保持了客户与代理对话在提示和补全之间的相同格式。所有的补全都应该是由代理完成的,当进行推断时,我们可以使用 \n 作为停止序列。
案例研究:基于技术属性列表的产品描述
在这个案例中,将输入数据转换为自然语言非常重要,这很可能会带来更好的性能。例如,以下两种格式中,后一个使用自然语言的性能更好:- {&#34;prompt&#34;:&#34;Item=handbag, Color=army_green, price=$99, size=S->&#34;, &#34;completion&#34;:&#34; This stylish small green handbag will add a unique touch to your look, without costing you a fortune.&#34;}
- {&#34;prompt&#34;:&#34;Item is a handbag. Colour is army green. Price is midrange. Size is small.->&#34;, &#34;completion&#34;:&#34; This stylish small green handbag will add a unique touch to your look, without costing you a fortune.&#34;}
复制代码 为了获得高性能,请确保补全是基于提供的描述。如果经常需要查阅外部内容来生成描述,那么以自动化的方式将这些外部内容添加到模型中,可能会提高模型的性能。如果描述是基于图像的,那么使用算法提取图像的文本描述可能会有所帮助。由于补全只有一句话长,在推断过程中,我们可以使用 . 作为停止序列。
高级应用
自定义模型名称
你可以使用 suffix(后缀) 参数为经过微调的模型名称添加最多 40 个字符的后缀。
OpenAI CLI:- openai api fine_tunes.create -t test.jsonl -m ada --suffix &#34;custom model name&#34;
复制代码 模型名称结果是:- ada:ft-your-org:custom-model-name-2022-02-15-04-21-04
复制代码 分析微调模型
我们在每个作业完成后都会附上一个结果文件。当你检索微调结果或查看微调事件时,将列出对应结果文件的 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 &#34;Authorization: Bearer $OPENAI_API_KEY&#34; > results.csv
复制代码 _results.csv 文件中,每个训练步骤一行数据,一个步骤指的是对一批数据进行一次前向传递和反向传递。除了步骤编号,每行还包含以下与该步骤相对应的字段:
- elapsed_tokens:模型到目前为止所见的 token 数(包括重复的 token)
- elapsed_examples:模型到目前为止所看到的示例数(包括重复的示例),一个示例是批次中的一个元素。例如,如果 batch_size = 4,则每个步骤将使 elapsed_examples 增加 4。
- training_loss:训练批次上的损失
- training_sequence_accuracy:训练批次中的 补全 中,模型预测的 token 与真实补全 token 完全匹配的百分比。例如,batch_size 为 3,如果你的数据包含补全 [[1, 2], [0, 5], [4, 2]],并且模型预测了 [[1, 1], [0, 5], [4, 2]],则此准确率为 2/3 = 0.67。
- training_token_accuracy:训练批次中被模型正确预测的 token 百分比。例如,batch_size 为 3,如果你的数据包含补全 [[1, 2], [0, 5], [4, 2]],模型预测了 [[1, 1], [0, 5], [4, 2]],则此准确率为 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:加权 F1 得分
用于二元分类
以下指标基于分类阈值为 0.5(即当概率 >0.5 时,一个示例被分类为属于正类)。
- classification/accuracy:准确率
- classification/precision:精确率
- classification/recall:召回率
- classification/f{beta}:F-beta 得分
- classification/auroc:AUROC
- classification/auprc:AUPRC
译者注:AUROC 和 AUPRC 是分类问题中常用的两个性能度量指标。
AUROC(Area Under the Receiver Operating Characteristic Curve)是一个二元分类器的常用性能指标,它基于真正例率(True Positive Rate, TPR)和假正例率(False Positive Rate, FPR)的曲线下面积。AUROC 的取值范围在 0 到 1 之间,值越大说明分类器性能越好,当 AUROC=0.5 时,说明分类器等同于随机分类器。
AUPRC(Area Under the Precision-Recall Curve)是另一个二元分类器的性能指标,它基于精确率(Precision)和召回率(Recall)的曲线下面积。AUPRC 的取值范围也在 0 到 1 之间,值越大说明分类器性能越好,当 AUPRC=0.5 时,说明分类器等同于随机分类器。相对于 AUROC,AUPRC 对于类别不平衡问题更加敏感,因为它更加关注少数类的分类性能。
在许多分类任务中,AUROC 和 AUPRC 都是重要的性能指标,因为它们可以帮助评估分类器在不同阈值下的性能,并且不同的问题可能会更关注其中一个指标。 请注意,这些评估假定你正在使用分词后只有一个 token 的文本标签来表示类别,如上所述。如果不满足这些条件,你得到的数字可能会是错误的。
验证
你可以保留一部分数据用于验证。验证文件与训练文件具有完全相同的格式,训练数据和验证数据应该是互斥的。
如果在创建微调作业时包含验证文件,那么对微调模型在训练期间定期针对验证数据的表现进行评估的结果,也会包含在生成的结果文件中。
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:验证批次中模型预测的 token 与真实 token 完全匹配的补全百分比。例如,对于 batch_size 为 3 的数据,如果你的数据包含补全 [[1, 2],[0, 5],[4, 2]],而模型预测 [[1, 1],[0, 5],[4, 2]],则此准确率为 2/3 = 0.67。
- validation_token_accuracy:模型正确预测验证批次中 token 的百分比。例如,对于 batch_size 为 3 的数据,如果你的数据包含补全 [[1, 2],[0, 5],[4, 2]],而模型预测 [[1, 1],[0, 5],[4, 2]],则此准确率为 5/6 = 0.83。
超参数
我们已经选择了适用于各种用例的默认超参数,唯一必需的参数是训练文件。
话虽如此,调整用于微调的超参数通常会导致产生更高质量输出的模型。特别是,你可能希望配置以下内容:
- model:微调的基础模型名称。你可以选择 &#34;ada&#34;、&#34;babbage&#34;、&#34;curie&#34; 或 &#34;davinci&#34; 中的一个。要了解有关这些模型的更多信息,请参阅模型文档。
- n_epochs:默认为 4,训练模型的周期数。一个周期指的是完整地遍历训练数据集一次。
- 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,则在分类任务的微调中,会在每个周期结束时计算验证集上的分类特定指标(准确率、F1 得分等)。
要配置这些额外的超参数,请通过 OpenAI CLI 的命令行 flag 进行传递,例如:- 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 同步,以跟踪实验、模型和数据集。
要开始使用,你需要一个 Weights & Biases 账户和一个付费的 OpenAI 计划。为确保使用的是最新版本的openai 和 wandb,请运行:- pip install --upgrade openai wandb
复制代码 要将你的微调结果与 Weights & Biases 同步,请运行:你可以阅读 Weights & Biases 文档了解更多有关此集成的信息。译者注:Weights & Biases(简称 W&B)是一个第三方工具,可以用于跟踪、记录和可视化机器学习实验的结果。它提供了许多功能,例如实时可视化训练指标、记录超参数、比较不同实验的性能等。W&B 还提供了一个 Web 界面,可以方便地查看和管理实验结果。在 OpenAI 框架中,W&B 是可选的,但它可以帮助用户更好地组织和管理机器学习实验,并提高实验效率。 示例 Notebooks
分类
finetuning-classification.ipynb
这个 Notebook 演示如何微调一个模型,可以分类输入文本是否与棒球或曲棍球相关。我们将在这个 Notebook 中完成此任务的四个步骤:
- 数据探索:概览数据源以及示例。
- 数据准备:把数据源转换为可用于微调的 jsonl 文件。
- 微调:启动微调作业并解释所得模型的性能。
- 使用模型:演示如何向微调模型发送请求以获取预测结果。
问答系统(Question answering)
olympics-1-collect-data.ipynb
olympics-2-create-qa.ipynb
olympics-3-train-qa.ipynb译者注:Question answering(问答)通常指问答系统,即通过计算机程序来回答自然语言问题的系统,通常使用自然语言处理和机器学习技术来理解和回答问题。 这个项目的想法是创建一个基于提供的几段文本的问答模型。基于 GPT-3 的基础模型在回答包含在段落中的问题时表现良好,但如果答案不包含在段落中,基础模型往往仍然尽力回答,经常导致答案混淆。
为了创建一个只有在有足够上下文的情况下才回答问题的模型,我们首先创建了一个基于文本段落的问题和答案数据集。为了训练模型只在有答案时回答,我们还添加了对抗性示例(adversarial examples),其中问题与上下文不匹配。在这些情况下,我们要求模型输出 &#34;No sufficient context for answering the question&#34;(没有足够的上下文来回答问题)。
我们将在三个 Notebook 中完成该任务
- 第一个 Notebook 着重于收集最近的数据,这些数据是 GPT-3 在其预训练期间没有看到过的。我们选择了 2020 年奥运会(实际上是在 2021 年夏季举行的),并下载了 713 个不同的页面。我们将数据集按照各个部分进行组织,这些部分将用作提问和回答的上下文。
- 第二个 Notebook 根据数据中的维基百科部分提出一些问题,并基于该部分数据回答这些问题。
- 第三个 Notebook 利用上下文、问题-答案对的数据集,另外创建对抗性问题-上下文对,其中问题不是基于该上下文生成的。在这些情况下,模型将被提示回答 &#34;No sufficient context for answering the question&#34;(没有足够的上下文来回答问题)。我们还将训练一个鉴别器模型(discriminator model),该模型预测问题是否可以基于上下文来回答。
|
|