你当前正在访问 Microsoft Azure Global Edition 技术文档网站。 如果需要访问由世纪互联运营的 Microsoft Azure 中国技术文档网站,请访问 https://docs.azure.cn

通过微调自定义模型

借助 Azure OpenAI 服务,你可以使用称为“微调”的过程根据个人数据集定制模型。 通过此自定义步骤,你可以更充分地利用服务,获得以下好处:

  • 结果的质量比从提示工程中获取的质量更高
  • 能够根据超出模型最大请求上下文限制的更多示例进行训练。
  • 由于提示较短,节省了令牌
  • 更低延迟的请求,尤其是在使用较小的模型时。

与少样本学习相比,微调通过训练超出提示范围的更多示例来改进模型,从而让你在处理大量任务时取得更好的结果。 由于微调会调整基本模型的权重以提高特定任务的性能,因此无需在提示中包含过多的示例或说明。 这意味着发送的文本更少,每次 API 调用处理的令牌更少,从而可能节省成本并改善请求延迟。

我们使用 LoRA(即低秩近似)来微调模型,以降低其复杂性而不显著影响其性能。 此方法的工作原理是用较低秩的矩阵来近似原始的高秩矩阵,因此在监督训练阶段仅微调较小的“重要”参数子集,从而使模型更易于管理和高效。 对于用户,这使得训练比其他技术更快、更经济实惠。

Azure AI Foundry 门户中提供了两种独特的微调体验。

如果只是微调 Azure OpenAI 模型,我们建议通过导航到 https://oai.azure.com 来获得以 Azure OpenAI 为中心的微调体验。

先决条件

模型

以下模型支持微调:

  • 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 Foundry 的工作流

请花点时间审阅使用 Azure AI Foundry 的微调工作流:

  1. 准备训练和验证数据。
  2. 使用 Azure AI Foundry 门户中的“创建自定义模型”向导来训练自定义模型
    1. 选择基础模型
    2. 选择训练数据
    3. (可选)选择验证数据
    4. (可选)为微调作业配置任务参数
    5. 审阅所做的选择并训练新的自定义模型
  3. 检查自定义微调模型的状态。
  4. 部署自定义模型以供使用。
  5. 使用自定义模型。
  6. (可选)分析自定义模型的性能和拟合度。

准备训练和验证数据

训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。

不同的模型类型需要不同格式的训练数据。

你使用的训练和验证数据必须格式化为 JSON 行 (JSONL) 文档。 对于 gpt-35-turbo(所有版本)、gpt-4gpt-4ogpt-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?"}]}

多轮次聊天文件格式 Azure OpenAI

还支持在 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}]}

使用视觉的聊天补全

{"messages": [{"role": "user", "content": [{"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://raw.githubusercontent.com/MicrosoftDocs/azure-ai-docs/main/articles/ai-services/openai/media/how-to/generated-seattle.png"}}]}, {"role": "assistant", "content": "The image appears to be a watercolor painting of a city skyline, featuring tall buildings and a recognizable structure often associated with Seattle, like the Space Needle. The artwork uses soft colors and brushstrokes to create a somewhat abstract and artistic representation of the cityscape."}]}

除 JSONL 格式外,训练和验证数据文件必须以 UTF-8 编码并包含字节顺序标记 (BOM)。 文件大小必须小于 512 MB。

创建训练和验证数据集

训练示例越多越好。 如果没有至少 10 个训练示例,微调作业将无法继续,但如此少的数量不足以显著影响模型响应。 最佳做法是提供数百个(如果不是数千个)训练示例来获得成功。

通常,将数据集大小加倍会促使模型质量呈线性增长。 但请记住,低质量的示例可能会对性能产生负面影响。 如果你根据大量内部数据来训练模型,而不是先修剪数据集以便获得最高质量的示例,则最终可能会得到一个性能比预期差得多的模型。

使用“创建自定义模型”向导

