你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn。
通过微调自定义模型
借助 Azure OpenAI 服务,你可以使用称为“微调”的过程根据个人数据集定制模型。 通过此自定义步骤,你可以更充分地利用服务,获得以下好处:
- 结果的质量比从提示工程中获取的质量更高
- 能够根据超出模型最大请求上下文限制的更多示例进行训练。
- 由于提示较短,节省了令牌
- 更低延迟的请求,尤其是在使用较小的模型时。
与少样本学习相比,微调通过训练超出提示范围的更多示例来改进模型,从而让你在处理大量任务时取得更好的结果。 由于微调会调整基本模型的权重以提高特定任务的性能,因此无需在提示中包含过多的示例或说明。 这意味着发送的文本更少,每次 API 调用处理的令牌更少,从而可能节省成本并改善请求延迟。
我们使用 LoRA(即低秩近似)来微调模型,以降低其复杂性而不显著影响其性能。 此方法的工作原理是用较低秩的矩阵来近似原始的高秩矩阵,因此在监督训练阶段仅微调较小的“重要”参数子集,从而使模型更易于管理和高效。 对于用户,这使得训练比其他技术更快、更经济实惠。
注意
Azure OpenAI 目前仅对所有受支持的模型(包括 GPT-4o mini)支持文本转文本优化。
先决条件
- 参阅何时使用 Azure OpenAI 微调指南。
- Azure 订阅。 免费创建一个。
- Azure OpenAI 资源位于支持微调 Azure OpenAI 模型的区域中。 查看模型摘要表和区域可用性,获取按区域列出的可用模型列表以及支持的功能。 有关详细信息,请参阅使用 Azure OpenAI 创建资源和部署模型。
- 微调访问需要认知服务 OpenAI 参与者角色。
- 如果尚无权查看配额并在 Azure OpenAI Studio 中部署模型,则需要其他权限。
模型
以下模型支持微调:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)*gpt-4o
(2024-08-06)gpt-4o-mini
(2024-07-18)
* 针对此模型的优化功能目前为公共预览版。
或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。
请参阅模型页,以查看当前支持微调的区域。
审阅 Azure OpenAI Studio 的工作流
花点时间审阅用于 Azure OpenAI Studio 的微调工作流:
- 准备训练和验证数据。
- 使用 Azure OpenAI Studio 中的“创建自定义模型”向导来训练自定义模型。
- 选择基础模型。
- 选择训练数据。
- (可选)选择验证数据。
- (可选)为微调作业配置任务参数。
- 审阅所做的选择并训练新的自定义模型。
- 检查自定义微调模型的状态。
- 部署自定义模型以供使用。
- 使用自定义模型。
- (可选)分析自定义模型的性能和拟合度。
准备训练和验证数据
训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。
不同的模型类型需要不同格式的训练数据。
你使用的训练和验证数据必须格式化为 JSON 行 (JSONL) 文档。 对于 gpt-35-turbo
(所有版本)、gpt-4
、gpt-4o
和 gpt-4o-mini
,必须以聊天补全 API 使用的对话格式来设置微调数据集的格式。
如果想要了解有关微调 gpt-4o-mini
(2024-07-18) 模型的逐步演练,请参阅 Azure OpenAI 微调教程。
示例文件格式
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Is Xbox better than PlayStation?"}, {"role": "assistant", "content": "I apologize, but I cannot provide personal opinions. My primary job is to assist you with any issues related to your Xbox device. Do you have any Xbox-related issues that need addressing?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Can I play PC games on my Xbox?"}, {"role": "assistant", "content": "While Xbox consoles don't natively support PC games, they can play an array of Xbox games, many of which are also available on PC. Can I assist you with finding games compatible with your Xbox device?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "I'm having trouble connecting my Xbox to the Wi-Fi."}, {"role": "assistant", "content": "No worries, let's go through the network settings on your Xbox. Can you please tell me what happens when you try to connect it to the Wi-Fi?"}]}
多轮次聊天文件格式
还支持在 jsonl 训练文件单行中的多轮次对话。 要跳过对特定助手消息的微调,请添加可选的 weight
键值对。 目前,weight
可设置为 0 或 1。
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
除 JSONL 格式外,训练和验证数据文件必须以 UTF-8 编码并包含字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
创建训练和验证数据集
训练示例越多越好。 如果没有至少 10 个训练示例,微调作业将无法继续,但如此少的数量不足以显著影响模型响应。 最佳做法是提供数百个(如果不是数千个)训练示例来获得成功。
通常,将数据集大小加倍会促使模型质量呈线性增长。 但请记住,低质量的示例可能会对性能产生负面影响。 如果你根据大量内部数据来训练模型,而不是先修剪数据集以便获得最高质量的示例,则最终可能会得到一个性能比预期差得多的模型。
使用“创建自定义模型”向导
Azure OpenAI Studio 提供了“创建自定义模型”向导,让你能够以交互方式为 Azure 资源创建和训练已微调的模型。
打开 Azure OpenAI Studio (https://oai.azure.com/),然后使用有权访问 Azure OpenAI 资源的凭据登录。 在登录工作流中,选择适当的目录、Azure 订阅和 Azure OpenAI 资源。
在 Azure OpenAI Studio 中,浏览到“工具”>“微调”窗格,然后选择“微调模型”。
随即将打开“创建自定义模型”向导。
选择基础模型
选择基础模型是创建自定义模型的第一步。 你可通过“基础模型”窗格选择用于自定义模型的基础模型。 所做的选择会影响模型的性能和成本。
从“基础模型类型”下拉列表中选择基础模型,然后选择“下一步”以继续。
可从以下可用基础模型之一创建自定义模型:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。
有关可进行优化的基本模型的详细信息,请参阅模型。
选择训练数据
下一步是选择已准备好的现有训练数据或上传已准备好的新训练数据,以便在自定义模型时使用。 “训练数据”窗格显示了任何现有的和以前上传的数据集,并提供了用于上传新训练数据的选项。
如果训练数据已上传到服务,请选择“来自 Azure OpenAI 连接的文件”。
- 从显示的下拉列表中选择文件。
上传新的训练数据时可使用以下选项之一:
选择“本地文件”,从本地文件上传训练数据。
选择“Azure Blob 或其他共享 Web 位置”,从 Azure Blob 或其他共享 Web 位置导入训练数据。
对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。 有关 Azure Blob 存储的详细信息,请参阅什么是 Azure Blob 存储?
注意
训练数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
从本地文件上传训练数据
可使用以下方法之一将新的训练数据集从本地文件上传到服务:
将文件拖放到“训练数据”窗格的工作区中,然后选择“上传文件”。
在“训练数据”窗格的工作区中选择“浏览文件”,在“打开”对话框中选择要上传的文件,然后选择“上传文件”。
选择并上传训练数据集后,选择“下一步”继续。
从 Azure Blob 存储导入训练数据
可通过提供文件的名称和位置从 Azure Blob 或其他共享 Web 位置导入训练数据集。
输入文件的文件名。
对于“文件位置”,请提供 Azure Blob URL、Azure 存储共享访问签名 (SAS) 或其他指向可访问共享 Web 位置的链接。
选择“导入”,以将训练数据集导入到服务。
选择并上传训练数据集后,选择“下一步”继续。
选择验证数据
下一步提供配置模型以在训练过程中使用验证数据的选项。 如果你不想使用验证数据,可以选择“下一步”为模型选择高级选项。 否则,如果你有验证数据集,可以选择已准备好的现有验证数据或上传已准备好的新验证数据,以便在自定义模型时使用。
“验证数据”窗格显示了任何现有的及以前上传的训练和验证数据集,并提供了用于上传新验证数据的选项。
如果验证数据已上传到服务,请选择“选择数据集”。
- 从“验证数据”窗格中显示的列表中选择文件。
上传新的验证数据时可使用以下选项之一:
选择“本地文件”,从本地文件上传验证数据。
选择“Azure Blob 或其他共享 Web 位置”,从 Azure Blob 或其他共享 Web 位置导入验证数据。
对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。
注意
与训练数据文件类似,验证数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
从本地文件上传验证数据
可使用以下方法之一将新的验证数据集从本地文件上传到服务:
将文件拖放到“验证数据”窗格的工作区中,然后选择“上传文件”。
在“验证数据”窗格的工作区中选择“浏览文件”,在“打开”对话框中选择要上传的文件,然后选择“上传文件”。
选择并上传验证数据集后,选择“下一步”继续。
从 Azure Blob 存储导入验证数据
可通过提供文件的名称和位置从 Azure Blob 或其他共享 Web 位置导入验证数据集。
输入文件的文件名。
对于“文件位置”,请提供 Azure Blob URL、Azure 存储共享访问签名 (SAS) 或其他指向可访问共享 Web 位置的链接。
选择“导入”,以将训练数据集导入到服务。
选择并上传验证数据集后,选择“下一步”继续。
配置任务参数
“创建自定义模型”向导在“任务参数”窗格中显示用于训练已微调的模型的参数。 提供了以下参数:
Name | 类型 | 描述 |
---|---|---|
batch_size |
integer | 要用于训练的批大小。 批大小表示用于训练单个前向和后向传递的训练示例的数量。 一般情况下,我们发现较大的批大小往往更适合较大的数据集。 此属性的默认值和最大值特定于基础模型。 批大小越大意味着模型参数的更新频率越低,但方差越小。 |
learning_rate_multiplier |
数字 | 用于训练的学习率乘数。 微调学习率是用于预训练的原始学习率乘以该值。 较大的学习率通常在较大的批大小中表现更好。 建议试验 0.02 到 0.2 范围内的值,以查看产生最佳结果的值。 较小的学习率可以用于避免过度拟合。 |
n_epochs |
integer | 训练模型的时期数。 一个时期是指训练数据集的一个完整周期。 |
seed |
integer | 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子 |
选择“默认”以便对微调作业使用默认值,或选择“自定义”以显示并编辑超参数值。 选择默认值后,我们会根据训练数据通过算法确定正确的值。
配置高级选项后,选择“下一步”以审阅所做的选择并训练已微调的模型。
查看所做的选择并训练模型
向导的“审阅”窗格显示有关配置选项的信息。
如果已准备好训练模型,请选择“开始训练作业”,以启动微调作业并返回到“模型”窗格。
检查自定义模型的状态
“模型”窗格在“自定义模型”选项卡中显示有关自定义模型的信息。该选项卡包含有关自定义模型的微调作业的状态和作业 ID 信息。 作业完成后,选项卡会显示结果文件的文件 ID。 可能需要选择“刷新”才能看到模型训练作业的更新状态。
启动微调作业后,可能需要一些时间才能完成。 你的作业可能排在系统上的其他作业后面。 训练模型可能需要几分钟或几小时,具体取决于模型和数据集大小。
可在“模型”窗格上执行以下任务:
在“自定义模型”选项卡的“状态”列中检查自定义模型的微调作业的状态。
在“模型名称”列中,选择模型名称以查看有关自定义模型的详细信息。 可以查看微调作业的状态、训练结果、训练事件和作业中使用的超参数。
选择“下载训练文件”以下载用于模型的训练数据。
选择“下载结果”,下载附加到模型微调作业的结果文件,并分析自定义模型的训练和验证性能。
选择“刷新”更新页面信息。
检查点
每个训练纪元完成时,都会生成一个检查点。 检查点是模型的完全功能版本,可以将其部署并用作后续微调作业的目标模型。 检查点特别有用,因为它们可以提供过度拟合发生之前模型的快照。 当微调作业完成时,你将拥有可供部署的三个最新版本的模型。
安全评估 GPT-4、GPT-4o 和 GPT-4o-mini 微调 - 公共预览版
GPT-4o、GPT-4o-mini 和 GPT-4 是我们最高级的模型,可以根据需要进行微调。 与 Azure OpenAI 模型相仿,微调模型的高级功能也伴随着与有害内容、操纵、类人行为、隐私问题等相关的日益增加的负责任 AI 挑战。 在负责任 AI 做法的概述和透明度说明中详细了解风险、功能和限制。 为了帮助缓解与高级微调模型相关的风险,我们实施了其他评估步骤,以帮助检测和防止微调模型的训练和输出中的有害内容。 这些步骤基于 Microsoft 负责任 AI 标准和 Azure OpenAI 服务内容筛选。
- 评估是在专用、特定于客户的私有工作区中进行的;
- 评估终结点与 Azure OpenAI 资源位于同一地理位置;
- 训练数据的存储与评估无关;仅保留最终模型评估(可部署或不可部署);并且
GPT-4o、GPT-4o-mini 和 GPT-4 微调模型评估筛选器已设置为预定义阈值,客户无法修改;它们不与可能已创建的任何自定义内容筛选配置绑定。
数据评估
在训练开始之前,系统会评估你的数据是否包含有害内容(暴力、性、仇恨、公平、自残 – 请参阅此处的类别定义)。 如果检测到高于指定严重级别的有害内容,则训练作业将失败,并且你将收到一条告知失败类别的消息。
示例消息:
The provided training data failed RAI checks for harm types: [hate_fairness, self_harm, violence]. Please fix the data and try again.
作为提供微调功能的一部分,系统会在数据导入作业中自动评估训练数据。
如果微调作业由于在训练数据中检测到有害内容而失败,则不会收取费用。
模型评估
训练完成后,但在微调模型可用于部署之前,将使用 Azure 的内置风险和安全指标来评估生成的模型是否包含潜在有害响应。 使用与基础大型语言模型相同的测试方法,我们的评估功能会模拟与微调模型的对话,以评估输出有害内容的可能性,它同样使用指定的有害内容类别(暴力、性、仇恨、公平、自残)。
如果检测到某个模型生成的输出包含有害内容,且其等级高于可接受的等级,则系统会通知你的模型不可用于部署,并提供有关检测到的特定危害类别的信息:
示例消息:
This model is unable to be deployed. Model evaluation identified that this fine tuned model scores above acceptable thresholds for [Violence, Self Harm]. Please review your training data set and resubmit the job.
与数据评估一样,作为提供微调功能的一部分,系统会在微调作业中自动评估模型。 服务仅记录生成的评估(可部署或不可部署)。 如果由于在模型输出中检测到有害内容而导致微调模型部署失败,则不会对训练运行收取费用。
部署微调模型
微调作业成功后,可以从“模型”窗格部署自定义模型。 必须部署自定义模型才能使其可用于完成调用。
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
注意
自定义模型只允许一个部署。 如果选择已部署的自定义模型,会显示错误消息。
要部署自定义模型,请选择要部署的自定义模型,然后选择“部署模型”。
此时会打开“部署模型”对话框。 在该对话框中,输入部署名称,然后选择“创建”,开始部署自定义模型。
可在 Azure OpenAI Studio 的“部署”窗格中监视部署进度。
跨区域部署
微调支持将微调后的模型部署到与模型最初进行微调时所在的区域不同的区域。 还可以部署到其他订阅/区域。
唯一的限制是新区域还必须支持微调,并且在部署交叉订阅时为部署生成授权令牌的帐户必须有权访问源订阅和目标订阅。
跨订阅/区域部署可以通过 Python 或 REST 完成。
使用已部署的自定义模型
部署自定义模型后,可像使用任何其他已部署的模型一样使用它。 可使用 Azure OpenAI Studio 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperature
和 max_tokens
,就像对其他已部署的模型一样。 对于微调的 babbage-002
和 davinci-002
模型,将使用“补全”操场和补全 API。 对于微调的 gpt-35-turbo-0613
模型,将使用“聊天”操场和聊天补全 API。
分析自定义模型
完成每个微调作业后,Azure OpenAI 会将一个名为 results.csv 的结果文件附加到该作业。 可以使用该结果文件来分析自定义模型的训练和验证性能。 Azure OpenAI Studio 的“模型”窗格的“结果文件 ID”列中,列出了每个自定义模型的结果文件的文件 ID。 可以使用文件 ID 从 Azure OpenAI Studio 的“数据文件”窗格中识别和下载结果文件。
结果文件是一个 CSV 文件,其中包含标题行,以及微调作业执行的每个训练步骤的行。 结果文件包含以下列:
列名称 | 说明 |
---|---|
step |
训练步数。 一个训练步骤代表针对一批训练数据的一次向前和向后的传递。 |
train_loss |
训练批的损失。 |
train_mean_token_accuracy |
训练批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
valid_loss |
验证批的损失。 |
validation_mean_token_accuracy |
验证批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
full_valid_loss |
在每个纪元结束时计算的验证损失。 训练正常时,损失应减少。 |
full_valid_mean_token_accuracy |
在每个纪元结束时计算的有效平均标记准确性。 训练正常时,标记准确性应增加。 |
还可以在 Azure OpenAI Studio 中以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到三个图表:损失、平均令牌准确度和令牌准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。
随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。
清理部署、自定义模型和训练文件
处理完自定义模型后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。
删除模型部署
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
可在 Azure OpenAI Studio 的“部署”页中删除自定义模型的部署。 选择要删除的部署,然后选择“删除”以删除部署。
删除自定义模型
可在 Azure OpenAI Studio 的“模型”窗格中删除自定义模型。 在“自定义模型”选项卡中选择要删除的自定义模型,然后选择“删除”以删除该自定义模型。
注意
如果自定义模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除自定义模型。
删除训练文件
可选择性地在 Azure OpenAI Studio 的“管理”>“数据文件”窗格中删除为训练上传的训练和验证文件,以及在训练期间生成的结果文件。 选择要删除的文件,然后选择“删除”以删除该文件。
持续微调
创建微调模型后,你可能希望在一段时间内通过进一步微调继续完善模型。 持续微调是选择已经微调的模型作为基础模型并在新的训练示例集上进一步对其进行微调的迭代过程。
若要对之前微调过的模型执行微调,可以使用创建自定义模型中所述的流程,但无需指定通用基础模型的名称,而只需指定已微调的模型。 自定义微调模型将类似于 gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7
我们还建议添加 suffix
参数,以便更轻松地区分已微调模型的不同迭代。 suffix
接受一个字符串,并设置为标识已微调的模型。 OpenAI Python API 支持最多 18 个字符的字符串,该字符串将添加到已微调的模型名称中。
重要
本文中标记了“(预览版)”的项目目前为公共预览版。 此预览版未提供服务级别协议,不建议将其用于生产工作负载。 某些功能可能不受支持或者受限。 有关详细信息,请参阅 Microsoft Azure 预览版补充使用条款。
先决条件
Azure 订阅 - 免费创建订阅。
Azure AI Studio 中的 Azure AI 项目。
与支持微调的区域中的资源的 Azure OpenAI 连接。
注意
如果在 AI Studio 项目内部(而不是在某个项目外部)使用 Azure OpenAI 模型,则支持的区域可能会有所不同。
微调访问需要 Azure OpenAI 资源上的“认知服务 OpenAI 参与者”角色。
如果尚无权查看配额并在 Azure AI Studio 中部署模型,则需要更多权限。
模型
以下模型支持微调:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)*gpt-4o
(2024-08-06)gpt-4o-mini
(2024-07-18)
* 针对此模型的优化功能目前为公共预览版。
或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。
请参阅模型页,以查看当前支持微调的区域。
审阅 Azure AI Studio 的工作流
花点时间审阅用于 Azure AI Studio 的微调工作流:
- 准备训练和验证数据。
- 使用 Azure AI Studio 中的“微调模型”向导来训练自定义模型。
- 选择模型。
- 选择训练数据。
- (可选)选择验证数据。
- (可选)为微调作业配置参数。
- 审阅所做的选择并训练新的自定义模型。
- 检查微调模型的状态。
- (可选)分析微调模型的性能和拟合度。
- 部署微调模型以供使用。
- 使用微调模型。
准备训练和验证数据
训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。
不同的模型类型需要不同格式的训练数据。
你使用的训练和验证数据必须格式化为 JSON 行 (JSONL) 文档。 对于 gpt-35-turbo-0613
,必须以聊天补全 API 使用的对话格式来设置微调数据集的格式。
如果想要了解有关微调 gpt-35-turbo-0613
模型的逐步演练,请参阅 Azure OpenAI 微调教程。
示例文件格式
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Is Xbox better than PlayStation?"}, {"role": "assistant", "content": "I apologize, but I cannot provide personal opinions. My primary job is to assist you with any issues related to your Xbox device. Do you have any Xbox-related issues that need addressing?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Can I play PC games on my Xbox?"}, {"role": "assistant", "content": "While Xbox consoles don't natively support PC games, they can play an array of Xbox games, many of which are also available on PC. Can I assist you with finding games compatible with your Xbox device?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "I'm having trouble connecting my Xbox to the Wi-Fi."}, {"role": "assistant", "content": "No worries, let's go through the network settings on your Xbox. Can you please tell me what happens when you try to connect it to the Wi-Fi?"}]}
多轮次聊天文件格式
还支持在 jsonl 训练文件单行中的多轮次对话。 要跳过对特定助手消息的微调,请添加可选的 weight
键值对。 目前,weight
可设置为 0 或 1。
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
除 JSONL 格式外,训练和验证数据文件必须以 UTF-8 编码并包含字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
创建训练和验证数据集
训练示例越多越好。 如果没有至少 10 个训练示例,微调作业将无法继续,但如此少的数量不足以显著影响模型响应。 最佳做法是提供数百个(如果不是数千个)训练示例来获得成功。
通常,将数据集大小加倍会促使模型质量呈线性增长。 但请记住,低质量的示例可能会对性能产生负面影响。 如果你根据大量内部数据来训练模型,而不是先修剪数据集以便获得最高质量的示例,则最终可能会得到一个性能比预期差得多的模型。
创建微调模型
要微调现有 Azure AI Studio 项目中的 Azure OpenAI 模型,请执行以下步骤:
登录到 Azure AI Studio 并选择项目。 如果你没有项目,请先创建一个项目。
在可折叠的左侧菜单中,选择“微调”>“+ 微调模型”。
选择基础模型
选择要微调的基础模型。 你所做的选择会影响模型的性能和成本。 在此示例中,我们选择的是
gpt-35-turbo
模型。 然后选择“确认”。对于
gpt-35-turbo
,我们有不同的版本可用于微调,因此请选择要微调的版本。 我们将选择 (0301)。我们还建议添加
suffix
参数,以便更轻松地区分已微调模型的不同迭代。suffix
接受一个字符串,并设置为标识已微调的模型。 OpenAI Python API 支持最多 18 个字符的字符串,该字符串将添加到已微调的模型名称中。
如果启用了多个 Azure OpenAI 连接进行微调,则选择要使用的资源。 请注意,有权访问 Azure OpenAI 资源的所有用户都将有权访问此微调模型。
选择训练数据
下一步是选择已准备好的现有训练数据或上传已准备好的新训练数据,以便在自定义模型时使用。 “训练数据”窗格显示了任何现有的和以前上传的数据集,并提供了用于上传新训练数据的选项。
如果训练数据已在项目中,请选择“Azure AI Studio 中的数据”。
- 从“训练数据”窗格中显示的列表中选择文件。
如果训练数据已上传到 Azure OpenAI 服务,请在“Azure OpenAI 连接”下选择你的 Azure OpenAI 连接。
若要上传训练数据以微调模型,请选择“上传数据”,然后选择“上传文件”。
- 确保所有训练示例遵循预期格式以进行推理。 要有效地微调模型,请确保拥有平衡且多样化的数据集。 这涉及到保持数据平衡(包括各种方案)和定期优化训练数据以符合实际预期,最终生成更准确和均衡的模型响应。 有关详细信息,请参阅数据准备。
- 对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。 有关 Azure Blob 存储的详细信息,请参阅什么是 Azure Blob 存储?
注意
训练数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
上传文件后,你将看到训练数据的预览。 选择“下一步”继续操作。
选择验证数据
(可选)你可以选择提供验证数据以微调模型。 如果你不想使用验证数据,可以选择“无”,然后选择“下一步”继续转到模型的高级选项。
否则,如果你有验证数据集,可以从之前上传的数据中进行选择或者上传新准备的验证数据,以便用于微调模型。
注意
与训练数据文件类似,验证数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
配置参数
(可选)为微调作业配置参数。 以下是可用的功能:
Name | 类型 | 描述 |
---|---|---|
batch_size |
integer | 要用于训练的批大小。 批大小表示用于训练单个前向和后向传递的训练示例的数量。 一般情况下,我们发现较大的批大小往往更适合较大的数据集。 此属性的默认值和最大值特定于基础模型。 批大小越大意味着模型参数的更新频率越低,但方差越小。 设置为 -1 时,batch_size 按训练集中 0.2% 的示例计算,最大值为 256。 |
learning_rate_multiplier |
数字 | 用于训练的学习率乘数。 微调学习率是用于预训练的原始学习率乘以该值。 较大的学习率通常在较大的批大小中表现更好。 建议试验 0.02 到 0.2 范围内的值,以查看产生最佳结果的值。 较小的学习率可以用于避免过度拟合。 |
n_epochs |
integer | 训练模型的时期数。 一个时期是指训练数据集的一个完整周期。 如果设置为 -1,则会根据输入数据动态确定纪元数。 |
seed |
integer | 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子。 |
可以选择保留默认配置或根据你的偏好自定义这些值。 完成配置后,选择“下一步”。
查看所做的选择并训练模型
查看你的选择,并选择“提交”开始训练新的微调模型。
检查微调模型的状态
提交微调作业后,将显示一个页面,其中包含有关微调模型的详细信息。 在 Azure AI Studio 的“微调”>“模型”页上,可以查找微调模型的状态和详细信息。
你的作业可能排在系统上的其他作业后面。 训练模型可能需要几分钟或几小时,具体取决于模型和数据集大小。
分析微调模型
成功完成微调后,可以从“详细信息”选项卡下的微调模型页中下载名为 results.csv 的结果文件。可以使用该结果文件来分析自定义模型的训练和验证性能。
结果文件是一个 CSV 文件,其中包含标题行,以及微调作业执行的每个训练步骤的行。 结果文件包含以下列:
列名称 | 说明 |
---|---|
step |
训练步数。 一个训练步骤代表针对一批训练数据的一次向前和向后的传递。 |
train_loss |
训练批的损失。 |
train_mean_token_accuracy |
训练批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
valid_loss |
验证批的损失。 |
validation_mean_token_accuracy |
验证批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
full_valid_loss |
在每个纪元结束时计算的验证损失。 训练正常时,损失应减少。 |
full_valid_mean_token_accuracy |
在每个纪元结束时计算的有效平均标记准确性。 训练正常时,标记准确性应增加。 |
还可以在 Azure AI Studio 中的微调模型“指标”选项卡下以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到两个图表:损失和标记准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。
随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。
检查点
每个训练纪元完成时,都会生成一个检查点。 检查点是模型的完全功能版本,可以将其部署并用作后续微调作业的目标模型。 检查点特别有用,因为它们可以提供过度拟合发生之前模型的快照。 当微调作业完成时,你将拥有可供部署的三个最新版本的模型。
安全评估 GPT-4、GPT-4o、GPT-4o-mini 微调 - 公共预览版
GPT-4o、GPT-4o-mini 和 GPT-4 是我们最高级的模型,可以根据需要进行微调。 与 Azure OpenAI 模型相仿,微调模型的高级功能也伴随着与有害内容、操纵、类人行为、隐私问题等相关的日益增加的负责任 AI 挑战。 在负责任 AI 做法的概述和透明度说明中详细了解风险、功能和限制。 为了帮助缓解与高级微调模型相关的风险,我们实施了其他评估步骤,以帮助检测和防止微调模型的训练和输出中的有害内容。 这些步骤基于 Microsoft 负责任 AI 标准和 Azure OpenAI 服务内容筛选。
- 评估是在专用、特定于客户的私有工作区中进行的;
- 评估终结点与 Azure OpenAI 资源位于同一地理位置;
- 训练数据的存储与评估无关;仅保留最终模型评估(可部署或不可部署);并且
GPT-4o、GPT-4o-mini 和 GPT-4 微调模型评估筛选器已设置为预定义阈值,客户无法修改;它们不与可能已创建的任何自定义内容筛选配置绑定。
数据评估
在训练开始之前,系统会评估你的数据是否包含有害内容(暴力、性、仇恨、公平、自残 – 请参阅此处的类别定义)。 如果检测到高于指定严重级别的有害内容,则训练作业将失败,并且你将收到一条告知失败类别的消息。
示例消息:
The provided training data failed RAI checks for harm types: [hate_fairness, self_harm, violence]. Please fix the data and try again.
作为提供微调功能的一部分,系统会在数据导入作业中自动评估训练数据。
如果微调作业由于在训练数据中检测到有害内容而失败,则不会收取费用。
模型评估
训练完成后,但在微调模型可用于部署之前,将使用 Azure 的内置风险和安全指标来评估生成的模型是否包含潜在有害响应。 使用与基础大型语言模型相同的测试方法,我们的评估功能会模拟与微调模型的对话,以评估输出有害内容的可能性,它同样使用指定的有害内容类别(暴力、性、仇恨、公平、自残)。
如果检测到某个模型生成的输出包含有害内容,且其等级高于可接受的等级,则系统会通知你的模型不可用于部署,并提供有关检测到的特定危害类别的信息:
示例消息:
This model is unable to be deployed. Model evaluation identified that this fine tuned model scores above acceptable thresholds for [Violence, Self Harm]. Please review your training data set and resubmit the job.
与数据评估一样,作为提供微调功能的一部分,系统会在微调作业中自动评估模型。 服务仅记录生成的评估(可部署或不可部署)。 如果由于在模型输出中检测到有害内容而导致微调模型部署失败,则不会对训练运行收取费用。
部署微调模型
微调模型后,可以部署模型,并在自己的应用程序中使用它。 无法从 Azure AI Studio 中的部署页或操场页部署经过微调的模型。 目前,部署经过微调的模型的唯一方法是前往该模型的模型详细信息页。
部署模型时,你将使模型可用于推理,这会产生每小时托管费用。 但是,经过微调的模型可以免费存储在 Azure AI Studio 中,直到你准备好使用它们。
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
注意
微调模型只允许一个部署。 如果选择已部署的微调模型,会显示错误消息。
可在 Azure AI Studio 的“部署”页中监视部署进度。
使用部署的微调模型
部署微调模型后,可像使用任何其他已部署的模型一样使用它。 可使用 Azure AI Studio 中的“操场”来试验新部署。 还可以使用 REST API 从自己的应用程序调用微调模型。 你甚至可以开始在提示流中使用此新的微调模型来生成你的生成式 AI 应用程序。
注意
对于聊天模型,用于指导微调模型的系统消息(无论是微调模型已部署还是可用于在操场中进行测试)必须与用于训练的系统消息相同。 如果使用其他系统消息,则模型可能无法按预期执行。
清理部署、微调模型和训练文件
使用微调模型完成操作后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。
删除微调模型部署
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
可在 Azure AI Studio 的“部署”页中删除微调模型的部署。 选择要删除的部署,然后选择“删除”以删除部署。
删除微调后模型
可在 Azure AI Studio 的“微调”页中删除微调模型。 选择要删除的微调模型,然后选择“删除”以删除该微调模型。
注意
如果微调模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除微调模型。
删除训练文件
可以选择性地删除为训练上传的训练和验证文件,以及在训练期间生成的结果文件。 为此,需要转到 Azure OpenAI Studio 并导航到“管理”>“数据文件”窗格。 选择要删除的文件,然后选择“删除”以删除该文件。
先决条件
- 参阅何时使用 Azure OpenAI 微调指南。
- Azure 订阅。 免费创建一个。
- Azure OpenAI 资源。 有关详细信息,请参阅使用 Azure OpenAI 创建资源和部署模型。
- 以下 Python 库:
os
、json
、requests
、openai
。 - OpenAI Python 库应至少为版本 0.28.1。
- 微调访问需要认知服务 OpenAI 参与者角色。
- 如果尚无权查看配额并在 Azure AI Studio 中部署模型,则需要其他权限。
模型
以下模型支持微调:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)*gpt-4o
(2024-08-06)gpt-4o-mini
(2024-07-18)
* 针对此模型的优化功能目前为公共预览版。
或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}
。
请参阅模型页,以查看当前支持微调的区域。
审阅 Python SDK 的工作流
花点时间审阅将 Python SDK 与 Azure OpenAI 配合使用的微调工作流:
- 准备训练和验证数据。
- 选择基础模型。
- 上传训练数据。
- 训练新的自定义模型。
- 检查自定义模型的状态。
- 部署自定义模型以供使用。
- 使用自定义模型。
- (可选)分析自定义模型的性能和拟合度。
准备训练和验证数据
训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。
不同的模型类型需要不同格式的训练数据。
你使用的训练和验证数据必须格式化为 JSON 行 (JSONL) 文档。 对于 gpt-35-turbo-0613
,必须以聊天补全 API 使用的对话格式来设置微调数据集的格式。
如果想要了解有关微调 gpt-35-turbo-0613
的逐步演练,请参阅 Azure OpenAI 微调教程
示例文件格式
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Is Xbox better than PlayStation?"}, {"role": "assistant", "content": "I apologize, but I cannot provide personal opinions. My primary job is to assist you with any issues related to your Xbox device. Do you have any Xbox-related issues that need addressing?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Can I play PC games on my Xbox?"}, {"role": "assistant", "content": "While Xbox consoles don't natively support PC games, they can play an array of Xbox games, many of which are also available on PC. Can I assist you with finding games compatible with your Xbox device?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "I'm having trouble connecting my Xbox to the Wi-Fi."}, {"role": "assistant", "content": "No worries, let's go through the network settings on your Xbox. Can you please tell me what happens when you try to connect it to the Wi-Fi?"}]}
多轮次聊天文件格式
还支持在 jsonl 训练文件单行中的多轮次对话。 要跳过对特定助手消息的微调,请添加可选的 weight
键值对。 目前,weight
可设置为 0 或 1。
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
除 JSONL 格式外,训练和验证数据文件必须以 UTF-8 编码并包含字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
创建训练和验证数据集
训练示例越多越好。 如果没有至少 10 个训练示例,微调作业将无法继续,但如此少的数量不足以显著影响模型响应。 最佳做法是提供数百个(如果不是数千个)训练示例来获得成功。
通常,将数据集大小加倍会促使模型质量呈线性增长。 但请记住,低质量的示例可能会对性能产生负面影响。 如果你根据大量内部数据来训练模型,而不是先修剪数据集以便获得最高质量的示例,则最终可能会得到一个性能比预期差得多的模型。
上传训练数据
下一步是选择已准备好的现有训练数据或上传已准备好的新训练数据,以便在自定义模型时使用。 准备好训练数据后,可将文件上传到服务。 可通过两种方式上传训练数据:
对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。 有关 Azure Blob 存储的详细信息,请参阅什么是 Azure Blob 存储?
注意
训练数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
以下 Python 示例使用 Python SDK 上传本地训练和验证文件,并检索返回的文件 ID。
# Upload fine-tuning files
import os
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-05-01-preview" # This API version or later is required to access seed/events/checkpoint capabilities
)
training_file_name = 'training_set.jsonl'
validation_file_name = 'validation_set.jsonl'
# Upload the training and validation dataset files to Azure OpenAI with the SDK.
training_response = client.files.create(
file=open(training_file_name, "rb"), purpose="fine-tune"
)
training_file_id = training_response.id
validation_response = client.files.create(
file=open(validation_file_name, "rb"), purpose="fine-tune"
)
validation_file_id = validation_response.id
print("Training file ID:", training_file_id)
print("Validation file ID:", validation_file_id)
创建自定义模型
上传训练和验证文件后,即可启动微调作业。
以下 Python 代码演示了使用 Python SDK 新建微调作业的示例:
在此示例中,我们同时也在传递种子参数。 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子。
response = client.fine_tuning.jobs.create(
training_file=training_file_id,
validation_file=validation_file_id,
model="gpt-35-turbo-0613", # Enter base model name. Note that in Azure OpenAI the model name contains dashes and cannot contain dot/period characters.
seed = 105 # seed parameter controls reproducibility of the fine-tuning job. If no seed is specified one will be generated automatically.
)
job_id = response.id
# You can use the job ID to monitor the status of the fine-tuning job.
# The fine-tuning job will take some time to start and complete.
print("Job ID:", response.id)
print("Status:", response.id)
print(response.model_dump_json(indent=2))
还可以传递其他可选参数(例如超参数),以更好地控制微调过程。 对于初始训练,我们建议使用存在的自动默认值,而不指定这些参数。
当前支持的微调超参数有:
Name | 类型 | 描述 |
---|---|---|
batch_size |
integer | 要用于训练的批大小。 批大小表示用于训练单个前向和后向传递的训练示例的数量。 一般情况下,我们发现较大的批大小往往更适合较大的数据集。 此属性的默认值和最大值特定于基础模型。 批大小越大意味着模型参数的更新频率越低,但方差越小。 |
learning_rate_multiplier |
数字 | 用于训练的学习率乘数。 微调学习率是用于预训练的原始学习率乘以该值。 较大的学习率通常在较大的批大小中表现更好。 建议试验 0.02 到 0.2 范围内的值,以查看产生最佳结果的值。 较小的学习率可以用于避免过度拟合。 |
n_epochs |
integer | 训练模型的时期数。 一个时期是指训练数据集的一个完整周期。 |
seed |
integer | 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子。 |
使用 1.x 版 OpenAI Python API 来设置自定义超参数:
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-02-01" # This API version or later is required to access fine-tuning for turbo/babbage-002/davinci-002
)
client.fine_tuning.jobs.create(
training_file="file-abc123",
model="gpt-35-turbo-0613", # Enter base model name. Note that in Azure OpenAI the model name contains dashes and cannot contain dot/period characters.
hyperparameters={
"n_epochs":2
}
)
检查微调作业状态
response = client.fine_tuning.jobs.retrieve(job_id)
print("Job ID:", response.id)
print("Status:", response.status)
print(response.model_dump_json(indent=2))
列出微调事件
若要检查训练期间生成的各个微调事件:
可能需要使用 pip install openai --upgrade
将 OpenAI 客户端库升级到最新版本才能运行此命令。
response = client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=10)
print(response.model_dump_json(indent=2))
检查点
每个训练纪元完成时,都会生成一个检查点。 检查点是模型的完全功能版本,可以将其部署并用作后续微调作业的目标模型。 检查点特别有用,因为它们可以提供过度拟合发生之前模型的快照。 当微调作业完成时,你将拥有可供部署的三个最新版本的模型。 最后一个纪元将由你的微调模型表示,前两个纪元将作为检查点提供。
可以运行列表检查点命令来检索与各个微调作业关联的检查点的列表:
可能需要使用 pip install openai --upgrade
将 OpenAI 客户端库升级到最新版本才能运行此命令。
response = client.fine_tuning.jobs.list_events(fine_tuning_job_id=job_id, limit=10)
print(response.model_dump_json(indent=2))
安全评估 GPT-4、GPT-4o、GPT-4o-mini 微调 - 公共预览版
GPT-4o、GPT-4o-mini 和 GPT-4 是我们最高级的模型,可以根据需要进行微调。 与 Azure OpenAI 模型相仿,微调模型的高级功能也伴随着与有害内容、操纵、类人行为、隐私问题等相关的日益增加的负责任 AI 挑战。 在负责任 AI 做法的概述和透明度说明中详细了解风险、功能和限制。 为了帮助缓解与高级微调模型相关的风险,我们实施了其他评估步骤,以帮助检测和防止微调模型的训练和输出中的有害内容。 这些步骤基于 Microsoft 负责任 AI 标准和 Azure OpenAI 服务内容筛选。
- 评估是在专用、特定于客户的私有工作区中进行的;
- 评估终结点与 Azure OpenAI 资源位于同一地理位置;
- 训练数据的存储与评估无关;仅保留最终模型评估(可部署或不可部署);并且
GPT-4o、GPT-4o-mini 和 GPT-4 微调模型评估筛选器已设置为预定义阈值,客户无法修改;它们不与可能已创建的任何自定义内容筛选配置绑定。
数据评估
在训练开始之前,系统会评估你的数据是否包含有害内容(暴力、性、仇恨、公平、自残 – 请参阅此处的类别定义)。 如果检测到高于指定严重级别的有害内容,则训练作业将失败,并且你将收到一条告知失败类别的消息。
示例消息:
The provided training data failed RAI checks for harm types: [hate_fairness, self_harm, violence]. Please fix the data and try again.
作为提供微调功能的一部分,系统会在数据导入作业中自动评估训练数据。
如果微调作业由于在训练数据中检测到有害内容而失败,则不会收取费用。
模型评估
训练完成后,但在微调模型可用于部署之前,将使用 Azure 的内置风险和安全指标来评估生成的模型是否包含潜在有害响应。 使用与基础大型语言模型相同的测试方法,我们的评估功能会模拟与微调模型的对话,以评估输出有害内容的可能性,它同样使用指定的有害内容类别(暴力、性、仇恨、公平、自残)。
如果检测到某个模型生成的输出包含有害内容,且其等级高于可接受的等级,则系统会通知你的模型不可用于部署,并提供有关检测到的特定危害类别的信息:
示例消息:
This model is unable to be deployed. Model evaluation identified that this fine tuned model scores above acceptable thresholds for [Violence, Self Harm]. Please review your training data set and resubmit the job.
与数据评估一样,作为提供微调功能的一部分,系统会在微调作业中自动评估模型。 服务仅记录生成的评估(可部署或不可部署)。 如果由于在模型输出中检测到有害内容而导致微调模型部署失败,则不会对训练运行收取费用。
部署微调模型
微调作业成功后,响应正文中的 fine_tuned_model
变量的值将设置为自定义模型的名称。 现在还可以从列表模型 API 中发现该模型。 但是,只有在部署自定义模型之后,才能对自定义模型发出完成调用。 必须部署自定义模型才能使其可用于完成调用。
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
还可以使用 Azure AI Studio 或 Azure CLI 部署自定义模型。
注意
自定义模型只允许一个部署。 如果选择已部署的自定义模型,则会发生错误。
与以前的 SDK 命令不同,必须使用需要单独授权的控制平面 API、不同的 API 路径和不同的 API 版本才能完成部署。
variable | 定义 |
---|---|
token | 可通过多种方式生成授权令牌。 初始测试的最简单方法是从 Azure 门户启动 Cloud Shell。 然后运行 az account get-access-token 。 可以将此令牌用作 API 测试的临时授权令牌。 建议将其存储在新的环境变量中。 |
订阅 | 关联的 Azure OpenAI 资源的订阅 ID。 |
resource_group | Azure OpenAI 资源的资源组名称。 |
resource_name | Azure OpenAI 资源名称。 |
model_deployment_name | 新微调模型部署的自定义名称。 这是在进行聊天补全调用时将在代码中引用的名称。 |
fine_tuned_model | 请从上一步的微调作业结果中检索此值。 该字符串类似于 gpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83 。 需要将该值添加到 deploy_data json。 或者,也可以通过传递将以 ftchkpt-e559c011ecc04fc68eaa339d8227d02d 格式显示的检查点 ID 来部署检查点 |
import json
import os
import requests
token= os.getenv("<TOKEN>")
subscription = "<YOUR_SUBSCRIPTION_ID>"
resource_group = "<YOUR_RESOURCE_GROUP_NAME>"
resource_name = "<YOUR_AZURE_OPENAI_RESOURCE_NAME>"
model_deployment_name ="gpt-35-turbo-ft" # custom deployment name that you will use to reference the model when making inference calls.
deploy_params = {'api-version': "2023-05-01"}
deploy_headers = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}
deploy_data = {
"sku": {"name": "standard", "capacity": 1},
"properties": {
"model": {
"format": "OpenAI",
"name": <"fine_tuned_model">, #retrieve this value from the previous call, it will look like gpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83
"version": "1"
}
}
}
deploy_data = json.dumps(deploy_data)
request_url = f'https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/Microsoft.CognitiveServices/accounts/{resource_name}/deployments/{model_deployment_name}'
print('Creating a new deployment...')
r = requests.put(request_url, params=deploy_params, headers=deploy_headers, data=deploy_data)
print(r)
print(r.reason)
print(r.json())
跨区域部署
微调支持将微调后的模型部署到与模型最初进行微调时所在的区域不同的区域。 还可以部署到其他订阅/区域。
唯一的限制是新区域还必须支持微调,并且在部署交叉订阅时为部署生成授权令牌的帐户必须有权访问源订阅和目标订阅。
下面是一个示例,说明了如何将已在一个订阅/区域中微调的模型部署到另一个订阅/区域。
import json
import os
import requests
token= os.getenv("<TOKEN>")
subscription = "<DESTINATION_SUBSCRIPTION_ID>"
resource_group = "<DESTINATION_RESOURCE_GROUP_NAME>"
resource_name = "<DESTINATION_AZURE_OPENAI_RESOURCE_NAME>"
source_subscription = "<SOURCE_SUBSCRIPTION_ID>"
source_resource_group = "<SOURCE_RESOURCE_GROUP>"
source_resource = "<SOURCE_RESOURCE>"
source = f'/subscriptions/{source_subscription}/resourceGroups/{source_resource_group}/providers/Microsoft.CognitiveServices/accounts/{source_resource}'
model_deployment_name ="gpt-35-turbo-ft" # custom deployment name that you will use to reference the model when making inference calls.
deploy_params = {'api-version': "2023-05-01"}
deploy_headers = {'Authorization': 'Bearer {}'.format(token), 'Content-Type': 'application/json'}
deploy_data = {
"sku": {"name": "standard", "capacity": 1},
"properties": {
"model": {
"format": "OpenAI",
"name": <"FINE_TUNED_MODEL_NAME">, # This value will look like gpt-35-turbo-0613.ft-0ab3f80e4f2242929258fff45b56a9ce
"version": "1",
"source": source
}
}
}
deploy_data = json.dumps(deploy_data)
request_url = f'https://management.azure.com/subscriptions/{subscription}/resourceGroups/{resource_group}/providers/Microsoft.CognitiveServices/accounts/{resource_name}/deployments/{model_deployment_name}'
print('Creating a new deployment...')
r = requests.put(request_url, params=deploy_params, headers=deploy_headers, data=deploy_data)
print(r)
print(r.reason)
print(r.json())
若要在同一订阅但不同区域之间进行部署,只需让源变量和目标变量的订阅和资源组相同,并且仅源资源名称和目标资源名称需要独一无二。
使用 Azure CLI 部署模型
以下示例演示如何使用 Azure CLI 部署自定义模型。 使用 Azure CLI 时,必须为自定义模型的部署指定名称。 有关使用 Azure CLI 部署自定义模型的详细信息,请参阅 az cognitiveservices account deployment
。
若要在控制台窗口中运行此 Azure CLI 命令,必须将以下 <占位符> 替换为自定义模型的相应值:
占位符 | 值 |
---|---|
<YOUR_AZURE_SUBSCRIPTION> | Azure 订阅的名称或 ID。 |
<YOUR_RESOURCE_GROUP> | Azure 资源组的名称。 |
<YOUR_RESOURCE_NAME> | Azure OpenAI 资源的名称。 |
<YOUR_DEPLOYMENT_NAME> | 用于模型部署的名称。 |
<YOUR_FINE_TUNED_MODEL_ID> | 自定义模型的名称。 |
az cognitiveservices account deployment create
--resource-group <YOUR_RESOURCE_GROUP>
--name <YOUR_RESOURCE_NAME>
--deployment-name <YOUR_DEPLOYMENT_NAME>
--model-name <YOUR_FINE_TUNED_MODEL_ID>
--model-version "1"
--model-format OpenAI
--sku-capacity "1"
--sku-name "Standard"
使用已部署的自定义模型
部署自定义模型后,可像使用任何其他已部署的模型一样使用它。 可使用 Azure AI Studio 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperature
和 max_tokens
,就像对其他已部署的模型一样。 对于微调的 babbage-002
和 davinci-002
模型,将使用“补全”操场和补全 API。 对于微调的 gpt-35-turbo-0613
模型,将使用“聊天”操场和聊天补全 API。
import os
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-02-01"
)
response = client.chat.completions.create(
model="gpt-35-turbo-ft", # model = "Custom deployment name you chose for your fine-tuning model"
messages=[
{"role": "system", "content": "You are a helpful assistant."},
{"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},
{"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},
{"role": "user", "content": "Do other Azure AI services support this too?"}
]
)
print(response.choices[0].message.content)
分析自定义模型
完成每个微调作业后,Azure OpenAI 会将一个名为 results.csv 的结果文件附加到该作业。 可以使用该结果文件来分析自定义模型的训练和验证性能。 将列出每个自定义模型的结果文件的文件 ID,你可以使用 Python SDK 检索该文件 ID,并下载结果文件进行分析。
以下 Python 示例检索附加到自定义模型微调作业的第一个结果文件的文件 ID,然后使用 Python SDK 将该文件下载到工作目录进行分析。
# Retrieve the file ID of the first result file from the fine-tuning job
# for the customized model.
response = client.fine_tuning.jobs.retrieve(job_id)
if response.status == 'succeeded':
result_file_id = response.result_files[0]
retrieve = client.files.retrieve(result_file_id)
# Download the result file.
print(f'Downloading result file: {result_file_id}')
with open(retrieve.filename, "wb") as file:
result = client.files.content(result_file_id).read()
file.write(result)
结果文件是一个 CSV 文件,其中包含标题行,以及微调作业执行的每个训练步骤的行。 结果文件包含以下列:
列名称 | 说明 |
---|---|
step |
训练步数。 一个训练步骤代表针对一批训练数据的一次向前和向后的传递。 |
train_loss |
训练批的损失。 |
train_mean_token_accuracy |
训练批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
valid_loss |
验证批的损失。 |
validation_mean_token_accuracy |
验证批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
full_valid_loss |
在每个纪元结束时计算的验证损失。 训练正常时,损失应减少。 |
full_valid_mean_token_accuracy |
在每个纪元结束时计算的有效平均标记准确性。 训练正常时,标记准确性应增加。 |
还可以在 Azure AI Studio 中以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到三个图表:损失、平均令牌准确度和令牌准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。
随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。
清理部署、自定义模型和训练文件
处理完自定义模型后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。
删除模型部署
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
可以使用各种方法来删除自定义模型的部署:
删除自定义模型
同样,可以使用各种方法删除自定义模型:
注意
如果自定义模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除自定义模型。
删除训练文件
可以选择性地在 Azure OpenAI 订阅中删除为训练上传的训练和验证文件,以及在训练期间生成的结果文件。 可使用以下方法删除训练、验证和结果文件:
- Azure AI Studio
- REST API
- Python SDK
以下 Python 示例使用 Python SDK 删除自定义模型的训练、验证和结果文件:
print('Checking for existing uploaded files.')
results = []
# Get the complete list of uploaded files in our subscription.
files = openai.File.list().data
print(f'Found {len(files)} total uploaded files in the subscription.')
# Enumerate all uploaded files, extracting the file IDs for the
# files with file names that match your training dataset file and
# validation dataset file names.
for item in files:
if item["filename"] in [training_file_name, validation_file_name, result_file_name]:
results.append(item["id"])
print(f'Found {len(results)} already uploaded files that match our files')
# Enumerate the file IDs for our files and delete each file.
print(f'Deleting already uploaded files.')
for id in results:
openai.File.delete(sid = id)
持续微调
创建微调模型后,你可能希望在一段时间内通过进一步微调继续完善模型。 持续微调是选择已经微调的模型作为基础模型并在新的训练示例集上进一步对其进行微调的迭代过程。
若要对之前微调过的模型执行微调,可以使用创建自定义模型中所述的流程,但无需指定通用基础模型的名称,而只需指定已微调的模型的 ID。 已微调的模型的 ID 类似于 gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7
from openai import AzureOpenAI
client = AzureOpenAI(
azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT"),
api_key=os.getenv("AZURE_OPENAI_API_KEY"),
api_version="2024-02-01"
)
response = client.fine_tuning.jobs.create(
training_file=training_file_id,
validation_file=validation_file_id,
model="gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7" # Enter base model name. Note that in Azure OpenAI the model name contains dashes and cannot contain dot/period characters.
)
job_id = response.id
# You can use the job ID to monitor the status of the fine-tuning job.
# The fine-tuning job will take some time to start and complete.
print("Job ID:", response.id)
print("Status:", response.id)
print(response.model_dump_json(indent=2))
我们还建议添加 suffix
参数,以便更轻松地区分已微调模型的不同迭代。 suffix
接受一个字符串,并设置为标识已微调的模型。 OpenAI Python API 支持最多 18 个字符的字符串,该字符串将添加到已微调的模型名称中。
如果不确定现有的已微调模型的 ID,可以在 Azure AI Studio 的“模型”页面中找到此信息,也可以使用 REST API 为某个给定 Azure OpenAI 资源生成模型列表。
先决条件
- 参阅何时使用 Azure OpenAI 微调指南。
- Azure 订阅。 免费创建一个。
- Azure OpenAI 资源。 有关详细信息,请参阅使用 Azure OpenAI 创建资源和部署模型。
- 微调访问需要认知服务 OpenAI 参与者角色。
- 如果尚无权查看配额并在 Azure AI Studio 中部署模型,则需要其他权限。
模型
以下模型支持微调:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)*gpt-4o
(2024-08-06)gpt-4o-mini
(2024-07-18)
* 针对此模型的优化功能目前为公共预览版。
或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。
请参阅模型页,以查看当前支持微调的区域。
审阅 REST API 的工作流
花点时间审查将 REST APIS 和 Python 与 Azure OpenAI 配合使用的微调工作流:
- 准备训练和验证数据。
- 选择基础模型。
- 上传训练数据。
- 训练新的自定义模型。
- 检查自定义模型的状态。
- 部署自定义模型以供使用。
- 使用自定义模型。
- (可选)分析自定义模型的性能和拟合度。
准备训练和验证数据
训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。
不同的模型类型需要不同格式的训练数据。
你使用的训练和验证数据必须格式化为 JSON 行 (JSONL) 文档。 对于 gpt-35-turbo-0613
和其他相关模型,必须按聊天补全 API 使用的对话格式来设置微调数据集的格式。
如果想要了解有关微调 gpt-35-turbo-0613
的逐步演练,请参阅 Azure OpenAI 微调教程。
示例文件格式
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Is Xbox better than PlayStation?"}, {"role": "assistant", "content": "I apologize, but I cannot provide personal opinions. My primary job is to assist you with any issues related to your Xbox device. Do you have any Xbox-related issues that need addressing?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "Can I play PC games on my Xbox?"}, {"role": "assistant", "content": "While Xbox consoles don't natively support PC games, they can play an array of Xbox games, many of which are also available on PC. Can I assist you with finding games compatible with your Xbox device?"}]}
{"messages": [{"role": "system", "content": "You are an Xbox customer support agent whose primary goal is to help users with issues they are experiencing with their Xbox devices. You are friendly and concise. You only provide factual answers to queries, and do not provide answers that are not related to Xbox."}, {"role": "user", "content": "I'm having trouble connecting my Xbox to the Wi-Fi."}, {"role": "assistant", "content": "No worries, let's go through the network settings on your Xbox. Can you please tell me what happens when you try to connect it to the Wi-Fi?"}]}
多轮次聊天文件格式
还支持在 jsonl 训练文件单行中的多轮次对话。 要跳过对特定助手消息的微调,请添加可选的 weight
键值对。 目前,weight
可设置为 0 或 1。
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already.", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "William Shakespeare", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?", "weight": 1}]}
{"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "384,400 kilometers", "weight": 0}, {"role": "user", "content": "Can you be more sarcastic?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters.", "weight": 1}]}
除 JSONL 格式外,训练和验证数据文件必须以 UTF-8 编码并包含字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
创建训练和验证数据集
训练示例越多越好。 如果没有至少 10 个训练示例,微调作业将无法继续,但如此少的数量不足以显著影响模型响应。 最佳做法是提供数百个(如果不是数千个)训练示例来获得成功。
通常,将数据集大小加倍会促使模型质量呈线性增长。 但请记住,低质量的示例可能会对性能产生负面影响。 如果你根据大量内部数据来训练模型,而不是先修剪数据集以便获得最高质量的示例,则最终可能会得到一个性能比预期差得多的模型。
选择基础模型
选择基础模型是创建自定义模型的第一步。 你可通过“基础模型”窗格选择用于自定义模型的基础模型。 所做的选择会影响模型的性能和成本。
从“基础模型类型”下拉列表中选择基础模型,然后选择“下一步”以继续。
可从以下可用基础模型之一创建自定义模型:
babbage-002
davinci-002
gpt-35-turbo
(0613)gpt-35-turbo
(1106)gpt-35-turbo
(0125)gpt-4
(0613)gpt-4o
(2024-08-06)gpt-4o-mini
(2023-07-18)
或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。
有关可进行优化的基本模型的详细信息,请参阅模型。
上传训练数据
下一步是选择已准备好的现有训练数据或上传已准备好的新训练数据,以便在微调模型时使用。 准备好训练数据后,可将文件上传到服务。 可通过两种方式上传训练数据:
对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。 有关 Azure Blob 存储的详细信息,请参阅什么是 Azure Blob 存储?
注意
训练数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。
上传训练数据
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/files?api-version=2023-12-01-preview \
-H "Content-Type: multipart/form-data" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-F "purpose=fine-tune" \
-F "file=@C:\\fine-tuning\\training_set.jsonl;type=application/json"
上传验证数据
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/files?api-version=2023-12-01-preview \
-H "Content-Type: multipart/form-data" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-F "purpose=fine-tune" \
-F "file=@C:\\fine-tuning\\validation_set.jsonl;type=application/json"
创建自定义模型
上传训练和验证文件后,即可启动微调作业。 以下代码演示了使用 REST API 新建微调作业的示例。
在此示例中,我们同时也在传递种子参数。 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子。
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs?api-version=2024-05-01-preview \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "gpt-35-turbo-0613",
"training_file": "<TRAINING_FILE_ID>",
"validation_file": "<VALIDATION_FILE_ID>",
"seed": 105
}'
还可以传递其他可选参数(例如超参数),以更好地控制微调过程。 对于初始训练,我们建议使用存在的自动默认值,而不指定这些参数。
当前支持的微调超参数有:
Name | 类型 | 描述 |
---|---|---|
batch_size |
integer | 要用于训练的批大小。 批大小表示用于训练单个前向和后向传递的训练示例的数量。 一般情况下,我们发现较大的批大小往往更适合较大的数据集。 此属性的默认值和最大值特定于基础模型。 批大小越大意味着模型参数的更新频率越低,但方差越小。 |
learning_rate_multiplier |
数字 | 用于训练的学习率乘数。 微调学习率是用于预训练的原始学习率乘以该值。 较大的学习率通常在较大的批大小中表现更好。 建议试验 0.02 到 0.2 范围内的值,以查看产生最佳结果的值。 较小的学习率可以用于避免过度拟合。 |
n_epochs |
integer | 训练模型的时期数。 一个时期是指训练数据集的一个完整周期。 |
seed |
integer | 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子。 |
检查自定义模型的状态
开始微调作业后,可能需要一些时间才能完成。 你的作业可能排在系统上的其他作业后面。 训练模型可能需要几分钟或几小时,具体取决于模型和数据集大小。 以下示例使用 REST API 检查微调作业的状态。 该示例使用上一示例返回的作业 ID 检索有关作业的信息:
curl -X GET $AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs/<YOUR-JOB-ID>?api-version=2024-05-01-preview \
-H "api-key: $AZURE_OPENAI_API_KEY"
列出微调事件
若要检查训练期间生成的各个微调事件:
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs/{fine_tuning_job_id}/events?api-version=2024-05-01-preview \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
检查点
每个训练纪元完成时,都会生成一个检查点。 检查点是模型的完全功能版本,可以将其部署并用作后续微调作业的目标模型。 检查点特别有用,因为它们可以提供过度拟合发生之前模型的快照。 当微调作业完成时,你将拥有可供部署的三个最新版本的模型。 最后一个纪元将由你的微调模型表示,前两个纪元将作为检查点提供。
可以运行列表检查点命令来检索与各个微调作业关联的检查点的列表:
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs/{fine_tuning_job_id}/checkpoints?api-version=2024-05-01-preview \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY"
安全评估 GPT-4、GPT-4o、GPT-4o-mini 微调 - 公共预览版
GPT-4o、GPT-4o-mini 和 GPT-4 是我们最高级的模型,可以根据需要进行微调。 与 Azure OpenAI 模型相仿,微调模型的高级功能也伴随着与有害内容、操纵、类人行为、隐私问题等相关的日益增加的负责任 AI 挑战。 在负责任 AI 做法的概述和透明度说明中详细了解风险、功能和限制。 为了帮助缓解与高级微调模型相关的风险,我们实施了其他评估步骤,以帮助检测和防止微调模型的训练和输出中的有害内容。 这些步骤基于 Microsoft 负责任 AI 标准和 Azure OpenAI 服务内容筛选。
- 评估是在专用、特定于客户的私有工作区中进行的;
- 评估终结点与 Azure OpenAI 资源位于同一地理位置;
- 训练数据的存储与评估无关;仅保留最终模型评估(可部署或不可部署);并且
GPT-4o、GPT-4o-mini 和 GPT-4 微调模型评估筛选器已设置为预定义阈值,客户无法修改;它们不与可能已创建的任何自定义内容筛选配置绑定。
数据评估
在训练开始之前,系统会评估你的数据是否包含有害内容(暴力、性、仇恨、公平、自残 – 请参阅此处的类别定义)。 如果检测到高于指定严重级别的有害内容,则训练作业将失败,并且你将收到一条告知失败类别的消息。
示例消息:
The provided training data failed RAI checks for harm types: [hate_fairness, self_harm, violence]. Please fix the data and try again.
作为提供微调功能的一部分,系统会在数据导入作业中自动评估训练数据。
如果微调作业由于在训练数据中检测到有害内容而失败,则不会收取费用。
模型评估
训练完成后,但在微调模型可用于部署之前,将使用 Azure 的内置风险和安全指标来评估生成的模型是否包含潜在有害响应。 使用与基础大型语言模型相同的测试方法,我们的评估功能会模拟与微调模型的对话,以评估输出有害内容的可能性,它同样使用指定的有害内容类别(暴力、性、仇恨、公平、自残)。
如果检测到某个模型生成的输出包含有害内容,且其等级高于可接受的等级,则系统会通知你的模型不可用于部署,并提供有关检测到的特定危害类别的信息:
示例消息:
This model is unable to be deployed. Model evaluation identified that this fine tuned model scores above acceptable thresholds for [Violence, Self Harm]. Please review your training data set and resubmit the job.
与数据评估一样,作为提供微调功能的一部分,系统会在微调作业中自动评估模型。 服务仅记录生成的评估(可部署或不可部署)。 如果由于在模型输出中检测到有害内容而导致微调模型部署失败,则不会对训练运行收取费用。
部署微调模型
重要
在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。
删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。
以下 Python 示例演示如何使用 REST API 为自定义模型创建模型部署。 REST API 为自定义模型的部署生成名称。
variable | 定义 |
---|---|
token | 可通过多种方式生成授权令牌。 初始测试的最简单方法是从 Azure 门户启动 Cloud Shell。 然后运行 az account get-access-token 。 可以将此令牌用作 API 测试的临时授权令牌。 建议将其存储在新的环境变量中。 |
订阅 | 关联的 Azure OpenAI 资源的订阅 ID。 |
resource_group | Azure OpenAI 资源的资源组名称。 |
resource_name | Azure OpenAI 资源名称。 |
model_deployment_name | 新微调模型部署的自定义名称。 这是在进行聊天补全调用时将在代码中引用的名称。 |
fine_tuned_model | 请从上一步的微调作业结果中检索此值。 该字符串类似于 gpt-35-turbo-0613.ft-b044a9d3cf9c4228b5d393567f693b83 。 需要将该值添加到 deploy_data json。 或者,也可以通过传递将以 ftchkpt-e559c011ecc04fc68eaa339d8227d02d 格式显示的检查点 ID 来部署检查点 |
curl -X POST "https://management.azure.com/subscriptions/<SUBSCRIPTION>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.CognitiveServices/accounts/<RESOURCE_NAME>/deployments/<MODEL_DEPLOYMENT_NAME>api-version=2023-05-01" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"sku": {"name": "standard", "capacity": 1},
"properties": {
"model": {
"format": "OpenAI",
"name": "<FINE_TUNED_MODEL>",
"version": "1"
}
}
}'
跨区域部署
微调支持将微调后的模型部署到与模型最初进行微调时所在的区域不同的区域。 还可以部署到其他订阅/区域。
唯一的限制是新区域还必须支持微调,并且在部署交叉订阅时为部署生成授权令牌的帐户必须有权访问源订阅和目标订阅。
下面是一个示例,说明了如何将已在一个订阅/区域中微调的模型部署到另一个订阅/区域。
curl -X PUT "https://management.azure.com/subscriptions/<SUBSCRIPTION>/resourceGroups/<RESOURCE_GROUP>/providers/Microsoft.CognitiveServices/accounts/<RESOURCE_NAME>/deployments/<MODEL_DEPLOYMENT_NAME>api-version=2023-05-01" \
-H "Authorization: Bearer <TOKEN>" \
-H "Content-Type: application/json" \
-d '{
"sku": {"name": "standard", "capacity": 1},
"properties": {
"model": {
"format": "OpenAI",
"name": "<FINE_TUNED_MODEL>",
"version": "1",
"source": "/subscriptions/{sourceSubscriptionID}/resourceGroups/{sourceResourceGroupName}/providers/Microsoft.CognitiveServices/accounts/{sourceAccount}"
}
}
}'
若要在同一订阅但不同区域之间进行部署,只需让源变量和目标变量的订阅和资源组相同,并且仅源资源名称和目标资源名称需要独一无二。
使用 Azure CLI 部署模型
以下示例演示如何使用 Azure CLI 部署自定义模型。 使用 Azure CLI 时,必须为自定义模型的部署指定名称。 有关使用 Azure CLI 部署自定义模型的详细信息,请参阅 az cognitiveservices account deployment
。
若要在控制台窗口中运行此 Azure CLI 命令,必须将以下 <占位符> 替换为自定义模型的相应值:
占位符 | 值 |
---|---|
<YOUR_AZURE_SUBSCRIPTION> | Azure 订阅的名称或 ID。 |
<YOUR_RESOURCE_GROUP> | Azure 资源组的名称。 |
<YOUR_RESOURCE_NAME> | Azure OpenAI 资源的名称。 |
<YOUR_DEPLOYMENT_NAME> | 用于模型部署的名称。 |
<YOUR_FINE_TUNED_MODEL_ID> | 自定义模型的名称。 |
az cognitiveservices account deployment create
--resource-group <YOUR_RESOURCE_GROUP>
--name <YOUR_RESOURCE_NAME>
--deployment-name <YOUR_DEPLOYMENT_NAME>
--model-name <YOUR_FINE_TUNED_MODEL_ID>
--model-version "1"
--model-format OpenAI
--sku-capacity "1"
--sku-name "Standard"
使用已部署的自定义模型
部署自定义模型后,可像使用任何其他已部署的模型一样使用它。 可使用 Azure AI Studio 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperature
和 max_tokens
,就像对其他已部署的模型一样。 对于微调的 babbage-002
和 davinci-002
模型,将使用“补全”操场和补全 API。 对于微调的 gpt-35-turbo-0613
模型,将使用“聊天”操场和聊天补全 API。
curl $AZURE_OPENAI_ENDPOINT/openai/deployments/<deployment_name>/chat/completions?api-version=2023-05-15 \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{"messages":[{"role": "system", "content": "You are a helpful assistant."},{"role": "user", "content": "Does Azure OpenAI support customer managed keys?"},{"role": "assistant", "content": "Yes, customer managed keys are supported by Azure OpenAI."},{"role": "user", "content": "Do other Azure AI services support this too?"}]}'
分析自定义模型
完成每个微调作业后,Azure OpenAI 会将一个名为 results.csv 的结果文件附加到该作业。 可以使用该结果文件来分析自定义模型的训练和验证性能。 将列出每个自定义模型的结果文件的文件 ID,你可以使用 REST API 检索该文件 ID,并下载结果文件进行分析。
以下 Python 示例使用 REST API 检索附加到自定义模型微调作业的第一个结果文件的文件 ID,然后将该文件下载到工作目录进行分析。
curl -X GET "$AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs/<JOB_ID>?api-version=2023-12-01-preview" \
-H "api-key: $AZURE_OPENAI_API_KEY")
curl -X GET "$AZURE_OPENAI_ENDPOINT/openai/files/<RESULT_FILE_ID>/content?api-version=2023-12-01-preview" \
-H "api-key: $AZURE_OPENAI_API_KEY" > <RESULT_FILENAME>
结果文件是一个 CSV 文件,其中包含标题行,以及微调作业执行的每个训练步骤的行。 结果文件包含以下列:
列名称 | 说明 |
---|---|
step |
训练步数。 一个训练步骤代表针对一批训练数据的一次向前和向后的传递。 |
train_loss |
训练批的损失。 |
train_mean_token_accuracy |
训练批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
valid_loss |
验证批的损失。 |
validation_mean_token_accuracy |
验证批中模型正确预测的标记百分比。 例如,如果批大小设置为 3 并且数据包含完成 [[1, 2], [0, 5], [4, 2]] ,在模型预测 [[1, 1], [0, 5], [4, 2]] 后,此值将设置为 0.83 (5/6)。 |
full_valid_loss |
在每个纪元结束时计算的验证损失。 训练正常时,损失应减少。 |
full_valid_mean_token_accuracy |
在每个纪元结束时计算的有效平均标记准确性。 训练正常时,标记准确性应增加。 |
还可以在 Azure AI Studio 中以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到三个图表:损失、平均令牌准确度和令牌准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。
随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。
清理部署、自定义模型和训练文件
处理完自定义模型后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。
删除模型部署
可以使用各种方法来删除自定义模型的部署:
删除自定义模型
同样,可以使用各种方法删除自定义模型:
注意
如果自定义模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除自定义模型。
删除训练文件
可以选择性地在 Azure OpenAI 订阅中删除为训练上传的训练和验证文件,以及在训练期间生成的结果文件。 可使用以下方法删除训练、验证和结果文件:
持续微调
创建微调模型后,你可能希望在一段时间内通过进一步微调继续完善模型。 持续微调是选择已经微调的模型作为基础模型并在新的训练示例集上进一步对其进行微调的迭代过程。
若要对之前微调过的模型执行微调,可以使用创建自定义模型中所述的流程,但无需指定通用基础模型的名称,而只需指定已微调的模型的 ID。 已微调的模型的 ID 类似于 gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7
curl -X POST $AZURE_OPENAI_ENDPOINT/openai/fine_tuning/jobs?api-version=2023-12-01-preview \
-H "Content-Type: application/json" \
-H "api-key: $AZURE_OPENAI_API_KEY" \
-d '{
"model": "gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7",
"training_file": "<TRAINING_FILE_ID>",
"validation_file": "<VALIDATION_FILE_ID>",
"suffix": "<additional text used to help identify fine-tuned models>"
}'
我们还建议添加 suffix
参数,以便更轻松地区分已微调模型的不同迭代。 suffix
接受一个字符串,并设置为标识已微调的模型。 后缀最多可包含 40 个字符(a-z、A-Z、0-9、- 和 _),这些字符将添加到已微调模型的名称中。
如果不确定已微调模型的 ID,可以在 Azure AI Studio 的“模型”页面中找到此信息,也可以使用 REST API 为某个给定 Azure OpenAI 资源生成模型列表。
故障排除
如何启用微调? “创建自定义模型”在 Azure OpenAI Studio 中灰显?
为了成功获取微调功能,你需要分配有 Azure 认知服务 OpenAI 参与者角色。 即使是具有高级服务管理员权限的人员也需要显式设置此帐户才能访问微调。 有关详细信息,请查看基于角色的访问控制指南。
为什么我上传失败?
如果 Azure OpenAI Studio 中的文件上传失败,可以在 Azure OpenAI Studio 中的“数据文件”下查看错误消息。 将鼠标悬停在显示“错误”(状态列下)的位置,将显示关于失败的说明。
我微调后的模型似乎没有改进
缺少系统消息:微调时需要提供系统消息;使用微调后的模型时,需要提供相同的系统消息。 如果提供不同的系统消息,你看到的结果可能会与微调后的结果不同。
数据不足:虽然运行管道的最小数量是 10,但需要数百到数千个数据点来教授模型一项新技能。 数据点过少可能会导致过度拟合和泛化性能不佳。 微调后的模型可能在训练数据上表现良好,但在其他数据上表现不佳,因为它记住了训练示例而不是学习模式。 为了获得最佳结果,请计划准备包含数百个或数千个数据点的数据集。
错误的数据:策展不当或不具有代表性的数据集将生成低质量模型。 模型可能会从数据集中学习不准确或有偏差的模式。 例如,如果你正在训练一个用于客户服务的聊天机器人,但仅提供一种场景(例如商品退货)的训练数据,它将不知道如何响应其他场景。 或者,如果训练数据不正确(包含不正确的响应),模型将学习提供不正确的结果。
后续步骤
- 在 Azure OpenAI 微调教程中了解微调功能。
- 查看微调模型区域可用性
- 详细了解 Azure OpenAI 配额