Azure OpenAI 精要(一)
原文:
annas-archive.org/md5/9abfdbcdb0ce520c427f6f94336e2401译者:飞龙
前言
在过去的十年里,我有幸参与了一些颠覆性的技术项目,这些技术正在重新定义企业的运营和创新方式。其中,生成式人工智能(GenAI)作为一种突破性进展,能够以前所未有的速度重塑各个行业。围绕 GenAI 的兴奋之情是显而易见的,全球各地的组织都在竞相理解它的潜力,并有效地加以应用。然而,对于许多人来说,从好奇心到实际实施的旅程充满了复杂性和不确定性。
在我们在微软的职业旅程中,我们与各种团队合作,从小型企业到财富 500 强医疗公司,探索并部署 AI 驱动的解决方案。这段经历揭示了一个反复出现的主题:尽管 GenAI 的潜力巨大,但在将概念理解与实际应用之间架起桥梁方面存在着显著的知识差距。组织往往难以在这个快速发展的领域中找到方向,迫切寻求可行的洞察力,以将愿景转化为现实。
本书正是我们试图弥补这一知识空白。它是一本全面指南,介绍 Azure OpenAI 这一 GenAI 领域领先平台,融合了基础知识和实践技巧。无论你是开发者、数据科学家还是决策者,本书都旨在帮助你了解 Azure OpenAI 的潜力,将其融入工作流,并充分发挥其能力。
本书将带你从生成式 AI 和大型语言模型(LLMs)的基础知识开始,一直到操作化、隐私、安全性和提示工程等高级话题。书中穿插了实际案例和逐步指南,确保你不仅能获得理论知识,还能掌握实际技能,有效地实施 Azure OpenAI 解决方案。
这个领域的一个独特之处是它的快速发展。在写这本书的过程中,我目睹了新技术在几周内迅速涌现,迫使我们不断更新内容以反映最前沿的技术。尽管如此,GenAI 和 LLMs 的核心原理仍然至关重要,它们构成了下一波创新的基础。
本书中的示例和用例主要利用 Azure OpenAI,考虑到其企业级功能以及与 Azure 服务的无缝集成。然而,书中的概念和技巧同样适用于其他平台,确保无论你选择哪个提供商都能具有实际意义。实现示例使用 Python,提供了一种简单而强大的方式与 AI 模型进行交互。
欢迎加入探索 Azure OpenAI Essentials 的旅程。本书旨在赋予你知识和信心,帮助你在项目中利用 GenAI 的强大功能。希望本书既能成为你的灵感来源,又能作为实践资源,助你迈向这个变革性的领域。
让我们一起建设未来!
本书适用人群
本书面向希望利用 Azure OpenAI 实现实际应用的专业人士和爱好者,无论其技术背景如何。它适用于开发人员、数据科学家、AI 工程师和 IT 决策者,帮助他们将 GenAI 集成到工作流或商业战略中。尽管对编程概念,尤其是 Python,具有基本理解将有益,但本书提供了清晰的解释和实践示例,以支持初学者。此外,商业领导者和非技术人员将从概念性概述和实际应用案例中受益,这有助于弥合技术与现实世界影响之间的鸿沟。无论你是首次探索 GenAI,还是希望深入提升自己的专业知识,本书都提供了一种结构化且易于理解的方式来掌握 Azure OpenAI。
本书内容涵盖
第一章,大语言模型简介,介绍了 LLM 的基础概念,包括其架构、关键示例如 ChatGPT,以及它们对商业和日常生活的变革性影响。还涵盖了基础模型的概念,并探讨了 LLM 在解决复杂问题中的各种实际应用。
第二章,Azure OpenAI 基础,深入介绍了 Azure OpenAI 服务。本章探讨了微软与 OpenAI 的合作关系、可用的模型类型、如何部署这些模型以及定价结构。本章将使你具备有效访问、创建和使用 Azure OpenAI 资源的知识。
第三章,Azure OpenAI 高级主题,介绍了 Azure OpenAI 的高级功能,如理解上下文窗口、不同的嵌入模型以及集成向量数据库。本章还探索了前沿特性,如 Azure OpenAI On Your Data、多模态模型、功能调用、助理 API、批处理 API 和微调,帮助你构建复杂的 AI 应用。
第四章,开发企业文档问答解决方案,解释了如何设计和构建查询非结构化企业文档的解决方案。主要内容包括嵌入概念、利用 Azure Cognitive Search,以及将 Azure OpenAI 与 LangChain 和 Semantic Kernel 集成。
第五章,构建联络中心分析解决方案,解释了如何使用 Azure OpenAI 和 Azure Communication Services 开发联络中心分析平台。本章涵盖了识别挑战、理解技术需求、设计架构以及实施解决方案以增强客户互动。
第六章,从结构化数据库查询数据,探索 SQL GPT,这是一种通过自然语言简化查询结构化数据的工具。本章还展示了架构设计和创建便于访问数据库洞察的用户界面,帮助各类专业背景的用户。
第七章,代码生成与文档编写,探讨了 Azure OpenAI 如何帮助学习者和专业人士生成和解释代码。本章还重点介绍了构建生成代码片段和文档的工具,使编程更加便捷和高效。
第八章,使用 Azure OpenAI 创建基础推荐系统,讲解了如何构建一个由聊天机器人驱动的个性化推荐系统,如电影或产品推荐。本章还将引导您设计和实施一种解决方案,以提升用户体验。
第九章,将文本转化为视频,揭示了如何利用 Azure OpenAI 和 Azure Cognitive Services 将文本提示转换为视频。您将学习架构设计、从文本生成图像,并整合音频,创建教育或宣传视频。
第十章,使用 Azure OpenAI 助理 API 创建多模态多代理框架,探讨了如何构建一个系统,其中多个智能代理共同协作完成任务,如图像生成和优化。本章还涉及多代理框架,展示了其在生成 AI(GenAI)应用中的潜力。
第十一章,隐私与安全,聚焦于通过强大的隐私和安全措施保护您的 Azure OpenAI 应用。主题包括遵守 Azure OpenAI 服务标准、确保数据隐私、利用内容过滤以及实施托管身份认证。此外,还深入探讨了配置虚拟网络、私有端点、数据加密,以及采用负责任的 AI 实践以确保安全和道德的 AI 使用。
第十二章,将 Azure OpenAI 转化为实际应用,讲解如何有效部署、管理和扩展 Azure OpenAI 服务。内容涵盖了基本的操作实践,如日志记录和监控、了解服务配额和限制、管理配额、配置吞吐量单元,以及实施可扩展的策略,以高效应对日益增长的工作负载。
第十三章,高级提示工程,探讨了掌握提示工程的艺术,以优化 AI 响应的行为和质量。本章深入探讨了有效提示的元素和策略,比较了提示工程与微调的区别,并介绍了提高大语言模型准确性的技术。它还讨论了重要的注意事项,如缓解提示注入攻击和调整 AI 输出以满足特定要求。
为了从本书中获得最大收益
为了充分利用本书,你应该安装或准备好以下前提条件:
-
笔记本电脑或电脑:需要一台运行 Windows、Linux 或 macOS 的设备来设置工具并跟随示例和练习。
-
Python 3.9、3.10 或 3.11:兼容的 Python 版本对运行书中提供的各种脚本和示例至关重要。你可以从
www.python.org/downloads下载所需版本。 -
Azure 开发者 CLI (azd):Azure 开发者 CLI 通过提供模板、工具和最佳实践,简化了云原生应用程序开发。按照
learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd?tabs=winget-windows%2Cbrew-mac%2Cscript-linux&pivots=os-windows上的说明进行安装。 -
Node.js 14 或更高版本:Node.js 是处理某些后端操作和运行示例中使用的工具所必需的。确保你已经安装了 14 或更高版本,可以从
nodejs.org/en/download下载。 -
Git:Git 是版本控制和管理源代码仓库所必需的工具。你可以从
git-scm.com/downloads下载安装 Git。 -
PowerShell 7 或更高版本 (pwsh):PowerShell 用于运行脚本并自动化与 Azure 环境相关的任务。你可以在
github.com/powershell/powershell下载最新版本。 -
Azure 账户:需要一个 Azure 账户才能探索书中讨论的基于云的示例和服务。如果你是 Azure 新手,可以注册一个免费账户并获得初始积分来开始使用。
-
具有 Azure OpenAI 服务访问权限的 Azure 订阅:为了使用 Azure OpenAI 示例,请确保你的 Azure 订阅已启用访问权限。你可以通过提交
learn.microsoft.com/en-in/legal/cognitive-services/openai/limited-access上的表单来申请访问权限。
这些前提条件将确保你具备必要的工具和环境,以有效跟随内容并实现动手练习。
如果您使用的是本书的电子版,建议您自己输入代码,或者从本书的 GitHub 仓库获取代码(链接在下一节中提供)。这样做可以帮助您避免与复制和粘贴代码相关的潜在错误。
下载示例代码文件
您可以从 GitHub 下载本书的示例代码文件,链接是 github.com/PacktPublishing/Azure-OpenAI-Essentials。如果代码有更新,它将会在 GitHub 仓库中同步更新。
我们还有其他代码包,您可以在我们的丰富书籍和视频目录中找到,网址是 github.com/PacktPublishing/。快去看看吧!
使用的约定
本书中使用了许多文本约定。
文本中的代码:表示文本中的代码单词、数据库表名、文件夹名、文件名、文件扩展名、路径名、虚拟 URL、用户输入和 Twitter 账号。例如:“每个消息对象由一个 role 类型(可以是 system、user 或 assistant)和 content 组成。”
代码块如下所示:
} response = openai.ChatCompletion.create(
engine="gpt-35-turbo",
messages=
{"role": "system", "content": "You are a helpful assistant that helps people find information"},
当我们希望引起您对代码块中特定部分的注意时,相关的行或项目将以粗体显示:
The final match of the ICC World Cup 2011 was played at the Wankhede Stadium in Mumbai, India.
任何命令行输入或输出如下所示:
!pip install -r requirements.txt
粗体:表示新术语、重要词汇或屏幕上显示的词语。例如,菜单或对话框中的词汇通常以粗体显示。示例:“一旦新资源可用,Azure 门户将通知您。点击转到资源以访问新创建的资源。”
提示或重要说明
以这样的形式出现。
联系我们
我们始终欢迎读者的反馈。
一般反馈:如果您对本书的任何内容有疑问,请通过电子邮件联系我们,邮箱地址是 [customercare@packtpub.com,并在邮件主题中注明书名。
勘误:虽然我们已尽最大努力确保内容的准确性,但错误难免。如果您在本书中发现错误,我们将非常感激您向我们报告。请访问 www.packtpub.com/support/err… 并填写表格。
盗版:如果您在互联网上发现我们作品的任何非法复制版本,请提供该网址或网站名称,我们将不胜感激。请通过 copyright@packt.com 联系我们,并提供链接。
如果您有兴趣成为作者:如果您在某个领域具有专业知识,并且有兴趣编写或贡献一本书,请访问 authors.packtpub.com。
分享您的想法
一旦您阅读完Azure OpenAI Essentials,我们非常希望听到您的反馈!请点击这里直接进入亚马逊评论页面并分享您的想法。
您的评价对我们以及技术社区非常重要,将帮助我们确保提供优质的内容。
下载本书的免费 PDF 副本
感谢您购买本书!
喜欢随时随地阅读,但无法随身携带纸质书籍?
您的电子书购买无法与所选设备兼容吗?
不用担心,现在每本 Packt 书籍都能免费获得一份没有数字版权管理(DRM)的 PDF 版本。
在任何地方、任何设备上阅读。搜索、复制并粘贴您喜爱的技术书籍中的代码,直接应用到您的项目中。
优惠不仅如此,您还可以独享折扣、新闻通讯以及每天送到邮箱的优质免费内容
按照以下简单步骤获取优惠:
- 扫描二维码或访问以下链接
packt.link/free-ebook/9781805125068
-
提交您的购买凭证
-
就是这样!我们会将您的免费 PDF 和其他福利直接发送到您的邮箱
第一部分:生成式人工智能和 Azure OpenAI 基础
本部分作为理解大型语言模型(LLMs)及其企业级应用的全面基础。我们首先介绍 LLMs,探讨它们的快速采用,并为理解其在商业和技术中的广泛影响奠定基础。接着,我们深入讲解 Azure OpenAI 服务的基本概念,详细说明与 OpenAI 的合作关系、模型部署过程以及定价策略。最后,我们深入探讨嵌入模型、多模态能力和微调等高级概念,使您更深入地理解 Azure OpenAI 的强大功能。
本部分包含以下章节:
-
第一章,大型语言模型简介
-
第二章,Azure OpenAI 基础知识
-
第三章,Azure OpenAI 高级主题
第一章:大型语言模型简介
在技术的世界里,聊天生成预训练变换器(ChatGPT)是一个基于大型语言模型(LLM)的聊天机器人,由 OpenAI 于 2022 年 11 月 30 日发布。在 ChatGPT 的首周内,已有超过一百万人开始使用这项技术。这是一个重要的时刻,因为它展示了普通人现在如何在日常生活中使用生成性人工智能(AI)。到 2023 年 1 月,ChatGPT 的用户数超过了 1 亿,成为历史上增长最快的应用,并使得背后的公司 OpenAI 的估值达到了 290 亿美元。
在本章节中,我们将建立 LLM 的基本概念,查看一些示例,理解基础模型的概念,并提供多个业务应用场景,展示 LLM 如何解决复杂问题。
本章将涵盖以下主题:
-
什么是 LLM?
-
LLM 示例
-
基础模型的概念
-
LLM 的应用场景
什么是 LLM?
LLM 是深度学习中的现代突破,专注于人类语言。它们在许多方面表现出了巨大的实用性,例如内容创作、客户支持、编码辅助、教育与辅导、医疗诊断、情感分析、法律援助等。简单来说,LLM 是一种智能计算机程序,能够像人类一样理解和生成文本,并且其底层使用了大型变换器模型。变换器架构使得模型能更有效地理解数据中的上下文和关系,这使得它在涉及人类语言和序列数据的任务中尤为强大。
对人类来说,文本是一堆拼凑在一起的单词。我们阅读句子,句子组成段落,段落组成文档中的章节。但是对计算机来说,文本只是一个由字母和符号组成的序列。为了让计算机理解文本,我们可以创建一个使用所谓的循环神经网络的模型。这个模型一次处理一个单词或字符,当它读完所有内容时,会给出一个答案。这个模型效果不错,但有时当它读取到一段文本的结尾时,它很难回忆起该段文本的开头部分。这就是变换器架构的亮点所在。变换器架构的关键创新是使用了自注意力机制,这使得它能够比以前的模型更有效地捕捉序列中不同部分之间的关系。
早在 2017 年,Ashish Vaswani 和他们的团队写了一篇名为 Attention is All You Need (arxiv.org/pdf/1706.03762.pdf) 的论文,介绍了一种叫做 Transformer 的新模型。这个模型使用了一种叫做注意力(attention)的技术。与旧的递归神经网络处理文本的方式不同,注意力可以让你一次性查看整个句子,甚至是整段话,而不是一次只看一个单词。这有助于 Transformer 更好地“理解”单词,因为它获得了更多的上下文信息。如今,许多最好的大型语言模型(LLM)都是基于 Transformer 构建的。
当你希望一个 Transformer 模型理解一段文本时,必须将其拆解为单独的单词或称为 token 的部分。这些 tokens 然后会被转化为数字,并映射到称为嵌入(embeddings)的特殊编码,这些嵌入就像是存储 token 语义信息的特殊地图。最终,Transformer 的编码器将这些嵌入转化为一种表示。这个“表示”是一个向量,能够捕捉输入 tokens 的上下文含义,使得模型能够更有效地理解和处理输入。简单来说,你可以将其理解为将所有碎片拼凑在一起,以便理解完整的故事。
这是一个文本字符串,它的 token 化及其向量嵌入。请注意,token 化可以将单词拆分成子单词。例如,单词“generative”可以被拆分为“gener”和“ative”。
让我们看看输入文本:
Generative AI, a groundbreaking technology fueled by intricate algorithms and machine learning, possesses the remarkable ability to independently craft content across diverse domains. By meticulously analyzing vast datasets and discerning intricate patterns, it generates textual compositions, artistic creations, and a myriad of other outputs that mirror human ingenuity. This innovative capability is reshaping industries far and wide, driving unprecedented advancements in fields such as language generation, creative arts, and data synthesis.
这是 token 化后的文本:
['Gener', 'ative', ' AI', ',', ' a', ' groundbreaking', ' technology', ' fueled', ' by', ' intricate', ' algorithms', ' and', ' machine', ' learning', ',', ' possesses', ' the', ' remarkable', ' ability', ' to', ' independently', ' craft', ' content', ' across', ' diverse', ' domains', '.', ' By', ' meticulously', ' analyzing', ' vast', ' datasets', ' and', ' discern', 'ing', ' intricate', ' patterns', ',', ' it', ' generates', ' textual', ' compositions', ',', ' artistic', ' creations', ',', ' and', ' a', ' myriad', ' of', ' other', ' outputs', ' that', ' mirror', ' human', ' ing', 'enuity', '.', ' This', ' innovative', ' capability', ' is', ' resh', 'aping', ' industries', ' far', ' and', ' wide', ',', ' driving', ' unprecedented', ' advancements', ' in', ' fields', ' such', ' as', ' language', ' generation', ',', ' creative', ' arts', ',', ' and', ' data', ' synthesis', '.']
现在,让我们来看看嵌入:
[-0.02477909065783024, -0.013280253857374191, 0.014264720492064953,0.002092828741297126, 0.008900381624698639, 0.017131058499217033, 0.04224500060081482, 0.012088178656995296, -0.028958052396774292, 0.04128062725067139, 0.020171519368886948, 0.034369271248579025, 0.005337550304830074, -0.011920752003788948, 0.0027072832453995943,0.008103433065116405, 0.035440798848867416, 0.015430007129907608,
…
…
-0.02812761813402176, -0.009549995884299278, 0.02203330025076866, 0.015215701423585415, 0.02339949831366539, -0.008967352099716663, 0.01867138035595417, -0.01762663945555687, 0.01278467196971178, 0.029922427609562874, -0.0002689284738153219, -0.010213003493845463]
把上下文向量看作是输入信息的核心。它使得 Transformer 的解码器能够确定接下来该说什么。例如,通过给解码器提供一个起始句子作为提示,它可以建议下一个合适的单词。这个过程会重复,每次新的建议都会成为提示的一部分,从而让解码器从一个初始句子生成一个自然流畅的段落。
基于解码器的内容生成就像是一场游戏,每一步都基于前一步,最终你将得到一个完整的故事。这种内容生成方法叫做“自回归生成”(autoregressive generation)。广义来说,这就是大型语言模型(LLM)的工作原理。基于自回归生成的模型能够处理长篇输入文本,同时保持足够大的上下文向量来处理复杂的概念。此外,解码器中有很多层,使得它非常复杂。它大到通常无法仅在一台计算机上运行,而必须依赖于多个节点协同工作,这些节点通常需要频繁访问。这就是为什么它通过 应用程序编程接口 (API) 提供服务的原因。如你所猜测,这个庞大的模型是通过大量文本的训练来学习语言的运作方式,包括句子的所有模式和结构。现在,让我们理解大型语言模型(LLM)的主要结构。
LLM 的结构(参见图 1.1)主要由不同层次的神经网络组成,例如递归层、前馈层、嵌入层和注意力层。这些层次协作处理输入文本并对输出进行预测。我们来仔细看看:
-
嵌入层将输入文本中的每个单词转换为一种特殊的详细描述,类似于独特的指纹。这些描述包含关于单词及其含义的重要细节,帮助模型理解更大的图景。
-
前馈层由许多连接的层组成,这些层处理在嵌入层中创建的详细描述。这些层对这些嵌入进行复杂的变换,帮助模型理解输入文本中更重要的思想。
-
递归层设计用于一步步地读取输入文本。这些层具有隐藏的记忆,随着每一步读取,它们会更新记忆。这帮助模型记住句子中单词之间的关系。
-
注意力机制是 LLM 的另一个重要部分。它就像一个聚光灯,模型将其聚焦于输入文本的不同部分。这帮助模型集中注意力于文本中最重要的部分,从而做出更好的预测。
例如,当你阅读时,并不会对每个词都给予同等的关注;而是更多地集中在关键词和重要短语上,以掌握主旨。例如,在句子“猫坐在垫子上”中,你可能会强调“猫”和“垫子”来理解发生了什么。此外,你还会利用前面句子的上下文来理解当前句子——如果你之前读到有只猫在玩耍,你就能理解为什么这只猫现在坐在垫子上。随着阅读的进行,你会根据理解的需要调整关注重点,重新审视或更加关注那些有助于理解整体情节的关键部分。
本质上,就像人类通过关注重要词汇并利用上下文理解含义来阅读文本一样,变换器中的注意力机制也会关注输入的关键部分,并动态调整,以捕捉单词之间的上下文和关系:
图 1.1:变换器架构(来源:arxiv.org/pdf/1706.03762.pdf)
现在我们已经了解了 LLM 背后的基本概念,接下来让我们关注一些行业中的顶级实例。
LLM 示例
许多公司已经开发出了先进的 LLM,包括 OpenAI(GPT-4)、Meta(Llama 3.1)、Anthropic(Claude)和 Google(Gemini),等等。OpenAI 在 LLM 领域一直保持着主导地位。我们来看一下在撰写时使用的顶级模型:
-
Generative Pre-trained Transformer (GPT): OpenAI 创建了多个 GPT 模型,包括 GPT1(1.17 亿参数)、GPT2(15 亿参数)、GPT-3(1750 亿参数)、GPT 3.5、GPT4-Turbo、GPT4-o 和 GPT4-o mini 等。GPT4-o 是全球最先进的语言大模型之一。这些模型从大量文本中学习,能够提供类似人类的回答,涵盖多个主题和问题,并且能记住对话中的各个部分。
-
Anthropic: Anthropic 的 Claude 模型是一系列先进的语言大模型(LLM),旨在以高效的方式处理复杂任务。最新版本 Claude 3 包括了 Opus、Sonnet 和 Haiku 等不同型号,每种型号都根据不同的性能需求进行了优化。Opus 是最强大的,擅长处理复杂的分析和高阶任务,而 Sonnet 则在速度和智能之间取得平衡,Haiku 则为轻量级操作提供最快的响应时间。这些模型注重安全性、可靠性和道德的人工智能实践。
-
Llama 3.1: Llama 3.1 是一款前沿的语言大模型,代表着人工智能研究的一个重要里程碑。凭借其先进的架构和庞大的规模,Llama 3.1 能够以前所未有的准确性和细致度理解和生成类似人类的文本。这款强大的工具在自然语言处理(NLP)、文本生成和对话式人工智能等多个应用领域具有深远的影响。
-
Llama 2: Llama 2 是 Meta 开发的第二代语言大模型。它是开源的,可以用来创建类似 ChatGPT 或 Google Bard 的聊天机器人。Llama 2 的训练数据比 Llama 1 多 40%,从而使其能提供更加逻辑清晰且自然的回应。Llama 2 可以供任何人用于研究或商业用途。Meta 表示,Llama 2 能够理解比 Llama 1 更多的上下文信息,这使得它成为一个更加智能的语言模型,能够提供听起来像人类回答的回复。
-
Gemini: Google Gemini 是由 Google DeepMind 开发的一系列先进的多模态语言大模型(LLM)。该系列于 2023 年 12 月 6 日发布,包括 Gemini Ultra、Gemini Pro、Gemini Flash 和 Gemini Nano 等版本。Gemini 旨在无缝理解和处理不同类型的信息,包括文本、图像、音频、视频和代码。作为 OpenAI GPT-4 的竞争者,Gemini 驱动着 Google 的 AI 聊天机器人,并旨在提升创造力和生产力。
-
PaLM 2:最后,PaLM 2 是谷歌更新的 LLM(大型语言模型)。它擅长处理复杂任务,如处理代码和数学、分类和回答问题、翻译语言、精通多种语言,并能创造类人句子。它的表现超过了前述的模型,包括最初的 PaLM。谷歌在创建和使用 AI 时非常谨慎,PaLM 2 就是这一方法的一部分。它经过了全面评估,以检查潜在的问题和偏见。PaLM 2 不仅单独使用,还被应用于其他先进模型,如 Med-PaLM 2 和 Sec-PaLM。它还为谷歌的 AI 功能和工具提供动力,如 Bard 和 PaLM API。
现代 LLM 的进化树(见图 1.2)展示了这些模型近年来的演变,并突出了其中一些最著名的模型。相关性较强的模型位于同一分支上。使用 Transformer 架构的模型显示在不同的颜色上:仅解码的模型位于蓝色分支,只有编码的模型位于粉色分支,而既进行编码又进行解码的模型位于绿色分支。模型在时间线上的位置表示它们的发布时点。开源模型以实心方块表示,而非开源模型则以空心方块表示。右下角的柱状图显示了不同公司和组织发布的模型数量:

图 1.2:现代 LLM 的进化树(来源:arxiv.org/abs/2304.13712)
在探讨了一些典型的 LLM 实例后,让我们讨论一下基础模型的概念及其优缺点。
基础模型的概念
最近几年,围绕 LLM(如 ChatGPT)的热议席卷了全球。LLM 是一个更广泛模型类别——基础模型(foundation models)的子集。有趣的是,“基础模型”这一术语最初由斯坦福大学的团队提出。他们观察到 AI 领域发生了变化,推动了一个新范式的出现。
过去,人工智能应用程序是通过训练单个人工智能模型构建的,每个模型都针对特定任务使用专门的数据进行训练。这种方法通常涉及以大多数是监督学习的方式组装一个包含各种人工智能模型的库。其基础能力,即基础模型(见 图 1.3),将成为各种应用和用例背后的驱动力。实际上,这个单一的模型能够满足那些曾经由传统方法中不同的人工智能模型支持的应用程序。这意味着一个模型可以驱动多种多样的应用程序。关键在于,这个模型拥有惊人的能力,能够适应多种任务。促使该模型实现这种多功能性的因素在于,它通过无监督的方式,在海量的非结构化数据上进行了广泛的训练:
图 1.3:基础模型(来源:arxiv.org/pdf/2108.07258.pdf)
考虑一个场景,我开始一句话说“不要在鸡还没孵出来之前就开始数它们。”现在,我的目标是引导模型预测最后一个词,这个词可能是“孵化”(hatched)、“生长”(grown)甚至是“消失”(gone)。这个过程包括通过分析句子中前面给出的上下文,训练模型预测合适的词。能够根据前面遇到的词的上下文来生成对下一个词的预测,这种令人印象深刻的能力使得基础模型处于生成性人工智能的领域。本质上,这些模型属于生成性人工智能,因为它们能够创造一些新东西——在这种情况下,就是预测句子中的下一个词。
尽管这些模型主要设计用来生成预测,特别是预测句子中的下一个词,但它们具有巨大的能力。只需添加少量带标签的数据,我们就可以调整这些模型,使其在更传统的自然语言处理(NLP)任务上表现得非常出色。这些任务包括分类或命名实体识别等活动,这些通常与生成能力无关。通过一种叫做微调的过程,可以实现这一转变。当你使用适量的数据集来微调你的基础模型时,你会调整其参数,使其能够在特定的自然语言任务上表现出色。通过这种方式,模型从主要是生成型的演变为一个强大的、针对性的 NLP 任务工具。
即使是在数据有限的情况下,基础模型也可以证明其高效性,特别是在数据稀缺的领域。通过称为提示或提示工程的过程,可以使用技术如上下文学习、零样本、一次样本和少样本学习来解决复杂的下游任务。让我们来分析一下如何为分类任务设置提示。想象一下,你向模型提供一个句子,然后跟上这样一个问题:“这个句子带有积极还是消极情绪?”模型会运用其魔法,生成完整的句子。它生成的下一个词将作为你分类问题的答案。根据它认为句子情感所在的位置,模型将回答“积极”或“消极”。这种方法利用了模型生成上下文相关文本的内在能力,以解决特定的分类挑战。我们将在本书后面讨论不同的提示技术和高级提示工程。
让我们来谈谈基础模型的一些关键优势:
-
性能:这些模型经过大量数据的训练,数据量通常达到了几 TB。当用于较小的任务时,这些模型展示出非凡的性能,远远超过仅训练在少量数据点上的模型。
-
生产力提升:LLM 可以极大地提升生产力。它们就像超高效的人类,可以完成通常需要大量时间和精力的任务。例如,在客户服务中,LLM 可以快速回答常见问题,从而让人类工作人员有更多时间处理更复杂的问题。在企业中,它们可以比人类更快地处理和组织数据。使用 LLM,公司可以节省时间和金钱。这让他们能够专注于重要任务,因此像生产力的涡轮增压器一样发挥作用。
然而,这些基础模型也存在关键的挑战和限制:
-
成本:由于需要大量的数据量来训练,这些模型的训练成本往往相当高昂。这通常对试图训练自己的基础模型的小型企业构成挑战。此外,随着这些模型规模的扩大,达到数十亿参数的规模,它们在推断方面的使用成本可能会昂贵。
诸如微软之类的云服务提供商提供了一项名为Azure OpenAI的服务。这项服务允许企业按需使用这些模型,并且仅支付他们使用的部分。这类似于租用一台强大的计算机一段时间,而不是直接购买一台。利用这种基于服务的能力使公司能够节省在模型训练和使用上的资金,特别是考虑到需要强大的基于 GPU 的硬件。
总结一下,通过使用 Azure OpenAI 等服务,企业可以利用这些先进的模型,而无需在资源和基础设施上花费大量资金。
-
可信度:就像数据对这些模型来说是巨大的优势一样,也有另一面需要考虑:LLM 是通过大量从互联网抓取的语言数据进行训练的,这些数据可能包含偏见、仇恨言论或有害内容,进而影响其可靠性。这将是一个艰巨的任务。此外,还有一个挑战是我们甚至不能完全了解这些数据的构成。对于许多开源模型来说,用于训练 LLM 的确切数据集不明确,这使得评估它们是否存在可信度和潜在偏见问题变得困难。LLM 训练数据的庞大规模几乎使得人工注释人员无法彻底审查每一个数据点,从而增加了无意中引发负面后果的风险,比如加剧有害偏见或生成有毒内容。
大型组织充分意识到这些技术蕴藏的巨大潜力。为了解决基础模型的可信度问题,OpenAI、微软、谷歌和 Anthropic 正联合推出“前沿模型论坛”(
blogs.microsoft.com/on-the-issues/2023/07/26/anthropic-google-microsoft-openai-launch-frontier-model-forum),这是一个旨在确保前沿 AI 模型安全和负责任发展的全新行业倡议。这个新的合作实体将利用成员公司在技术和运营方面的集体优势,推动整个 AI 领域的进展。它的核心目标之一是推动技术评估和基准测试的前进。此外,论坛还将努力构建一个公开可访问的解决方案库,促进 AI 领域行业最佳实践和标准的采用。 -
幻觉:有时,LLM 可能会生成一些信息或答案,这些内容可能并不完全准确。这就像是你做了一个看起来很真实的梦,但它并不基于现实中的情况。LLM 可能生成听起来正确但实际上并不完全真实或准确的文本。因此,虽然 LLM 具有高度智能,但有时它们也会犯错或生成并不存在的内容。
LLM 的应用通常需要人工监督,以确保输出结果值得信赖。然而,有一种前景广阔的技术叫做 模型对接,旨在改善这种情况。对接意味着将 LLM 的理解与现实世界的信息和上下文联系起来。这就像是确保模型牢牢扎根于现实中一样。本书后面会详细讨论如何使用这种技术来防止模型凭空捏造内容,并只给出基于给定上下文的答案。
-
有限的上下文窗口:LLM 有一个有限的上下文窗口或令牌大小。上下文窗口或令牌大小可以看作是模型每次能处理的记忆量。LLM 一次只能理解一定数量的信息。例如,ChatGPT(GPT4-o)可以处理 128K 输入令牌。这意味着如果给它的输入太多,它将无法处理并会报错。因此,保持输入在此限制内对于模型正常运行非常重要。
在我们理解基础模型概念的基础上,接下来让我们深入探讨 LLM 的一些实际应用案例。
探索 LLM 的应用案例
LLM 在各个领域和行业中有着广泛的应用案例,因为它们能够理解并生成类人文本。让我们来看看其中的一些:
-
内容生成:LLM 可以生成博客、文章、营销材料和社交媒体帖子的书面内容。它们可以用于自动化内容创作并提供创意灵感。
-
客户支持:LLM 可以为客户查询和支持工单提供自动化回应,从而处理常见问题和问题,将更复杂的案例交由人工代理处理。
-
语言翻译:LLM 可以用于在不同语言之间翻译文本,使全球范围内的沟通更加便捷和可达。
-
文本摘要:LLM 可以快速总结长篇文本,使得更容易把握文章、报告及其他书面材料的要点。
-
聊天机器人和虚拟助手:LLM 可以驱动聊天机器人和虚拟助手,与用户进行自然语言对话,帮助完成任务、解答询问和获取信息。
-
内容个性化:LLM 可以分析用户偏好和行为,个性化推荐、广告和在社交媒体和流媒体服务平台上的内容推送。
-
数据录入与提取:LLM 可以从非结构化文本中提取相关信息,例如文档或电子邮件,并将其录入结构化的数据库或电子表格中。
-
创意写作:LLM 可以通过生成故事创意、对话、角色描述甚至整个叙事来协助作家。
-
医疗聊天机器人:LLM 驱动的聊天机器人可以回答与健康相关的问题,提供急救建议,并提供有关常见医疗状况的信息。
-
医学诊断:LLM 可以通过分析患者症状和病历来帮助诊断医疗状况,提供潜在的诊断和治疗方案。
-
心理健康支持:LLM 可以为寻求心理健康支持的个人提供同情的回应和资源。
-
旅游和旅行规划:LLM 可以通过建议行程、推荐景点并提供有关当地习俗和美食的信息来协助旅行者。
-
食谱创作:LLM 可以根据食材和饮食偏好设计创意食谱,提供全新的烹饪体验。
-
网络安全分析:LLM 可以分析网络安全威胁,并建议保护数字系统和数据的策略。
-
时尚推荐:LLM 可以根据个人风格偏好和当前流行趋势,推荐服装和配饰搭配。
-
法律文件审查:LLM 可以审查法律文件、合同和案件历史,识别相关信息、异常情况和潜在问题。
-
学术研究:LLM 可以通过提供学术论文摘要、帮助进行文献综述,并生成进一步研究的想法,来协助研究人员。
-
财务分析:LLM 可以处理和分析财务数据,生成报告,并提供市场趋势和投资机会的洞察。
-
语言学习:LLM 可以通过与学习者对话、提供解释和提供练习,帮助学习者练习和提升语言技能。
-
无障碍工具:LLM 可以用于为视障人士创建音频描述、为视频生成字幕,并将文本转化为语音,帮助有阅读困难的人群。
尽管这些只是一些示例用例,但 LLM 的无限灵活性使其能够在技术进步的过程中应用于更多的场景。
想要创建生成型 AI 应用程序但不想自己训练 LLM 或花钱购买昂贵硬件的人,可以使用 Azure OpenAI API。这使他们能够使用由 OpenAI 制作的先进 LLM。
到目前为止,我们已经介绍了 LLM 的基础知识。接下来的一章将更详细地讨论 Azure OpenAI 服务。
总结
在这一章中,我们从介绍 LLM 及其如何受 Transformer 网络影响开始。然后,我们探讨了构成 LLM 的各个部分。接下来,我们深入研究了由 OpenAI、Meta 和 Google 创建的一些顶级 LLM 模型,讨论了这些模型如何演变。我们还介绍了基础模型的概念,包括其优势和局限性。最后,我们查看了 LLM 在各个商业应用中的巨大潜力。
在接下来的章节中,我们将专注于 Azure OpenAI 服务。我们将学习如何访问该服务,包括 GPT 3.5、GPT-4、嵌入式模型和 DALL.E 2 等模型。我们还将解释定价机制,讨论按需付费和预留容量等选项。
进一步阅读
-
AI 解释器:基础模型与 AI 的下一个时代 (
www.microsoft.com/en-us/research/blog/ai-explainer-foundation-models-and-the-next-era-of-ai/) -
Orca: 来自 GPT-4 的复杂解释轨迹的渐进学习 (
www.microsoft.com/en-us/research/publication/orca-progressive-learning-from-complex-explanation-traces-of-gpt-4/) -
Florence: 计算机视觉的新基础模型 (
www.microsoft.com/en-us/research/publication/florence-a-new-foundation-model-for-computer-vision/) -
加速基础模型研究 (
www.microsoft.com/en-us/research/collaboration/accelerating-foundation-models-research/) -
注意力即是你所需要的 (
arxiv.org/abs/1706.03762) -
关于基础模型的机会与风险 (
arxiv.org/abs/2108.07258)
第二章:Azure OpenAI 基础知识
在上一章中,我们讨论了大型语言模型(LLMs)、LLM 的概念以及不同的企业级 LLM 示例。我们还讨论了基础模型的概念,并探讨了 LLM 的不同应用场景。在本章中,我们将深入探讨Azure OpenAI(AOAI)服务、不同的模型类型、如何部署模型以及各种定价方面。
在本章中,我们将探讨以下内容:
-
什么是 AOAI 服务?
-
AOAI 模型类型
-
访问 AOAI 服务
-
创建 AOAI 资源
-
部署 AOAI 模型
-
利用 AOAI 模型
-
定价
在深入探讨这些内容之前,让我们先更好地了解微软与 OpenAI 的合作关系。
微软向 OpenAI 投资了数十亿美元,确保他们能够开发先进的 AI 技术,并与大家共享其成果。这一合作关系建立在微软 2019 年和 2021 年的先前投资基础上。这使得微软和 OpenAI 能够将他们所创造的先进 AI 技术应用于各自的业务中。微软还投资了强大的超级计算机,以帮助 OpenAI 进行重要的 AI 研究。
微软与 OpenAI 建立了战略合作伙伴关系,并在此过程中整合了其先进的大型语言模型(LLM)。他们在多种产品中使用 OpenAI 的模型,并创造出创新的数字体验。微软有一项名为 AOAI 的服务,开发者可以利用前沿模型的强大功能,同时结合微软的强大工具。微软是唯一为 OpenAI 提供云服务的公司,这意味着他们将处理 OpenAI 的研究、产品和服务所需的所有计算工作,以便构建复杂的 AI 应用程序。此次合作促成了变革性解决方案的诞生,为基于 AI 的开发开启了新的可能性。在下一节中,我们将深入探讨 AOAI 服务以及如何使用它。
什么是 AOAI 服务?
微软提供了广泛的 AI 工具和解决方案,帮助客户在 AI 旅程的各个阶段取得进展,无论其团队的技术水平如何。无论你是 AI 的新手,还是已经有具体应用场景的用户,微软都能满足你的需求。对于初学者,他们提供了易于使用的选项;对于有更高需求的数据科学家,他们也提供了支持。探索 Azure AI 产品时,你可以自由地从高级 AI 服务入手,深入了解 Azure 机器学习平台,构建、训练、调优并大规模部署深度学习模型。整体 Azure AI 架构如下图所示:
图 2.1 – Azure AI 架构
在最上层,你可以找到针对特定应用的 AI 服务,如认知搜索、机器人服务和文档智能。还有一些领域特定的预训练模型,如视觉、语音、语言、决策和Azure OpenAI 服务。这些模型建立在 Azure 机器学习的基础上,作为一个托管端点。如果你使用 AI 服务,就不需要担心基础层。然而,如果你希望访问基础层并控制它,可以使用最底层:Azure 机器学习。它是一个端到端托管的机器学习平台,旨在负责任且安全地大规模构建、训练、部署和操作机器学习模型。
AOAI 服务(在图 2.1中的红色矩形框内标记)是一个新的 Azure AI 服务,提供对 OpenAI 强大语言模型的 REST API 访问,包括 GPT-4 Turbo、GPT-4o、GPT-4o mini、GPT-3.5 Turbo、Whisper、DALL-E 3 和 Embeddings 模型系列。它们具有企业级功能,如安全性、私有网络、合规性、区域可用性和负责任的 AI 内容过滤,这些功能仅在 Microsoft Azure 上提供。这些模型可以轻松适应各种任务,包括但不限于内容生成、摘要、语义搜索和自然语言到代码的翻译。用户可以通过 REST API、Python SDK 或 Azure AI Foundry 中的基于 Web 的界面访问各种服务。
现在,让我们来讨论 AOAI 中的不同模型类型。
AOAI 模型类型
AOAI 服务提供了多种不同的模型,它们可以做不同的事情,并且有不同的费用。让我们深入了解不同的模型类型及其可用性:
-
GPT 基础模型:GPT 基础模型可以理解并生成自然语言和代码,但在遵循指令方面没有经过特别训练。它们设计为原始 GPT-3 基础模型的替代品,并依赖于传统的 Completions API。对于大多数用户,我们建议使用 GPT-3.5 或 GPT-4 来完成他们的任务。这些模型有两种不同的变体:
-
Babbage-002:作为 GPT-3 的 Ada 和 Babbage 基础模型的替代品。它可以支持最多 16,384 个 token 并可以进行微调。
-
Davinci-002:作为 GPT-3 的 Curie 和 Davinci 基础模型的替代品。它可以支持最多 16,384 个 token 并可以进行微调。
-
-
GPT-4:这是最新的模型,适用于解决复杂问题。它比 OpenAI 之前的任何模型都更准确。GPT-4 模型能够理解并生成自然语言和计算机代码,并具备高级推理能力。它是一个优化的聊天完成模型,意味着它最适合互动聊天应用,并且在常规的完成任务中表现优异。作为一个大型、高度优化的模型,GPT-4 在互动聊天和完成任务方面都能出色地表现。最新的 GPT-4 类模型包括三种旗舰型号:
-
GPT-4 Turbo:此模型支持最多 128,000 个输入标记/上下文窗口和 4,096 个输出标记。
-
GPT-4o:此模型支持最多 128,000 个输入标记/上下文窗口和 4,096 个输出标记。
-
GPT-4o mini:此模型支持最多 128,000 个输入标记/上下文窗口和 16,384 个输出标记。
-
-
GPT-3.5:GPT-3.5 代表一系列基于 GPT-3 能力的模型。这些模型在理解和生成自然语言以及计算机代码方面表现出色。在 GPT-3.5 模型中,最强大且最具成本效益的是 GPT-3.5 Turbo。它专门为互动对话进行微调,在常规完成任务中表现良好。GPT-3.5 的最新版本还提供两种不同的版本:
-
gpt-35-turbo-1106:此模型支持最多 16,385 个输入标记/上下文窗口和 4,096 个输出标记。
-
gpt-35-turbo-0125:此模型支持最多 16,385 个输入标记/上下文窗口和 4,096 个输出标记。
-
isgpt-35-turbo-instruct:此模型支持最多 4,097 个输入标记/上下文窗口。此模型无法进行微调。
-
重要说明
GPT-3.5 Turbo Instruct 提供的能力与 text-davinci-003 相当,但使用的是 Completions API,而非 Chat Completions API。我们强烈建议使用 GPT-3.5 Turbo 和 GPT-3.5 Turbo Instruct,而不是旧版本的 GPT-3.5 和 GPT-3 模型。
这是一个互动聊天示例,可以使用 GPT-3.5 或 GPT-4。通常,用户输入提示,模型生成完成(模型输出)。这可以是一个持续的对话交流:
图 2.2:基础提示和完成示例
除了提示完成,您还需要理解令牌的另一个概念。当您将提示发送到 GPT-3.5 或 GPT-4 时,它会通过嵌入过程进行分词,其中单词或—更常见的是—单词的一部分会转换为数字向量表示。数字令牌代替完整的单词或句子来处理信息。这种设计使得 GPT 模型能够处理相对较大量的文本。然而,GPT-3.5 和 GPT-4(根据您选择的模型类型,如前所述)在输入提示和生成的完成内容上有令牌约束。
为了确保您不超过令牌限制,您可以估算输入提示和生成结果所需的令牌数量。作为粗略指南,英语中每四个字符通常对应一个令牌。因此,您可以通过将提示的字符数与期望的回复长度相加,然后将总数除以四来计算所需的令牌数。这个计算可以为您提供一个大致的令牌数量估算,这对于需要考虑令牌约束的任务规划非常有价值。图 2.3展示了给定句子的令牌示例:
图 2.3:令牌计数器
在此示例中,总共有七个令牌。值得注意的是,“generative”一词由两个不同的令牌表示,而其余词汇则每个由一个令牌表示。
- 嵌入模型:嵌入是浮动点数字向量的列表。当我们衡量两个向量之间的距离时,它告诉我们它们的相似性或差异性。如果距离较小,表示它们非常相似;如果距离较大,则表示它们差异较大。当您将原始文本输入嵌入模型时,它会生成该文本的向量表示列表:
图 2.4:基本嵌入过程
在实际应用中,您将一组文档词汇提供给嵌入模型作为输入,嵌入模型随后使用这些词汇生成嵌入向量。该向量通常存储在一个向量数据库中,如 Azure Cognitive Search 或 Azure Cosmos DB。随后,当用户提交查询时,它会通过相同的嵌入模型生成一个查询向量,该向量用于在向量数据库中搜索相似的向量。这种模式称为检索增强生成(RAG)。
以下图示展示了这一过程:
图 2.5:文档嵌入过程
在撰写本文时,AOAI 服务提供了四种不同类型的嵌入模型:
-
text-embedding-ada-002(版本 1):此版本使用 GPT-2/GPT-3 分词器。它可以处理最多2,046个输入令牌,并提供1,024维度的输出。
-
text-embedding-ada-002 (版本 2): 该版本使用 cl100k_base 分词器,支持四倍于前版本的输入,最多可处理8,191个令牌,并返回1,536维的输出。这是第二代嵌入模型。我们强烈推荐使用 text-embedding-ada-002 版本 2,因为它在功能和性能上与 OpenAI 的 text-embedding-ada-002 模型相当。该模型不仅更加经济高效,而且更简单、更高效。
-
text-embedding-3-small: 新的 text-embedding-3-small 模型显著优于其前身 text-embedding-ada-002,在多语言检索的基准分数上从 31.4%提高至 44.0%,在英语任务上从 61.0%提高至 62.3%。此外,它在成本效益方面提高了五倍,将每千个令牌的价格从0.00002。虽然 text-embedding-ada-002 仍将保持可用,但由于其更高的效率和性能,推荐使用 text-embedding-3-small。一款新模型 text-embedding-3-large 提供了更大的容量,支持最多 3,072 维度的嵌入。
-
text-embedding-3-large: 新的 text-embedding-3-large 模型是性能最强的嵌入模型,较 text-embedding-ada-002 有了显著的提升。在 MIRACL 基准测试中,它的平均分为 54.9%,在 MTEB 基准测试中的分数为 64.6%,分别高于 31.4%和 61.0%。text-embedding-3-large 的定价为每千个令牌$0.00013,在所有嵌入模型中提供了最高的性能,超越了 text-embedding-3-small 和 text-embedding-ada-002。
要创建一个生成式 AI 应用程序,您主要需要的关键模型就是此处提到的模型。值得注意的是,这些模型仅在一个截止到 2021 年 9 月的大型数据集上进行过训练。因此,它们不具备该日期之后的任何知识或信息。如果您想要创建一个包含最新信息的生成式 AI 应用,您可以探索一种被称为RAG的技术。我们将在本书后面详细探讨这一技术,提供实践教程和深入讨论。
AOAI 服务中还提供了其他模型,包括以下模型:
-
DALL-E 3: 该模型能够根据自然语言描述生成真实感的图像和艺术作品。
-
Whisper: 这是一个通用的语音识别(ASR)模型。它已经在包含音频和文本的 680,000 小时的庞大且多样化的数据集上进行训练,能够处理多种任务,例如识别多种语言的语音、翻译口语和识别语言。Whisper 采用基于 Transformer 的编码器-解码器架构,能够将口语转化为书面文本,并且还可以处理特殊令牌来指示涉及的任务或语言。此模型可以通过 AOAI 服务或 Azure 语音访问。
现在我们已经讨论了各种类型的模型,接下来我们来讨论如何获得 AOAI 服务的访问权限。
访问 AOAI 服务
要访问 AOAI,您需要拥有一个有效订阅和启用 AOAI 访问的 Azure 账户。本节将引导您如何获取 AOAI 服务访问权限。
步骤 1:创建 Azure 账户。
在本文写作时,AOAI 的访问权限仅限于企业客户和合作伙伴。因此,技术上,您可以使用四种选项中的一种创建一个 Azure 账户(learn.microsoft.com/en-us/dotnet/azure/create-azure-account)。但是,在创建账户时,您必须使用公司的电子邮件地址;个人邮箱将无法获得 AOAI 访问权限:
-
选项 1:Visual Studio 订阅者可以使用每月的 Azure 积分。此选项允许您激活积分并将其用于 AOAI。
-
选项 2:注册免费 Azure 账户。此选项为您提供 12 个月的免费服务和 200 美元的积分,您可以在 30 天内使用这些积分探索 Azure。如果您已获得批准,可以使用这些积分用于 AOAI。
-
选项 3:注册按需付费账户。此选项会根据您超出免费额度的使用量收费。如果您已获得批准,您可以使用此选项为 AOAI 付费。
-
选项 4:使用企业账户。此选项要求您的公司有一个云管理员来授予您访问 AOAI 的权限。
创建 Azure 账户后,您将获得一个默认的 Azure 订阅。您可以使用该订阅,或者创建一个新的订阅来访问 AOAI:
- 您可以在订阅资源下找到您的订阅信息:
图 2.6:查找订阅
- 记下订阅 ID值;您将需要它来申请 AOAI 访问权限:
图 2.7:检索订阅详细信息
步骤 2:申请 AOAI 访问权限。
要申请 AOAI 访问权限,请按照以下步骤操作:
-
AOAI 是一个受限的通用可用性服务。通常,您可以在您的订阅中创建 AOAI 资源。如果您没有访问权限,必须填写
aka.ms/oaiapply提供的表单。请确保在填写表单时使用公司的电子邮件地址。 -
填写表单后,大约需要 3-4 天才能批准。一旦您的访问权限获得批准,您将收到 Azure 认知服务团队的电子邮件。
此批准将允许您访问和使用 AOAI 模型。
到此为止,我们已经介绍了如何获得 AOAI 服务的访问权限。接下来,我们将重点讨论如何有效地利用这些模型。
创建 AOAI 资源
获得 AOAI 模型的访问权限后,您可以创建 AOAI 资源来部署模型。本节将指导您完成创建 AOAI 资源的过程:
-
登录到您之前在 Azure 门户(
portal.azure.com/)中创建的 Azure 订阅。 -
转到
Azure OpenAI。找到该服务后,点击创建:
图 2.8:创建 AOAI 资源
-
在 AOAI创建页面中,在基本选项卡的字段中提供以下详细信息:
字段 描述 订阅 在您的应用程序中提到的 Azure 订阅,用于接入 AOAI 服务。 资源组 包含您的 AOAI 资源的 Azure 资源组。您可以创建一个新的资源组或使用现有的资源组。 区域 您实例的地理位置。不同的区域可能会引入延迟,但不会影响资源的操作可用性。 名称 为您的 AOAI 服务资源提供一个描述性的名称。 定价层级 资源的定价层级。目前,AOAI 服务仅提供标准层。
表 2.1:AOAI 资源创建详细信息
- 现在,让我们通过在基本选项卡中提供以下详细信息来创建 AOAI 资源:
图 2.9:创建 AOAI 资源的基本信息
-
点击下一步。
-
网络选项卡提供三种安全选项。如果在部署过程中需要增强的安全性,您可以从网络选项卡中选择选项 2 或选项 3。此选项允许您为 AOAI 配置更高的安全性,使其可以通过 Azure 虚拟网络集成和私有端点连接访问。本书稍后将重点介绍选项 2 和选项 3。目前,选择选项 1(所有网络,包括互联网,都可以访问此资源。)以访问资源:
图 2.10:创建 AOAI 资源的公共访问网络设置
-
继续点击下一步,根据需要为您的资源配置标签。
-
点击下一步进入过程的最后阶段:审阅+提交。
-
验证您的配置设置,然后点击创建以启动过程。请耐心等待;该过程可能需要 2-3 分钟完成。
一旦新资源可用,Azure 门户会通知您。点击转到资源以访问新创建的资源。
到目前为止,我们已经设置了 AOAI 服务。在下一节中,我们将部署模型。
部署 AOAI 模型
在上一节中,您已经创建了一个 AOAI 资源。有了这个资源,您可以通过各种方式部署和使用模型,例如 Azure AI Foundry、REST API 或 SDK。本节将指导您通过 Azure AI Foundry 部署这些模型,并通过 Studio 和 Python SDK 访问它们:
-
在 Azure 门户内(
portal.azure.com/)登录到您的 Azure 订阅。 -
在资源搜索栏中,搜索
Azure OpenAI。定位之前在上一节创建的 AOAI 资源:
图 2.11:定位之前创建的 AOAI 资源
-
点击正确的服务名称(在前述图中以红色矩形突出显示)。
-
通过点击探索 Azure AI Foundry 门户或转到 Azure AI Foundry 门户来导航到 Azure AI Foundry:
图 2.12:访问 Azure AI Foundry
- 在管理部分,选择部署:
图 2.13:创建新的 AOAI 模型部署
- 选择部署模型并继续配置以下字段:
| Field | 描述 |
|---|---|
| 选择一个模型 | 从下拉列表中选择一个模型。模型的可用性因地区而异。要查看每个地区可用模型的列表,请参阅模型总结表格和地区可用性。 |
| 部署名称 | 在选择部署名称时要考虑周到。部署名称至关重要,因为它将用于通过客户端库和 REST API 调用模型。 |
| 高级选项(可选) | 您可以根据资源的需要配置高级设置,例如内容过滤、每分钟令牌(TPM)等。 |
对于初始部署,将高级选项保持不变。关于内容过滤和 TPM 的更多详细信息将在接下来的章节中提供:
图 2.14:部署 gpt-35-turbo 模型
-
点击创建继续。
-
部署表将显示与刚刚创建的模型对应的新条目,状态为成功:
图 2.15:gpt-35-turbo 模型的部署状态
(可选):如果您可以访问 GPT-4,您还可以重复所有先前的步骤来部署 GPT-4 或 GPT 基础模型。
现在您已成功使用 Azure AI Foundry 部署了模型,请探索如何在 Azure AI Foundry 内和通过 Python SDK 中利用这些模型。
利用 AOAI 模型
要有效利用模型,了解与聊天模型相关的一些基本要素至关重要。这些概念对于正确利用模型是必不可少的。
GPT-3.5 Turbo 和 GPT-4 模型是经过优化的语言模型(LLMs),适用于对话接口。它们与旧版的 GPT-3 模型在操作方式上有所不同。GPT-3 模型是基于文本输入输出的,即它们接受输入(提示)字符串并返回输出(完成内容);而 GPT-3.5 Turbo 和 GPT-4 模型是为对话风格的互动而设计的。这些模型期望输入以类似聊天记录的结构格式呈现,并返回一个代表模型在聊天中生成的消息的完成内容。虽然这种格式主要是为多轮对话设计的,但它也可以有效地用于非聊天场景。
在 AOAI 中,与 GPT-3.5 Turbo 和 GPT-4 等模型互动有两种不同的选择:
-
messages参数期望一个按角色组织的消息对象数组。在使用 Python API 与这些模型互动时,你通常提供一个字典列表,以有效表示对话格式。列表中的每个字典应该包括消息的角色和内容,使你能够与模型进行有意义的来回交换。基本的聊天完成 API 格式如下代码所示:
response = openai.ChatCompletion.create( engine="gpt-35-turbo", messages=[ {"role": "system", "content": "You are a helpful assistant that helps people find information"}, {"role": "user", "content": "Who won the ICC world cup series in 2011?"}, {"role": "assistant", "content": "India won the ICC world Cup series in 2011."}, {"role": "user", "content": "Where the final match played?"}, {"role": "assistant", "content": "The final match of the ICC World Cup 2011 was played at the Wankhede Stadium in Mumbai, India"} ] )与这些模型互动的主要输入是
messages参数,它期望接收一个消息对象的数组。每个消息对象包含一个role类型(可以是system、user或assistant)和content。对话可以简短至单条消息,也可以包括多个来回交换。让我们仔细看看这些不同的角色:-
system:system角色,也称为系统消息,通常放在消息数组的开头。它作为向模型提供的初始指令,用于引导模型的响应和互动。这些角色由开发者设定,可以影响模型处理各种任务和与用户沟通的方式。在system角色中,你可以灵活地提供多种类型的信息:-
system角色定义了模型应如何与用户互动。例如,某个模型可能有一个角色,优先考虑提供有用和信息丰富的回答,或者一个确保它保持中立和无偏见立场的角色。 -
行为约束:该角色设定了模型应该做什么和不应该做什么的边界。这可以包括避免某些话题、遵守隐私指南,或避免提供医学或法律建议:
-
-
-
system角色可以影响响应的语气和风格。例如,模型可能被设置为在专业场合以正式的方式回应,或在更轻松的互动中采用随意的语气。 -
system角色设计用于客户支持,模型可能针对故障排除和提供与特定产品或服务相关的帮助进行了优化。 -
system角色通常包括参数,以确保回应遵守伦理指南和安全协议,帮助防止生成有害或不当的内容。
总体而言,system角色有助于定制 LLM 的行为,以更好地满足用户需求并与预期的使用场景对接,无论是用于具体详细的指令,还是仅仅提供基本的指导。虽然system角色是可选的,但通常建议至少包含一个基本的消息,以确保获得最佳的结果,并有效地引导助手的行为。
-
user:user角色指的是用户在互动过程中所承担的功能或角色。它影响用户如何构建问题以及他们从模型中寻求什么,比如信息、建议或创意帮助。user角色通过为互动提供背景,进而影响模型的回应方式,并根据用户的需求和期望塑造回答的风格和细节。它还影响模型如何调整回答,以适应用户的目标,无论是用于教育目的、技术支持还是日常对话。总体来说,user角色有助于定制互动,使其更加有效并符合用户的具体需求。 -
assistant:assistant角色代表的是与用户对话的模型。它用于区分模型所写的消息与用户所写的消息。assistant角色还用于指示模型在对话中是回应谁。例如,如果对话记录中的最后一条消息是assistant角色,那么模型将生成一个回应,仿佛它在继续与用户的对话。
通常,一个对话结构是先有系统消息,然后交替出现用户消息和助手消息。系统消息在设定助手的行为上起着至关重要的作用。它可以用于自定义助手的个性,或者提供特定的指令,指导助手如何在整个对话中作出回应。用户消息用于传达用户的请求或评论,供助手处理。助手消息不仅存储了之前的助手回应,还可以由你编写,用来提供期望助手在对话中表现的示例。这种结构化的格式允许与模型进行有效的沟通,控制地引导其回应。图 2.16 提供了这一结构的更清晰理解:
图 2.16:系统、用户和助手角色/消息的框架
第一个方框表示系统消息,在这里你设置元提示来引导 LLM 的回应。第二个方框是用户消息,用户在这里提出问题。最后一个方框展示了助手消息,即模型对用户问题的回应。
-
带有 Chat 标记语言(ChatML)的完成 API:ChatML 使用的是与你用于其他 GPT-3 模型(如 davinci-002 或 babbage-002)相同的完成 API,但它采用了不同的基于令牌的提示格式。虽然 ChatML 提供的访问级别低于专用的聊天完成 API,但它也有一些限制和注意事项:
-
输入验证:在使用 ChatML 时,你必须进行额外的输入验证,以确保消息的格式和结构正确。
-
模型兼容性:ChatML 仅与 GPT-3.5 Turbo 模型兼容,无法与新的 GPT-4 模型一起使用。
-
潜在格式变化:ChatML 的基础格式可能会随时间变化。
因此,虽然 ChatML 提供了灵活性,但在与 GPT-3.5 Turbo 模型一起使用时,了解这些约束条件以及格式可能会发生变化是非常重要的。
-
现在你已经对 Chat Completion API 及其结构有了基本了解,接下来我们将探索如何通过 Azure AI Foundry 和 Python SDK 来使用该模型。
Azure AI Foundry 体验
要在 Azure AI Foundry 中使用该模型,请按照以下步骤操作:
-
在 Azure 门户中登录你的 Azure 订阅 (
portal.azure.com/)。 -
在资源搜索栏中,搜索
Azure OpenAI。找到你在上一节中创建的 AOAI 资源:
图 2.17:定位之前创建的 AOAI 实例
-
点击前面图中红色矩形框内的服务名称。
-
通过点击探索 Azure AI Foundry 门户或前往 Azure AI Foundry 门户来导航至 Azure AI Foundry:
图 2.18:启动 Azure AI Foundry
- 在沙盒部分,选择聊天:
图 2.19:使用 Azure AI Foundry 的聊天沙盒测试提示
在聊天沙盒中,你可以灵活地提供自定义的系统消息,以满足你的特定业务需求。我们将在后面的章节中深入探讨各种提示技术。但现在,你可以随意使用提供的默认系统消息。
在配置面板中,导航到部署标签,并从部署下拉菜单中选择你在上一节中创建的部署名称。在这里,你可以选择与之互动的 gpt-3.5 或 gpt-4 模型。
-
选择默认的会话设置。此设置决定了你在模型上下文中可以保留多少个持续的对话,以便更好地响应用户的提示。它用于管理令牌限制,这是我们在本章开头所提到的。
-
接下来,选择 配置 面板中的 参数 标签。选择参数的默认设置:
图 2.20:设置参数
需要考虑几个参数。让我们逐一查看:
-
最大回复:在聊天完成回复中生成的最大标记数。输入标记和生成标记的总长度受模型上下文长度的限制。
-
温度:选择使用的采样温度,范围从 0 到 1,这是一个关键决定。选择较高的值(如 0.9)会使输出更加随机,而选择较低的值(如 0.1)则会增强其专注性和确定性。需要注意的是,设置为 0 并不会使模型变得确定性;相反,它会减少回复的整体变异性。
-
0.1意味着只考虑位于前 10% 概率质量范围内的标记。通常建议调整 Top P 参数或 Temperature 参数,但不要同时调整这两个参数。 -
停止序列:这有助于您在特定点结束模型的回复,并确保它不包含提供的停止序列文本。通过这样做,您可以防止模型生成后续的用户查询。您可以选择最多包含四个不同的停止序列用于此目的。
-
频率惩罚:该数字范围为 0 到 2.0。它会根据标记在文本中先前出现的频率降低标记重复的可能性,从而减少在回复中重复相同文本的几率。
-
出现惩罚:该数字范围为 0 到 2.0。它最小化了重复使用文本中已经出现的任何标记的概率,从而提高了在回复中引入新话题的可能性。
在这些参数中,您最有可能根据特定使用场景调整的是 Temperature 参数。当您处理需要创造性的用例(如内容生成)时,通常会将该值设置得接近 1。相比之下,对于需要事实性和精确答案的用例,通常会选择接近 0 的值。
- 现在,让我们使用 GPT-3.5 模型进行聊天交互,如图 2.21所示。在这个例子中,我们首先提出问题:“2011 年 ICC 世界杯系列赛的冠军是谁?”模型的回答是:“印度在 2011 年 ICC 世界杯系列赛中获胜。”随后,我们提出跟进问题:“决赛在哪里举行?”模型的回答是:“2011 年 ICC 世界杯系列赛的决赛在印度孟买的万科德体育场举行。”这展示了可以持续进行的对话式交互:
图 2.21:描述代理和用户聊天互动
这样,您就已经有效地利用了 AOAI 模型进行类似 ChatGPT 的对话。在下一节中,我们将讨论如何使用 Python SDK 利用相同的 GPT-3.5 Turbo 或 GPT-4 模型。
编程体验
在本节中,我们将引导您通过使用 Python SDK 进行首次调用 AOAI 的过程:
-
在您的计算机上安装 Python 版本 3.7.1 或更高版本。或者,您可以使用 Azure Machine Learning 笔记本获取 Python 环境。在此示例中,我们使用了 Anaconda 和 Visual Studio Code 作为 IDE。
-
通过运行
pipinstall openai安装 OpenAI Python 客户端库。 -
要向 AOAI 服务发起请求,您需要以下输入:
ENDPOINT您可以在 API-KEY中找到此值您可以在 DEPLOYMENT-NAME中找到此值此值对应您在部署 AOAI 模型部分中为部署选择的自定义名称。 要获取前两个值,请导航到 Azure 门户中的资源。您可以在资源管理部分找到密钥和终结点。确保复制您的终结点和访问密钥;您需要这两个信息来验证 API 调用。您可以选择使用KEY 1或KEY 2。这两个密钥的存在使得密钥轮换和再生在不中断服务的情况下进行:
图 2.22:检索 AOAI 密钥和终结点信息
-
在您偏好的 IDE 中,创建一个名为
quickstart.py的 Python 文件,并执行以下代码:-
导入必要的 Python 包,并设置 AOAI 密钥和终结点信息。确保将部署名称的值更改为您在创建部署时提供的自定义名称:
import os import requests import json import openai openai.api_key = "<ENTER YOUR API KEY>" openai.api_base = "<ENTER YOUR ENDPOINT>" openai.api_type = 'azure' openai.api_version = '2023-08-01-preview' # API version may change in the future deployment_name='gpt-35-turbo' # Enter your Deployment Name. -
调用 AOAI 聊天完成 API,并提供 AOAI 部署名称,以及系统和用户消息详细信息:
# Send a chat completion call to generate an answer response = openai.ChatCompletion.create( / engine="gpt-35-turbo", # This is your deployment name messages=[ {"role": "system", "content": "You are an AI assistant that helps people find information."}, {"role": "user", "content": "Who won the ICC world cup series in 2011?"}, {"role": "assistant", "content": "India won the ICC world Cup series in 2011."}, {"role": "user", "content": "Where the final match played?"}] ) -
打印模型的最终响应:
print(response['choices'][0]['message']['content'])
输出应该类似于以下内容:
The final match of the ICC World Cup 2011 was played at the Wankhede Stadium in Mumbai, India. -
重要提示
在生产环境中,建议使用安全的方法存储和访问凭据,例如 Azure Key Vault。这确保了敏感信息的最高安全级别。
至此,您已了解如何使用 AOAI GPT-3.5 和 GPT-4 模型。我们尚未讨论的是如何使用嵌入模型;我们将在下一章中进行介绍。在下一节中,我们将讨论 AOAI 定价。
定价
在本节中,我们将讨论各种 AOAI 定价选项,并帮助您选择最适合您需求的计划。
AOAI 有两种不同的定价计划:
- 按需计费:在此定价模型下,您将根据每 1,000 个标记的提示和完成的消耗量进行计费。请注意,每个模型在提示和完成方面有其独特的定价。此计划更适用于开发和测试环境,以及那些 API 调用和处理的标记量不大的特定生产工作负载。有关完整的定价表,请参阅
azure.microsoft.com/en-us/pricing/details/cognitive-services/openai-service/。需要注意的是,这些费用可能会在未来发生变化,因此建议您检查提供的前述链接,以获取最准确的定价信息:
| 模型 | 上下文窗口 | 提示(每1,000 个标记) | 完成(每1,000 个标记) |
|---|---|---|---|
| gpt-35-turbo | 4K | $0.0015 | $0.002 |
| gpt-35-turbo | 16K | $0.003 | $0.004 |
| gpt-4 | 8K | $0.03 | $0.06 |
| gpt-4 | 32K | $0.06 | $0.12 |
| text-embedding-ada-002 | 8K | $0.0001 |
-
PAUG:在此定价计划下,您将最初获得默认的吞吐量级别,也称为配额。这意味着模型将根据您选择的地区每分钟处理一定数量的标记。您可以选择请求额外的配额,直到达到一定的上限。如果您的需求超过预定的限制,您应考虑使用预配置吞吐量单元(PTU)定价计划,我们将稍后讨论。在后续章节中,我们将详细介绍配额管理。有关最新的配额和限制,请参考以下链接:
以下表格将帮助您确定每个模型能够提供的吞吐量:
模型 上下文窗口 默认 吞吐量(标记/分钟) gpt-35-turbo 4K 240K gpt-35-turbo 16K 240K gpt-4 8K 20K gpt-4 32K 40K text-embedding-ada-002 8K 240K 请注意,这些信息可能会随时间变化,因此请始终查阅最新文档,以获取最准确的信息:
learn.microsoft.com/en-us/azure/ai-services/openai/quotas-limits。- 预配吞吐量单元 - 托管 (PTU-M):PTU-M 是 AOAI 服务中的一项新功能,允许您为高容量或对延迟敏感的工作负载预留专用的处理能力。PTU 处理能力提供一致的延迟和吞吐量水平,非常适合具有稳定特征的工作负载,例如均匀的提示大小、完成大小和并发 API 请求数。PTU 可按小时(无承诺)、按月或按年(有承诺)购买。在此定价计划中,您支付固定的统一费率,在承诺期内可以自由发送无限数量的标记。此外,与标准按需支付选项相比,此计划提供更高的吞吐量。PTU 吞吐量可能会根据输入标记、输出标记和每分钟 API 调用次数等因素波动。为了准确评估特定 PTU 单元的吞吐量,您可以使用微软提供的基准脚本。您可以在此处访问基准工具:
github.com/Azure/azure-openai-benchmark。
让我们来解析一下 PTU 的定价结构。对于没有任何承诺的按小时使用 PTU,每小时每个 PTU 的费用为 2 美元。对于按月承诺的费用,每个 PTU 每月 260 美元,而按年承诺则是每个 PTU 每年 221 美元。
每个模型都有最低的 PTU 要求和最小的扩展增量。例如,GPT-4o 需要至少 50 个 PTU 才能运行,并且需要 50 个单位进行增量扩展。因此,如果选择按月承诺,GPT-4o 每月的费用为 260 美元乘以 50 个 PTU,总计 13,000 美元。如果您需要扩展 GPT-4o 的使用量,仍然需要按增量添加 50 个 PTU。
有关各种模型的详细定价信息,请参阅所提供的表格。现在,让我们深入了解定价结构的运作方式。每个 PTU 每月的费用为 312 美元。不同的模型类型需要不同数量的 PTU 才能最佳运行。例如,具有 4K 上下文窗口的 GPT-35 Turbo 至少需要 300 个 PTU,提供 90 万到 270 万 TPM 的吞吐量。如果需要额外的吞吐量,可以每次增加 100 个 PTU,带来额外的 30 万到 90 万 TPM 的吞吐量。
另一方面,GPT-35 Turbo 具有 16K 上下文窗口,最小需要 600 个 PTU,提供 180 万到 540 万 TPM 的吞吐量。为了进一步提升吞吐量,可以每次增加 200 个 PTU,带来每分钟 60 万到 180 万个标记的额外吞吐量。有关每种模型类型的最低 PTU 要求、相关费用和吞吐能力的详细信息,请参见下表:
- 预配吞吐量单元 - 托管 (PTU-M):PTU-M 是 AOAI 服务中的一项新功能,允许您为高容量或对延迟敏感的工作负载预留专用的处理能力。PTU 处理能力提供一致的延迟和吞吐量水平,非常适合具有稳定特征的工作负载,例如均匀的提示大小、完成大小和并发 API 请求数。PTU 可按小时(无承诺)、按月或按年(有承诺)购买。在此定价计划中,您支付固定的统一费率,在承诺期内可以自由发送无限数量的标记。此外,与标准按需支付选项相比,此计划提供更高的吞吐量。PTU 吞吐量可能会根据输入标记、输出标记和每分钟 API 调用次数等因素波动。为了准确评估特定 PTU 单元的吞吐量,您可以使用微软提供的基准脚本。您可以在此处访问基准工具:
图 2.23:PTU 定价信息
尽管 AOAI 提供了多种 LLM,客户通常根据具体的使用场景选择不同的模型,以便平衡成本和精度。对于复杂任务,如临床协议编写、药物发现和临床试验匹配,客户通常选择 GPT-4o,因为它具有更高的准确性。对于不那么复杂的任务,如客户支持聊天机器人或实体提取,客户可能会选择 GPT-3.5 或 GPT-4o mini,这些模型提供了更好的性价比,更具经济可行性。
重要提示
需要注意的是,您不能像其他服务一样直接通过 Azure 门户购买 PTU。要为您的订阅购买 PTU,您必须联系微软账户代表,他们将帮助您获得在订阅中使用 PTU 的批准。批准后,您可以继续购买 PTU。PTU 的价格未来可能会有所变动。因此,建议您始终与微软账户代表咨询,以获取最新的定价信息。
摘要
本章深入探讨了 AOAI 服务。我们首先定义了 AOAI 服务是什么,接着讨论了它提供的各种模型类型。我们还指导您完成了访问此服务的步骤,从创建 AOAI 资源到部署模型并将其用于实际应用。最后,我们阐明了定价结构,确保您清楚了解如何在 Azure 生态系统中利用这一强大的 AI 服务。有了这些知识,您已具备了在 AI 和机器学习项目中利用 AOAI 服务的能力。
展望下一章,我们的注意力将转向深入探讨 AOAI 中的高级主题。我们将探索嵌入模型,并学习如何将这些嵌入存储在向量数据库中,借助 Azure Cognitive Search 服务。此外,我们还将深入了解模型基础和微调模型的复杂性,以满足特定需求。
此外,我们还将讨论一些最新的功能,如函数调用、助手 API、微调和批量 API。这些高级主题将提供对 AOAI 功能的更深理解,使您能够充分利用其潜力。最后,我们将强调 LLM 应用开发框架的重要性,如 LangChain 和 Semantic Kernel。这些框架在简化应用程序创建方面起着至关重要的作用。通过利用这些框架的能力,开发人员可以简化开发过程,充分利用 LLM 的力量,轻松构建创新和智能的应用程序。随着我们在 AI 和语言处理领域的前进,这些框架作为重要工具,帮助我们充分发挥 LLM 在各种应用中的潜力。
进一步阅读
要了解本章中涉及的更多内容,请查看以下资源:
-
AOAI 服务简介 (
learn.microsoft.com/en-us/training/modules/explore-azure-openai/) -
AOAI:生成式 AI 模型及其使用方法 (它们) (
www.linkedin.com/learning/azure-openai-generative-ai-models-and-how-to-use-them)
第三章:Azure OpenAI 高级主题
在前面的章节中,我们已经介绍了Azure OpenAI(AOAI)服务的基础知识,包括模型部署和各种定价结构。现在,我们将转向深入探讨 AOAI 中的更多高级主题。
在本章中,我们将深入探讨以下高级 AOAI 主题:
-
AOAI 模型上下文窗口
-
AOAI 嵌入模型
-
Azure 向量数据库
-
AOAI 在您的数据上
-
AOAI 多模态模型
-
AOAI 函数调用
-
AOAI 助理 API
-
AOAI 批量 API
-
AOAI 微调
AOAI 模型上下文窗口
在大型语言模型(LLMs)的世界中,上下文窗口定义了模型一次可以处理的文本量,影响模型如何生成和理解语言。这个窗口通过令牌的数量来衡量(可以是完整的单词或碎片),直接影响模型用于预测下一个令牌的信息量。简单来说,它决定了模型在形成预测或生成响应时,考虑了多少上下文信息。
例如,GPT-3.5-Turbo(0125)模型的上下文具有 16,385 个输入令牌和 4,096 个输出令牌,而 GPT-4o 和 GPT-4o mini 模型的上下文则大得多,拥有 128,000 个输入令牌和 16,384 个输出令牌。有关 AOAI 模型上下文窗口的信息,请访问learn.microsoft.com/en-us/azure/ai-services/openai/concepts/models?#gpt-4-and-gpt-4-turbo-models。
LLM 的趋势正在向更大的上下文窗口发展,这使得输出更为详细和连贯。然而,这也带来了代价:更大的上下文窗口需要更多的计算能力和内存。实际上,上下文窗口定义了模型在交互过程中能够“记住”多少先前的对话内容。当对话超过上下文窗口时,模型将丢失最早的部分对话,这可能影响它在长时间交互或复杂任务中的一致性。因此,上下文窗口大小是构建使用 LLM 的应用程序时需要考虑的一个关键因素。
虽然更大的上下文窗口使得 LLMs 能够处理更多的数据,但它们也伴随着巨大的计算和财务成本。处理大量上下文长度非常昂贵且极其缓慢,这只在有限的情况下是可以接受的。例如,当处理数百万个令牌时,百万令牌的上下文窗口可能需要近一分钟才能生成一个响应。
相比之下,检索增强生成(RAG)更加高效,因为它仅获取每个查询最相关的信息,从而减少了模型需要处理的令牌数量。这种高效性使得 RAG 成为一种更具成本效益的解决方案,尤其适用于需要频繁查询或高频数据密集型任务的应用。我们将在后面的章节中详细解释 RAG。
在文本被拆分为标记后,每个标记都会转换为一种称为嵌入的数字形式。嵌入是旨在捕捉标记意义的密集向量表示。这些向量存在于一个高维空间中,其中向量之间的距离和方向可以表示它们所代表的词语之间的语义和句法关系。
在下一部分,我们将讨论 AOAI 使用的嵌入模型,该模型将标记转换为嵌入向量。
AOAI 嵌入模型
AOAI 拥有四种不同的嵌入模型,每种模型都有特定的输入标记数和输出维度限制:
-
text-embedding-ada-002(****版本 2):
-
最大输入 标记数:8,191
-
输出 维度:1536
-
-
text-embedding-ada-002(****版本 1):
-
最大输入 标记数:2046
-
输出 维度:1536
-
-
text-embedding-3-large:
-
最大输入 标记数:8191
-
输出 维度:3072
-
-
text-embedding-3-small:
-
最大输入 标记数:8191
-
输出 维度:1536
-
text-embedding-3-small 和 text-embedding-3-large 是最新且最强大的嵌入模型。它们现在已在 AOAI 上可用。
text-embedding-ada-002(版本 2)
text-embedding-ada-002 模型整合了五种不同模型的功能,用于搜索文本、比较文本相似性和搜索代码。它在大多数任务中比我们之前的顶级模型 Davinci 表现更好,并且便宜 99.8%。此模型的上下文长度为 8,192,比之前的 text-embedding-ada-002 版本更长。
你可以像使用之前的版本一样,使用几行代码调用此嵌入模型,方法是使用我们的 OpenAI Python 库:
from openai import AzureOpenAI
client = AzureOpenAI(
api_key = os.getenv("AZURE_OPENAI_API_KEY"),
api_version = "2024-04-01-preview",
azure_endpoint =os.getenv("AZURE_OPENAI_ENDPOINT")
)
response= client.embeddings.create(input = "<INPUT TEXT>",
model=<deployment name>).data[0].embedding
print (response)
text-embedding-3-small
text-embedding-3-small 是一种全新的、高效的嵌入模型,相比于 2022 年 12 月发布的 text-embedding-ada-002(版本 2)提供了显著的升级。
它具有改进的性能:
-
text-embedding-3-small 在 多语言检索 (MIRACL) 上表现优于 text-embedding-ada-002,平均得分从 31.4% 提升至 44.0%。
-
对于 英语任务 (MTEB),平均得分从 61.0% 提升至 62.3%
它还具有更低的成本。text-embedding-3-small 比 text-embedding-ada-002 的成本效率高五倍,将每千个标记的价格从 0.00002。
text-embedding-3-large
text-embedding-3-large 是另一种新型、下一代的嵌入模型,生成的嵌入具有最多 3,072 个维度。
它具有改进的性能:
-
text-embedding-3-large 是表现最好的模型
-
在 MIRACL 上,它将平均得分从 31.4%(text-embedding-ada-002)提升至 54.9%
-
在 MTEB 上,平均得分从 61.0% 增加到 64.6%
就成本而言,text-embedding-3-large 的成本略高于 text-embedding-3-small,每千个标记的价格为 $0.00013。
AOAI 并不会停止提供 text-embedding-ada-002(版本 2),因此客户如果更喜欢,仍然可以继续使用它。然而,推荐切换到更新的模型,以获得更好的性价比。
两种新的嵌入模型都使用一种叫做dimensions API 参数的技术,你可以在不丢失含义的情况下减少嵌入的大小。
例如,在 MTEB 基准测试中,一个 text-embedding-3-large 嵌入可以缩短至 256 维,同时仍然优于一个未缩短的 text-embedding-ada-002 嵌入(1,536 维)。
通常,在创建嵌入时最好使用dimensions参数。如果之后需要更改维度,请确保嵌入已标准化,如下所示:
from openai import AzureOpenAI
import numpy as np
client = AzureOpenAI(
api_key = os.getenv("AZURE_OPENAI_API_KEY"),
api_version = "2024-04-01-preview",
azure_endpoint =os.getenv("AZURE_OPENAI_ENDPOINT")
)
def normalize(x):
x = np.array(x)
if x.ndim == 1:
norm = np.linalg.norm(x)
if norm == 0:
return x
return x / norm
else:
norm = np.linalg.norm(x, 2, axis=1, keepdims=True)
return np.where(norm == 0, x, x / norm)
response = client.embeddings.create(
model="<DEPLOYMENT NAME>",
input="<INPUT TEXT>",
encoding_format="float"
)
cut_dim = response.data[0].embedding[:256]
norm_dim = normalize(cut_dim)
print(norm_dim)
动态变化维度允许灵活使用。例如,如果一个向量数据库仅支持最多 1,536 维的嵌入,开发者仍然可以通过将dimensions API 参数设置为1536,使用最好的模型 text-embedding-3-large。这样可以将嵌入从 3,072 维缩减,牺牲一些准确度换取更小的向量大小。这为我们在下一节讨论 Azure AI Search 服务中的向量搜索功能奠定了基础。
Azure 向量数据库
在前一节中,我们探讨了多种 AOAI 嵌入模型用于生成向量嵌入。创建这些向量后,必须拥有一个优化过的数据库来有效存储和管理它们。向量数据库与其他类型数据库的关键区别在于其能够处理高维数据。向量数据库专门设计用于将数据存储为高维向量,这些向量是各种特征或属性的数学表示。每个向量包含多个维度,数量从几十到上千不等,具体取决于数据的复杂性和细节。这些向量通常是通过将转换或嵌入函数应用于原始数据源(如文本、图像、音频、视频等)生成的。此类数据库使得可以使用向量搜索算法进行嵌入的索引和查询,评估向量的距离或相似度。为了确保准确检索相关信息,必须有一个强大的机制。主要的向量搜索算法包括层次可导航小世界(HNSW)、倒排文件(IVF)和 DiskANN 等。
向量数据库的主要优势在于它能够基于向量距离或相似度进行快速且精确的相似性搜索和数据检索。与依赖精确匹配或预定义查询标准的传统数据库不同,向量数据库可以根据语义或上下文意义识别最相似或最相关的数据。以下是一些实际应用:
-
搜索引擎:向量数据库通过支持基于相似性的高效搜索,改变了搜索引擎的运作方式。它们帮助查找相似的项目,提高搜索相关性,并增强用户体验。
-
图像检索:根据视觉内容和风格,识别与给定图像相似的图像。
-
文档搜索:根据主题和情感等因素,定位与给定文档相似的文档。
-
产品推荐:根据特征和评分,发现与给定产品相似的产品。
-
语义搜索:向量数据库增强了语义搜索能力,使应用能够找到具有上下文相关性的内容。这使得它们在信息检索、聊天机器人和问答系统中具有重要价值。
-
推荐系统:推荐系统通过利用向量数据库,根据用户的偏好提供个性化的产品推荐或内容建议,从而提高推荐的准确性。
-
医学和科学研究:在基因组学和化学等领域,向量数据库促进了基因数据分析、化学化合物相似性的识别,以及科学发现的加速。
要在向量数据库中执行相似性搜索和检索,需要一个封装了您期望信息或标准的查询向量。这个查询向量可以来自与存储向量相同类型的数据(例如,使用图像查询图像数据库),也可以来自不同类型的数据(例如,使用文本查询图像数据库)。下一步是使用相似性度量来确定两个向量在向量空间中的接近度或距离。为此目的,可以采用各种度量标准,如余弦相似度、欧几里得距离、汉明距离和杰卡德指数。相似性搜索和检索过程的结果通常是一个按与查询向量相似度得分排序的向量列表。随后,您可以从原始源或索引中检索与每个向量相关联的数据。
Azure 提供六种不同种类的向量数据库选项,旨在满足多样化的需求和使用场景:
-
Azure AI Search:Azure AI Search 是一个强大的工具,具有向量搜索功能。它利用 HNSW 算法进行向量搜索,使用 Best Match 25(BM25)算法进行全文搜索。此外,它还提供了一种混合搜索选项,结合了全文搜索和向量查询的结果,每种查询使用不同的排序方法,例如 BM25 和 HNSW。Reciprocal Rank Fusion(RRF)算法用于整合这些结果,确保生成一个统一、连贯的结果集,突出显示搜索索引中最相关的匹配项。实际上,OpenAI 利用 Azure AI Search 来增强其 ChatGPT 应用的功能。通过集成 Azure AI Search,OpenAI 受益于先进的搜索功能,如向量搜索、全文搜索和混合搜索,这些功能结合了 BM25 和 HNSW 算法的优势。这种集成使 ChatGPT 能够通过高效地检索和排序来自搜索索引的信息,提供更准确和相关的响应。
但是,需要注意的是,Azure AI Search 不会为您的内容生成向量嵌入;您需要自己提供这些嵌入。生成这些嵌入的一个可行选项是使用 AOAI 嵌入模型。
从架构角度来看,AI Search 服务充当外部数据存储和客户端应用之间的中介,外部数据存储存放您的未索引数据,而客户端应用则发送查询请求到搜索索引并管理响应。
图 3.1:Azure AI Search 应用架构
在您的客户端应用中,搜索体验是通过 Azure AI Search API 打造的,这些 API 可以包括相关性调整、语义排名、自动完成、同义词匹配、模糊匹配、模式匹配、筛选和排序等功能。
Azure AI Search 还提供与其他 Azure 服务的无缝集成。这通过索引器得以实现,索引器自动从各种 Azure 数据源中提取和检索数据,以及结合 Azure AI 服务的技能集,这些技能集可以包括图像和自然语言处理,或者封装在 Azure Functions 中的自定义代码。
-
WHERE子句。这使得您的向量搜索能够为您的应用提供最相关的数据。该功能增强了 Azure Cosmos DB 的核心能力,使其在处理 AI 应用中的向量数据和搜索需求时更加多样化。
-
Azure Cosmos DB for MongoDB:Azure Cosmos DB for MongoDB 还提供集成的向量数据库功能,允许将嵌入存储、索引并与其他关系数据一起查询。此功能使得在 MongoDB 集合中高效管理和检索向量数据成为可能,从而增强了 Azure Cosmos DB 在多种应用需求中的适用性。
MongoDB vCore 提供了两种类型的向量索引方法:
-
IVF:IVF 索引是一种在向量搜索中使用的方法,通过将向量分组进行聚类,有效组织和管理大量向量。每个聚类由一个质心或中心点表示。在搜索过程中,查询向量首先与这些质心进行比较,以确定最接近的聚类。然后,在该特定聚类内进行搜索,显著减少搜索空间并提高检索速度。此方法平衡了速度和准确性,非常适合需要快速且高效向量搜索的应用。
-
HNSW:这是一种用于高维空间中近似最近邻(ANN)搜索的先进算法,利用多层图结构组织数据点。每一层代表不同的接近度级别,较高的层包含较少、代表性更广的点,而较低的层包含更为详细的点。这个可导航的图通过从顶部层开始,向下移动以找到更近的邻居,利用“随机小世界”属性快速访问整个数据集。HNSW 提供了快速且准确的 ANN 搜索,非常适用于推荐系统、图像检索和自然语言处理等应用。
-
-
在 Azure PostgreSQL 灵活服务器上提供
pgvector扩展,您可以将向量功能无缝集成到您的 PostgreSQL 环境中。pgvector是一个为 PostgreSQL 定制的开源扩展,能够直接在 PostgreSQL 中存储和检索来自自然语言处理或深度学习模型的向量。pgvector特别吸引人的地方在于其熟悉的基于 SQL 的接口,类似于传统 PostgreSQL 操作,用于创建向量列、定义包含向量列的表以及使用 L2 距离执行最近邻搜索等任务。无论您是开发 AI 应用、创建推荐系统,还是处理高维数据,pgvector都简化了在熟悉的数据库框架中进行向量管理,免去了专门的存储解决方案和深入了解向量数据库的需求。 -
Azure SQL:Azure SQL 数据库现在支持直接在数据库中执行向量操作,能够高效地进行向量相似度搜索。结合全文搜索和 BM25 排序,这一功能使得开发适用于各种应用的强大搜索引擎成为可能。执行向量操作有两种方法:本地选项和经典选项:
-
本地选项:利用 Azure SQL 数据库中新引入的向量函数。这些函数旨在直接在数据库中执行向量操作,提供简化且高效的方法。
-
经典选项:使用传统的 T-SQL 进行向量操作,利用列存储索引实现高性能。
这两种选项都为实现向量搜索提供了强大的解决方案,使得 Azure SQL 数据库成为一个适用于高级搜索场景的多功能工具。
微软最近宣布的SQL Server 2025标志着数据库演变的重要一步,将其推出为企业级向量数据库。这一版本集成了内置安全性和合规性,强调其支持企业级AI 解决方案的重点。一个突出特点是原生向量存储和索引,由 DiskANN 提供支持,利用磁盘存储执行高性能搜索,适用于大规模数据集。这个功能支撑语义搜索,使得高效的分块和准确的数据检索成为可能——这是 AI 驱动的洞察所必需的关键功能。这一进展使得高维数据的高效处理成为可能,非常适合 AI 工作负载,如推荐系统、自然语言处理和图像搜索。
-
-
RediSearch模块提供了全面的搜索功能,包括多种距离度量方法,如欧几里得距离、余弦相似度和内积,并支持使用 FLAT 索引的 KNN 和使用 HNSW 索引的 ANNs。它支持以哈希或 JSON 格式存储向量,并支持通过 top-K 和向量范围查询来查找位于特定向量距离内的项。此外,Redis 通过高级功能增强了搜索功能,如地理空间过滤、数值和文本过滤、前缀和模糊匹配、语音匹配和布尔查询。Redis 通常被认为是一种具有成本效益的解决方案,广泛用于缓存或会话存储,使其能够同时处理传统的缓存角色和向量搜索应用。
大多数 Azure 向量数据库,如 AI Search、CosmosDB 和 Azure 托管 Redis,都与 LLM 框架如 Semantic Kernel、LangChain 和 LlamaIndex 集成,以便轻松创建向量并将其导入到各自的服务中。这些集成简化了嵌入生成、存储和检索的过程,使得向量数据的高效处理成为可能,并增强了 GenAI 应用的能力。
Azure 还提供了一种无需编码的解决方案,用于创建向量嵌入并将其自动导入到 Azure AI Search 或 Cosmos DB,作为其原生功能的一部分。在接下来的部分,我们将探索这个能力,作为AOAI On Your Data的一部分。
AOAI On Your Data
在各行各业中,一个常见的应用是利用生成性 AI 创建个性化聊天机器人,通过使用自身的企业数据。传统上,这要求客户手动编写代码,从非结构化数据中提取文本,生成嵌入,并将其存储在向量数据库中,这对开发者来说既耗时又劳动密集。然而,Azure OpenAI 的 On Your Data 功能显著简化了这一工作流程,使开发者能够在几乎不编写任何代码的情况下实现相同的结果。这意味着,构建一个聊天机器人应用程序现在只需几次点击即可完成。
此功能在后台使用 RAG 技术,如图 3.2所示。
图 3.2:AOAI 在您的数据中的 RAG 架构
当你上传各种格式的文档集合时,这些文档会被拆分成更小的块。每个块会被转换为嵌入,例如 text-embedding-ada-002,并使用 AOAI 的嵌入模型进行处理。这些嵌入会存储在 AI 搜索向量数据库中,利用 HNSW 索引进行语义搜索。用户可以通过 GPT4-o 聊天输入查询,这些查询也会使用相同的嵌入模型转换为嵌入。然后,使用 ANN 技术在 HNSW 索引上进行相似性搜索,找到最相关的文档向量。接着,将检索到的上下文和原始用户查询提供给 GPT 模型,以生成对用户问题的回答。
此外,Azure RBAC 确保整个系统的安全访问和权限控制。整个过程简化且用户友好,让你可以专注于利用洞察,而不必处理技术复杂性。
重要提示
在使用“On your Data”功能之前,请确保已设置 Azure AI Search 资源。要设置 Azure AI Search 资源,请参考 learn.microsoft.com/en-us/azure/search/search-create-service-portal 中提供的说明。
现在,让我们演示如何在不编写任何代码的情况下轻松使用此功能:
-
登录到 Azure AI Foundry 门户。
-
如果你还没有设置聊天模型和嵌入模型,前往
text-embedding-ada-002。 -
从 Playgrounds 菜单中导航到 Chat,然后选择 Add your data 标签。
-
点击 Add a data source。
你可以选择多种数据源。在本演示中,我们手动上传文件。你也可以选择直接使用 Blob 存储帐户,如果你的数据已经在那里。如果你有一个 AI 搜索索引,数据已经预先索引并向量化,你也可以连接到该索引。
-
选择适当的订阅和您上传数据将存储的 blob 存储账户。接下来,选择用于存储向量索引的Azure AI 搜索资源选项,最后指定索引名称。
-
勾选复选框以启用此 AI 搜索资源的向量搜索功能。有关详细信息,请参见图 3.3。
图 3.3:AOAI On Your Data 设置
-
点击下一步。
-
在接下来的屏幕上,上传一个 PDF 文件。您还可以上传
.txt、.md、.html、.pdf、.docx或.pptx格式的文件。在此示例中,我上传的是一张酒店发票的 PDF 收据。有关收据的示例视图,请参见图 3.4。
图 3.4:AOAI On Your Data 的示例数据
-
点击下一步。
-
选择您想要使用的搜索类型选项。您可以从以下三种选项中进行选择:
-
向量:该选项通过向量嵌入查找与查询相似的文档。
-
混合(向量 + 关键词):该选项结合了基于向量字段的相似性搜索和基于关键词的全文搜索。
-
混合 + 语义:该选项利用向量嵌入、语言理解和灵活的查询解析,提供高级搜索体验。由于其卓越的搜索质量,强烈推荐此选项。
选择正确的类型可以根据您的具体需求增强搜索能力。
-
-
选择块大小。分块涉及将文档拆分为更小的部分,以提高搜索和检索效率,块大小以标记为单位进行测量。
-
点击下一步。在接下来的屏幕上,选择认证类型。
-
索引所需的时间可能会随着文档大小的增加而增加。
-
选择要使用的部署选项,并填写系统消息字段,如图 3.5所示。然后点击应用更改。
图 3.5:On Your Data 设置
-
现在,您已准备好从Chat playground开始聊天。
-
请参见图 3.6了解示例问题。您可以根据提供的文档提问并获得准确的答案。点击参考文献查看答案的引用。
图 3.6:带参考的示例问题和答案
您已经观察到答案是如何基于您的数据使用 AOAI On Your Data 功能生成的。如果您打算开发一个 Web 应用并将其部署到生产环境,只需点击作为 Web 应用部署,并按照图 3.7所示填写应用服务详情。然后点击部署,为用户创建一个 Web 应用。
图 3.7:Chat On Your Data 网络应用设置
部署后,您将收到应用程序的公共 URL,允许最终用户与他们上传的文档进行互动,如下所示:
图 3.8:Web 应用视图
这个过程简化了应用部署,使你只需几次点击就能将聊天应用提供给最终用户,无需编写代码。这是一个快速部署和共享应用的高效方式。然而,需要注意的是,虽然该功能非常适合小规模的概念验证,但开发一个健壮的生产应用仍需要仔细考虑各个因素,以提高准确性。这些因素包括分块策略、查询重写以及定制提示模板的设计。鉴于这些能力的局限性,通常需要采用代码优先的方法来创建更复杂和量身定制的解决方案。
到目前为止,我们已经将 AOAI 模型应用于文本相关的场景。然而,也有一些场景需要理解图像。在接下来的部分,我们将探索 AOAI 的多模态能力,其中输入是图像,输出是文本。通过结合视觉数据分析,这种方法拓宽了 AOAI 的应用范围。
AOAI 多模态模型
AOAI 多模态能力可以应用于各种现实世界场景,具体如下:
-
图像标注:自动生成图像的描述性文本,适用于组织数字照片集或帮助视障用户
-
音频处理:低延迟对话场景,要求用户与模型之间实时互动,例如客户支持聊天机器人、语音助手和实时翻译服务
-
视觉问答:回答关于图像的问题,可以增强互动教育工具或客户支持系统
-
内容审查:分析图像以检测不当或有害内容,提高社交媒体平台的安全性
-
电子商务:从图像中提供产品描述,帮助目录管理并改善用户搜索体验
-
医疗健康:通过解读医学图像并提供初步报告来辅助医学诊断
这些应用场景展示了集成视觉和文本数据处理的多样性。为了实现这些功能,AOAI 提供了一个带有内建多模态特性的 GPT-4 类别模型。目前,AOAI 在 GPT-4 系列中提供了三种不同的模型,支持这些原生的多模态能力:
-
GPT4-Turbo
-
GPT4-o
-
GPT4-o-mini
现在,让我们测试 GPT4-o 的多模态能力,来自Chat playground:
-
登录到 Azure AI Foundry 门户。
-
导航到Playgrounds菜单中的Chat from。
-
上传图片到聊天中并提问。或者,你可以通过 SDK 提供一个 base64 编码的图像作为输入,以便模型处理。为了说明,我使用了图 3.9。
图 3.9:GPT4-o 示例图
你可以提问如下问题:
"CB 线的尺寸是多少?"
尽管 AOAI GPT4-o 的视觉能力在各类应用中非常多样且有用,但必须认识到它的局限性。以下是需要注意的几个关键限制:
-
医学图像:模型并不适用于解释专门的医学图像,如 CT 扫描,因此不应用于医学建议
-
非英语文本:处理包含非拉丁字母文本的图像(如日语或韩语)时,性能可能会下降
-
小文本:为了提高可读性,放大图像中的小文本,但要确保没有重要细节被裁剪掉
-
旋转问题:模型可能会误解被旋转或倒置的文本或图像
-
视觉元素:理解带有不同颜色或样式的图表或文本,如实线、虚线或点线,对于模型来说可能是具有挑战性的
-
空间推理:需要精确空间定位的任务,如识别国际象棋位置,对于模型来说是困难的
-
准确性:在某些情况下,模型可能会生成不准确的描述或说明
-
图像形状:全景图和鱼眼图像对模型来说存在困难
-
元数据和调整大小:模型不会处理原始文件名或元数据,图像会在分析前调整大小,这可能会影响其原始尺寸
-
计数:模型可能会提供图像中物体的近似计数
-
验证码:出于安全原因,系统配置为阻止提交验证码
了解这些限制有助于客户设定现实的期望,并确保模型的正确应用。
现在我们已经了解了 GPT4-o 视觉功能的能力和局限性,让我们来看看图像输入的成本模型。
图像的 token 成本
图像输入与文本输入一样,都是按 tokens 计费。图像的 token 成本受两个主要因素的影响:图像的尺寸和为每个图像 URL 块指定的细节级别。以下是详细的分解:
-
低细节:每张设置为低细节的图像需要 85 个 tokens。
-
高细节:对于高细节图像,处理过程较为复杂。首先,图像被缩放至 2,048 x 2,048 的正方形,并保持其长宽比。接着,图像再次缩放,使其最短边为 768 像素。然后,计算构成图像的 512 像素方块数量,每个方块需要 170 个 tokens。最终,额外增加 85 个 tokens。
让我们看一些例子:
-
1,024 x 1,024 高细节图像:
-
由于 1,024 小于 2,048,因此不需要初步调整大小
-
图像被缩小至 768 x 768,因为最短边为 1,024
-
这需要四个 512 像素的块
-
token 成本计算如下:170 tokens/块 * 4 块 + 85 tokens = 765 tokens。
-
-
2,048 x 4,096 高细节图像:
-
图像首先被缩放到 1,024 x 2,048,以适应 2,048 平方的范围
-
最短边为 1,024,因此进一步缩放至 768 x 1,536
-
这需要 6 个 512 像素的瓦片
-
令牌成本计算如下:170 令牌/瓦片 * 6 个瓦片 + 85 令牌 = 1,105 令牌
-
-
4,096 x 8,192 图像的 低细节:
-
无论输入大小如何,低细节图像具有固定成本
-
令牌成本为 85 个令牌
-
理解这个令牌成本结构可以帮助有效管理图像输入时的资源使用。
到目前为止,我们已经探讨了 AOAI 模型的自包含功能。然而,企业中有一些用例需要客户将 LLM 与外部系统或工具集成。这允许将自然语言查询转换为这些系统可执行的结构化输入。在下一部分,我们将讨论开发人员如何通过使用 AOAI 的函数调用功能来实现这一功能。
AOAI 函数调用
AOAI 函数调用允许你将 GPT-4o 等模型与外部工具和系统连接。这对于增强 AI 助手的能力或在应用程序与模型之间创建无缝集成非常有利。
此功能并不会直接为你运行函数。相反,你在 API 调用中定义函数,模型会弄清楚如何生成所需的参数。在这些参数生成后,你可以用它们在代码中执行函数。
函数调用对许多应用程序有益,例如:
-
允许助手检索信息:AI 助手可能需要访问来自内部系统(例如 Azure Cosmos DB 或 Azure SQL)的最新客户数据,以回答用户关于近期订单的查询
-
使助手执行任务:AI 助手可以根据用户偏好和日历可用性安排会议
-
协助计算:数学辅导助手可以根据需要执行计算
-
创建复杂工作流:例如,数据提取过程可以收集原始文本,将其转换为结构化数据,并将其存储在数据库中
-
修改应用程序的用户界面:函数调用可以根据用户的操作更新 UI,例如在地图上显示一个图钉
现在,让我们讨论一下 AOAI 函数调用的生命周期。
函数调用生命周期
函数调用有五个不同的阶段,如图 3.10所示:
-
你的代码通过调用 API 并提供提示和 LLM 可以访问的函数来启动该过程。
-
模型评估是否直接响应用户,还是需要调用一个或多个函数。
-
API 回复你的应用程序,指定应该调用哪个函数以及所需的参数是什么。
-
你的应用程序使用提供的参数运行指定的函数。
-
您的应用程序将与 API 进行通信,发送初始提示以及已执行函数的结果。
图 3.10:函数调用生命周期
在使用 OpenAI API 进行函数调用时,模型本身并不会执行这些函数。相反,在步骤 3中,模型生成函数的参数,供您的应用程序使用。您的代码决定如何处理这些参数,通常通过调用指定的函数。这确保了您的应用程序对执行过程保持完全控制。
函数调用支持在 Chat Completions、Assistants 和 Batch APIs 中。本节重点介绍使用 Chat Completions API 进行函数调用。Assistant 和 Batch APIs 将在下一节中讨论。
让我们开始吧。
步骤 1 – 定义函数
首先,指定您打算调用的函数。该函数应为一个 Python 函数,能够接受输入并提供输出。函数的输入将由模型生成。
在此示例中,假设您希望启用模型在您的代码库中执行 get_weather 函数。该函数将城市作为参数,以从天气 API 检索天气信息。您的函数可能如下所示:
图 3.11:get_weather 函数定义
步骤 2 – 为模型使用描述函数
现在我们已经确定了要让模型调用的函数,我们将开发一个函数定义。它将解释函数的功能、何时使用以及调用该函数所需的参数。
函数定义中的参数部分应使用 JSON Schema 进行概述。当模型生成函数调用时,它将参考此模式以适当创建参数。
在此示例中,它可能看起来像图 3.12。
图 3.12:函数的 JSON Schema
步骤 3 – 将函数定义作为“工具”提供给模型
接下来,我们需要在使用 Chat Completions API 时,将我们的函数定义包含在可用的工具数组中。像往常一样,我们会提供一个消息数组,可能包括您的提示或用户与助手之间的完整对话。
如图 3.13所示,本示例演示了如何调用 Chat Completions API,提供相关的函数和消息,以便正确生成带有唯一 ID 的函数调用。
图 3.13:生成函数调用
默认情况下,模型设置为自动决定调用哪些函数,基于 tool_choice:“auto” 配置。
我们提供了三种选项来修改此默认行为:
-
要强制模型始终调用一个或多个函数,你可以设置
tool_choice: "required"。这确保模型总是会选择至少一个函数来执行,在你希望模型在多种操作之间做出选择时,这会非常有用。 -
要指示模型使用特定的函数,你可以定义
tool_choice: {"type": "function", "function": {"name": "my_function"}}。这将强制模型只调用指定的函数。 -
为了防止任何函数调用并使模型只返回面向用户的消息,你可以完全省略工具,或者设置
tool_choice: "none"。
第 4 步 - 进行实际的函数调用
如前所述,AOAI 函数调用不会自动触发实际的函数。相反,你必须根据模型生成的输入参数添加代码来触发调用。为此,请参考图 3.14中所示的代码。
图 3.14:进行函数调用
当你在请求中包含一个函数时,函数的详细信息(如定义和参数)会成为系统消息的一部分,然后与用户输入一起由模型处理。这种集成使得模型能够根据提示上下文评估是否应该调用该函数。
这个过程确实会使用到令牌,因为函数定义和参数会影响总体令牌计数。因此,采用提示工程策略,例如简洁明了、去除不必要的细节以及专注于提示的关键部分,可以提高函数调用的效率。
这里还有一些优化函数调用效率的方法:
-
增加更多的函数定义细节:包括详细的函数定义和有意义的描述对于清晰度和高效的函数调用至关重要。定义函数时,每个参数应以便于模型和任何审查代码的人员理解的方式进行描述。以下是如何使函数定义更全面的详细说明。
-
search_hotels,你可以设置如下的系统消息:{"role": "system", "content": "You're an AI assistant designed to help users search for hotels. When a user asks for help finding a hotel, you should call the search_hotels function."}这可以根据用户输入通知模型何时调用函数。
-
search_hotels,如果用户请求中缺少位置详情,询问相关信息。在你的系统消息中包括类似的指示,以指导模型:{"role": "system", "content": "Avoid assuming values for functions; instead, seek clarification when a user's request is unclear."} -
错误处理:提示工程中的另一个关键方面是最小化函数调用中的错误。尽管模型经过训练能够根据你定义的模式生成函数调用,但有时它们可能会创建与模式不匹配的调用,或者尝试调用未包含的函数。
为了解决这个问题,你可以在系统消息中加入如下语句:
{"role": "system", "content": "Only use the functions you have been provided with."}这有助于确保模型严格遵守你定义的函数。
现在你已经了解如何调用 AOAI 函数,接下来的部分将重点介绍 AOAI 助手 API,它简化了开发人员的应用开发过程。
AOAI 助手 API
AOAI 助手 API 支持创建可以直接集成到你自己应用中的 AI 助手。这些助手基于一套预定义的指令操作,并可以通过利用各种功能,如模型、工具和文件,来与用户互动。目前,助手 API 支持三种主要类型的工具:
-
代码解释器:此功能使得助手能够处理用户对计算或脚本执行的请求,通过允许助手在安全的、多租户的 Kubernetes 环境中编写和运行 Python 代码。Kubernetes 沙箱利用嵌套虚拟化技术来隔离每个容器,提供独特的用户空间内核,而非传统的内核。这种设置通过隔离环境来增强安全性,减少通过防止容器间干扰来降低风险,并提高系统灵活性。通过在安全的虚拟化环境中促进代码执行,助手能够动态应对复杂的计算、数据处理和文件处理。
该工具支持多种数据格式(
learn.microsoft.com/en-us/azure/ai-services/openai/how-to/code-interpreter?tabs=python#supported-file-types),可以处理各种结构的文件,根据需要提取信息。代码解释器支持迭代代码执行,使得助手在初次执行失败时能够调整代码并重新执行,这对于复杂的编码和数学问题特别有帮助。常见的应用场景包括从 CSV 文件中提取数据、创建结构化数据可视化(如图表和图形)以及解决数学问题。 -
文件搜索:AOAI 文件搜索工具允许助理通过访问和检索用户提供的文档中的信息来增强基于文件的查询处理。作为一个外部知识库,它让助理能够超越模型训练数据,检索专有内容或其他基于文档的信息。AOAI 的系统会自动按切块策略将文档拆分,并通过创建向量嵌入并将其存储在由 Azure AI Search 支持的管理向量存储中来索引文档。这使得基于向量和关键词的搜索都可以进行,从而支持更精确、基于上下文的信息检索,支持各种格式,详情请见
learn.microsoft.com/en-us/azure/ai-services/openai/how-to/file-search?tabs=python#supported-file-types。通过将文档内容转化为向量嵌入,文件搜索使得搜索能够理解上下文和意义,而不仅仅是匹配确切的关键词。这一功能特别适用于需要细致理解和快速检索的任务,如详细的问答、总结和数据提取。该工具也非常灵活,可以处理各种文档格式,便于集成到需要复杂文档交互的工作流中。 -
函数调用:此工具允许助理调用应用程序中的特定函数,使其能够通过 API 接口执行任务或检索数据。我们之前已经详细介绍了函数调用,突出了它在增强助理互动能力方面的作用。
这些工具使得构建针对应用程序中具体用例的动态和响应性 AI 助理变得更加容易。
现在,让我们讨论助理的流程。
助理流程
设置和运行一个 AI 助理(如财务机器人)通常涉及四个关键步骤。以财务机器人为例,如图 3.15所示,步骤如下:
图 3.15:AOAI 助理的流程
第 1 步——创建助理
助理是一个实体,可以通过各种参数(如模型、指令和工具)进行定制,以响应用户输入。助理可以通过 AOAI 使用 OpenAI 模型,并可以根据提供的指令定制以适应不同的个性或能力。你可以为助理配备工具,既可以是预先构建的工具,如code_interpreter和file_search,也可以通过函数调用提供自定义工具。这些工具帮助助理根据用户的查询执行特定任务。Assistants API 支持多个参数,允许你定制助理的输出。tool_choice参数允许你强制助理使用指定的工具。
第 2 步——创建线程
线程(Thread)是用户与一个或多个助手之间对话的记录。当用户(或 AI 应用程序)发起对话时,会创建一个新的线程。助手可以访问持久化的线程,从而在不丢失上下文的情况下进行连续对话。这简化了 AI 应用程序的开发,通过保留消息历史并通过在对话超出模型的上下文窗口时截断较旧的数据,有效管理内存。线程一旦创建,就会随着新消息的交换而更新。
步骤 3 – 向线程添加一条消息
在对话过程中交换的消息,无论是来自用户还是应用程序,都会作为消息对象存储在线程中。这些消息可以包含文本和文件。虽然线程可以存储最多 100,000 条消息,但系统通过智能管理对话,在超出模型上下文窗口时自动截断任何内容,确保助手自动截断文本以保证对话保持在模型的最大令牌限制内。然而,您可以通过指定每次运行应包含多少令牌或最近消息来调整此行为。
为了在单次运行中管理令牌使用量,可以在开始时设置max_prompt_tokens和max_completion_tokens。这些限制适用于整个运行过程中所有的补全。例如,如果将max_prompt_tokens设置为500,将max_completion_tokens设置为1000,助手首先会截断提示词,使其适应 500 个令牌,并将输出限制为 1000 个令牌。如果提示词只用了 200 个令牌,补全用了 300 个令牌,下一次补全将有 300 个提示词令牌和 700 个补全令牌可用。
如果补全达到了max_completion_tokens的限制,运行将以不完整状态停止,并且原因将包含在Run对象的incomplete_details字段中。
在使用文件搜索工具时,建议将max_prompt_tokens设置为不少于20000。对于更大规模的对话或使用文件搜索的多个交互,考虑将此限制提高到50000,甚至完全去除该限制以获得最佳效果。
您还可以定义一个截断策略来控制线程如何适应模型的上下文窗口:
-
使用
auto截断策略将应用 OpenAI 的默认截断行为 -
使用
last_messages策略可以指定在上下文中包含多少条最近的消息。
这种方法让你在管理对话长度和确保每次运行的最佳性能方面有更多控制权。
步骤 4 – 创建一个运行
在所有用户消息添加到线程后,启动一个运行来处理对话。该运行利用为助手定义的模型和工具生成回应。然后,助手的回应作为新消息添加到线程中,继续对话的流程。
现在我们已经涵盖了助手的 API 流程,让我们继续设置助手。
AOAI 助手 - 代码解释器
在本节中,我们将指导您逐步完成在 Azure AI Foundry 门户中设置助手的过程,并演示如何使用代码解释器工具处理 CSV 数据上的用户查询。您也可以通过基于 API 的方法实现相同的功能:
-
登录 Azure AI Foundry 门户。
-
如果您尚未设置聊天模型,请转到 共享资源 菜单中的 部署 部分。从那里启动新聊天模型的部署,例如 GPT4-o。
-
导航到 来自 Playground 的助手 菜单,选择 GPT4-o 部署,并点击 创建助手。
-
在 设置 页面,您会看到已经创建了一个助手 ID。在这里,您可以为助手指定名称并编写自定义指令,以明确其目标,如下所示:
图 3.16:助手设置
- 在 工具 部分,启用 代码解释器 并上传 CSV 文件以查询。对于此示例,我们将使用一个包含零售订单数据的示例 CSV 文件。该文件的一部分如下所示:
图 3.17:CSV 文件示例
- 上传 CSV 数据后,您可以开始询问相关查询。例如,您可以询问:“
到目前为止已发货多少订单?”。或者,您也可以使用以下提示:“创建一个图表,横轴为订单状态,纵轴为数量。”。
对于这种类型的问题,代码解释器工具将在 Microsoft 管理的沙箱环境中执行 Python 代码,并为您提供结果,如下所示:
图 3.18:代码解释器输出
在下一节中,我们将介绍如何使用 SDK 方法将文件搜索功能集成到助手中。
AOAI 助手 - 文件搜索
使用 OpenAI SDK,您可以直接编程助手以搜索文档并根据需要提取特定的函数签名。文件搜索将使助手能够解析、分块并索引文档,以便通过 SDK 高效地检索。您可以在应用程序中无缝配置这些工具,从而增强助手的数据检索和交互能力:
- 首先,我们需要创建一个新的助手,并将文件搜索作为其工具集的一部分,如下所示:
图 3.19:创建助手
- 上传您的文件以启用自动分块(分块大小为 800 个标记,分块重叠为 400 个标记)。嵌入并创建一个向量存储,驱动文件搜索工具,如下所示:
图 3.20:向量存储创建
- 将向量存储附加到助手上,以便访问文件,如下所示:
图 3.21:将向量存储附加到助手
- 创建线程并运行助手,如下所示:
图 3.22:创建线程并运行
- 显示带引用的助手响应,如下所示:
图 3.23:带引用的助手响应
现在,你可以看到如何使用各种工具(如文件搜索和代码解释器)简单地调用助手 API。此外,你还可以通过函数调用功能使用助手 API 与外部系统进行交互。这些助手能够利用 OpenAI 的先进语言模型,使用如代码解释器和文件搜索等工具,并在整个对话过程中保持上下文。
在接下来的部分,我们将讨论 AOAI 批处理,它是为不需要实时处理的用例设计的。
AOAI 批处理 API
一些应用需要同步请求处理,也叫实时推理,要求立即响应。然而,也有许多情况下响应可以延迟,或者速率限制可能会限制多个查询处理的速度。在这种情况下,批处理作业显得特别有用,尤其是在以下任务中:
-
大规模数据处理
-
生成大量内容并进行大规模数据转换
-
评估 LLM 模型并全面评估性能
AOAI 批处理 API 提供了一套用户友好的端点。这些端点允许你将多个请求打包成一个文件,启动一个批处理作业以异步处理这些请求,检查批处理的状态并运行任务,最后在处理完成后获取合并的结果。
相较于传统的 PAUG 部署,批处理 API 提供了以下优势:
-
成本效益:相对于标准的 PAUG 部署,提供 50%的成本减少
-
专用配额:使用单独排队的令牌配额,与在线端点配额不同,确保在线工作负载不受影响;批处理配额也显著更大
-
24 小时周转:每个批处理在 24 小时内完成,通常能更快地获得结果
提交批处理并获取结果涉及六个步骤。让我们详细了解每个步骤:
-
批处理部署创建:你需要首先为批处理创建一个单独的部署。为此,请按照以下步骤操作:
-
登录到 Azure AI Foundry。
-
导航至部署下的共享资源。
-
点击部署模型并选择部署基础模型。
-
选择任何聊天完成模型,如 gpt-4o-mini,并点击确认。
-
在部署名称下提供一个值,将部署类型设置为全局批处理,将排队令牌值调整为最大限制,然后点击部署。
-
图 3.24:批处理部署
您还可以切换启用动态配额,当有额外容量可用时,它允许您使用更多配额。
完成前面的步骤后,您的全局批处理部署将会创建。然后,这个部署将用于运行批处理任务。
-
.jsonl文件,其中每一行指定一个单独 API 请求的详细信息。目前,支持的端点是/chat/completions(用于聊天完成 API)。在此输入文件中,每行的正文字段中的参数应与相应端点的参数匹配。每个请求必须包含一个唯一的
custom_id值,该值有助于在处理完成后引用结果。文件中的model名称应与您在前一步骤中创建的部署名称匹配。以下是一个输入文件的示例,如下所示,包含三个请求。每个输入文件必须仅限于单一模型的请求:
图 3.25:批处理输入 .jsonl 文件
- 上传批处理输入文件:在准备好输入文件后,您需要上传它才能启动批处理任务。您可以通过编程方式或通过Studio界面上传文件。在此示例中,我们使用 Python SDK 方法从本地驱动器上传文件。请参见图 3.26以获取参考。
图 3.26:批处理文件上传
-
File对象用于启动批处理。在此示例中,文件 ID 为file-0a27a5cd4d94440789971497e6d80391。目前,完成窗口固定为 24 小时。您还可以使用可选的metadata参数包含自定义元数据,如图 3.27所示。这将返回一个批处理对象,包含批处理 ID 和状态字段。您可以在
learn.microsoft.com/en-us/azure/ai-services/openai/how-to/batch?tabs=standard-input%2Cpython-key&pivots=programming-language-python#batch-object中查看批处理对象的完整详情。
图 3.27:批处理任务提交
- 跟踪批处理任务状态:成功创建批处理任务后,您可以通过Studio或编程方式监控其进度。在检查状态时,建议每次状态调用之间等待至少 60 秒,如图 3.28所示。
图 3.28:批处理任务状态检查
给定批处理对象的状态可以是下表中显示的任何一种状态,见表 3.1。
| Status | Description |
|---|---|
validating | 输入文件正在验证中,批处理才能开始 |
failed | 输入文件未通过验证过程 |
in_progress | 输入文件已成功验证,批处理正在运行 |
finalizing | 批处理已完成,结果正在准备中 |
completed | 批处理已完成,结果已准备好 |
expired | 批处理未在 24 小时内完成 |
cancelling | 批处理正在取消中(可能需要最多 10 分钟) |
cancelled | 批处理已取消 |
表 3.1:批处理作业状态表
- 从
Batch对象中获取output_file_id。然后将其保存为您计算机上的文件,例如batch_output.jsonl。output.jsonl文件将包含每个成功请求的响应。任何失败的请求将在单独的错误文件中包含其错误详情,该文件可以通过批处理的error_file_id访问。
重要提示
输出行的顺序可能与输入顺序不匹配。请不要依赖顺序,而应使用每个输出行中的 custom_id 字段,将输入请求与其对应的结果关联。
图 3.29:检索输出文件
通过按照上述步骤操作,您可以手动提交批处理作业。
尽管这些步骤适用于演示目的,但对于存储帐户中有数百万个文件的企业来说,仍然需要一个自动化解决方案来有效地提交批处理并检索结果。在这种情况下,您可以使用以下解决方案加速器:
github.com/Azure-Samples/aoai-batch-api-accelerator
AOAI 批处理 API 有一定的服务限制,可以在 learn.microsoft.com/en-us/azure/ai-services/openai/how-to/batch?tabs=standard-input%2Cpython-key&pivots=programming-language-python#global-batch-limits 查找。配额限制详见 learn.microsoft.com/en-us/azure/ai-services/openai/how-to/batch?tabs=standard-input%2Cpython-key&pivots=programming-language-python#global-batch-quota。这些限制可以根据您的工作负载进行增加;如果需要增加配额,请联系微软。
您还可以使用 AOAI 批处理 API 批量处理图像。此功能适用于特定的多模态模型,目前只有 GPT-4o 支持批量请求中的图像。图像可以通过 URL 或 Base64 编码的数据提供。请注意,GPT-4 Turbo 当前不支持批处理中的图像输入。
AOAI 批处理具有全球性质,这意味着数据处理可能发生在世界任何地方。这可能会引发那些有严格法规要求的行业的关注。然而,你可以为 AOAI 批处理选择数据区域,限制数据处理仅在特定地区进行。通过选择美国数据区,处理将在美国的某个区域进行;选择欧盟数据区,处理则会在欧盟的某个区域进行。这确保了企业可以遵守数据合规和监管要求。
现在我们已经讲解了 AOAI 批量 API,接下来的部分将聚焦于微调,它使你能够根据特定任务定制模型。
AOAI 微调
微调使你能够通过以下方式最大化 Azure AI Foundry 或 API 提供的模型潜力:
-
与仅使用基本提示相比,响应质量得到改进
-
能够在更大的数据集上进行训练,突破了模型上下文窗口的限制
-
通过最小化提示长度减少令牌使用
-
更快速的响应时间和更低延迟的请求
AOAI 的文本生成模型是基于大量文本数据预训练的。为了有效使用这些模型,用户通常会在提示中加入指令和示例案例——这种方法被称为少量示例学习。少量示例学习通过在提示中展示少量示例来演示如何完成任务。
微调通过在模型上训练更多的示例数据来增强少量示例法,从而在更广泛的任务中提升性能,而这些数据无法完全包含在单个提示中。经过微调后,通常在提示中所需的示例较少,这样不仅减少了令牌使用量,还进一步降低了响应延迟。
利用微调的理想情况
在评估微调是否适用于特定用例时,理解一些基础概念是有益的:
-
提示工程:该技术涉及精确地为自然语言处理模型设计提示。通过仔细设计提示,用户可以提高模型响应的准确性和相关性,从而提升整体性能。第十三章深入探讨了各种提示工程技术。
-
RAG:RAG 通过将外部数据集成到提示中,增强了 LLM 的效果。通过从外部来源检索相关信息,RAG 使企业能够创造量身定制的解决方案,这些解决方案既具有成本效益,又在上下文上更加准确。
-
微调:微调是通过在特定示例数据上重新训练现有的 LLM,从而调整其以反映提供的示例数据集的细微差别和要求,结果是一个定制化的模型。
AOAI 微调是一个监督微调过程,与持续预训练或通过人类反馈强化学习(RLHF)不同。监督微调涉及在精心选择的数据集上重新训练预训练模型,以提高在特定任务上的表现。我们建议从提示工程、提示链(将复杂任务分解为更小、更易管理的提示)和利用函数调用等技术开始,以实现最佳效果。
AOAI 使用低秩近似(LoRA)通过降低模型复杂度,且对性能影响最小,来高效地微调模型。该方法通过使用低维矩阵来近似模型原始的高维矩阵,允许在监督训练过程中仅对部分关键参数进行微调。通过专注于这些关键参数,模型保持了高效性并更易于管理。对于用户而言,与传统方法相比,这将带来更快速的训练和更具成本效益的微调。
微调是一个复杂的过程,要求有扎实的领域和数据理解才能有效应用。接下来五个常见问题旨在帮助您评估是否准备好进行微调,指导您考虑关键因素,并帮助您决定微调是否是最佳方法,或是否有更适合的替代方法:
-
为什么微调 一个模型?
为了有效进行微调,您应该清晰定义具体的应用场景,并识别您打算微调的模型。适合微调的情况包括需要模型以特定风格、语气或格式输出,或者当用于指导模型的指令或数据过于复杂或冗长,无法放入标准提示中时。
以下是一些表明您可能还没有准备好进行微调的指标:
-
用例不明确:如果您无法清楚地表达出一个明确的目的,除了我想要改进模型之外,微调可能不是下一步正确的选择。
-
成本驱动的动机:微调可以在允许使用更短提示或更小模型的情况下减少成本。然而,它也涉及到为训练和托管定制模型的前期成本。请留意这些费用,并参考 AOAI 的定价页面,了解更多关于微调成本的细节。
-
超出领域的知识需求:如果您的主要目标是将超出模型原始训练范围的信息整合进来,考虑从 RAG 开始。AOAI 的 RAG 功能,例如基于嵌入的检索,可以根据您的具体数据和目标提供更加灵活且通常更具成本效益的解决方案。
-
-
您到目前为止 尝试了什么?
微调是一项高级功能,通常不是与生成性 AI 合作的第一步。你需要熟悉 LLM 的基础知识,并从测试模型性能、使用提示工程和/或 RAG 开始。这些技术帮助你建立一个基准性能水平,这对于评估微调是否真正提升了模型非常重要。
没有微调的性能基准也起到了保障作用:它有助于检测微调带来的负面影响,因为准备不充分的训练数据可能会降低模型质量。
让我们来看一些你准备好进行微调的关键指标:
-
有提示工程和 RAG 经验:你应该能够展示来自提示工程或基于 RAG 方法的知识和结果
-
文档化的挑战和应用案例测试:有具体的例子表明在你的应用案例中,提示工程或 RAG 未能达到预期效果
-
量化基准评估:在可能的情况下,确保有可衡量的模型性能基准,且没有微调
接下来,让我们看看一些常见的微调可能还不适合的迹象:
-
从没有测试其他可用技术的微调开始
-
缺乏对微调如何具体增强 LLM 的清晰理解
-
没有基准数据来衡量微调的影响
-
-
在提示中
始终返回 SQL并使用 RAG 来检索数据库架构时,模型常常产生不正确的语法,尤其是在边缘案例中。为了解决这个问题,他们收集了数千个问题及其等效的数据库查询的示例,包括先前模型的失败,并用这些数据来微调模型。结果,经过微调的模型,结合他们工程化的提示和检索设置,达到了实际应用所需的准确性。这里有一些你准备好进行微调的指标:
-
先前尝试的文档化示例:你已经测试了各种提示工程或 RAG 解决方案,并记录了具体的限制。
-
识别模型短板:这些可能包括边缘案例处理不一致、无法在上下文窗口内包含足够的少量提示,或延迟问题
另一方面,这里有一些迹象表明你可能需要等一等,才能进行微调:
-
缺乏对模型限制或所需数据的深入理解
-
难以识别合适的数据来有效地训练模型
-
-
你将使用什么数据 进行微调?
即使有强有力的应用案例,微调的成功在很大程度上取决于你提供的数据质量。必须投入必要的时间和资源来收集高质量、精心整理的数据。不同的模型可能需要不同量的数据,但在大多数情况下,你需要提供大量精心整理的示例,以实现有意义的改进。
除了数据质量外,数据格式同样重要。即使是高质量的数据,也可能需要付出大量努力才能正确格式化以进行微调。这可能需要分配工程资源以确保数据结构正确。
一些你已准备好进行微调的迹象包括:
-
已选择数据集:你已经选择了打算用于微调的数据集。
-
正确格式:数据集按选定模型的要求正确构建。
-
数据策划工作:已经对数据进行了一定程度的策划,以确保数据的质量。
另一方面,以下是一些你可能还没有准备好进行微调的常见迹象:
-
未选择数据集:你还没有选择用于微调的数据集。
-
格式不正确:数据集格式与您打算微调的模型要求不符。
-
-
你将如何衡量你的 微调模型的质量?
没有一种通用的方法来衡量微调模型的成功,但明确且清晰的目标是至关重要的。成功不仅应该进行定性评估,还应包括定量指标。一种好的方法是使用保留验证数据集来客观评估性能。此外,你还可以通过进行用户接受度测试或执行A/B 测试,将微调模型与基础模型进行比较,看看改进是否达到了预期。
为了优化模型的上下文,你应探索如提示工程和 RAG 等技术。对于优化 LLM 本身,重点应放在提示工程和随后的微调上,如图 3.30所示。
图 3.30:优化 LLM 准确度
一旦确定微调是合适的策略,你可以按照后续章节中详细的步骤来有效地微调模型。
微调步骤
从高层次来看,微调过程包括以下步骤:
-
准备并上传训练数据。
-
训练一个新的微调模型。
-
进行安全评估。
-
进行模型性能评估。
-
部署微调后的模型。
让我们详细了解每个步骤:
- 准备并上传训练数据:你的训练和验证数据集应包含能够展示所需模型行为的输入和输出示例。这些数据集必须采用JSON Lines(JSONL)文档格式。对于如 gpt-3.5-turbo(所有版本)、gpt-4、gpt-4o 和 gpt-4o-mini 等模型,微调数据应遵循 Chat completions API 使用的对话格式。以下是示例格式:
| {“messages“: [{“role”: “system”, “content”: “你是 Ontoso 客户支持代理,帮助客户解决与 Ontoso 账户和服务相关的问题。你友好且简洁,只提供与 Ontoso 相关的事实性答案。”}, {“role”: “user”, “content”: “我需要帮助恢复我的 Ontoso 账户。我忘记了密码。”}, {“role”: “assistant”, “content”: “你好!我很高兴为你提供帮助。请提供你的注册邮箱地址,我将引导你重置密码。”}]}{“messages”: [{“role”: “system”, “content”: “你是 Ontoso 客户支持代理,帮助客户解决与 Ontoso 账户和服务相关的问题。你友好且简洁,只提供与 Ontoso 相关的事实性答案。”}, {“role”: “user”, “content”: “我可以在 Ontoso 上追踪我的订单吗?”}, {“role”: “assistant”, “content”: “是的,你可以通过登录 Ontoso 账户并查看‘订单历史’部分来追踪订单。在那里,你可以查看当前和过去订单的状态。”}]} |
|---|
表 3.2:示例训练数据 JSONL 格式
除了采用 JSONL 格式,训练和验证数据文件必须使用带有字节顺序标记(BOM)的 UTF-8 编码。此外,文件大小不得超过 512 MB。
你还可以在 JSONL 训练文件的单一行中包含多轮对话。要排除特定的助手消息不参与微调,你可以添加可选的 weight 键值对。目前,weight 可以设置为 0 或 1。以下是另一个多轮示例格式:
| {“messages”: [{“role”: “system”, “content”: “你是 Contoso 客户支持代理,友好且简洁,但有点讽刺的语气。”}, {“role”: “user”, “content”: “你们的营业时间是什么?”}, {“role”: “assistant”, “content”: “我们的营业时间是周一至周五,上午 9 点至下午 5 点。”,“weight”: 0}, {“role”: “user”, “content”: “你能再讽刺一点吗?”}, {“role”: “assistant”, “content”: “当然,我们的营业时间是从早上 9 点到下午 5 点,周一至周五。真是一个让人吃惊的时间吧?”, “weight”: 1}]}{“messages”: [{“role”: “system”, “content”: “你是 Contoso 客户支持代理,友好且简洁,但有点讽刺的语气。”}, {“role”: “user”, “content”: “我该如何重置密码?”}, {“role”: “assistant”, “content”: “你可以点击登录页面上的‘忘记密码’链接来重置密码。”,“weight”: 0}, {“role”: “user”, “content”: “你能再讽刺一点吗?”}, {“role”: “assistant”, “content”: “哦,你只需点击‘忘记密码’链接。这可是一个革命性的功能,已经存在了很久。”,“weight”: 1}]} |
|---|
表 3.3:示例多轮训练数据 JSONL 格式
提供的训练示例越多,微调的结果就越好。虽然微调至少需要 10 个训练示例才能进行,但这个最小数量通常不足以对模型的性能产生有意义的影响。理想情况下,应该提供数百甚至数千个示例,以获得最佳效果。
通常,增加数据集的大小可以带来模型质量的成比例提升。然而,值得注意的是,低质量的示例可能会影响模型的性能。如果你在没有精心筛选数据的情况下,用大量的内部数据训练模型,且数据只包含低质量示例,那么模型的表现可能会比预期更差。
-
训练新的微调模型:训练新的微调模型可以通过 Azure AI Foundry 或使用 API 完成。在本次演示中,我们将使用 Azure AI Foundry 来展示如何轻松地微调基础聊天完成功能模型。AOAI 支持多种模型进行微调。要查看完整的支持模型列表,请参考
learn.microsoft.com/en-us/azure/ai-services/openai/how-to/fine-tuning?tabs=azure-openai%2Ccompletionfinetuning%2Cpython-new&pivots=programming-language-studio#models:-
首先,打开 Azure AI Foundry 网站
oai.azure.com/,并使用具有 AOAI 资源访问权限的凭据登录。在登录过程中,确保选择正确的目录、Azure 订阅以及与你的帐户关联的 AOAI 资源。 -
在 Azure AI Foundry 中,导航到左侧菜单中的 工具 部分,然后选择 微调 面板。接着,点击 微调模型 选项以开始微调过程。
-
图 3.31:AOAI 微调向导
- 创建自定义模型的第一步是选择一个基础模型。在 基础模型 面板中,你可以从 基础模型类型 下拉菜单中选择一个基础模型。你的选择将影响你所创建的自定义模型的性能和成本。选择好基础模型后,点击 下一步 继续微调过程,如 图 3.31 所示:
图 3.32:选择基础模型进行微调
AOAI 还支持增量微调,这意味着你可以对已经进行过微调的模型进行再次微调。这样,你可以通过在新的或更新的数据集上进一步训练模型,持续提升其性能,增强模型处理更具体任务或响应不断变化需求的能力。
- 继续操作时,您可以根据具体的定制需求,选择之前上传的训练数据集,或上传新的数据集。训练数据部分将显示所有可用的数据集,您可以查看并选择现有选项,或上传新的数据进行训练。在此示例中,我们演示了如何直接从本地驱动器上传新的数据集,过程如图 3.32所示。
对于处理大型数据文件,建议直接从 Azure Blob 存储导入。通过多部分表单上传大型文件可能导致不稳定,因为这些上传依赖于原子请求,这意味着如果上传中断,无法恢复或重试。使用 Azure Blob 存储进行此类传输可确保更高的可靠性和容错能力,尤其是在处理大型数据集时。
图 3.33:训练数据上传
- 在下一步中,您将找到设置验证数据的选项,适用于您的模型训练过程。如果不需要验证数据,只需选择下一步,直接进入高级配置设置。然而,如果您希望使用验证数据,可以从现有数据集中选择,或者上传专门为此目的准备的新验证数据集。
验证数据部分显示所有可用的训练和验证数据集,提供灵活性,可以使用现有数据或根据需要添加新的验证数据以进行模型定制。在此示例中,我们演示了如何直接从本地驱动器上传新的验证数据集,过程如下:
图 3.34:验证数据上传
-
batch_size(整数):指定在单次前向和反向传播过程中处理的训练示例数量。通常,对于较大的数据集,推荐使用较大的批次大小,因为它们有助于稳定训练过程。较大的批次大小减少了模型参数更新的频率,从而降低了更新的方差。 -
learning_rate_multiplier(数值):这是应用于预训练学习率的乘数,用于设置微调学习率。较大的值可以提高较大批次大小的训练效率,但如果值过大,可能会导致过拟合。通常可以尝试在0.02和0.2之间的值,以找到最佳学习率。 -
n_epochs(整数):指模型训练的轮次数,即完整地通过数据集的次数。每一轮表示从数据集中学习的一个完整周期。 -
seed(整数):控制训练过程的可复现性。设置特定的种子值可确保训练结果在相同作业参数下具有一致性。如果未指定种子,则会自动生成一个种子。
选择默认使用精细调优任务的默认值,或选择自定义显示并编辑超参数值。当选择默认时,微软会根据你的训练数据通过算法确定正确的值,如下所示:
图 3.35:超参数选择
配置完高级选项后,选择下一步来检查你的选择并训练你精细调优后的模型。
-
在向导的审查窗格中,你可以查看所选配置设置的摘要。确认所有配置正确后,点击提交以启动精细调优任务。提交后,你将被重定向到模型窗格,在那里你可以监控精细调优任务的状态和进度。最后一步确认你的设置并启动模型训练过程。
-
模型窗格提供了你自定义模型精细调优过程的详细概览,显示了精细调优任务状态和结果的关键信息,如图 3.36所示。一旦你启动精细调优任务,可能需要一些时间才能完成。你的任务可能会排在系统中其他任务的队列后面。训练过程的持续时间可能会有所不同,从几分钟到几个小时不等,这取决于模型和数据集的大小。点击刷新以更新状态页面上的信息。
图 3.36:精细调优状态
完成此处提到的七个步骤后,你将拥有一个精细调优的模型。在训练过程中,每个训练周期结束时会生成一个检查点。检查点代表了一个功能完整的模型版本,可以部署并作为未来精细调优任务的基础模型。这些检查点非常有价值,因为它们提供了在过拟合发生之前的模型快照。在精细调优任务完成后,你将可以访问模型的三个最新版本,可以根据需要进行部署。
- GPT-4o 和 GPT-4o-mini 是我们最先进的模型,旨在根据你的特定需求进行精细调优。然而,和所有 AOAI 模型一样,这些模型的精细调优版本也面临着更多负责任的人工智能挑战,包括与有害内容、操控、人类行为、隐私问题等相关的风险。
为了减少这些风险,已实施额外的评估步骤,以检测和防止精细调优模型的训练和输出中有害内容。这些措施符合微软负责任的人工智能标准以及 AOAI 服务的内容过滤政策。
主要的评估功能包括以下内容:
-
专用的私人工作空间为每个客户提供,确保在评估过程中安全性和隐私。
-
评估端点位于与 AOAI 资源相同的地理区域内,以确保遵守地区数据政策。
-
训练数据隐私得到了保障,因为用于评估的数据不会被存储;仅保留最终模型评估结果(是否可以部署)。
-
预定义评估过滤器:GPT-4o、GPT-4o-mini 和 GPT-4 微调模型的过滤器设置为固定的阈值,客户无法更改;这些过滤器独立于您可能已设置的任何自定义内容过滤配置。
这些步骤旨在帮助确保微调后的模型遵循负责任的 AI 实践,并尽量减少生成有害或不当内容的风险。
AOAI 微调服务在训练过程中结合了两项关键的保障措施,以促进 AOAI 微调服务的负责任和伦理使用:
提供的训练数据未通过 RAI 检查,存在以下危害类型:[仇恨公平性、自残、暴力]。请修复数据并重试。
表 3.3:训练数据评估通知
在数据导入过程中,您的训练数据会自动评估,作为启用微调功能的一部分。如果在训练数据中检测到有害内容,导致微调任务失败,您将不会产生任何费用。
-
模型评估:训练完成后,在微调模型部署之前,模型将接受评估,以评估其潜在的有害响应,使用 Azure 内置的风险和安全度量标准。这一评估过程与对基础 LLM 的测试过程相同。它模拟与微调模型的对话,评估模型是否会根据预定义类别(暴力、色情内容、仇恨言论、公平性问题和自残)生成有害内容。如果模型生成有害内容的比例超过可接受阈值,您将收到通知,如表 3.5所示,表示该模型无法部署。同时,您还会收到关于具体有害内容类别的详细信息。
此模型无法部署。模型评估发现该微调模型在[暴力、自残]方面的得分超过了可接受的阈值。请使用安全数据集重新训练您的模型。
表 3.4:模型评估通知
类似于数据评估,模型在微调过程中会自动评估。这是微调过程的一部分。只有最终评估结果——模型是否可以部署——会被服务记录。如果由于模型输出中检测到有害内容导致微调模型无法部署,您将不会被收取训练费用。
- 每个任务的
results.csv文件。该文件帮助您分析自定义模型在训练和验证过程中的表现。您可以在 Azure AI Foundry 的 模型 面板下找到结果文件的文件 ID,从而在 数据 文件 面板中下载该文件。
results.csv 文件包含以下列,如表 3.5所示:
表格:3.5:模型训练和验证性能
在 Azure AI Foundry 中,你可以将 results.csv 文件中的数据可视化为图表。通过选择你的训练模型链接,你将能够查看两个关键图表:损失和标记准确率。如果你提供了验证数据,那么训练和验证数据集的结果将显示在同一图表中,如下所示:
图 3.37:微调指标
这是你在图表中需要关注的内容:
-
损失应随时间减少,这表示模型随着学习的进行在不断改进。
-
准确率应提高,这表明模型在预测标记时变得更加准确。
-
如果你注意到训练数据和验证数据之间存在发散(即训练损失继续减少,而验证损失增加或保持平稳),这可能是过拟合的信号。在这种情况下,你可能需要做以下几件事:
-
使用更少的训练轮次来训练模型
-
使用较小的学习率倍增器,防止模型过度拟合训练数据
-
在微调模型时,有几个重要的考虑因素,以确保最佳性能:
-
缺失系统消息:在微调和使用微调模型时,提供一致的系统消息非常重要。如果系统消息发生变化,模型可能会生成与微调时不同的结果。因此,部署时使用的系统消息应与训练过程中使用的消息保持一致,以确保一致性。
-
数据不足:虽然微调管道运行所需的最小数据量为 10 个示例,但建议使用数百甚至数千个数据点来教会模型新技能。数据点太少,存在过拟合的风险,模型会记住特定的示例,而不是泛化模式。这可能导致在应用到真实世界、未见过的数据时表现不佳。为了取得最佳结果,目标应是准备一个包含数百或数千个多样化数据点的数据集。
-
糟糕的数据:训练数据的质量直接影响到微调模型的质量。一个精心策划或存在偏见的数据集可能导致模型学习到不准确的模式。例如,如果你只用一个场景(例如退货)的数据来训练一个客服聊天机器人,它将难以应对其他情况。此外,如果训练数据包含不正确或误导性的信息,模型将学会生成错误或有偏见的响应。始终确保你的数据集是多样化的、准确的,并且能代表你希望模型处理的任务。
- 部署微调后的模型:一旦微调任务成功,您可以通过 Azure AI Foundry 中的Models面板部署您的自定义模型。部署是使微调后的模型能够在完成调用中使用的必要步骤。要部署模型,只需选择自定义模型并点击Deploy model,如下所示:
图 3.38:微调模型部署
当您打开Deploy model对话框时,您需要为您的自定义模型输入一个部署名称。输入名称后,点击Deploy以启动微调模型的部署过程。您可以在 Azure AI Foundry 的Deployments面板中跟踪部署进度。
AOAI 微调还支持将您的自定义模型部署到与原始微调位置不同的区域,包括跨订阅和区域的部署。
然而,需要考虑一些关键的限制:
-
目标区域必须支持微调
-
如果跨订阅部署,生成授权令牌的账户必须同时具有源订阅和目标订阅的访问权限
重要提示
一旦您部署了自定义模型,如果它在15 天内没有任何活动,部署将自动被删除。如果在连续的 15 天内没有对模型进行任何完成或聊天完成调用,则该部署将被视为非活动状态。需要注意的是,删除非活动部署不会影响底层的自定义模型。模型本身将被保留,可以随时重新部署。此外,每个已部署的微调模型都会产生按小时计算的托管费用,即使在该时间段内没有调用该模型。
一旦您的自定义模型部署完成,您可以像使用任何其他已部署的模型一样使用它。您可以通过调整temperature和max_tokens等参数来测试新的部署,就像对其他已部署的模型一样:
-
对于微调后的
babbage-002和davinci-002模型,您将使用Completions沙盒和 Completions API -
对于微调后的 gpt-4o 模型,您将使用Chat沙盒和 Chat Completion API
这些工具允许您与微调后的自定义模型互动并进行测试。
摘要
在本章中,我们重点介绍了 AOAI,它提供了一整套旨在增强 AI 模型能力和集成的工具和服务。这些服务的核心是 AOAI 模型上下文窗口,它定义了模型一次可以处理的信息量。我们了解到,这对于维持复杂任务中的连贯性和理解力至关重要。我们还了解到,AOAI 嵌入模型有助于将文本转化为数值向量,从而实现更好的语义理解和相似性搜索。这些嵌入向量可以通过 Azure 向量数据库高效存储和查询,而这些数据库已经针对高维数据的处理进行了优化,从而提高了 AI 应用的性能。我们还讨论了标准 RAG 模式,概述了其逐步流程。此外,我们了解到,AOAI On Your Data 允许组织快速原型化,并在其专有数据集上利用这些模型,确保 AI 解决方案能够根据特定的业务需求进行定制。
AOAI 的功能扩展到多模态模型,这些模型能够处理和整合来自多种数据类型的信息,如文本和图像,从而拓宽了人工智能应用的范围。我们了解到,功能调用特性允许 AI 模型与 Azure 强大的生态系统无缝集成,便于根据 AI 输出执行预定义函数。开发者可以利用 AOAI Assistants API 创建复杂的、具备上下文意识的对话代理,提升用户交互体验。对于需要高吞吐量的操作,AOAI Batch API 提供了一个可扩展的解决方案,能够高效地处理大量数据,正如我们在本章中学到的那样。最后,我们了解到,AOAI 微调功能使用户能够定制预训练模型,以更好地适应特定任务或领域,从而提升在专业应用中的性能和准确性。所有这些工具共同提供了一个强大且灵活的平台,用于开发针对多样化商业需求的先进 AI 解决方案,正如我们在本章中学到的那样。
在接下来的章节中,我们将重点关注生成型 AI 应用的实际示例,并附有编码练习,帮助你轻松构建这些应用。通过动手实现,你将全面理解如何将生成型 AI 技术应用于现实世界的用例。内容将涵盖各种场景,如基于文档的问答和联络中心分析,以及查询结构化数据、使用 AOAI 生成代码、创建推荐系统、生成文本到视频的内容,并通过 Assistant API 构建多模态多代理系统。每个示例都将包括逐步指导和代码片段,帮助你将这些功能集成到你的项目中。
第二部分:Azure OpenAI 的实际应用:真实世界用例
在第二部分中,我们从基础概念过渡到实际操作,探索展示 Azure OpenAI 在解决现实世界挑战中的变革潜力的实际用例。每一章都介绍一个独特的应用,提供有关问题背景、技术架构以及逐步解决方案开发的详细见解。从创建企业级文档问答系统到构建多模态、多智能体框架,本部分将帮助读者掌握 Azure OpenAI 的知识和工具,以应对各种具有影响力的应用。
本部分包含以下章节:
-
第四章,开发企业文档问答解决方案
-
第五章,构建联络中心分析解决方案
-
第六章,从结构化数据库中查询
-
第七章,代码生成与文档编写
-
第八章,使用 Azure OpenAI 创建基础推荐系统
-
第九章,将文本转化为视频
-
第十章,使用 Azure OpenAI 助手 API 创建多模态多智能体框架
第四章:开发企业文档问答解决方案
在上一章,我们深入探讨了扩展我们对语言模型理解的高级话题。我们了解了诸如嵌入(embedding)等概念,嵌入是指将单词或短语以数字形式表示,供语言模型处理,并将嵌入存储到 Azure Cognitive Search 中,便于相关性搜索。此外,我们还探讨了模型上下文窗口(Model Context Window),它决定了语言模型生成预测时所考虑的上下文量。我们还发现了诸如 Azure OpenAI On Your Data 的功能,它允许客户进行聊天、模型微调和 OpenAI 函数调用,支持在语言模型内执行特定功能。本章还介绍了 OpenAI 插件,提供了扩展语言模型功能的选项。最后,我们了解了 LangChain 和 Semantic Kernel,这是一个为大语言模型开发应用的框架。
本章涉及以下主题:
-
企业使用非结构化文档的案例
-
架构设计
-
使用 Azure OpenAI 和 Azure Cognitive Search 索引开发问答解决方案
在深入探讨企业使用非结构化文档的案例之前,让我们先解决一个许多人都会遇到的常见挑战:如何在大量文档中找到特定的信息。每个主题或项目通常都会附带大量文档,这些文档由各种来源提供,涵盖了成功的关键,但它们往往是零散且混乱的。
当需要查找特定信息时,这项任务可能变得让人望而却步。你可能会花费数小时,仔细翻阅一页又一页、一个又一个文档,只为寻找那一条关键信息。这一过程既费时又令人沮丧。
然而,还是有希望的。试想有一个解决方案能够简化这一过程,让查找所需信息变得更加轻松和快速。今天,我们将探索这样一个革命性的解决方案,它利用 Azure OpenAI,旨在高效解决这些问题。
企业拥有大量非结构化文档,这些文档中蕴藏着能够回答特定问题的宝贵知识。这一挑战不仅仅是企业面临的问题,许多行业的组织也都面临这一困境。让我们通过一个真实的案例来感受这一问题的严重性。
想象一下,你是一个成功的旅游公司老板,专门为热爱冒险的旅客定制旅行体验。多年来,你的公司为旅行者策划了许多独特的旅程,积累了大量的非结构化文档。
在这个数字化的宝库中,你会发现各种各样的资料:详细的行程安排、旅游指南、客户评价、预订记录,以及与世界各地的酒店、航空公司和当地旅游运营商之间的大量通讯。这些文档蕴含着丰富的信息,从游客的偏好到隐藏的瑰宝,再到为打造难忘旅行而涉及的物流复杂性。
现在,让我们聚焦于一个特定的场景。一位忠实的客户,在经历了你们几次非凡的冒险后,带着特殊的请求找到了你。他们寻求一趟精心策划的旅行,能够满足他们的特定兴趣:穿越原始的自然风光,通过镜头捕捉野生动植物,沉浸于真实的文化体验中。他们的要求很明确——他们需要一份详细的行程,能够无缝地将这些独特的元素融合成一场难忘的旅程。
当你和你的团队踏上这项任务时,挑战变得尤为明显。手动筛选成千上万的无结构文档,去发掘相关的旅游目的地、住宿选项、旅游活动和物流细节,不仅耗时,而且还存在遗漏关键信息的风险。这项艰苦的工作可能会延续数周,即便如此,最终结果也未必如你所愿。
旅游公司面临的困境并非独特。许多企业也在处理类似的情况,他们收集了大量无结构的文档,每份文档都承载着开启非凡体验的钥匙。在本章中,我们将看到如何通过使用 Azure OpenAI 和 Azure Cognitive Search 索引来解决这个问题。
技术要求
要跟随本章中的实践练习,访问本章在 GitHub 上的源代码,链接为:github.com/PacktPublishing/Azure-OpenAI-Essentials/blob/main/Chapter4.ipynb。
在本地机器上安装以下工具以开始解决方案的工作:
-
Python 3.9、3.10 或 3.11 –
www.python.org/downloads/ -
Azure 开发者 CLI –
learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd?tabs=winget-windows%2Cbrew-mac%2Cscript-linux&pivots=os-windows -
Node.js 14+ –
nodejs.org/en/download -
Git –
git-scm.com/downloads -
PowerShell 7+(pwsh)–
github.com/powershell/powershell -
Azure 账户 – 如果你是 Azure 新手,可以免费创建一个 Azure 账户,开始时还会获得一些免费的 Azure 信用额度。
-
启用访问的 Azure 订阅(你可以通过此表单请求访问:
learn.microsoft.com/en-in/legal/cognitive-services/openai/limited-access) -
Azure OpenAI 连接和模型信息:
-
OpenAI API 密钥
-
OpenAI 嵌入模型部署名称
-
OpenAI API 版本
-
除了上述系统要求外,掌握基础的 Azure 服务和 Python 编程语言的基本能力(相当于初学者水平,Python 100)非常重要。这些技能对于在本章中高效地使用 Azure 服务至关重要。放心,即使你是 Azure 环境的新手,我们已将本章设计为适合初学者。它提供了清晰的解释并包括详细的截图,帮助你更好地学习并顺利入门。
架构设计
要构建这个系统,我们需要以下基本服务:
-
Azure Cognitive Search
-
Azure OpenAI 服务
我们的主要目标是将非结构化数据转化为嵌入向量,这些向量将存储在向量数据库中。当用户提交查询时,系统会利用 Azure OpenAI 嵌入向量进行处理。随后,执行向量搜索操作,从向量数据库中检索出前 K 段内容。这些选中的段落将被发送到 Azure OpenAI 回答提示中,提取答案并将其交付给用户。
以下是使用 Azure OpenAI 的问答解决方案的简单架构图:
图 4.1:架构设计
在前面的图示中,我们将 Azure OpenAI 服务的嵌入向量发送到向量数据库,用户提出的问题会被发送到这些嵌入向量,结果将被提取。现在,我们将使用这个设计来开发我们的解决方案。
使用 Azure OpenAI 和 Azure Cognitive Search 索引开发问答解决方案
现在我们已经熟悉了创建这个解决方案所需的架构元素,让我们继续在 Azure 门户中实现这些组件。如前所述,拥有一个有效的 Azure 账户是构建此应用程序的先决条件。
Azure 订阅先决条件
以下先决条件在第二章中已经建立,并且可以重复使用:
-
Azure 订阅
-
Azure OpenAI 资源
-
部署的 Azure OpenAI 模型
创建以下工具,排除在第二章中已经建立的内容。
由于我们已经设置好了 Azure OpenAI 及其部署,下一步是在我们设置 Azure OpenAI 的同一资源组中创建 Azure Cognitive Search:
- 在顶部导航栏的搜索框中搜索
Azure Cognitive Search,如图所示:
图 4.2:Azure Cognitive Search
当您访问 Azure OpenAI 服务页面时,您会看到一个创建选项,如此处所示:
图 4.3:Azure Cognitive Search 创建
- 点击创建选项后,将出现一个表单,类似于图 4.4所示。选择资源组——在我的案例中,我选择了之前创建的azure-openai-rg。在此部分的最后一步中,选择定价层级;我选择了标准 S0。完成第一步后,它应该显示如下:
图 4.4:Azure Cognitive Search 基础
- 完成第二步后,点击下一步按钮进入规模设置步骤,在此步骤中您可以根据所选的服务层级查看定价详情。您可以保持默认设置,然后点击下一步继续:
图 4.5:Azure Cognitive Search 规模
- 点击下一步后,您将进入网络选项卡,默认情况下,端点连接性设置为公开。请保持为公开,然后点击下一步继续:
图 4.6:Azure Cognitive Search 网络
-
点击下一步按钮后,您将进入标签步骤。现在可以忽略此部分。标签是名称/值对,它允许您对资源进行分类,并通过将相同标签应用于多个搜索和资源组来简化集中计费。您可以在标签步骤中找到类似的详细信息。继续点击下一步,然后进入审查 + 创建步骤。
此处将显示您在前一步骤中选择的详细信息。审核所有信息后,点击创建按钮:
图 4.7:Azure Cognitive Search 标签
创建 Cognitive Search 可能需要几分钟时间。一旦搜索部署完成,您可以访问资源页面,页面如下所示:
图 4.8:Azure Cognitive Search 概览
- 要创建用于向量搜索的索引并将文档添加到向量存储中,请点击添加索引链接。或者,您也可以从索引选项卡创建:
图 4.9:Azure Cognitive Search 索引创建
- 当您点击添加索引选项时,将会出现一个表单,如图 4.10所示。填写应用程序所需的字段,包括索引名称:
图 4.10:Azure 认知搜索索引创建
- 点击创建,创建索引需要几分钟时间。当您导航到索引选项卡时,可以验证其创建:
图 4.11:Azure 认知搜索索引概述
在前面的截图中,我们可以清楚地看到已创建的azureblob-index。因此,借此,我们已经创建了构建解决方案所需的基础设施。
在下一节中,我们将从实现我们解决方案的代码开始。
使用 Azure OpenAI 的解决方案
现在我们已经在 Azure 门户中设置了所有基本服务,可以开始构建我们的解决方案。为了开发代码,我将使用 Azure ML Studio notebook。在这个解决方案中,我将使用 Python 版本 3.12。如前所述,任何高于 3.7.1 的版本都应能无缝工作。您可以访问我们 GitHub 仓库中的代码;我建议在本章进展过程中参考它。在仓库中,您将找到一个 requirements.txt 文件,列出了我们解决方案所需的所有 Python 库。请查看该文件,并使用以下命令安装所需的包:
!pip install -r requirements.txt
一旦您成功配置了 .env 文件中的这些常量,您就可以继续将它们集成到代码中:
-
我们将首先导入包:
import os from dotenv import load_dotenv import openai from langchain import OpenAI from langchain.llms import AzureOpenAI from langchain.retrievers import AzureCognitiveSearchRetriever from langchain.embeddings import OpenAIEmbeddings from langchain.vectorstores import Chroma from langchain.llms import AzureOpenAI from langchain.chains import RetrievalQA您可以在前面的代码中看到使用了多种库。让我们在下面的表格中深入了解这些库:
| 模块/库 | 描述 |
|---|---|
os | 提供与操作系统交互的功能 |
dotenv | 从 .env 文件加载环境变量 |
openai | 用于与 OpenAI 服务交互的 Python 库,包括 GPT-3 |
langchain | 与自然语言处理和机器 学习(ML)相关的自定义库或包 |
langchain.llms.AzureOpenAI | 与 OpenAI 在 Azure 上的语言模型相关的实现或类 |
langchain.retrievers.AzureCognitiveSearchRetriever | 用于从 Azure 认知搜索中检索信息的模块或类 |
langchain.embeddings.OpenAIEmbeddings | 可能与使用 OpenAI 模型从文本中提取向量嵌入相关 |
langchain.vectorstores.Chroma | 自定义向量存储或数据结构,可能用于处理机器学习中的向量 |
langchain.chains.RetrievalQA | 用于构建基于检索方法的问答系统的模块或类 |
表 4.1:使用的模块及其描述
-
现在,让我们使用
.env文件中提供的密钥初始化所有必要的常量:# Azure load_dotenv() OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") OPENAI_DEPLOYMENT_ENDPOINT = os.getenv( "OPENAI_DEPLOYMENT_ENDPOINT") OPENAI_DEPLOYMENT_NAME = os.getenv( "OPENAI_DEPLOYMENT_NAME") OPENAI_MODEL_NAME = os.getenv( "OPENAI_MODEL_NAME") OPENAI_API_VERSION = os.getenv( "OPENAI_API_VERSION") OPENAI_EMBEDDING_DEPLOYMENT_NAME = os.getenv( "OPENAI_EMBEDDING_DEPLOYMENT_NAME") OPENAI_EMBEDDING_MODEL_NAME = os.getenv( "OPENAI_EMBEDDING_MODEL_NAME") OPENAI_DEPLOYMENT_VERSION = os.getenv( "OPENAI_DEPLOYMENT_VERSION") OPENAI_EMBEDDING_VERSION = os.getenv( "OPENAI_EMBEDDING_VERSION") OPENAI_SIMILARITY_DEPLOYMENT_NAME = os.getenv( "OPENAI_SIMILARITY_DEPLOYMENT_NAME") # Cognitive service vector_store_address = os.getenv("VECTOR_STORE_ADDRESS") vector_store_password = os.getenv("VECTOR_STORE_PASSWORD") AZURE_COGNITIVE_SEARCH_SERVICE_NAME = os.getenv( "AZURE_COGNITIVE_SEARCH_SERVICE_NAME") AZURE_COGNITIVE_SEARCH_INDEX_NAME = os.getenv( "AZURE_COGNITIVE_SEARCH_INDEX_NAME") AZURE_COGNITIVE_SEARCH_API_KEY = os.getenv( "AZURE_COGNITIVE_SEARCH_API_KEY") #init Azure OpenAI openai.api_type = "azure" openai.api_version = OPENAI_DEPLOYMENT_VERSION openai.api_base = OPENAI_DEPLOYMENT_ENDPOINT openai.api_key = OPENAI_API_KEY load_dotenv() We have provided a sample `.env` file that needs to be configured with the connection strings from your Azure portal. Follow these steps to set it up:1. Adjust the `OPENAI_API_BASE` and `OPENAI_DEPLOYMENT_ENDPOINT` values to match your Azure OpenAI resource name. For example, if you’ve named your Azure OpenAI resource `oai-documents-qna`, the `OPENAI_API_BASE` value should be set to [`oai-documents-qna.azure.com/`](https://oai-documents-qna.azure.com/).2. Update the `OPENAI_API_KEY` value with the access key found in your Azure OpenAI resource under the `AZURE_SEARCH_SERVICE_NAME` and `AZURE_SEARCH_ADMIN_KEY` to match your Azure Search resource details, which can be obtained from Azure Cognitive Search.
完成这些配置后,您将拥有连接资源所需的设置。
我们现在将按照以下步骤测试与 Azure OpenAI 的连接:
# using model engine for testing the connectivity OpenAI
llm = AzureOpenAI(engine=OPENAI_MODEL_NAME, temperature=0)
print(llm('tell me about yourself'))
语言模型(简称llm)使用AzureOpenAI类进行初始化,并指定引擎(可能是 OpenAI 模型),该引擎名为OPENAI_MODEL_NAME,温度设置为0,温度控制模型回应的随机性。随后,使用初始化后的模型生成对tell me about yourself输入提示的回应,并打印出生成的回应以测试 OpenAI 语言模型的连接性和功能。
这是输出:
图 4.12:连接性输出
接下来,我们将加载文档,创建嵌入,并将它们添加到向量搜索中:
# load documents
loader = DirectoryLoader('data/', glob='*.pdf', show_progress=True)
documents = loader.load()
在之前的代码中,我们将数据文件夹中所有.pdf扩展名的文件加载到加载器中。
在下一行,我们将它们加载到documents对象中:
# split documents into chunks
text_splitter = CharacterTextSplitter(chunk_size=1000,
chunk_overlap=0)
docs = text_splitter.split_documents(documents)
我们正在初始化CharacterTextSplitter并使用它来分割文档,分割大小为 1000:
# vector search
index_name: str = " azureblob-index"
embeddings: OpenAIEmbeddings = OpenAIEmbeddings(deployment=model,
chunk_size=1)
vector_store: AzureSearch = AzureSearch(
azure_search_endpoint = vector_store_address,
azure_search_key=vector_store_password,
index_name=index_name,
embedding_function=embeddings.embed_query,
)
list_of_docs = vector_store.add_documents(documents=docs)
在之前的代码中,我们将向量存储初始化为AzureSearch并将文档添加到向量存储中。
让我们回顾一下到目前为止写的代码。
代码首先使用DocumentLoader从指定目录加载 PDF 文档,然后使用CharacterTextSplitter将其分割成更小的文本块。接着,它使用OpenAIEmbeddings模块创建嵌入,最后设置一个Azure Search 服务用于基于向量的文档搜索,并通过vector_store实例将之前分割的文本文档(docs)添加到向量存储中。
输出:
图 4.13:文档和嵌入输出
现在,我们将对向量数据库执行相似度搜索:
# Perform a similarity search
docs_search = vector_search.similarity_search(
query="What are some good places in Goa to visit in December",
k=3,
search_type="similarity",
)
print(docs_search[0].page_content)
使用vector_search对象进行相似度搜索。它接收查询“在十二月,果阿有哪些好去处?”并从向量存储中检索出与此查询最相似的前三个文档。然后打印出最相似文档的内容,使你能够基于文档的向量表示找到并展示与查询紧密匹配的文档。
输出:
图 4.14:相似度搜索输出
最后,我们将使用llm – AzureOpenAI创建一个链:
chain = RetrievalQA.from_chain_type(
llm=AzureOpenAI(
deployment_name=OPENAI_DEPLOYMENT_NAME,
model=OPENAI_DEPLOYMENT_NAME
),
chain_type="stuff",
retriever=vector_search.as_retriever()
)
chain
代码初始化了一个RetrievalQA链。它使用一个AzureOpenAI模型(配置了特定的部署和模型)来回答与stuff类别相关的问题。通过vector_search对象作为检索器,辅助进行相关信息的检索以回答问题。
输出:
图 4.15:使用 RetrievalQA 的链输出
我们将使用以下查询进行测试:
query = " What are some good places in Goa to visit in December"
chain.run(query)
具体问题“在 12 月,Goa 有哪些值得游览的好地方?”被提交给配置好的 QA 系统,该系统由链表示。该系统利用AzureOpenAI模型和向量搜索检索器来查找并生成对该问题的回答。问题的实际答案由模型的理解和系统索引中可用的内容决定。
输出:
图 4.16:查询输出
现在我们的解决方案已经清晰地给出了来自向量搜索的所需响应。通过这一点,我们已经达到了期望的输出。
总结
本章我们探讨了通过利用 Azure OpenAI 和 Azure Cognitive Search 来开发企业级文档 QA 解决方案。我们解决了一个常见的组织挑战——管理大量包含宝贵信息的非结构化文档,并突出了这种解决方案的变革潜力。我们概述了设置开发环境所需的基本工具和软件,确保了实施的准备工作。我们还详细讲解了架构,解释了 Azure Cognitive Search 和 Azure OpenAI 服务如何协同工作,将非结构化数据转换为嵌入,以便高效检索。最后,我们提供了构建该解决方案的实用指南,包括设置 Azure OpenAI 部署和 Azure Cognitive Search 组件。
在下一章中,我们将集成 OpenAI 和 Azure 通讯服务,构建一个先进的分析解决方案。
第五章:构建一个联系中心分析解决方案
在我们之前的章节中,我们解决了如何管理多个文档中分散信息的问题。我们探讨了如何通过在 Azure 门户中设置工具并利用 Python 代码将文档组织成可搜索的格式,从而简化查找相关内容的过程。在 Azure OpenAI 的帮助下,我们高效地应对了特定的挑战,将混乱转变为秩序,并简化了内容搜索。
本章中,我们将深入探讨构建联系中心分析解决方案的过程。我们将概述这一过程中的挑战、技术需求和设计要点。我们的目标是展示如何将 Azure OpenAI 和 Azure 通信服务集成,构建一个先进的分析平台。通过掌握这些概念,你将学会如何提升联系中心的运营,并高效地利用 AI 和通信技术。
在本章中,我们将涵盖以下主题:
-
问题陈述介绍
-
架构设计
-
使用 Azure OpenAI 和 Azure 通信服务构建一个联系中心分析解决方案
问题陈述介绍
假设你在你的城市运营一个外卖应用,管理一个由 10 名成员组成的专门团队,负责处理客户查询。随着更多人使用该应用,客户聊天数量激增。管理这些成千上万的聊天已成为你团队面临的一个重大挑战,导致在外卖过程中解决客户问题变得更加困难。数据量庞大使得很难准确找出应用或整体外卖流程中的问题。更糟糕的是,关于接下来应该采取什么步骤的种种不确定性,使得事情更加复杂。有效地管理和理解这些聊天数据、发现应用及流程中的问题,并确定开发的下一步变得越来越关键,以确保你的外卖平台保持成功。
技术要求
要跟随本章中的实际练习,请访问本章 GitHub 仓库中的源代码:github.com/PacktPublishing/Azure-OpenAI-Essentials/blob/main/Chapter5.ipynb
以下是我们在第四章中已经配置的需求:
-
Python 3.9、3.10 或 3.11:
www.python.org/downloads/ -
Azure 开发者 CLI:
learn.microsoft.com/en-us/azure/developer/azure-developer-cli/install-azd -
Node.js 14+:
nodejs.org/en/download -
Powershell 7+ (pwsh):
github.com/powershell/powershell -
Azure 账户:如果你是 Azure 新手,可以免费注册 Azure 账户,并获得一些免费的 Azure 积分开始使用
-
启用了 Azure OpenAI 服务访问权限的 Azure 订阅:你可以在
aka.ms/oaiapply申请访问权限 -
Azure OpenAI 连接和模型信息:
-
OpenAI API 密钥
-
OpenAI 嵌入模型部署名称
-
OpenAI API 版本
-
除了在第四章中指定的要求外,还需要满足以下额外的技术要求:
- Azure 通信服务
快速提醒,请确保你有一个有效的 Azure 账户,正如我们在第四章中讨论的那样。如果你需要关于设置 Azure 账户和激活订阅的指导,所有详细信息可以在第四章中找到。
架构设计
现在我们已经掌握了构建解决方案所需的关键架构元素,接下来我们将展示如何在 Azure 门户中将这些组件组合在一起。在前几章中,我们讨论了如何成功部署 Azure OpenAI 服务模型,无论是 GPT-3、ChatGPT 还是 GPT-4。本章中,我们将重点介绍如何创建一个全新的 Azure 通信服务。接下来,让我们深入细节,并开始将这个计划付诸实践。
首先,我们将手动向 Azure 通信服务发送一堆消息。之后,我们将从相同位置获取这些消息并将它们用作提示。然后,这个提示将被发送到 OpenAI 服务,并为我们提供所需的摘要。这是一个动手过程,旨在使我们的通信更顺畅,并为我们的食品配送应用提供重要见解。
使用 Azure OpenAI 和其他 Azure 服务构建联系中心分析解决方案
快速提醒,请确保你有一个有效的 Azure 账户,正如我们在第四章中讨论的那样。如果你需要关于设置 Azure 账户和激活订阅的指导,所有详细信息可以在第四章中找到。
Azure 订阅前提条件
在第二章中已建立的以下前提条件可以重用:
-
一个 Azure 订阅
-
Azure OpenAI 资源
-
部署的 Azure OpenAI 模型
创建以下工具,排除在第二章中已建立的工具。
在本节中,你的重点将转向创建一个全新的 Azure 通信服务。
要设置你的 Azure 通信服务,请前往 Azure 首页顶部导航栏的搜索框,输入Communication Service。
如果你没有看到它,点击Communication Service并点击创建:
图 5.1:创建资源
一旦点击 创建,你将看到可以从服务列表中选择的选项。从下拉菜单中选择 通信服务,如下所示:
图 5.2:选择通信服务
一旦你进入 通信服务 页面,你需要点击 创建 按钮,如下所示:
图 5.3:在通信服务下创建
一旦你成功创建了来自市场的通信服务,就可以进入下一步。在你之前在 第四章中设置的 azure-openai-rg 中继续操作。现在是将各个部分连接起来,确保一切顺利对接。
图 5.4:输入通信服务数据
现在,输入你想要的资源名称(例如 azure-openai-communication-service)和通信服务的数据位置,然后点击 下一步 按钮进入 标签 标签页。你现在可以忽略 标签 部分。标签是名称/值对,它们可以帮助你对资源进行分类,并通过将相同标签应用于多个搜索和资源组来简化账单管理。继续点击 下一步,然后进入 审核 + 创建 标签页。在这里,它会显示你在前面步骤中选择的详细信息。检查所有信息后,点击 创建 按钮:
图 5.5:审查和创建数据
现在,我们将开始使用我们配置的服务来构建解决方案。
使用 Azure Communication Services 和 OpenAI 服务构建解决方案
现在我们已经在 Azure 门户中设置了所有必要的服务,可以开始构建我们的解决方案了。为了开发代码,我将使用 Python Jupyter Notebook,剩余的安装与 第四章的“使用 Azure OpenAI 解决方案”部分定义的相同。
除了在 第四章中安装的那些包之外,你还需要安装一个额外的 Python 库。
创建一个新的 Jupyter notebook 并安装以下包:
pip install openai azure.communication.chat azure.communication.identity
我们的代码包括以下几个部分,在这些部分中我们将开发我们的解决方案:
-
导入包
-
建立聊天用户身份
-
配置聊天客户端
-
生成对话记录
-
总结聊天线程
导入包
我们将导入所有构建模型所需的包:
from azure.communication.chat import ChatClient, CommunicationTokenCredential, ChatMessageType,ChatParticipant
from azure.communication.identity import CommunicationIdentityClient, CommunicationUserIdentifier
from datetime import datetime
from datetime import datetime, timedelta
import os
import requests
import json
import openai
你可以在前面的代码中看到各种库。让我们在下面的表格中详细介绍每个库:
| 导入的包 | 描述 |
|---|---|
from azure.communication.chat import ChatClient, CommunicationTokenCredential, ChatMessageType, ChatParticipant | 使 Azure Communication Services 实现实时聊天 |
from azure.communication.identity import CommunicationIdentityClient, CommunicationUserIdentifier | 管理用户身份和身份验证令牌 |
from datetime import datetime, timedelta | 处理日期和时间操作 |
import os | 与操作系统交互并管理环境变量 |
import requests | 发送 HTTP 请求,通常用于 API 交互 |
import json | 编码和解码 JSON 数据 |
import openai | 访问 OpenAI API 进行高级语言处理 |
dotenv | 从 .env 文件加载环境变量 |
表 5.1:导入包的解释
现在,让我们使用 .env 文件中提供的密钥初始化所有必要的常量。将 COMMUNICATION_CONNECTION_STRING 和 COMMUNICATION_ENDPOINT 添加到你已有的 .env 文件中:
# Azure
load_dotenv()
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_DEPLOYMENT_ENDPOINT = os.getenv("OPENAI_DEPLOYMENT_ENDPOINT")
OPENAI_DEPLOYMENT_NAME = os.getenv("OPENAI_DEPLOYMENT_NAME")
OPENAI_MODEL_NAME = os.getenv("OPENAI_MODEL_NAME")
OPENAI_API_VERSION = os.getenv("OPENAI_API_VERSION")
OPENAI_DEPLOYMENT_VERSION = os.getenv("OPENAI_DEPLOYMENT_VERSION")
## Azure Communication Service
COMMUNICATION_CONNECTION_STRING = os.getenv(
"COMMUNICATION_CONNECTION_STRING")
COMMUNICATION_ENDPOINT = os.getenv("COMMUNICATION_ENDPOINT")
#init Azure OpenAI
openai.api_type = "azure"
openai.api_version = OPENAI_DEPLOYMENT_VERSION
openai.api_base = OPENAI_DEPLOYMENT_ENDPOINT
openai.api_key = OPENAI_API_KEY
load_dotenv()
将这些添加到 第四章 中创建的 .env 文件,该文件包含连接字符串和端点:
COMMUNICATION_CONNECTION_STRING = "{communication-service-connection-string}"
COMMUNICATION_ENDPOINT = "{communication-serivce-endpoint}"
按照以下步骤设置通信服务端点:
-
更新
COMMUNICATION_CONNECTION_STRING值,使用你在 Azure Communication Service 中 Keys 部分找到的连接字符串值。 -
类似地,使用你在 Azure Communication Service 中 Keys 部分找到的值修改
COMMUNICATION_ENDPOINT的值。
完成这些配置后,你将拥有所需的连接设置来访问你的资源。
我们得到以下输出:
Out[15]: True
建立聊天用户身份
这段代码在 Azure Communication Services 中建立了用户身份 (identity1 和 identity2),并检索了各自的访问令牌 (token_result1 和 token_result2):
client = CommunicationIdentityClient.from_connection_string(
COMMUNICATION_CONNECTION_STRING)
identity1 = client.create_user()
token_result1 = client.get_token(identity1, ["chat"])
identity2 = client.create_user()
token_result2 = client.get_token(identity2, ["chat"])
这些令牌用于身份验证,在与 Azure Communication Services 的聊天功能交互时,每个用户身份都与一个独特的令牌关联,该令牌特定地授予对定义范围的访问权限,在这个实例中是 chat。
配置聊天客户端
在这段代码中,我们使用 Azure Communication Services 在 Agent 和 Customer 之间建立一个聊天线程:
Agent = ChatParticipant(identifier=identity1, display_name="Agent", share_history_time=datetime.utcnow())
Customer = ChatParticipant(identifier=identity2, display_name="Customer", share_history_time=datetime.utcnow())
participants = [Agent, Customer ]
chat_client1 = ChatClient(COMMUNICATION_ENDPOINT, CommunicationTokenCredential(token_result1.token))
chat_client2 = ChatClient(COMMUNICATION_ENDPOINT, CommunicationTokenCredential(token_result2.token))
topic="Support conversation"
create_chat_thread_result = chat_client1.create_chat_thread(topic, thread_participants=participants)
chat_thread_client1 = chat_client1.get_chat_thread_client(create_chat_thread_result.chat_thread.id)
chat_thread_client2 = chat_client2.get_chat_thread_client(create_chat_thread_result.chat_thread.id)
每个用户都会初始化聊天客户端,并创建一个具有指定参与者和主题的聊天线程,从而允许在创建的线程内进行后续的互动和消息传递。
现在,我们将在聊天线程中填充一个代理和客户之间的示例对话:
agentText = [
"Thank you for reaching out to our customer support! How can I assist you with your food delivery today?"
"I'm sorry to hear that. Could you provide me with your name and order number so I can check your details and assist you better?"
"Thanks. Can you please share more details about the issue you're facing with your food delivery?"
"I understand. It can be frustrating. Can you check if the delivery address is correct and accessible? Also, ensure that your contact details are up to date."
"Alright. Please verify the delivery address and ensure there are no obstacles for our delivery team. Let me know if the issue persists."
"That might be causing the delay. Can you confirm the delivery address and try placing the order again?"
"Great to hear that! Is there anything else I can help you with regarding your food delivery?"
"You're welcome. Feel free to reach out if you have any more questions. Enjoy your meal!"
]
customerText = [
"Hi, I'm having an issue with my food delivery. It hasn't arrived yet."
"Yes, my name is John, and my order number is."
"Well, it seems like my food hasn't been delivered on time. What could be the issue?"
"I've checked the delivery address, and it's correct. Also, my phone is working fine."
"Okay, let me check. Yes, it seems like there's a small issue with the delivery address. Let me correct that."
"Sure, let me try that. Alright, I've updated the delivery address. Can you check the status now?"
"No, that's all. Thanks for your help. Looking forward to my meal!"
"Goodbye."
]
接下来,这段代码使用 for 循环模拟代理和客户之间的对话,通过向聊天线程发送消息来进行双向对话:
for x in range(len(agentText)):
chat_thread_client1.send_message(content= agentText[x], sender_display_name="Agent", chat_message_type=ChatMessageType.TEXT)
chat_thread_client2.send_message(content= customerText[x], sender_display_name="Customer", chat_message_type=ChatMessageType.TEXT)
消息涉及洗碗机问题的故障排除步骤,且对话流程在代理和客户视角之间交替进行。
生成对话记录
这段代码从过去一天内发送的聊天记录中获取文本消息,过滤掉非文本消息,并通过连接发件人姓名和消息内容构建对话提示。然后打印出该提示,提供按时间倒序排列的近期对话总结:
start_time = datetime.utcnow() - timedelta(days=1)
messages = []
chat_messages = chat_thread_client1.list_messages(results_per_page=1, start_time=start_time)
for chat_message_page in chat_messages.by_page():
for chat_message in chat_message_page:
if(chat_message.type == ChatMessageType.TEXT):
messages.append(chat_message)
# didn't know I had to filter out other messages
prompt = ""
for m in range(len(messages)-1, -1, -1):
prompt = prompt + messages[m].sender_display_name + ": " + messages[m].content.message + "\n"
print(prompt)
我们得到了以下输出:
图 5.6:对话输出概览
总结聊天记录
这段代码利用 OpenAI 的 GPT 模型根据提供的提示生成扩展响应,提示包括介绍性文本和对话提示。然后生成的总结文本会被处理并与原始提示一起打印出来:
# Send a completion call to generate an answer
start_phrase = 'For the following conversation, extract a topic, summary, highlights (1-3 bullet points of key information) and the sentiment of both of the users.\n\n' + prompt
response = openai.Completion.create(engine=OPENAI_DEPLOYMENT_NAME,
prompt=start_phrase, max_tokens=500)
text = response['choices'][0]['text'].replace('\n', '').replace(' .', '.').strip()
print(start_phrase + '\n' + text)
我们得到了以下输出:
图 5.7:总结输出概览
因此,我们创建了一个结合 OpenAI 和 Azure 的分析解决方案,适用于联络中心。
总结
在本章中,我们深入探讨了实现和利用 Azure 通信服务的复杂性。我们的实际探索包括创建一个模拟的聊天对话,涉及一名代理和一名客户。通过运用 ChatGPT,我们对全面的对话总结进行了深入分析。
尽管我们的示例专注于基于文本的聊天交互,但需要注意的是,Azure 通信服务的多功能性远不止于文本。它能够无缝地支持音频、视频或多种格式的混合使用,以提供更具动态的用户体验。这种整体方法使我们能够深入了解客户关切,让得出的统计数据成为塑造未来产品路线图的重要输入。通过探索各种对话格式,我们可以发现潜在的痛点并识别改进的关键领域,从而最终促进我们产品和服务的提升。
在下一章,我们将深入探讨使用提示与 SQL 数据库交互的世界。