借助 Azure AI Foundry 提供的“创建自定义模型”向导,你能够以交互方式为 Azure 资源创建和训练经过微调的模型。

  1. 打开位于 (https://oai.azure.com/) 的 Azure AI Foundry,然后使用有权访问 Azure OpenAI 资源的凭据登录。 在登录工作流中,选择适当的目录、Azure 订阅和 Azure OpenAI 资源。

  2. 在 Azure AI Foundry 门户中,浏览到“工具”>“微调”窗格,然后选择“微调模型”。

    屏幕截图显示了如何访问 Azure AI Foundry 门户中的“创建自定义模型”向导。

随即将打开“创建自定义模型”向导。

选择基础模型

选择基础模型是创建自定义模型的第一步。 你可通过“基础模型”窗格选择用于自定义模型的基础模型。 所做的选择会影响模型的性能和成本。

从“基础模型类型”下拉列表中选择基础模型,然后选择“下一步”以继续。

可从以下可用基础模型之一创建自定义模型:

  • babbage-002

  • davinci-002

  • gpt-35-turbo (0613)

  • gpt-35-turbo (1106)

  • gpt-35-turbo (0125)

  • gpt-4 (0613)

  • 或者,可以微调以前微调过的模型,格式为 base-model.ft-{jobid}。

具有自定义微调模型的模型选项屏幕截图。

有关可进行优化的基本模型的详细信息,请参阅模型

选择训练数据

下一步是选择已准备好的现有训练数据或上传已准备好的新训练数据,以便在自定义模型时使用。 “训练数据”窗格显示了任何现有的和以前上传的数据集,并提供了用于上传新训练数据的选项。

Azure AI Foundry 门户中“创建自定义模型”向导的“训练数据”窗格屏幕截图。

对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。 有关 Azure Blob 存储的详细信息,请参阅什么是 Azure Blob 存储?

注意

训练数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。

从本地文件上传训练数据

可使用以下方法之一将新的训练数据集从本地文件上传到服务:

  • 将文件拖放到“训练数据”窗格的工作区中,然后选择“上传文件”。

  • 在“训练数据”窗格的工作区中选择“浏览文件”,在“打开”对话框中选择要上传的文件,然后选择“上传文件”。

选择并上传训练数据集后,选择“下一步”继续。

“创建自定义模型”向导的“训练数据”窗格的屏幕截图,其中显示了本地文件选项。

从 Azure Blob 存储导入训练数据

可通过提供文件的名称和位置从 Azure Blob 或其他共享 Web 位置导入训练数据集。

  1. 输入文件的文件名。

  2. 对于“文件位置”,请提供 Azure Blob URL、Azure 存储共享访问签名 (SAS) 或其他指向可访问共享 Web 位置的链接。

  3. 选择“导入”,以将训练数据集导入到服务。

选择并上传训练数据集后,选择“下一步”继续。

“创建自定义模型”向导的“训练数据”窗格的屏幕截图,其中显示了 Azure Blob 和共享 Web 位置选项。

选择验证数据

下一步提供配置模型以在训练过程中使用验证数据的选项。 如果你不想使用验证数据,可以选择“下一步”为模型选择高级选项。 否则,如果你有验证数据集,可以选择已准备好的现有验证数据或上传已准备好的新验证数据,以便在自定义模型时使用。

“验证数据”窗格显示了任何现有的及以前上传的训练和验证数据集,并提供了用于上传新验证数据的选项。

Azure AI Foundry 门户中“创建自定义模型”向导的“验证数据”窗格屏幕截图。

对于大型数据文件,建议从 Azure Blob 存储导入数据。 大型文件在通过多部分表单上传时可能会变得不稳定,因为请求是原子化的,无法重试或继续。

注意

与训练数据文件类似,验证数据文件的格式必须设置为 JSONL 文件,采用 UTF-8 编码并带有字节顺序标记 (BOM)。 文件大小必须小于 512 MB。

从本地文件上传验证数据

可使用以下方法之一将新的验证数据集从本地文件上传到服务:

  • 将文件拖放到“验证数据”窗格的工作区中,然后选择“上传文件”。

  • 在“验证数据”窗格的工作区中选择“浏览文件”,在“打开”对话框中选择要上传的文件,然后选择“上传文件”。

选择并上传验证数据集后,选择“下一步”继续。

“创建自定义模型”向导的“验证数据”窗格的屏幕截图,其中显示了本地文件选项。

从 Azure Blob 存储导入验证数据

可通过提供文件的名称和位置从 Azure Blob 或其他共享 Web 位置导入验证数据集。

  1. 输入文件的文件名。

  2. 对于“文件位置”,请提供 Azure Blob URL、Azure 存储共享访问签名 (SAS) 或其他指向可访问共享 Web 位置的链接。

  3. 选择“导入”,以将训练数据集导入到服务。

选择并上传验证数据集后,选择“下一步”继续。

“创建自定义模型”向导的“验证数据”窗格的屏幕截图,其中显示了 Azure Blob 和共享 Web 位置选项。

配置任务参数

“创建自定义模型”向导在“任务参数”窗格中显示用于训练已微调的模型的参数。 提供了以下参数:

Name 类型 描述
batch_size integer 要用于训练的批大小。 批大小表示用于训练单个前向和后向传递的训练示例的数量。 一般情况下,我们发现较大的批大小往往更适合较大的数据集。 此属性的默认值和最大值特定于基础模型。 批大小越大意味着模型参数的更新频率越低,但方差越小。
learning_rate_multiplier 数字 用于训练的学习率乘数。 微调学习率是用于预训练的原始学习率乘以该值。 较大的学习率通常在较大的批大小中表现更好。 建议试验 0.02 到 0.2 范围内的值,以查看产生最佳结果的值。 较小的学习率可以用于避免过度拟合。
n_epochs integer 训练模型的时期数。 一个时期是指训练数据集的一个完整周期。
seed integer 种子控制作业的可重现性。 传入相同的种子和作业参数应会产生相同的结果,但在极少数情况下可能会有差异。 如果未指定种子,则会为你生成一个种子
Beta integer dpo 损失的温度参数,通常在 0.1 到 0.5 范围内。 这会控制我们对参考模型的关注程度。 beta 越小,我们允许模型偏离参考模型的程度就越大。 随着 beta 变得越来越小,我们将忽略参考模型。

“创建自定义模型”向导的“高级选项”窗格的屏幕截图,其中选择了默认选项。

选择“默认”以便对微调作业使用默认值,或选择“自定义”以显示并编辑超参数值。 选择默认值后,我们会根据训练数据通过算法确定正确的值。

配置高级选项后,选择“下一步”以审阅所做的选择并训练已微调的模型

查看所做的选择并训练模型

向导的“审阅”窗格显示有关配置选项的信息。

Azure AI Foundry 门户中“创建自定义模型”向导的“审阅”窗格屏幕截图。

如果已准备好训练模型,请选择“开始训练作业”,以启动微调作业并返回到“模型”窗格。

检查自定义模型的状态

“模型”窗格在“自定义模型”选项卡中显示有关自定义模型的信息。该选项卡包含有关自定义模型的微调作业的状态和作业 ID 信息。 作业完成后,选项卡会显示结果文件的文件 ID。 可能需要选择“刷新”才能看到模型训练作业的更新状态。

Azure AI Foundry 中的“模型”窗格屏幕截图,其中显示了自定义模型。

启动微调作业后,可能需要一些时间才能完成。 你的作业可能排在系统上的其他作业后面。 训练模型可能需要几分钟或几小时,具体取决于模型和数据集大小。

可在“模型”窗格上执行以下任务:

  • 在“自定义模型”选项卡的“状态”列中检查自定义模型的微调作业的状态。

  • 在“模型名称”列中,选择模型名称以查看有关自定义模型的详细信息。 可以查看微调作业的状态、训练结果、训练事件和作业中使用的超参数。

  • 选择“下载训练文件”以下载用于模型的训练数据。

  • 选择“下载结果”,下载附加到模型微调作业的结果文件,并分析自定义模型的训练和验证性能。

  • 选择“刷新”更新页面信息。

Azure AI Foundry 门户中的“模型”窗格屏幕截图,其中显示了自定义模型。

检查点

每个训练纪元完成时,都会生成一个检查点。 检查点是模型的完全功能版本,可以将其部署并用作后续微调作业的目标模型。 检查点特别有用,因为它们可以提供过度拟合发生之前模型的快照。 当微调作业完成时,你将拥有可供部署的三个最新版本的模型。

安全评估 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 AI Foundry 门户中部署自定义模型。

此时会打开“部署模型”对话框。 在该对话框中,输入部署名称,然后选择“创建”,开始部署自定义模型。

Azure AI Foundry 门户中的“部署模型”对话框屏幕截图。

可在 Azure AI Foundry 门户的“部署”窗格中监视部署进度

跨区域部署

微调支持将微调后的模型部署到与模型最初进行微调时所在的区域不同的区域。 还可以部署到其他订阅/区域。

唯一的限制是新区域还必须支持微调,并且在部署交叉订阅时为部署生成授权令牌的帐户必须有权访问源订阅和目标订阅。

跨订阅/区域部署可以通过 PythonREST 完成。

使用已部署的自定义模型

部署自定义模型后,可像使用任何其他已部署的模型一样使用它。 可使用 Azure AI Foundry 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperaturemax_tokens,就像对其他已部署的模型一样。 对于微调的 babbage-002davinci-002 模型,将使用“补全”操场和补全 API。 对于微调的 gpt-35-turbo-0613 模型,将使用“聊天”操场和聊天补全 API。

Azure AI Foundry 门户中的“操场”窗格屏幕截图,其中突出显示了某些部分。

分析自定义模型

完成每个微调作业后,Azure OpenAI 会将一个名为 results.csv 的结果文件附加到该作业。 可以使用该结果文件来分析自定义模型的训练和验证性能。 在 Azure AI Foundry 的“模型”窗格的“结果文件 ID”列中,列出了每个自定义模型的结果文件的文件 ID。 可以使用文件 ID 从 Azure AI Foundry 的“数据文件”窗格中标识和下载结果文件。

结果文件是一个 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 Foundry 门户中以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到三个图表:损失、平均令牌准确度和令牌准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。

随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。

清理部署、自定义模型和训练文件

处理完自定义模型后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。

删除模型部署

重要

在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。

删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。

可以在 Azure AI Foundry 门户的“部署”窗格中删除自定义模型的部署。 选择要删除的部署,然后选择“删除”以删除部署。

删除自定义模型

可以在 Azure AI Foundry 门户的“模型”窗格中删除自定义模型。 在“自定义模型”选项卡中选择要删除的自定义模型,然后选择“删除”以删除该自定义模型。

注意

如果自定义模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除自定义模型。

删除训练文件

可以选择在 Azure AI Foundry 门户的“管理”>“数据文件”窗格中删除为进行训练上传的训练和验证文件,以及在训练期间生成的结果文件。 选择要删除的文件,然后选择“删除”以删除该文件。

持续微调

创建微调模型后,你可能希望在一段时间内通过进一步微调继续完善模型。 持续微调是选择已经微调的模型作为基础模型并在新的训练示例集上进一步对其进行微调的迭代过程。

若要对之前微调过的模型执行微调,可以使用创建自定义模型中所述的流程,但无需指定通用基础模型的名称,而只需指定已微调的模型。 自定义微调模型将类似于 gpt-35-turbo-0613.ft-5fd1918ee65d4cd38a5dcf6835066ed7

“创建自定义模型 UI”的屏幕截图,其中突出显示了微调模型。

我们还建议添加 suffix 参数,以便更轻松地区分已微调模型的不同迭代。 suffix 接受一个字符串,并设置为标识已微调的模型。 OpenAI Python API 支持最多 18 个字符的字符串,该字符串将添加到已微调的模型名称中。

先决条件

模型

以下模型支持微调:

  • 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 配合使用的微调工作流:

  1. 准备训练和验证数据。
  2. 选择基础模型。
  3. 上传训练数据。
  4. 训练新的自定义模型。
  5. 检查自定义模型的状态。
  6. 部署自定义模型以供使用。
  7. 使用自定义模型。
  8. (可选)分析自定义模型的性能和拟合度。

准备训练和验证数据

训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。

不同的模型类型需要不同格式的训练数据。

你使用的训练和验证数据必须格式化为 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}]}

