企业聊天应用程序能够通过对话交互来提升员工的能力。 由于 OpenAI 的 GPT 模型和 Meta 的 LLaMA 模型等语言模型的不断进步,情况尤其如此。 这些聊天应用程序包括聊天用户界面 (UI)、包含与用户查询相关的特定于域信息的数据存储库、对特定领域数据进行推理以生成相关响应的语言模型,以及负责监督这些组件之间交互的业务流程协调程序。
本文提供了生成和部署使用 Azure OpenAI 语言模型的企业聊天应用程序的基线体系结构。 该体系结构采用提示流来创建可执行流。 这些可执行流程协调了从传入提示到数据存储的工作流程,以便为语言模型获取基础数据以及其他所需的 Python 逻辑。 可执行流部署到具有托管计算的托管联机终结点。
自定义聊天用户界面(UI)的托管遵循基线应用服务 Web 应用程序指南,用于在Azure App 服务上部署安全、区域冗余和高度可用的 Web 应用程序。 在该体系结构中,应用程序服务通过专用终结点的虚拟网络集成与 Azure 平台即服务 (PaaS) 解决方案通信。 聊天 UI App 服务通过专用终结点与托管联机终结点通信。 已禁用对 Azure AI Studio 的公共访问。
重要
本文不讨论基线应用程序服务 Web 应用程序中的组件或体系结构决策。 请阅读这篇文章,了解如何托管聊天 UI 的体系结构指导。
Azure AI Studio 中心配置了 托管虚拟网络隔离 ,需要批准所有出站连接。 使用此配置可创建一个托管虚拟网络以及托管专用终结点,这些终结点支持连接到工作场所 Azure 存储、Azure 容器注册表和 Azure OpenAI 等专用资源。 这些专用连接在流创作和测试期间使用,以及部署到 Azure 机器学习计算的流。
中心是顶级 Azure AI Studio 资源,它提供了一种控制跨多个项目的安全、连接和其他问题的核心方法。 此体系结构仅需要一个项目用于其工作负荷。 如果有其他体验需要具有不同逻辑的不同提示流,则可能使用不同的后端资源(如数据存储),则可以考虑在不同的项目中实现这些资源。
提示
本文以参考实现提供支持,展示了 Azure 上的基线端到端聊天实现。 在生产的第一步中,你可以使用此实现作为自定义解决方案开发的基础。
体系结构
下载此体系结构的 Visio 文件。
组件
此体系结构的许多组件与基本 Azure OpenAI 端到端聊天体系结构均相同。 以下列表仅突出显示对基本体系结构的更改。
- Azure OpenAI 同时用于基本体系结构和此基线体系结构。 Azure OpenAI 是一项完全托管的服务,提供对 Azure OpenAI 语言模型(包括 GPT-4、GPT-3.5-Turbo 和嵌入模型集)的 REST API 访问。 基线体系结构利用基本体系结构未实现的企业功能,例如 虚拟网络和专用链接 。
- Azure AI Studio 是一个可用于构建、测试和部署 AI 解决方案的平台。 AI Studio 在此体系结构中用于构建、测试和部署聊天应用程序的提示流业务流程逻辑。 在此体系结构中,Azure AI Studio 提供用于网络安全的 托管虚拟网络 。 有关详细信息,请参阅 网络部分 以获取更多详细信息。
- 应用程序网关 是第 7 层 (HTTP/S) 负载平衡器和 Web 流量路由器。 它使用基于 URL 路径的路由跨可用性区域分配传入流量,并卸载加密以提高应用程序性能。
- Web 应用程序防火墙 (WAF) 是一项云原生服务,可保护 Web 应用免受常见攻击,如 SQL 注入和跨站脚本。 Web 应用程序防火墙提供对进出 Web 应用程序的流量的可见性,使您能够监控和保护应用程序。
- Azure 密钥保管库是可安全存储和管理机密、加密密钥与证书的服务。 它集中管理敏感信息。
- Azure 虚拟网络 是一项服务,支持你在 Azure 中创建隔离和安全的专用虚拟网络。 对于应用程序服务上的 Web 应用程序,需要使用虚拟网络子网才能使用专用终结点在资源之间进行网络安全通信。
- 使用专用链接,客户端能够直接从专用虚拟网络访问 Azure 平台即服务 (PaaS) 服务,而无需使用公共 IP 寻址。
- Azure DNS 是面向 DNS 域的托管服务,它使用 Microsoft Azure 基础结构提供名称解析。 专用 DNS 区域提供了一种将服务的完全限定域名 (FQDN) 映射到专用终结点的 IP 地址的方法。
备选方法
此体系结构具有多个组件,这些组件可由其他 Azure 服务提供服务,这些组件可能更好地满足工作负荷的功能和非功能要求。 下面是一些需要注意的替代方法。
Azure 机器学习工作区(和门户体验)
此体系结构使用 Azure AI Studio 生成、测试和部署提示流。 或者,可以使用Azure 机器学习工作区,因为两个服务都有重叠的功能。 虽然在设计提示流解决方案时,AI Studio 是一个不错的选择,但目前有一些功能Azure 机器学习具有更好的支持。 有关详细信息,请参阅 功能比较。 建议不要混合和匹配 Azure AI Studio 和Azure 机器学习。 如果你的工作可以在 AI 工作室中完全完成,请使用 AI Studio。 如果仍需要Azure 机器学习工作室的功能,请继续使用Azure 机器学习工作室。
应用程序层组件
Azure 中提供了多个托管应用程序服务产品/服务,可用作聊天 UI 前端的应用程序层。 请参阅 针对所有计算选择 Azure 计算服务 ,并为 容器解决方案选择 Azure 容器服务 。 例如,虽然为聊天 UI API 和提示流主机分别选择了用于容器的 Azure Web 应用 和 Web 应用,但可以使用 Azure Kubernetes 服务 (AKS) 或 Azure 容器应用实现类似的结果。 根据工作负荷的特定功能和功能要求选择工作负荷的应用程序平台。
提示流托管
部署提示流不限于机器学习计算群集,此体系结构演示了在Azure App 服务中使用替代方法。 流最终是容器化应用程序,可以部署到任何与容器兼容的 Azure 服务。 这些选项包括Azure Kubernetes 服务(AKS)、Azure 容器应用和Azure App 服务等服务。 根据业务流程层的要求选择 Azure 容器服务 。
本文稍后将讨论为何在备用计算中托管提示流的示例。
地面数据存储
虽然此体系结构与 Azure AI 搜索有关,但为地面数据选择数据存储是特定于工作负荷的体系结构决策。 许多工作负荷实际上是多面体,具有不同的源和技术来建立数据。 这些数据平台从现有的 OLTP 数据存储、云本机数据库(如 Azure Cosmos DB)到 Azure AI 搜索等专用解决方案不等。 此类数据存储的常见但不需要特征是矢量搜索。 请参阅 选择 Azure 服务进行矢量搜索 ,以浏览此空间中的选项。
注意事项和建议
可靠性
可靠性可确保应用程序符合你对客户的承诺。 有关详细信息,请参阅可靠性设计评审核对清单。
基线应用程序服务 Web 应用程序体系结构侧重于关键区域服务的区域冗余。 可用性区域是区域中在物理上独立的位置。 当跨区域部署两个或多个实例时,它们会在区域内为支持服务提供冗余。 当一个区域出现停机时,该区域内的其他区域可能仍不受影响。 该体系结构还确保有足够的 Azure 服务实例和这些服务的配置分布在各个可用性区域。 有关详细信息,请参阅查看该指南的基线。
本节将从此体系结构中未在应用程序服务基线中解决的组件(包括机器学习、Azure OpenAI 和 AI 搜索)的角度来解决可靠性问题。
流部署的区域冗余
企业部署通常需要做到区域冗余。 要在 Azure 中实现区域冗余,资源必须支持可用性区域,并且必须至少部署三项资源实例,或者在实例控制不可用时启用平台支持。 目前,机器学习计算不支持可用性区域。 为了减轻数据中心级灾难对机器学习组件的潜在影响,有必要在不同地区建立群集,并部署负载均衡器以便在这些集群之间分配调用。 你可以使用运行状况检查来帮助确保调用只会被路由到正常运行的群集。
有一些替代方法可用于机器学习计算群集,例如Azure Kubernetes 服务(AKS)、Azure Functions、Azure 容器应用和Azure App 服务。 这些服务均支持可用性区域。 要实现提示流执行的区域性冗余,而不增加多区域部署的复杂性,则应将流部署到其中一个服务。
下图显示将提示流部署到应用程序服务的另一种体系结构。 之所以在此体系结构中使用应用程序服务,是因为工作负荷已将其用于聊天 UI,在工作负荷中引入新技术不会带来任何好处。 有 AKS 使用经验的工作负荷团队应考虑在该环境中进行部署,尤其是在工作负荷的其他组件也使用 AKS 的情况下。
图中对该体系结构中的重要区域进行了编号:
流仍以提示流编写,网络体系结构保持不变。 流作者仍通过专用终结点连接到 AI Studio 项目中的创作体验,托管专用终结点用于在测试流时连接到 Azure 服务。
这条虚线表示已将容器化可执行流推送到容器注册表。 图中未显示将流容器化并推送到容器注册表的管道。 运行这些管道的计算必须具有对 Azure 容器注册表和 AI Studio 项目等资源的网络视线。
还有另一个 Web 应用部署到已托管聊天 UI 的同一应用服务计划。 新的 Web 应用托管容器化提示流,并置在同一应用服务计划中,该计划已至少运行三个实例,分布在可用性区域。 加载提示流容器映像时,这些应用程序服务实例会通过专用终结点连接到容器注册表。
提示流容器需要连接到所有依赖服务才能执行流。 在此体系结构中,提示流容器连接到 AI 搜索和 Azure OpenAI。 现在,仅向机器学习托管专用终结点子网公开的 PaaS 服务也需要在虚拟网络中公开,以便从应用程序服务建立连接。
Azure OpenAI - 可靠性
Azure OpenAI 目前不支持可用性区域。 要减轻数据中心级灾难对 Azure OpenAI 中模型部署的潜在影响,必须将 Azure OpenAI 部署到不同的区域,同时部署负载均衡器以便在各区域之间分配调用。 你可以使用运行状况检查来帮助确保调用只会被路由到正常运行的群集。
为有效支持多个实例,建议将微调文件外部化,例如转移到异地冗余 Azure 存储帐户。 这种方法最大限度地减少了每个区域存储在 Azure OpenAI 中的状态。 仍必须微调每个实例的文件才能托管模型部署。
在每分钟令牌 (TPM) 和每分钟请求 (RPM) 方面监视所需的吞吐量非常重要。 确保从配额中分配足够的 TPM 以满足部署需求,并防止对已部署模型的调用受到限制。 Azure API 管理等网关可部署在 OpenAI 服务之前,并可在出现暂时性错误和限制的情况下进行重试配置。 API 管理还可以用作断路器,以防止服务因超出其配额的调用而过载。
AI 搜索 - 可靠性
在支持可用性区域的区域部署具有标准或更高定价层的的 AI Search,并部署三个或更多副本。 副本会自动均匀分布到各个可用性区域。
请考虑以下指南来确定适当的副本和分区数:
使用监视指标、日志和性能分析来确定适当的副本数量以避免基于查询的限制,并确定分区数量以避免基于索引的限制。
Azure AI Studio - 可靠性
如果部署到机器学习托管联机终结点后面的计算群集,请考虑以下有关缩放的指导:
自动扩展联机终结点,确保有足够的容量来满足需求。 如果由于突发使用导致使用信号不够及时,则应考虑超量预配,以防止可用实例太少而影响可靠性。
积极的生产部署应部署不少于三个实例。
避免针对正在使用的实例进行部署。 改为部署到一个新的部署,并在部署准备好接收流量后将流量转移过来。
托管联机终结点充当其后面运行的托管计算的负载均衡器和路由器。 可以配置应路由到每个部署的流量百分比,只要百分比增加至 100%。 还可以部署托管联机终结点,并将 0% 流量路由到任何部署。 如果在提供的参考实现中,使用基础结构即代码(IaC)部署资源(包括托管联机终结点),则存在可靠性问题。 如果流量配置为路由到部署(通过 CLI 或 Azure AI Studio 创建),并且执行包含托管联机终结点的后续 IaC 部署,即使它不会以任何方式更新托管联机终结点,终结点流量也会恢复为路由 0% 流量。 实际上,这意味着在将流量调整回所需位置之前,将无法再访问已部署的提示流。
注意
如果将流部署到应用程序服务,则基线体系结构中的应用程序服务可扩展性指南同样适用。
多区域设计
此体系结构不是在多区域体系结构中构建为区域标记。 它确实在单个区域中提供高可用性,因为它完全使用可用性区域,但缺少一些关键组件,使它真正为多区域解决方案做好准备。 以下是此体系结构中缺少的一些组件或注意事项:
- 全局入口和路由
- DNS 管理策略
- 数据复制(或隔离)策略
- 主动-主动、主动-被动或主动冷指定
- 实现工作负荷 RTO 和 RPO 的故障转移和故障回复策略
- 有关 Azure Studio Hub 资源中开发人员体验的区域可用性决策
如果工作负荷的要求需要多区域策略,则需要在此体系结构中提供的内容的基础上,在组件和操作流程方面投入额外的设计工作。 你设计为支持以下层的负载均衡或故障转移:
- 接地数据
- 模型托管
- 业务流程层(此体系结构中的提示流)
- 面向客户端的 UI
此外,还需要在可观测性、门户体验和负责任的 AI 问题(如内容安全)中保持业务连续性。
安全性
安全性针对蓄意攻击及滥用宝贵数据和系统提供保障措施。 有关详细信息,请参阅可靠性设计审查检查表。
此体系结构扩展了在基本端到端聊天与 Azure OpenAI 体系结构中实现的安全占用空间。 虽然基本体系结构使用系统分配的托管标识和系统分配的角色分配,但此体系结构使用具有手动创建的角色分配的用户分配标识。
该体系结构除了在基本体系结构中实现身份识别外,还实现了网络安全边界。 从网络的角度来看,唯一可以从 Internet 访问的是通过应用程序网关访问聊天 UI。 从身份的角度来看,聊天 UI 应对请求进行身份验证和授权。 在可能的情况下,使用托管标识对 Azure 服务应用程序进行身份验证。
除了网络注意事项外,本部分还介绍了密钥轮换和 Azure OpenAI 模型微调的安全注意事项。
标识和访问管理
使用用户分配的托管标识时,请考虑以下指南:
- 为以下 Azure AI Studio 和机器学习资源创建单独的托管标识(如果适用):
- AI Studio 中心
- 用于流创作和管理的 AI Studio 项目
- 如果流量已部署到托管联机端点,则使用已部署流中的联机终结点
- 使用 Microsoft Entra ID 为聊天 UI 实现身份-访问控制
为要从权限角度隔离其他提示流的不同提示流创建单独的项目和联机终结点。 为每个项目和托管联机终结点创建单独的托管标识。 仅向提示流作者提供对所需项目的访问权限。
将用户加入 Azure AI Studio 项目以执行创作流等功能时,需要对所需的资源进行最低特权角色分配。
基于机器学习角色的访问角色
与在基本体系结构中一样,系统会自动为系统分配的托管标识创建角色分配。 由于系统不知道可以使用的中心和项目的功能,因此它会创建角色分配支持所有潜在功能。 根据用例,自动创建的角色分配可能会超过预配权限。 例如,分配给容器注册表中心的“参与者”角色,其中可能只需要“读取者”访问控制平面。 如果需要进一步限制最低特权目标的权限,则必须使用用户分配的标识。 你将自行创建和维护这些角色分配。
由于管理所有所需分配的维护负担,此体系结构优先于绝对最低特权角色分配的操作卓越性。 请注意,必须使表中列出的所有工作分配。
托管的标识 | 范围 | 角色分配 |
---|---|---|
中心托管标识 | 参与者 | 资源组 |
中心托管标识 | 中心 | Azure AI 管理员 |
中心托管标识 | 容器注册表 | 参与者 |
中心托管标识 | 密钥保管库 | 参与者 |
中心托管标识 | 密钥保管库 | 管理员 |
中心托管标识 | 存储帐户 | 读者 |
中心托管标识 | 存储帐户 | 存储帐户参与者 |
中心托管标识 | 存储帐户 | 存储 Blob 数据参与者 |
中心托管标识 | 存储帐户 | 存储文件数据特权参与者 |
中心托管标识 | 存储帐户 | 存储表数据参与者 |
项目托管标识 | 集成 | Azure AI 管理员 |
项目托管标识 | 容器注册表 | 参与者 |
项目托管标识 | 密钥保管库 | 参与者 |
项目托管标识 | 密钥保管库 | 管理员 |
项目托管标识 | 存储帐户 | 读者 |
项目托管标识 | 存储帐户 | 存储帐户参与者 |
项目托管标识 | 存储帐户 | 存储 Blob 数据参与者 |
项目托管标识 | 存储帐户 | 存储文件数据特权参与者 |
项目托管标识 | 存储帐户 | 存储表数据参与者 |
联机终结点托管标识 | 集成 | Azure 机器学习工作区连接机密 |
联机终结点托管标识 | 集成 | AzureML 指标编写器 |
联机终结点托管标识 | 容器注册表 | ACRPull |
联机终结点托管标识 | Azure OpenAI | 认知服务 OpenAI 用户 |
联机终结点托管标识 | 存储帐户 | 存储 Blob 数据参与者 |
联机终结点托管标识 | 存储帐户 | 存储 Blob 数据读者 |
App 服务(将提示流部署到App 服务时) | Azure OpenAI | 认知服务 OpenAI 用户 |
门户用户(提示流开发) | Azure OpenAI | 认知服务 OpenAI 用户 |
门户用户(提示流开发) | 存储帐户 | 存储 Blob 数据参与者(使用条件访问) |
门户用户(提示流开发) | 存储帐户 | 存储文件数据特权参与者 |
请务必了解 AI Studio 中心具有跨项目共享的 Azure 资源,例如存储帐户和容器注册表。 如果你的用户只需要访问项目子集,请考虑对支持它们的 Azure 服务使用 角色分配条件,以提供对资源的最低特权访问权限。 例如,Azure 存储中的 blob 支持角色分配条件。 对于需要访问项目子集的用户,而不是按容器分配权限,请使用角色访问条件来限制这些项目使用的 Blob 容器的权限。 每个项目都有一个唯一的 GUID,用作该项目中使用的 Blob 容器名称的前缀。 该 GUID 可用作角色分配条件的一部分。
中心必须有权 Contributor
访问中心资源组,以便允许其创建和管理中心和项目资源。 中心的副作用是控制平面对资源组中任何资源的访问。 任何与中心无关的 Azure 资源及其项目都应在单独的资源组中创建。 建议至少使用自托管 Azure AI Studio 中心为工作负荷团队创建两个资源组。 一个资源组,用于包含中心、其项目及其所有直接依赖项,例如 Azure 容器注册表、密钥库等。 一个资源组,用于包含工作负荷中的其他所有内容。
建议尽量减少使用中心操作所需的 Azure 资源(容器注册表、存储帐户、密钥库、Application Insights)和工作负荷中的其他组件。 例如,如果需要将机密存储为工作负荷的一部分,则应在与中心关联的密钥保管库之外创建单独的密钥库。 中心密钥库只能由中心用来存储中心和项目机密。
确保对于每个不同的项目,其依赖项的角色分配不提供对门户用户和托管联机终结点托管标识不需要的资源的访问权限。 例如, Cognitive Services OpenAI User
Azure OpenAI 的角色分配授予对该资源的所有部署的访问权限。 无法限制流作者或托管联机终结点托管标识,该角色分配有权访问 Azure OpenAI 中的特定模型部署。 对于此类方案,我们的指导是按项目部署 Azure OpenAI 和 Azure AI 搜索等服务,并且不会将资源部署到流作者或托管联机终结点托管标识不应有权访问的服务。 例如,仅将模型部署到项目需要访问的项目 Azure OpenAI 实例。 仅将索引部署到该项目应有权访问的项目 Azure AI 搜索实例。
网络
除了基于身份的访问,网络安全也是使用 OpenAI 的基线端到端聊天体系结构的核心。 网络体系结构可在高级别上确保:
- 聊天 UI 流量只有单一安全入口点。
- 筛选网络流量。
- 传输中的数据使用传输层安全性 (TLS) 进行端到端加密。
- 通过使用专用链接将流量保持在 Azure 中,可最大限度地减少数据外泄。
- 网络资源通过网络分段进行逻辑分组和相互隔离。
网络流
此图中的两个流包含在基线应用程序服务 Web 应用程序体系结构中:从最终用户到聊天 UI (1) 的入站流,以及从应用程序服务流到 Azure PaaS 服务 (2)。 本节重点介绍机器学习联机终结点流。 以下流程从基线应用程序服务 Web 应用程序中运行的聊天 UI 到部署到机器学习计算的流程:
- 来自应用程序服务托管聊天 UI 的调用会通过专用终结点路由到机器学习联机终结点。
- 联机终结点将调用路由到运行已部署流的服务器。 联机终结点既充当负载均衡器,又充当路由器。
- 对部署的流所需的 Azure PaaS 服务的调用会通过托管专用终结点来进行路由。
流入机器学习
在此体系结构中,禁用对机器学习工作区的公共访问。 用户可以通过专用访问访问工作区,因为体系结构遵循机器学习工作区配置的专用终结点。 事实上,专用终结点在整个体系结构中被用来补充基于身份的安全性。 例如,应用程序服务托管聊天 UI 可以连接到未公开到公共 Internet(包括 Azure 机器学习终结点)的 PaaS 服务。
连接到机器学习工作区进行流创作也需要使用专用终结点访问。
此图显示了通过 Azure Bastion 连接到虚拟机跳转框的提示流作者。 作者可以从跳转盒通过与跳转盒位于同一网络中的专用终结点连接到机器学习工作区。 与虚拟网络的连接也可以通过 ExpressRoute 或 VPN 网关和虚拟网络对等互联来实现。
从 Azure AI Studio 托管虚拟网络流向 Azure PaaS 服务
建议将 Azure AI Studio 中心配置为 托管虚拟网络隔离 ,要求批准所有出站连接。 此体系结构遵循这一建议。 经批准的出站规则有两种。 所需的出站规则是解决方案正常运行所需的资源,例如容器注册表和存储。 用户定义的出站规则适用于工作流要使用的自定义资源,例如 OpenAI 或 AI 搜索。 必须配置用户定义的出站规则。 创建托管虚拟网络时配置所需的出站规则。 首次使用托管虚拟网络时,会按需部署托管虚拟网络,并且从此保持。
出站规则可以是外部公共终结点的专用终结点、服务标记或目标完全限定域名 (FQDN)。 在此体系结构中,将通过专用链接连接到 Azure 服务,例如容器注册表、存储、Azure 密钥保管库、Azure OpenAI 服务和 AI 搜索。 尽管不在此体系结构中,但一些常见操作可能需要配置 FQDN 出站规则,如下载 pip 包、克隆 GitHub 存储库或从外部存储库下载基础容器映像。
虚拟网络分段和安全
此体系结构中的网络具有独立子网,用于以下目的:
应用程序网关
应用程序服务集成组件
专用终结点
Azure Bastion
跳转盒虚拟机
训练和评分子网 - 这两个子网都用于自带与训练和推理相关的计算。 在此体系结构中,我们不执行训练,并且使用的是托管计算。
计分
每个子网都有一个网络安全组 (NSG),可将这些子网的入站和出站流量限制为仅限所需的流量。 下表显示了基线添加到每个子网的 NSG 规则的简化视图。 该表提供了规则名称和函数。
子网 | 入站 | 出站 |
---|---|---|
snet-appGateway | 为聊天 UI 用户源 IP(如公共 Internet)已预留的空间,以及服务所需的项目。 | 访问应用程序服务专用终结点,以及服务所需的项目。 |
snet-PrivateEndpoints | 仅允许来自虚拟网络的流量。 | 仅允许到虚拟网络的流量。 |
snet-AppService | 仅允许来自虚拟网络的流量。 | 允许访问专用终结点和 Azure Monitor。 |
AzureBastionSubnet | 请参阅使用 NSG 访问和 Azure Bastion 的指南。 | 请参阅使用 NSG 访问和 Azure Bastion 的指南。 |
snet-jumpbox | 允许来自 Azure Bastion 主机子网的入站远程桌面协议 (RDP) 和 SSH。 | 允许访问专用终结点 |
snet-agents | 仅允许来自虚拟网络的流量。 | 仅允许到虚拟网络的流量。 |
snet-training | 仅允许来自虚拟网络的流量。 | 仅允许到虚拟网络的流量。 |
snet-scoring | 仅允许来自虚拟网络的流量。 | 仅允许到虚拟网络的流量。 |
明确拒绝所有其他流量。
在实现虚拟网络分段和安全性时,请考虑以下几点。
使用属于带公共 IP 地址的应用程序网关的子网为虚拟网络启用 DDoS 保护。
向每个子网添加 NSG(如果可能)。 使用最严格的规则来启用完整的解决方案功能。
使用应用程序安全组对 NSG 进行分组。 对 NSG 进行分组可简化复杂环境的规则创建。
密钥轮换
此体系结构中有一个服务使用基于密钥的身份验证:机器学习托管联机终结点。 由于为此服务使用基于密钥的身份验证,因此请务必:
将密钥存储在密钥保管库等安全存储中,以便从授权客户端(例如托管提示流容器的 Azure Web 应用)进行按需访问。
实施密钥轮换策略。 如果手动轮换密钥,请创建密钥过期策略,并使用 Azure Policy 监视密钥是否已轮换。
OpenAI 模型微调
如果在实现过程中微调 OpenAI 模型,请考虑以下指南:
如果上传训练数据进行微调,请考虑使用客户托管密钥来加密这些数据。
如果在 Azure Blob 存储等存储中存储训练数据,请考虑使用客户托管密钥来进行数据加密,使用托管标识来控制对数据的访问,并使用专用终结点来连接到数据。
通过策略进行治理
为了确保与安全性保持一致,请考虑使用 Azure Policy 和网络策略,使部署符合工作负荷的要求。 通过策略使用平台自动化可减轻手动验证步骤的负担,并确保即使绕过管道,也可确保治理。 请考虑以下安全性策略:
- 在 Azure AI 服务和密钥库等服务中禁用密钥或其他本地身份验证访问。
- 需要对网络访问规则或 NSG 进行特定配置。
- 需要加密,例如使用客户管理的密钥。
适用于 Azure 密钥库的 Azure AI Studio 角色分配
Azure AI Studio 托管标识需要控制平面(参与者)和数据平面(密钥库管理员)角色分配。 这意味着该身份对 Azure Key Vault 中存储的所有机密、密钥和证书都具有读写权限。 如果工作负荷具有除 Azure AI Studio 以外的服务,这些服务需要访问密钥库中的机密、密钥或证书,则工作负荷或安全团队可能对有权访问这些项目的 Azure AI Studio 中心托管标识感到不自在。 在这种情况下,请考虑为 Azure AI Studio 中心专门部署密钥库实例,以及其他适用于工作负荷的其他部分的 Azure 密钥库 实例。
成本优化
成本优化是关于寻找减少不必要的费用和提高运营效率的方法。 有关详细信息,请参阅成本优化设计评审核对清单。
要查看此方案的定价示例,请使用 Azure 定价计算器。 需要对示例进行定制以符合自己的使用情况,因为本示例仅包含体系结构中的组件。 方案中最昂贵的组件是 DDoS 防护和作为托管联机终结点的一部分部署的防火墙。 其他值得注意的成本是聊天 UI 和提示流计算和 AI 搜索。 优化这些资源,可节省最大成本。
计算
提示流支持多个选项来托管可执行流。 这些选项包括机器学习、AKS、应用程序服务和 Azure Kubernetes 服务中的托管联机终结点。 其中每个选项都有自己的计费模型。 计算选择会影响解决方案的总体成本。
Azure OpenAI
Azure OpenAI 是一种基于消费的服务,与任何基于消费的服务一样,控制需求与供应是控制成本的首要手段。 具体来说,要在 Azure OpenAI 中做到这一点,需要综合运用多种方法:
控制客户端。 在消耗模型中,客户端请求是成本的主要来源,因此控制客户行为至关重要。 所有客户端都应:
获得批准。 避免以支持免费访问的方式公开服务。 通过网络和身份控制,如密钥或基于角色的访问控制 (RBAC),限制访问。
自我控制。 要求客户端使用 API 调用提供的令牌限制约束,如 max_tokens 和 max_completions。
在可行的情况下使用批处理。 查看客户端,确保它们对提示进行了适当的批处理。
优化提示输入和响应长度。 较长的提示会消耗更多的令牌,从而增加成本,但缺少足够上下文的提示无助于模型产生良好的结果。 创建简明扼要的提示,提供足够的上下文,让模型能够生成有用的响应。 同样,要确保优化响应长度的限制。
Azure OpenAI 操场的使用应视需要在预生产实例上进行,因此这些活动不会产生生产成本。
选择正确的 AI 模型。 模型选择对 Azure OpenAI 的总体成本也有很大影响。 所有模型都各有优缺点,并且价格也各不相同。 对用例使用正确的模型,确保在成本较低的模型产生可接受的结果时,不会在较昂贵的模型上花费过多。 在此聊天参考实现中,GPT 3.5-Turbo 是在 GPT-4 上选择的,以节省大约一个数量级的模型部署成本,同时获得足够的结果。
了解计费断点。 微调按小时收费。 为了达到最高效率,需要尽可能多地利用每小时可用的时间来改善微调结果,同时避免不知不觉就进入下一个计费周期。 同样,生成 100 个图像的成本与生成 1 个图像的成本相同。 最大限度地发挥价格突破点的优势。
了解计费模型。 Azure OpenAI 还可通过预配的吞吐量产品/服务在基于承诺的计费模型中使用。 有了可预测的使用模式后,如果根据使用量计算出这种预购计费模式更符合成本效益,则考虑改用这种模式。
设置预配限制。 确保所有预配配额只分配给预期属于工作负荷的模型(基于每个模型)。 在启用动态配额时,已部署模型的吞吐量不受此预配配额限制。 配额并不直接与成本挂钩,并且成本可能会有所不同。
监视即用即付使用情况。 如果使用即用即付定价,请监视 TPM 和 RPM 的使用情况。 用这些信息来告知体系结构设计决策,比如要使用的模型,以及优化提示大小。
成本管理。 遵循有关将成本管理功能与 OpenAI 配合使用的指南,以便监视成本、设置预算以管理成本,并创建警报以通知利益干系人风险或异常情况。
卓越运营
卓越运营涵盖了部署应用程序并使其在生产环境中保持运行的运营流程。 有关详细信息,请参阅设计卓越运营的审查清单。
内置提示流运行时
与基本体系结构一样,此体系结构使用自动运行时,以尽量减轻操作负担。 自动运行时是机器学习中的无服务器计算选项,可简化计算管理,并将大部分提示流配置委托给运行中应用的 requirements.txt
文件和 flow.dag.yaml
配置。 因此,此选项的维护、临时性和应用程序驱动性较低。 使用计算实例运行时或外部化计算(如在此体系结构中)需要更多工作负荷团队管理的计算生命周期,并且当工作负荷要求超过自动运行时选项的配置功能时,应选择此生命周期。
监视
与基本体系结构一样,所有服务都配置了诊断功能。 除应用程序服务外,所有服务都配置为捕获所有日志。 应用程序服务被配置为捕获 AppServiceHTTPLogs、AppServiceConsoleLogs、AppServiceAppLogs 和 AppServicePlatformLogs。 在生产环境中,所有日志可能过多。 根据操作需求优化日志流。 对于此体系结构,Azure AI Studio 项目使用的Azure 机器学习日志包括:AmlComputeClusterEvent、AmlDataSetEvent、AmlEnvironmentEvent 和 AmlModelsEvent。
评估为此体系结构中的资源(例如 Azure Monitor 基线警报中找到的资源)生成自定义警报。 例如:
语言模型操作
基于 Azure OpenAI 的聊天解决方案(如本体系结构)的部署应遵循使用提示流和 Azure DevOps 的 GenAIOps以及使用提示流和 GitHub 的 GenAIOps 中的指南。 此外,还必须考虑持续集成和持续交付 (CI/CD) 以及网络安全体系结构的最佳实践。 以下指南介绍了基于 GenAIOps 建议实现流及其关联的基础结构。 此部署指南不包括前端应用程序元素,它们与基线高度可用的区域冗余 Web 应用程序体系结构中的元素相同。
开发
提示流在 Azure AI Studio 中或通过 Visual Studio Code 扩展提供基于浏览器的创作体验。 这两个选项将流代码存储为文件。 使用 Azure AI Studio 时,文件存储在存储帐户中。 在使用 Microsoft Visual Studio Code 服务时,文件会存储在本地文件系统上。
为了遵循协作开发的最佳做法,源文件应在联机源代码存储库(如 GitHub)中维护。 这种方法有助于跟踪所有代码更改、流作者之间的协作以及与测试并验证所有代码更改的部署流的集成。
对于企业开发,应使用 Microsoft Visual Studio Code 扩展和提示流 SDK/CLI 进行开发。 提示流作者可以从 Microsoft Visual Studio Code 生成和测试其流,并将本地存储的文件与联机源代码管理系统和管道集成。 虽然基于浏览器的体验非常适合探索性开发,但对于某些工作,它可以与源代码管理系统集成。 可以从 Files
面板中的流页面下载流文件夹,然后将其解压缩并推送到源代码管理系统。
计算
像测试其他软件项目一样测试聊天应用程序中使用的流。 指定和断言语言模型输出的单个“正确”答案非常困难,但你可以使用语言模型本身来评估响应。 考虑对语言模型流程实现以下自动评估:
分类准确性:评估语言模型提供的分数“正确”还是“不正确”,并聚合结果以生成准确性等级。
一致性:评估模型的预测答案中句子的编写好坏程度,以及它们如何相互保持连贯。
流畅性:评估模型预测答案的语法和语言准确性。
以上下文为基准:评估模型根据预配置的上下文预测答案的准确程度。 即使语言模型做出正确响应,但如果不能根据给定的上下文进行验证,那么响应也是没有根据的。
相关性:评估模型预测的答案与所提问题的吻合程度。
实现自动评估时,请考虑以下指南:
从评估中得出分数,并根据预定义的成功阈值对其进行度量。 使用这些分数来报告管道中的测试通过/失败。
其中一些测试需要输入预先配置的问题、上下文和基本事实的数据。
包含足够的问答对,以确保测试结果可靠,建议至少包含 100-150 个问答对。 这些问答对被称为“黄金数据集”。可能需要更大的数据规模,具体取决于数据集的大小和领域。
避免使用语言模型来生成黄金数据集中的任何数据。
部署流
提示工程师/数据科学家会打开一个功能分支,在其中可以处理特定任务或功能。 提示工程师/数据科学家使用 Microsoft Visual Studio Code 的提示流循环访问流,定期提交更改并将这些更改推送到功能分支。
本地开发和实验完成后,提示工程师/数据科学家会从功能分支向主分支打开一个拉取请求。 拉取请求 (PR) 会触发 PR 管道。 此管道可快速进行质量检查,其中应包括:
- 执行试验流
- 执行配置的单元测试
- 编译代码库
- 静态代码分析
管道可以包含一个步骤,要求至少一名团队成员在合并之前手动批准 PR。 审批者不能是提交者,他们必须拥有提示流专业知识,并熟悉项目要求。 如果 PR 未获批准,则合并就会被阻止。 如果 PR 已或批准,或者没有审批步骤,则功能分支合并到主分支中。
合并到主分支会触发开发环境的生成和发布流程。 具体而言:
- CI 管道从合并到主分支触发。 CI 管道会执行 PR 管道中完成的所有步骤,并执行以下步骤:
- 实验流
- 评估流
- 检测到更改时,在机器学习注册表中注册流
- CD 管道会在 CI 管道完成后触发。 该流执行以下步骤:
- 将流从机器学习注册表部署到机器学习联机终结点
- 运行面向联机终结点的集成测试
- 运行面向联机终结点的冒烟测试
发布升级流程中包含审批过程 - 经批准后,执行步骤 4.a 中所述的 CI 和 CD 流程。 并且会以测试环境为目标重复步骤 4.b。 步骤 a.和 b. 相同,只是用户验收测试会在测试环境中冒烟测试后运行。
执行步骤 4.a 中所述的 CI 和 CD 流程。 然后运行 4.b.,以便在测试环境得到验证和批准后,将发布推广到生产环境。
发布到实时环境后,将执行监视性能指标和评估已部署语言模型的操作任务。 这包括但不限于:
- 检测数据偏移
- 观察基础结构
- 管理成本
- 将模型的性能传达给利益干系人
部署指南
可以使用机器学习终结点在将模型发布到生产环境时灵活地部署模型。 请考虑以下策略,以确保最佳的模型性能和质量:
蓝/绿部署:使用此策略,可以在将所有流量定向到新部署之前,将新版本的 Web 服务安全地部署到有限的用户组或请求。
A/B 测试:蓝/绿部署不仅能有效安全地推出变更,还可用于部署新行为,让一部分用户能够评估变更的影响。
在管道中包含作为提示流一部分的 Python 文件的 Lint 分析。 Lint 分析会检查是否符合样式标准以及错误、代码复杂性、未使用的导入和变量命名。
将流部署到网络隔离机器学习工作区时,请使用自托管代理将项目部署到 Azure 资源。
机器学习模型注册表只应在模型发生更改时更新。
语言模型、流和客户端 UI 应松散耦合。 可以并且应该对流和客户端 UI 进行更新,但不能影响模型,反之亦然。
在开发和部署多个流时,每个流都应有自己的生命周期,这样才能在将流从试验阶段推广到生产阶段时获得松散耦合的体验。
基础结构
在部署基线 Azure OpenAI 端到端聊天组件时,预配的某些服务在体系结构中是基础性和永久性的,而其他组件本质上更具有临时性,其存在与部署有关。 此外,虽然托管虚拟网络是基础的,但创建计算实例时会自动预配它,这会导致一些注意事项。
基础组件
此体系结构中的某些组件的生命周期超出了任何单个提示流或任何模型部署的范围。 这些资源通常由工作负荷团队作为基础部署的一部分部署一次,并在新增、删除或更新提示流或模型部署时进行维护。
- 机器学习工作区
- 机器学习工作区的存储帐户
- 容器注册表
- AI 搜索
- Azure OpenAI
- Azure Application Insights
- Azure Bastion
- 用于跳转盒的 Azure 虚拟机
临时组件
某些 Azure 资源更紧密地耦合到特定提示流的设计。 此方法允许这些资源绑定到组件的生命周期,并在此体系结构中成为临时资源。 当工作负荷发生变化时,例如添加或删除流量或引入新模型时,Azure 资源会受到影响。 这些资源会被重新创建,而之前的实例会被删除。 其中有些资源是直接的 Azure 资源,有些则是包含在其服务中的数据平面表现形式。
如果机器学习模型注册表中的模型发生更改,应将其作为为 CD 管道的一部分进行更新。
作为 CD 管道的一部分,容器映像应在容器注册表中更新。
如果部署引用不存在的终结点,则会在部署提示流时创建机器学习终结点。 该终结点需要更新才能关闭公共访问。
在部署或删除流时,机器学习终结点的部署会被更新。
在创建新终结点时,必须使用终结点的密钥来更新客户端 UI 的密钥库。
按需托管虚拟网络
首次创建计算实例时,会自动预配托管虚拟网络。 如果使用基础结构即代码部署中心,并且 Bicep 中没有 AI Studio 计算资源,则不会部署托管虚拟网络,并且连接到 Azure AI Studio 时会收到错误。 需要在 IaC 部署后执行一次性操作来 手动预配托管虚拟网络 。
资源组织
如果有一个场景,中心由工作负荷团队以外的团队集中拥有,则可以选择将项目部署到单独的资源组。 如果使用基础结构作为代码,可以通过在 Bicep 中设置其他资源组来实现此目的。 如果使用门户,则可以将defaultWorkspaceResourceGroup
属性设置为要创建项目的资源组。workspaceHubConfig
性能效率
性能效率是指工作负荷能够以高效的方式扩展以满足用户对它的需求。 有关详细信息,请参阅性能效率设计评审核对清单。
本节将从 Azure 搜索、Azure OpenAI 和机器学习的角度介绍性能效率。
Azure 搜索 - 性能效率
按照指南分析 AI 搜索中的性能。
Azure OpenAI - 性能效率
确定应用程序是否需要预配的吞吐量或使用共享托管或消耗模型。 预配的吞吐量可为 OpenAI 模型部署确保预留处理能力,为模型提供可预测的性能和吞吐量。 此计费模型与共享托管或消耗模型不同。 消费模式是尽力而为的,可能会受到平台上嘈杂的邻居或其他压力源的影响。
对于预配吞吐量,监视预配托管利用率
Azure 机器学习 - 性能效率
如果将机器学习模型部署到联机终结点:
按照有关如何自动扩展联机终结点的指导进行操作。 这样做可以与需求保持密切一致,而无需过度预配,尤其是在低使用率期间。
为联机终结点选择适当的虚拟机 SKU 以满足性能目标。 测试较少实例计数和较大 SKU 与较大实例计数和较小 SKU 的性能,以找到最佳配置。
部署此方案
要部署并运行参考实现,请按照 OpenAI 端到端基线参考实现中的步骤进行操作。
作者
本文由 Microsoft 维护, 它最初是由以下贡献者撰写的。
- Rob Bagby | 模式和做法 - Microsoft
- Freddy Ayala | 云解决方案架构师 - Microsoft
- Prabal Deb | 高级软件工程师 - Microsoft
- Raouf Aliouat | 软件工程师 II - Microsoft
- Ritesh Modi | 首席软件工程师 - Microsoft
- Ryan Pfalz | 高级解决方案架构师 - Microsoft
要查看非公开的 LinkedIn 个人资料,请登录到 LinkedIn。