继我们最近更新Azure OpenAI (AOAI) 服务的新特性和功能之后,本博客重点介绍函数调用的微调。我们将深入探讨函数调用的微调如何工作(当您可能想要使用它时),并提供使用股票价格数据的深入案例研究。
在这篇博客中,我们将讨论……
- Azure OpenAI 服务中的函数调用是什么
- 微调与函数调用有什么关系
- 用例:通过调用股票价格的函数进行微调
- 函数调用的最佳实践
Azure OpenAI 中的函数调用是什么?
函数调用是指定义和描述对外部应用程序编程接口(API)的调用的能力。通过函数调用,您可以根据提示提供的上下文,指示您的语言模型在适当的时候使用这些 API。此功能允许 LLM 与外部服务交互、访问其他数据源或执行超出其内置功能的特定任务,从而扩展了 LLM 的能力。
在 AOAI 上,最新版本的 Open AI 的 gpt-35-turbo 和 gpt-4 现在支持函数调用。当请求函数时,模型会评估上下文来决定是否应使用任何函数,并提供包含函数详细信息的 JSON 对象。它还允许并行函数调用、同时执行任务并减少 API 请求数量以获得更好的性能。
函数调用的典型应用场景包括:
- 创建 能够通过外部 API 调用回答查询的助手
- 将自然语言请求转换为 API 交互
- 从测试输入中解析结构化数据
请注意,函数调用会根据需要触发 API 调用,但不会直接执行。相反,您的应用程序会处理调用并将响应返回到语言模型。这种方法使您能够管理外部调用,确保控制应用程序的交互。
微调与函数调用有什么关系?
通过函数调用进行微调可以教会您的模型如何以及何时调用外部 API。 gpt-35-turbo (0613) 和较新的模型支持训练数据和推理中的函数调用。所以,现在定制模型和基础模型都可以调用外部API。通过函数调用进行微调有很多好处。以下列出了一些重要的好处:
- 新技能:教您的模型何时进行函数调用,或者如何处理结果。
- 节省成本:缩短函数调用的描述和签名,以减少提示长度。微调提供了简化令牌使用的机会,在处理大量详细函数时特别有用。通过利用微调技术,实现资源效率更高、优化的模型。
- 增强的准确性、可靠性和响应能力:提高模型输出的精度和可靠性。微调使模型能够产生更准确和一致的结果,特别是在动态场景中,从而增强对系统功能的信心。
目前,gpt-35-turbo (0613) 和 gpt-35-turbo-16k (1106) 型号可通过函数调用进行微调。通过对函数调用的支持,您可以将函数合并到训练数据中,并让微调后的模型进行函数调用。
除了数据集之外,微调和函数调用的体验与训练任何其他模型进行微调的体验相同。请参阅文档了解更多详细信息。
案例研究:通过调用股票价格的函数进行微调
为了演示使用微调模型进行函数调用的实用性,让我们使用一个实际问题作为案例研究。我们希望构建一个聊天机器人,可以从外部 API 检索股票价格,以响应用户查询。仅使用基本模型,我们就发现了两个挑战:(1)该模型在区分真公司和假公司方面表现不佳,(2)我们的函数调用定义非常长,并且每个提示的令牌都急剧增加。
我们将探索如何通过函数调用进行微调来提高模型的准确性和性能。对于每个场景,我们将构建一个训练数据集,将微调模型与基本模型进行比较,并衡量微调的改进。
一旦我们创建了满足我们需求的微调模型,我们将通过开发一个基本应用程序将其整合在一起,该应用程序允许用户检查不同公司的股票价格。我们将使用 YFinance Python 库来轻松检索当前股票价格。
场景一:幻觉
大型语言模型的一个常见问题是幻觉——提供看似合理但错误的响应。对于函数调用,当模型在错误的上下文中调用函数或为函数调用提供错误的信息时,可能会发生幻觉。
我们评估了基本模型是否能够正确识别虚假公司并做出适当的反应,而不是试图报价股票价格。我们的测试数据集由 10 个样本组成,其中包括 5 个假公司和 5 个真实公司。尽管我们提供了明确的系统消息,不要做出假设(如果未找到确切的股票代码,则要求澄清),但基本模型仍难以准确地区分假公司和真公司。请参阅下面的示例,其中基础模型为 Titan Robotics 生成了一个假符号并输出一个函数。
使用基本模型进行推理 – gpt-35-turbo (0613)
{“role”: “user”, “content”: “泰坦机器人公司股票上周五的收盘价是多少”},
我们需要教导模型何时进行函数调用以及何时拒绝。微调来救援!
为了解决幻觉并提高准确性,我们创建了一个具有函数调用功能的训练数据集。该数据集的每一行都包含与库存函数配对的多组“消息”(来自用户、系统和助理角色)。我们包含了虚假公司的示例,并提供了适当的响应,因此我们可以教我们的模型如何识别和响应这些虚假请求。我们的数据集由 96 个样本组成。
我们使用不同超参数的组合训练了 gpt-35-turbo (0613) 模型,并使用相同的测试数据集对其进行了评估。虽然我们的基本模型在区分真假公司方面表现不佳,但我们的微调模型可以智能地识别无效的公司条目。请参阅 Titan Robotics 示例以供参考。
下表说明了测试数据集评估的结果。它清楚地展示了微调如何识别幻觉并提供更准确、更可靠的结果。
测试数据集 | 基础型号GPT-35-涡轮 (0613) | 微调模型gpt-35-turbo (0613) 微调 |
真实公司 | 5/5 的示例检测正确 | 5/5 的示例检测正确 |
假公司 | 0/5 个示例被正确检测 | 4/5 个示例检测正确 |
整体准确度 | 50% | 90% |
幻觉准确度 | 0% | 80% |
虽然微调模型并不完美,但它明显优于基本模型。根据您的使用案例以及对准确性的需求,您可以选择使用更多数据进行微调以获得更好的性能。
场景二:代币优化
系统消息中包含的功能直接影响令牌的使用。随着功能数量的增加,系统消息中的令牌数量也会增加,从而导致冗长的提示并增加成本。微调可让您通过以下方式缩短函数调用:
- 通过从函数和参数中删除描述字段来省略函数和参数描述。
- 通过从参数对象中删除属性字段来完全省略参数(将属性字段保留为空字典)。
- 通过从函数数组中删除整个函数对象来排除函数。
如果没有微调,如果没有这些附加信息,模型可能很难正确使用该函数,但是通过微调,您可以向模型显示何时调用该函数,而无需在提示中解释太多。
在我们的两个 Stock 函数中,通过从函数和参数中删除描述字段,并从每个函数的参数对象中删除属性字段(保留属性字段,但使用空字典),我们实现了 55% 的标记减少。功能。以下是更新、缩短的函数。
为了启动我们的测试过程,我们首先建立一个基线。我们将分三个阶段进行:
- 最初,我们将使用详细函数定义(完整函数)通过基本模型 gpt-35-turbo (0613) 进行推理来评估我们的测试数据集。
- 在第二阶段,我们将检查具有缩短功能的基本模型 gpt-35-turbo (0613) 的性能。
- 最后,在第三阶段,我们将使用缩短的函数定义来评估微调模型。
让我们从建立基本模型和完整详细函数作为我们的基线开始。基础模型 gpt-35-turbo (0613) 在我们的测试数据集上表现出 100% 的准确性,表明它在提供完整提示时能够生成正确的函数。然而,当我们在保持基本模型不变的情况下过渡到缩短的函数时,它的准确度为 0%,无法正确检测任何样本,并在所有 10 个样本中提供空参数。
{“role”: “user”, “content”: “Uber 目前的价格是多少?”}
{“role”: “user”, “content”: “沃尔玛股票上季度达到的最高价格是多少?”}
为了研究微调是否可以解决这个问题,我们构建了一个包含 100 个样本的数据集,其中包含两个缩短的股票函数。我们尝试了系统消息和超参数的各种组合,以提高微调过程的准确性。最后,我们成功地微调了一个模型,在使用我们的缩短函数时,该模型在测试数据集上实现了 100% 的准确率。有关更多详细信息,请参阅下表摘要和微调模型的输出。
{“role”: “user”, “content”: “Uber 目前的价格是多少?”}
{“role”: “user”, “content”: “沃尔玛股票上季度达到的最高价格是多少?”}
基本模型+详细 | 基础型号+短款 | FT模型 | |
准确性 | 100% | 0% | 100% |
代币数量 | 230 | 108 | 108 |
计算总拥有成本:较短的提示是否可以省钱?
当考虑使用缩短的函数进行微调和使用具有完整详细函数的基本模型之间的成本权衡时,必须评估请求数量和相关成本等因素。由于长度原因,基本模型的每次提示成本较高,但通过微调,我们支付代币和托管模型的费用。对于我们的库存用例,下图比较了微调与基本模型的成本:每天有很多请求,微调比基本模型便宜!
连接起来:在 e2e 应用程序中使用我们微调的函数调用模型
函数调用仅创建对外部 API 的调用,而不执行它。要实际执行请求,您需要从 LLM 响应中提取函数名称和参数,并继续使用这些参数调用函数。该函数的输出采用 JSON 格式,然后传递回 gpt-35-turbo 以为用户生成适当的结果消息。
函数调用的最佳实践:
尽管我们可能让它看起来很简单,但获得有效且比基本模型更好的高质量示例需要大量的迭代和实验。我们运行了许多试验模型,以确定每个用例的最佳性能模型。根据我们的经验,有一些建议:
- 充足的训练示例:虽然微调只需 10 个示例即可运行,但建议提供至少 100 个高质量训练示例,以获得最佳性能。许多用例需要数千个示例!您还可以使用更多示例重新训练之前微调的模型。
- 一致的函数定义:保持训练和推理之间函数定义的一致性,以保证响应准确可靠。
- 探索不同的参数组合:虽然我们提供默认参数,但您应该尝试一系列参数以提高性能。您可能需要调整学习率乘数和纪元数。
- 细化函数定义:增强函数定义的清晰度和独特性。清晰且定义明确的功能为提高准确性奠定了基础。在我们的库存用例中,系统消息中清晰详细的说明显着提高了基础模型和微调模型的性能。
部署应用程序时,请考虑
- 令牌管理:注意令牌的使用,如果需要,探索策略,例如省略描述或整个功能以保持在令牌限制内。
- 现实世界影响评估:在语言模型中使用函数调用时,通过验证函数调用、使用可信数据源并遵循最小权限原则来确保负责任的使用。
- 用户确认步骤:考虑现实世界的影响,并针对具有增强控制和安全性后果的操作实施用户确认步骤。
参考资料:
good