使用视觉的聊天补全

{"messages": [{"role": "user", "content": [{"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://raw.githubusercontent.com/MicrosoftDocs/azure-ai-docs/main/articles/ai-services/openai/media/how-to/generated-seattle.png"}}]}, {"role": "assistant", "content": "The image appears to be a watercolor painting of a city skyline, featuring tall buildings and a recognizable structure often associated with Seattle, like the Space Needle. The artwork uses soft colors and brushstrokes to create a somewhat abstract and artistic representation of the cityscape."}]}

除 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 FoundryAzure 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 Foundry 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperaturemax_tokens,就像对其他已部署的模型一样。 对于微调的 babbage-002davinci-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 Foundry 门户中以绘图形式查看 results.csv 文件中的数据。 选择已训练模型的链接,你将看到三个图表:损失、平均令牌准确度和令牌准确度。 如果你提供了验证数据,则这两个数据集将显示在同一绘图上。

随着时间的推移,损失会减少,而准确度提高。 如果训练和验证数据之间存在分歧,这可能表明过度拟合。 请尝试使用更少的循环次数或较小的学习速率乘数进行训练。

清理部署、自定义模型和训练文件

处理完自定义模型后,可以删除部署和模型。 如果需要,还可以删除已上传到服务的训练和验证文件。

删除模型部署

重要

在你部署自定义模型之后,如果部署处于非活动状态的时间超过十五 (15) 天,则会删除部署。 如果模型是在超过十五 (15) 天前部署的且在连续 15 天内无补全或聊天补全调用,则自定义模型的部署处于非活动状态。

删除非活动状态的部署时,不会删除或影响基础自定义模型,并且可以随时重新部署自定义模型。 如 Azure OpenAI 服务定价中所述,部署的每个自定义(微调)模型都会产生每小时的托管成本,无论是否对模型进行补全或聊天补全调用,都是如此。 要详细了解如何使用 Azure OpenAI 规划和管理成本,请参阅计划管理 Azure OpenAI 服务的成本中的指南。

可以使用各种方法来删除自定义模型的部署:

删除自定义模型

同样,可以使用各种方法删除自定义模型:

注意

如果自定义模型具有现有部署,则无法删除它。 必须先删除模型部署,然后才能删除自定义模型。

删除训练文件

可以选择性地在 Azure OpenAI 订阅中删除为训练上传的训练和验证文件,以及在训练期间生成的结果文件。 可使用以下方法删除训练、验证和结果文件:

以下 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 Foundry 的“模型”页面中查找此信息,也可以使用 REST API 为给定 Azure OpenAI 资源生成模型列表

先决条件

模型

以下模型支持微调:

  • 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 配合使用的微调工作流:

  1. 准备训练和验证数据。
  2. 选择基础模型。
  3. 上传训练数据。
  4. 训练新的自定义模型。
  5. 检查自定义模型的状态。
  6. 部署自定义模型以供使用。
  7. 使用自定义模型。
  8. (可选)分析自定义模型的性能和拟合度。

准备训练和验证数据

训练数据和验证数据集由输入和输出示例组成,这些示例表示你希望模型如何执行。

不同的模型类型需要不同格式的训练数据。

你使用的训练和验证数据必须格式化为 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}]}

使用视觉的聊天补全

{"messages": [{"role": "user", "content": [{"type": "text", "text": "What's in this image?"}, {"type": "image_url", "image_url": {"url": "https://raw.githubusercontent.com/MicrosoftDocs/azure-ai-docs/main/articles/ai-services/openai/media/how-to/generated-seattle.png"}}]}, {"role": "assistant", "content": "The image appears to be a watercolor painting of a city skyline, featuring tall buildings and a recognizable structure often associated with Seattle, like the Space Needle. The artwork uses soft colors and brushstrokes to create a somewhat abstract and artistic representation of the cityscape."}]}

除 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 Foundry 中的“操场”来试验新部署。 可以继续对自定义模型使用相同的参数,例如 temperaturemax_tokens,就像对其他已部署的模型一样。 对于微调的 babbage-002davinci-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 Foundry 门户中以绘图形式查看 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 Foundry 的“模型”页面中查找此信息,也可以使用 REST API 为给定 Azure OpenAI 资源生成模型列表

全球标准

对于以下版本,Azure OpenAI 微调在“美国东部 2”、“美国中北部”和“瑞典中部”支持全球标准部署

  • gpt-4o-2024-08-06
  • gpt-4o-mini-2024-07-18

全球标准微调部署提供成本节省,但自定义模型权重可能会暂时存储于 Azure OpenAI 资源所在的地理位置之外。

使用微调模型的“全球标准”部署用户体验的屏幕截图。

“全球标准”微调部署目前不支持视觉和结构化输出。

视觉微调

还可以对 JSONL 文件中的图像进行微调。 正如你可以向聊天补全发送一个或多个图像输入一样,也可以在训练数据中包含这些相同的消息类型。 可以将图像提供为可公开访问的 URL 或包含 base64 编码图像的数据 URI。

图像数据集要求

  • 训练文件最多可以包含 50,000 个包含图像的示例(不包括文本示例)。
  • 每个示例最多可以包含 64 个图像。
  • 每个图像最大可以为 10 MB。

Format

图像必须是:

  • JPEG
  • PNG
  • WEBP

图像必须处于 RGB 或 RGBA 图像模式。

不能包含作为带有助手角色的消息的输出的图像。

内容审核政策

在训练之前,我们会扫描你的图像,以确保它们符合我们的使用策略透明度说明。 在微调开始之前,这可能会导致文件验证延迟。

包含以下内容的图像将从数据集中排除,不会用于训练:

  • People
  • CAPTCHA

重要

对于视觉微调人脸筛选过程:我们会筛选人脸/人,以在训练模型时跳过这些图像。 筛选功能利用人脸检测,而不进行人脸识别,这意味着我们不会创建面部模板或测量特定的面部几何图形,用于筛查人脸的技术无法唯一地识别个人。 若要详细了解人脸的数据和隐私,请参阅 - 人脸的数据和隐私 - Azure AI 服务 | Microsoft Learn

提示缓存

Azure OpenAI 微调对一组精选的模型支持提示缓存。 通过使用提示缓存,可以减少提示开头具有相同内容的较长提示的总体请求延迟和成本。 若要了解有关提示缓存的详细信息,请参阅提示缓存入门

直接偏好优化 (DPO)(预览版)

直接偏好优化 (DPO) 是一种针对大型语言模型的对齐技术,用于根据人类偏好调整模型权重。 它与人类反馈强化学习 (RLHF) 的不同之处在于,它不需要拟合奖励模型,而是使用更简单的二元数据偏好进行训练。 它在计算上比 RLHF 更轻、更快,同时在对齐方面同样有效。

为什么 DPO 有用?

在没有明确的正确答案且语气、风格或特定内容偏好等主观元素很重要的情况下,DPO 特别有用。 这种方法还使模型能够从正面示例(被认为是正确或理想的)和负面示例(不太理想或不正确的)中学习。

DPO 被认为是一种可以让客户更轻松地生成高质量训练数据集的技术。 虽然许多客户很难生成足够大的数据集来进行监督式微调,但他们通常已经根据用户日志、A/B 测试或较少量的手动注释工作收集了偏好数据。

直接偏好优化数据集格式

直接偏好优化文件的格式与监督式微调不同。 客户提供包含系统消息和初始用户消息的“对话”,然后提供带有配对偏好数据的“补全”。 用户只能提供两个补全。

三个顶级字段:inputpreferred_outputnon_preferred_output

  • preferred_output/non_preferred_output 中的每个元素都必须至少包含一条助手消息
  • preferred_output/non_preferred_output 中的每个元素都只能具有 (assistant, tool) 中的角色
{  
  "input": {  
    "messages": {"role": "system", "content": ...},  
    "tools": [...],  
    "parallel_tool_calls": true  
  },  
  "preferred_output": [{"role": "assistant", "content": ...}],  
  "non_preferred_output": [{"role": "assistant", "content": ...}]  
}  

训练数据集必须采用 jsonl 格式:

{{"input": {"messages": [{"role": "system", "content": "You are a chatbot assistant. Given a user question with multiple choice answers, provide the correct answer."}, {"role": "user", "content": "Question: Janette conducts an investigation to see which foods make her feel more fatigued. She eats one of four different foods each day at the same time for four days and then records how she feels. She asks her friend Carmen to do the same investigation to see if she gets similar results. Which would make the investigation most difficult to replicate? Answer choices: A: measuring the amount of fatigue, B: making sure the same foods are eaten, C: recording observations in the same chart, D: making sure the foods are at the same temperature"}]}, "preferred_output": [{"role": "assistant", "content": "A: Measuring The Amount Of Fatigue"}], "non_preferred_output": [{"role": "assistant", "content": "D: making sure the foods are at the same temperature"}]}
}

直接偏好优化模型支持

  • gpt-4o-2024-08-06 在其各自的微调区域中支持直接偏好优化。 模型页中更新了最新的区域可用性

用户可以对基础模型以及已经使用监督式微调进行微调的模型进行偏好微调,只要它们属于受支持的模型/版本即可。

如何使用直接偏好优化微调?

偏好优化微调步骤的 GIF。

  1. 偏好格式准备 jsonl 数据集。
  2. 选择模型,然后选择自定义的方法“直接偏好优化”
  3. 上传数据集 – 训练和验证。 根据需要进行预览。
  4. 选择超参数,建议使用默认值进行初始试验。
  5. 查看选择并创建微调作业。

故障排除

如何启用微调?

为了成功获取微调功能,你需要分配有 Azure 认知服务 OpenAI 参与者角色。 即使是具有高级服务管理员权限的人员也需要显式设置此帐户才能访问微调。 有关详细信息,请查看基于角色的访问控制指南

为什么我上传失败?

如果 Azure OpenAI Studio 中的文件上传失败,可以在 Azure OpenAI Studio 中的“数据文件”下查看错误消息。 将鼠标悬停在显示“错误”(状态列下)的位置,将显示关于失败的说明。

微调错误消息的屏幕截图。

我微调后的模型似乎没有改进

  • 缺少系统消息:微调时需要提供系统消息;使用微调后的模型时,需要提供相同的系统消息。 如果提供不同的系统消息,你看到的结果可能会与微调后的结果不同。

  • 数据不足:虽然运行管道的最小数量是 10,但需要数百到数千个数据点来教授模型一项新技能。 数据点过少可能会导致过度拟合和泛化性能不佳。 微调后的模型可能在训练数据上表现良好,但在其他数据上表现不佳,因为它记住了训练示例而不是学习模式。 为了获得最佳结果,请计划准备包含数百个或数千个数据点的数据集。

  • 错误的数据:策展不当或不具有代表性的数据集将生成低质量模型。 模型可能会从数据集中学习不准确或有偏差的模式。 例如,如果你正在训练一个用于客户服务的聊天机器人,但仅提供一种场景(例如商品退货)的训练数据,它将不知道如何响应其他场景。 或者,如果训练数据不正确(包含不正确的响应),模型将学习提供不正确的结果。

使用视觉的微调

如果跳过了图像该怎么办

由于以下原因,可能会跳过图像:

  • 包含 CAPTCHA
  • 包含人
  • 包含人脸

移除图像。 目前,无法微调包含这些实体的图像的模型。

常见问题

问题 原因/解决方案
图像被跳过 由于以下原因,可能会跳过图像:包含 CAPTCHA、人或人脸。

移除图像。 目前,无法微调包含这些实体的图像的模型。
URL 无法访问 检查图像 URL 是否可公开访问。
图像太大 检查图像是否符合数据集大小限制。
图像格式无效 检查图像是否符合我们的数据集格式。

如何上传大型文件

训练文件可能会很大。 可以使用上传 API(而不是文件 API,它仅允许上传最大 512 MB 的文件)上传最大 8 GB 的文件(分为多个部分)。

降低训练成本

如果将图像的细节参数设置为低,则图像的大小将调整为 512 x 512 像素,并且仅由 85 个标记表示,而不论其大小如何。 这将降低训练成本。

{ 

    "type": "image_url", 

    "image_url": { 

        "url": "https://raw.githubusercontent.com/MicrosoftDocs/azure-ai-docs/main/articles/ai-services/openai/media/how-to/generated-seattle.png", 

        "detail": "low" 

    } 

} 

视觉微调的其他注意事项

若要控制图像理解的保真度,请将每个图像的细节参数 image_url 设置为 lowhighauto。 这也会影响模型在训练期间看到的每个图像的标记数,并会影响训练成本。

后续步骤