MLOps 工程指南(二)
原文:
annas-archive.org/md5/c0519d92859e86c99b606931513a3258译者:飞龙
第七章:构建健壮的 CI/CD 管道
在本章中,你将了解 MLOps 管道中的持续操作。本章中你将学习的原则对于在业务环境中推动持续部署至关重要。为了获得全面的理解和第一手经验,我们将同时探讨概念和动手实施。在学习持续集成(CI)和持续部署(CD)、管道测试以及发布和触发器类型的同时,我们将为测试环境设置 CI/CD 管道。这将使你具备在云上为任何给定场景自动部署具有持续学习能力机器学习(ML)模型所需的技能,并与业务保持一致。让我们首先看看为什么我们需要在 MLOps 中使用 CI/CD。接下来,我们将继续探讨以下其他主题:
-
MLOps 中的持续集成、交付和部署
-
设置 CI/CD 管道和测试环境(使用 Azure DevOps)
-
管道执行和测试
-
管道执行触发器
MLOps 中的持续集成、交付和部署
自动化是 MLOps 工作流程中 CI/CD 的主要原因。启用持续向 ML 服务交付的目标是维护模型的数据和源代码版本,启用触发器并行执行必要的作业,构建工件,并发布生产部署。一些云服务提供商正在推广 DevOps 服务以监控生产中的 ML 服务和模型,以及与云上的其他服务进行编排。使用 CI 和 CD,我们可以启用持续学习,这对于 ML 系统的成功至关重要。没有持续学习,ML 系统被认为最终会以失败的概念验证(PoC)告终。
只有部署了持续学习能力模型的模型才能带来商业价值。
为了学习如何使用持续学习能力在生产中部署模型,我们将探索 CI、CD 和持续交付方法。
如你在图 7.1中看到的,CI 是 CD 和持续交付的关键。让我们看看这三个是如何相互关联的:
图 7.1 – 持续集成、交付和部署管道
持续集成
CI(持续集成)旨在实时同步应用程序(机器学习管道和应用程序)与开发者。开发者在提交或合并中的更改将通过创建应用程序构建和针对构建执行自动化测试来得到验证。CI 强调自动化测试,重点关注在将新提交合并到主分支或主分支时检查应用程序的健壮性(如果它没有损坏或出现错误)。每当向主分支提交新的提交时,就会创建一个新的构建版本,并使用自动化测试对其进行健壮性测试。通过自动化此过程,我们可以避免软件延迟交付和其他可能导致用户等待数天的集成挑战。自动化和测试是 CI 的核心。
持续交付
持续交付从 CI 扩展,以确保新的更改或发布被部署并高效地带给用户;这通过自动化测试和发布流程来实现。自动化测试和发布流程使开发者和产品经理能够通过一键操作部署更改,并在过程的任何阶段实现无缝控制和监督能力。在持续交付过程中,通常会有一个人工代理(来自质量保证团队)参与批准构建(通过或失败),在将其部署到生产环境中之前(如图 7.1 所示,在持续交付管道中)。在一个典型的持续交付管道中,构建在部署到预发布阶段之前会经过初步的验收测试,在这个阶段,人工代理会使用烟雾测试和其他合适的测试来监督性能。
一旦通过了烟雾测试,人工代理会将构建版本传递到生产环境中部署。自动化构建和发布流程,并让人工代理参与其中,可以确保生产质量,我们还可以避免一些在完全自动化管道中可能被忽视的陷阱。使用持续交付,企业可以对其发布流程拥有完全的控制权,并可以分批次(在出现阻塞或错误时易于调试)发布新的构建版本,或者在一个必要的时间框架内(每日、每周或每月)进行完整发布。
持续部署
CD(持续部署)实现了完全自动化,并且比持续交付更进一步。将构建和发布到生产环境的所有阶段都完全自动化,没有任何人工干预,这与持续交付不同。在这样的自动化管道中,只有失败的测试才能阻止新的更改部署到生产环境中。持续部署减轻了团队维护发布管道的压力,并加速了直接向客户部署,通过客户反馈循环实现持续学习。
通过这样的自动化,开发者不再有发布日。这减轻了他们的压力,他们可以专注于构建软件,而无需担心测试和发布管理。开发者可以在方便的时候构建、测试和部署软件,可以在几分钟内上线,而不是等待发布日或人工审批,这可能会延迟软件向用户发布几天甚至几周。持续部署确保了部署和服务的完全自动化,向用户提供强大且可扩展的软件。
设置 CI/CD 管道和测试环境(使用 Azure DevOps)
在上一节中,我们介绍了 CI、持续交付和持续部署的理论,现在是时候看到它在实践中是如何应用的。使用 Azure DevOps,我们将为之前一直在工作的业务问题(天气预测)设置一个简单的 CI/CD 管道,我们之前在 第六章 的“关键部署原则”部分(针对业务问题)中已经讨论过。
Azure DevOps 是由微软提供的一项服务,它简化了源代码管理(版本控制)、项目管理、CI(持续集成)、持续交付和持续部署(自动化构建、测试和发布功能)。它还使软件应用程序的生命周期管理成为可能。我们将使用 Azure DevOps 进行实战培训,因为它与 Azure ML 服务无缝集成,我们之前在 第六章 中已经使用过。您将体验这两种服务的集成和同步,以便轻松进行部署。让我们开始吧。
前往您的 Azure DevOps 项目,Learn_MLOps。进入克隆的仓库并访问 07_CICD_Pipeline 文件夹。我们将使用这些文件(在名为 07_CICD_Pipeline 的文件夹中)作为驱动程序来构建发布管道:
Learn_MLOps
├──07_CICD_Pipeline
│ ├── AciDeploymentconfig.yml
├── AksDeploymentconfig.yml
└── InferenceConfig.yml
└── myenv.yml
└── score.py
我们将在两个部署目标上部署之前训练的 ML 模型(来自 第四章,机器学习管道),一个是 AciDeployment.yml 文件包含 ACI 部署目标的配置,另一个是 AksDeployment.yml 文件包含 AKS 集群的配置。InferenceConfig.yml 指向推理工件,如 score.py 和 myenv.yml。
在 score.py 中定义的函数将用于预处理传入的数据,并使用 ML 模型推断预处理后的数据以进行预测。myenv.yml 文件是推理环境的配置,例如,环境中的 Python 版本和要安装的包。这些文件将用作驱动程序,以简化发布管道。现在您已经熟悉了这些文件,让我们开始通过使用服务主体连接 Azure ML 服务和 Azure DevOps 项目。
创建服务主体
我们需要同步 Azure ML 服务和 Azure DevOps,以便在两者之间方便地进行 CI。之前(在 第四章,机器学习管道)我们使用 Azure ML 服务开发和管理工作流模型,并使用了 Learn_MLOps 工作区。现在,我们将使用服务主体将 Azure ML 工作区(命名为 Learn_MLOps)与 Azure DevOps 项目(命名为 Learn_MLOps)连接起来。
服务主体是为应用程序间通信创建的标识;它是访问 Azure 资源的连接自动化工具。服务主体还负责应用程序的网络和连接方面。执行以下步骤来设置用于管道的服务主体:
-
前往项目设置(位于屏幕左下角)并选择服务连接。点击新建服务连接选项/按钮以显示新建服务连接窗口,如图 图 7.2 所示:![图 7.2 – 新的服务主体连接
![img/B16572_07_02.jpg]
图 7.2 – 新的服务主体连接
-
选择Azure 资源管理器作为连接类型,然后点击下一步。选择服务主体(自动)并继续创建服务主体的最后一步。
-
您将提示创建新的服务连接。将范围设置为机器学习工作区并指向订阅、资源组和机器学习工作区,如图 图 7.3 所示:![图 7.3 – 创建服务主体的最后一步
![img/B16572_07_03.jpg]
图 7.3 – 创建服务主体的最后一步
-
在
mlops_sp中命名服务主体,如图 图 7.3 所示)。最后,勾选复选框(授予所有管道访问权限)并点击保存以创建服务主体。
这样,具有给定名称(例如,mlops_sp)的服务主体就准备好用于编排 CI/CD 管道。接下来,我们将安装用于管道的扩展。
安装扩展以连接到 Azure ML 工作区
微软开发了一个名为 Machine Learning 的扩展。它在 Azure DevOps 市场 place 中可用。它用于编排我们所需的 Azure ML 工作区中的模型和工件。它允许我们将工作区中的模型部署到我们想要的部署目标,如 ACI 或 AKS。我们将安装 ML 扩展并使用它来编排 CI/CD 管道。执行以下步骤来安装扩展:
-
前往市场以查找机器学习扩展。要进入市场,点击屏幕右上角的购物袋图标,如图 图 7.4 所示:![图 7.4 – 查找 Azure DevOps 市场 place
![img/B16572_07_04.jpg]
图 7.4 – 查找 Azure DevOps 市场 place
进入市场后,您将看到多个扩展选项,可以添加到您的 Azure DevOps 项目中。接下来,我们将搜索机器学习扩展。
-
搜索机器学习扩展,免费安装扩展。点击免费获取按钮,如图图 7.5所示安装扩展:
![图 7.5 – 安装机器学习扩展
图 7.5 – 安装机器学习扩展
点击免费获取按钮后,将安装机器学习扩展。安装成功后,您可以使用机器学习扩展在 CI/CD 管道中编排作业。具备这些先决条件后,您就可以配置持续部署或持续交付管道。
为测试环境设置持续集成和部署管道
在本节中,我们将为预发布环境(也称为测试环境)配置 CI/CD 管道。我们将使用此管道促进持续学习和自动化部署。让我们按照图 7.6所示,通过管道>>发布开始操作:
![图 7.6 – 设置您的 CI/CD 管道
图 7.6 – 设置您的 CI/CD 管道
在Port Weather ML Pipeline中创建一个新的管道。接下来,我们将开始连接必要的工件以启用管道,例如包含代码的仓库和包含要部署的模型的 Azure ML 工作区。
将工件连接到管道
连接到您的 Azure DevOps 仓库。Azure DevOps 仓库作为中央代码仓库,用于在 Azure DevOps 上协调部署和操作。因此,让我们将仓库(Learn_MLOps)连接到发布管道:
-
如图 7.7所示,转到
Learn_MLOps以连接到发布管道:![图 7.7 – 将 Azure DevOps 仓库作为工件连接图 7.7 – 将 Azure DevOps 仓库作为工件连接
-
在工件部分选择默认分支(例如,
Learn_MLOps)和图标。 -
连接到您的 Azure ML 工作区。要将您的 Azure ML 工作区连接到发布管道,请转到之前在第四章中注册的
scaler工件,机器学习管道,以使用标准缩放传入数据:![图 7.8 – 将缩放器作为工件连接图 7.8 – 将缩放器作为工件连接
-
在选择
model_scaler工件后,通过点击model_scaler工件将其添加到发布管道中,你将能够在support_vector_classifier模型中看到模型名称(model_scaler)和模型图标。首先点击mlops_sp并选择在第四章,机器学习流水线中训练的support_vector_classifier模型。通过点击添加按钮将模型工件添加到管道中:
![图 7.9 – 连接的工件
![img/B16572_07_09.jpg]
图 7.9 – 连接的工件
在添加support_vector_classifier模型后,你将在工件部分看到模型名称(support_vector_classifier)和模型图标,如图图 7.9所示。
恭喜!我们已经将三个所需的工件(Learn_MLOps、scaler和support_vector_classifier)连接到发布管道中。我们可以使用这些工件来编排管道中的部署。接下来,准备好配置 Staging/TEST 环境!
设置测试环境
让我们在管道中为 TEST 环境设置一个持续集成和持续部署流水线。在这个阶段,我们测试服务的鲁棒性并执行各种测试以验证服务对生产的准备情况:
-
要开始,点击
DEVTEST。我们将该阶段命名为DEVTEST,因为这将是我们的开发和测试环境。理想情况下,DEV 和 TEST 是不同的阶段,但为了简单和避免重复实现,我们将它们合并。请参阅以下图 7.10:![图 7.10 – 设置 DEV TEST 阶段![img/B16572_07_10.jpg]
图 7.10 – 设置 DEV TEST 阶段
-
在命名阶段后,通过点击顶部的保存按钮保存阶段。每个阶段都是由一系列步骤或作业组成的,用于检查阶段的鲁棒性。接下来,我们将配置DEV TEST阶段内的作业。简单来说,CI/CD 作业是一个执行或测试部署(例如,在 Kubernetes 集群上部署模型的作业)的过程或脚本。要配置作业,点击DEV TEST阶段中的1 作业,0 任务链接,如图图 7.11所示:![图 7.11 – 配置 DEV TEST 作业
![img/B16572_07_11.jpg]
图 7.11 – 配置 DEV TEST 作业
在点击DEV TEST阶段的1 作业,0 任务链接后,你必须添加代理作业。
-
通过点击
AzureML 模型部署将任务添加到代理作业中,如图图 7.12所示:![图 7.12 – 添加作业 – AzureML 模型部署![img/B16572_07_12.jpg]
图 7.12 – 添加作业 – AzureML 模型部署
添加
inferenceconfig文件后。 -
接下来,您将被提示输入部署信息。如图 图 7.13 所示,指向您的 Azure ML 工作区(例如,
mlops_ws)并将模型源选项设置为 模型工件(因为我们正在使用之前在训练和打包模型时生成的模型工件):
图 7.13 – 添加作业 – Azure ML 模型部署
接下来,我们将查看 inferenceConfig 文件及其功能。以下代码片段来自 inferenceConfig.yml(在仓库中)。以下是 inferenceConfig.yml 的快照:
inferenceConfig.yml
entryScript: score.py
runtime: python
condaFile: myenv.yml
它表示我们将部署模型的自定义环境的设置。它指向 score.py 文件(在 第六章,部署您的 ML 系统的关键原则)和 conda 文件 myenv.yml,该文件定义了 conda 环境(要安装的包和依赖项)。以下是 myenv.yml 的快照:
myenv.yml
name: project_environment
dependencies:
# The python interpreter version.
# Currently Azure ML only supports 3.5.2 and later.
- python=3.6.2
- pip:
- numpy
- onnxruntime
- joblib
- azureml-core~=1.10.0
- azureml-defaults~=1.10.0
- scikit-learn==0.20.3
- inference-schema
- inference-schema[numpy-support]
- azureml-monitoring
channels:
- anaconda
- conda-forge
score.py 和 myenv.yml 文件都与 inferenceConfig.yml 文件相关联,以简化机器学习模型的部署和推理。按照图 图 7.14 所示,选择您的推理配置文件(inferenceConfig.yml):
图 7.14 – 选择您的推理配置文件
在您的 Azure DevOps 仓库中指向 inferenceConfig.yml 文件后,您的部署基本配置已完成。最后,我们将通过指向 AciDeploymentConfig.yml) 为 ACI 配置部署信息:
AciDeploymentConfig.yml
computeType: ACI
containerResourceRequirements:
cpu: 1
memoryInGB: 1
authEnabled: False
sslEnabled: False
appInsightsEnabled: True
它包含为部署提供所需计算的基础设施定义,例如 CPU 单位、内存(以 GB 计)以及其他身份验证或安全定义。让我们选择此部署配置文件以设置预发布环境的发布管道,如图 图 7.15 所示:
图 7.15 – 添加部署信息
添加部署配置文件后,通过点击屏幕右上角的 保存 按钮保存作业,然后转到 管道 >> 发布(位于您的屏幕左侧)以查看您的管道成功设置。让我们从这里继续测试管道。
管道执行和测试
现在,是时候测试您的管道了。为此,我们将创建一个发布版本并验证管道发布是否成功执行。以下步骤将帮助您测试您的管道:
-
点击 创建发布 按钮以执行管道上配置的作业。屏幕右侧将出现一个弹出窗口(如图 图 7.16 所示),用于查看和选择在预发布环境中部署的工件。
-
选择工件(
_scaler和_support-vector-classifier)并选择它们的版本。为了简单起见,推荐两个都使用版本 1。如果你想选择模型或缩放器的另一个版本,请确保在
score.py文件中更改你的模型和缩放器的路径(即在scaler和model路径model-scaler/{版本号}/modelscaler.pkl和support-vector-classifier/{版本号}/svc.onnx中插入适当的版本号。如果你选择版本 1,你不需要担心更改score.py文件中的代码,因为路径包含版本 1。 -
在选择工件和所需版本(推荐版本 1)后,点击创建按钮以创建所选工件的发布:
图 7.16 – 创建发布
-
现在,发布管道(CI/CD 管道)被触发执行。管道中定义的所有步骤都将执行,例如下载工件、为部署提供 ACI 计算实例以及部署 Web 服务。在成功执行后,你将在发布上收到一个绿色的勾号通知,如图 7.17 所示:
图 7.17 – 监控发布
-
你可以在
scaler和_support-vector-classifier中监控所有你的发布,它们已作为 Web 服务部署在 ACI 上,如图 7.18 所示:图 7.18 – 发布中的成功作业(测试环境)
-
最后,前往检查你的 Azure ML 工作区(从端点部分),查看已部署的 Web 服务,如图 7.19 所示:
图 7.19 – 部署在 Azure ML 工作区的 Web 服务
我们已在测试环境中成功部署了一个 Web 服务。我们可以看到 REST 端点和服务名称devtest-webservice。这标志着测试环境的 CI/CD 管道构建和测试的成功完成。管道可以通过触发器驱动,在下一节中,我们将探讨触发器的类型以及如何使用它们构建最优的 CI/CD 管道。
管道执行触发器
在一个有效的 CI/CD 管道中,通过多种事件或触发器执行流程应该是可能的。只有通过常规事件(如代码仓库或推送或拉取请求)触发管道的选项可能会成为系统的障碍或限制。通过使用多个事件触发管道流程的选项可以增强 CI/CD 管道的灵活性和功能性。让我们看看一些可以增加 CI/CD 管道流程价值的触发器类型:
-
Artifactory 触发器
在管道和开发过程的各个阶段都会生成工件。生成的工件,如训练好的模型、元数据、上传的 Docker 镜像或任何已上传的文件,都可以触发在 CI/CD 管道中执行某个过程。拥有这样的选项可以为 CI/CD 管道提供极大的灵活性和功能性。
-
Docker Hub 触发器
每当你将新的 Docker 镜像推送到你选择的 Docker Hub 仓库时,CI/CD 管道中的触发器可以按照需求执行。例如,当你将新的 Docker 镜像上传到 Docker Hub(或 Azure 容器注册表)时,管道被触发以部署 Docker 镜像作为 Web 服务。
-
计划触发器
管道过程可以按照特定的时间表触发。这种类型的触发器对于计划清理、cron 作业或任何需要按时间间隔运行的流程非常有用;例如,每天中午 12:00 重新训练 ML 模型的触发器。
-
在开发者的平台上进行
retrain,管道可以被触发以重新训练现有的已部署模型。这些触发器是通过 API 调用来实现的。 -
Git 触发器
Git 触发器通常用于触发管道执行,例如当新代码提交到分支或创建新的拉取请求时。当对仓库进行更改时,可以根据需求在管道中触发某些过程。
Azure DevOps 提供了多种触发选项(以上所有选项)。现在,让我们基于对仓库提交的 Git 提交来设置一个 Git 触发器:
-
前往屏幕右上角的
编辑(Edit)来编辑现有的管道。 -
点击仓库工件(命名为
_Learn_MLOps),如图 图 7.20 所示,并通过点击切换开关启用(启用)持续部署触发器。 -
通过包含 develop 分支添加分支过滤器。这将触发管道在仓库的 develop 分支上发生更改或提交时执行。对于测试或预发布阶段,只为 develop 分支配置 Git 触发器(而不是 master 或其他分支)。对于生产,我们可以为 master 分支配置 Git 触发器。这样,我们可以为测试和生产阶段分离 Git 触发器分支:![图 7.20 – 启用测试环境的 Git 触发器
![img/B16572_07_20.jpg]
图 7.20 – 启用测试环境的 Git 触发器
-
点击顶部的 保存 按钮来配置 Git 触发器。恭喜!您已成功为测试环境设置了一个持续部署 Git 触发器。每当仓库的 develop 分支有更改时,管道将被触发以在测试(DEV TEST)环境中部署 Web 服务。
摘要
在本章中,我们学习了 MLOps 中持续操作的关键原则,主要是持续集成、交付和部署。我们通过在 Azure DevOps 上设置 CI/CD 管道和测试环境的实际操作来学习这一点。我们测试了管道的执行稳健性,并最终探讨了增强管道功能的一些触发器,并为测试环境设置了 Git 触发器。本章是 MLOps 持续操作的基础,并为您提供了在云上自动化部署任何给定场景的 ML 模型部署管道的技能,这些技能与您的业务持续学习能力相匹配。
在下一章中,我们将探讨 API、微服务和它们为基于 MLOps 的解决方案提供的功能。
第八章:API 和微服务管理
在本章中,你将了解 API 和微服务管理。到目前为止,我们已经部署了作为 API 提供服务的 ML 应用程序。现在我们将探讨如何开发、组织、管理和提供 API。你将学习 API 和微服务设计的原理,以便你可以设计自己的定制 ML 解决方案。
在本章中,我们将通过构建使用 FastAPI 和 Docker 的微服务并将其作为 API 提供服务来实践学习。为此,我们将学习设计用于之前训练的 ML 模型(在第四章,机器学习管道)的 API 和微服务的基础知识。最后,我们将反思一些关键原则、挑战和技巧,以设计一个健壮且可扩展的微服务和 API,用于测试和生产环境。本章将涵盖以下主题:
-
API 和微服务的介绍
-
ML 对微服务的需求
-
旧的是金子 - 基于 REST API 的微服务
-
实践实现将 ML 模型作为 API 提供服务
-
使用 Docker 开发微服务
-
测试 API 服务
API 和微服务的介绍
API 和微服务是强大的工具,有助于使你的ML(ML)模型在生产或遗留系统中变得有用,用于提供模型或与系统的其他组件进行通信。使用 API 和微服务,你可以设计一个健壮且可扩展的 ML 解决方案,以满足你的业务需求。让我们看看 API 和微服务是什么,以及它们如何实现你的模型在现实世界中的潜力。
什么是应用程序编程接口(API)?
API是开发者与应用程序通信的网关。API 使开发者能够实现两件事:
-
访问应用程序的数据
-
使用应用程序的功能
通过访问和与应用程序数据和功能进行通信,API 已经使世界的电子设备、应用程序和网页能够相互通信,以便共同完成以业务或运营为中心的任务。
![图 8.1 – API 的工作原理
![img/B16572_08_01.jpg]
图 8.1 – API 的工作原理
在图 8.1中,我们可以看到 API 的作用,它使得访问应用程序数据(来自数据库)以及与第三方或其他应用程序(如移动应用程序[为移动用户],天气应用程序[在移动或网页上],电动汽车等)进行通信成为可能。API 自计算机诞生以来一直在运行,旨在实现应用程序间的通信。随着时间的推移,我们在 21 世纪初看到了开发者就简单对象访问协议(SOAP)和表示状态转换(REST)等协议达成共识。近年来,一代新的 API 协议类型被开发出来,如远程过程调用(RPC)和 GraphQL,如下表所示:
表 8.1 – API 协议比较
如果你是应用开发者(托管在云端或与其他服务进行通信),了解主流的 API 协议是非常有价值的。这有助于你根据你的业务或功能需求来设计你的 API。作为一名程序员,你应该感到幸运,因为现在你有许多 API 协议可供选择,而在 20 年前,只有 SOAP 和 REST 可用。现在,根据你的需求,你可以选择各种协议,例如 GraphQL、Thrift 和 JSON-RPC。这些协议各有优缺点,使得找到最适合你情况的协议变得容易。
微服务
微服务是一种现代的设计和部署应用程序以运行服务的方式。微服务使分布式应用程序成为可能,而不是一个大的单体应用程序,其中功能被分解成更小的片段(称为微服务)。微服务是微服务架构中的一个独立应用程序。这与集中式或单体架构相反,在集中式或单体架构中,所有功能都绑定在一个大应用程序中。由于面向服务的架构(SOA)的出现,微服务因其作为传统单体(单一且自给自足)应用程序的替代方案而越来越受欢迎。
微服务因其使开发者能够轻松地开发、集成和维护应用程序而得到了广泛的应用。最终,这归结于这样一个事实:单个功能被独立对待,最初允许你逐步开发服务的一个单独功能。最后,它允许你在整合整个系统以协调服务的同时,独立地工作在每个功能上。这样,你可以添加、改进或修复它,而不会风险破坏整个应用程序。对于大型公司来说,微服务非常有价值,因为它们允许团队在没有复杂组织的情况下独立工作。在图 8.2中,我们可以看到单体和微服务之间的区别。与单体(非分布式应用程序)相比,微服务使分布式应用程序成为可能:
图 8.2 – 微服务与单体架构
软件开发团队被赋予了独立工作和在明确的服务责任范围内工作的能力。基于微服务的架构鼓励软件开发团队对其服务或模块负责。基于微服务的架构的一个可能的缺点是,如果你将应用程序分解成部分,那么这些部分之间需要有效地沟通,以便保持服务的运行。
API 与微服务之间的关系非常有趣,因为它有两个方面。由于基于微服务的架构,API 是你在应用程序中实施该架构的直接结果。同时,API 是微服务架构中服务之间高效通信的必要工具。让我们看看下一节,我们将浏览一些机器学习应用的示例。
机器学习对微服务的需求
为了了解基于微服务的架构对于机器学习应用的需求,让我们看看一个假设用例,并探讨开发该用例的机器学习应用的各个阶段。
假设用例
一个大型汽车维修设施需要一个解决方案来估计设施中的汽车数量及其准确位置。在维修站安装了一堆 IP 摄像头以监控设施。设计一个机器学习系统来监控和管理汽车维修设施。
第 1 阶段 – 概念验证(单体)
在典型情况下,通过使用可用数据点和应用机器学习来展示和验证用例,并向业务利益相关者证明机器学习可以解决他们的问题或改善他们的业务,快速开发了一个 PoC。
在我们的假设用例中,开发了一个单体 Python 应用程序,执行以下操作:
-
从所有摄像头获取流
-
从每个摄像头确定汽车的位置(头部或尾部)
-
将所有估计汇总到设施状态估计器
我们可以在图 8.3中看到,应用程序已经容器化并部署到服务器上:
![图 8.3 – 单体机器学习应用(假设用例的 PoC)
![图 8.3 – 单体机器学习应用(假设用例的 PoC)所有摄像头都通过本地网络连接到这台服务器。汽车位置估计算法和设施状态估计器正在工作,但需要进一步改进,总体上 PoC 是有效的。由于摄像头、本地网络和其他错误的不稳定性,这个单体应用程序非常容易崩溃。微服务可以更好地处理这种不稳定性。让我们在第二阶段看看实际情况。## 第 2 阶段 – 生产(微服务)在这个阶段,一个不太容易崩溃的应用程序对于持续运行汽车维修设施的监控操作至关重要。因此,将单体应用程序替换为如图 8.4所示基于微服务的架构:![图 8.4 – 微服务(假设用例的生产就绪应用程序)
图 8.4 – 微服务(假设用例的生产就绪应用程序)
应用程序以下列方式分解为多个服务:
-
视频流收集器。
-
图像处理器:此处理器汇总图像 – 它接收、处理和缓存图像,并为进一步处理生成数据包。
-
位置分类器:估计停放在维修设施中的汽车的位置(头部或尾部)。
-
设施设置估算器:它异步接收汽车位置估算并校准设施设置,然后将实时数据发送到云端。
-
云使用 MQTT(一种标准轻量级、发布/订阅网络协议,用于在设备之间传输消息)收集和存储数据。数据在仪表板上呈现,供汽车设施操作员分析操作。
所有微服务之间的通信都通过 API 进行。微服务架构的优势在于,如果任何服务崩溃或发生错误,将启动特定的微服务来替换失败的服务,以保持整个服务的运行。其次,每个微服务都可以由一个专门的团队(数据科学家、开发人员和 DevOps 工程师)持续维护和改进,而不是协调团队来工作于一个单体系统。
旧的就是好的 – 基于 REST API 的微服务
旧的就是好的。此外,最好从有各种 API 协议的地方开始。多年来,表示状态转移(REST)协议已成为许多应用的黄金标准,对于今天的机器学习应用来说也并不那么不同。大多数公司更倾向于基于 REST API 协议开发他们的机器学习应用。
REST API 或 RESTful API 基于 REST,这是一种用于主要是 Web 服务开发的架构方法。
RESTful API 被广泛使用;例如,亚马逊、谷歌、领英和推特等公司都在使用它们。通过 RESTful API 提供我们的机器学习模型有许多好处,例如以下:
-
为多个用户提供即时预测服务。
-
向负载均衡器后面的应用程序添加更多实例以进行扩展。
-
可能需要使用不同的 API 端点来组合多个模型。
-
将我们的模型操作环境与用户界面环境分开。
-
启用基于微服务的架构。因此,团队可以独立工作以开发和增强服务。
RESTful API 使用由 RFC 2616 协议定义的现有 HTTP 方法。表 8.2总结了 HTTP 方法及其在机器学习应用中的 CRUD 操作和目的。
表 8.2 – REST API HTTP 方法
基本的 HTTP 方法有GET、POST、PUT、PATCH和DELETE。这些方法对应于创建、读取、更新和删除。使用这些方法,我们可以开发 RESTful API 来服务机器学习模型。由于 OpenAPI 等驱动因素,RESTful API 得到了广泛的应用。OpenAPI 规范是一种标准化的 REST API 描述格式。它已成为人类和机器的标准格式;它使 REST API 易于理解,并提供了扩展的工具,如 API 验证、测试和交互式文档生成器。在实践中,OpenAPI 文件使您能够描述整个 API,包括以下关键信息:
-
可用端点(
/names)以及每个端点的操作(GET /names,POST /names) -
每个操作的输入和输出(操作参数)
-
认证方法
-
开发者文档
-
使用条款、许可和其他信息
您可以在此网站上了解更多关于 OpenAPI 的信息:swagger.io/specification/.
在下一节中,我们将开发一个 RESTful API 来提供 ML 模型,并使用基于 OpenAPI 的界面 Swagger UI 进行测试。
实践操作:将 ML 模型作为 API 提供服务
在本节中,我们将应用之前学到的 API 和微服务原则(在API 和微服务简介部分中),并开发一个 RESTful API 服务来提供 ML 模型。我们将提供的 ML 模型是之前我们工作的业务问题(使用 ML 进行天气预测)。我们将使用 FastAPI 框架将模型作为 API 提供服务,并使用 Docker 将 API 服务容器化为微服务。
FastAPI 是一个用于部署 ML 模型的框架。它易于编码且速度快,具有异步调用和数据完整性检查等特性,可实现高性能。FastAPI 易于使用,遵循 OpenAPI 规范,使其易于测试和验证 API。更多关于 FastAPI 的信息请访问:fastapi.tiangolo.com/.
API 设计和开发
我们将开发 API 服务并在本地计算机上运行它。(这也可以在我们在 Azure 机器学习工作区中创建的虚拟机上开发。为了学习,建议在本地练习以便于操作。)
要开始,请在您的 PC 或笔记本电脑上克隆本书的仓库,并转到08_API_Microservices文件夹。我们将使用这些文件来构建 API 服务:
Learn_MLOps
├──08_API_Microservices
│ ├── Dockerfile
├── app
└── variables.py
└── weather_api.py
└── requirements.txt
└── artifacts
└── model-scaler.pkl
└── svc.onnx
文件夹08_API_Microservices中的目录树列出的文件包括一个 Dockerfile(用于从FASTAPI服务构建 Docker 镜像和容器)和一个名为app的文件夹。app文件夹包含weather_api.py文件(包含 API 端点定义的代码),variables.py文件(包含输入变量定义),以及requirements.txt文件(包含运行 API 服务所需的 Python 包),以及包含模型工件(如用于缩放传入数据的模型缩放器)和序列化模型文件(svc.onnx)的文件夹。
模型之前已在模型训练和评估阶段进行了序列化,如第五章中所述,“模型评估和打包”。模型从 Azure 机器学习工作区(Learn_MLOps)中的模型注册表中下载并放置在文件夹中,如图图 8.3所示:
图 8.5 – 下载序列化的模型文件
您可以将 svc.onnx 和 model-scalar.pkl 文件替换为您在 Azure Machine learning 工作区中训练的文件,或者继续使用这些文件进行快速实验。现在我们将查看每个文件中的代码。让我们从 variables.py 开始。
variables.py
我们仅使用一个包来定义输入变量。我们使用的包名为 pydantic;它是一个使用 Python 类型注解进行数据验证和设置管理的包。使用 pydantic,我们将在用于 fastAPI 服务的名为 WeatherVariables 的类中定义输入变量:
from pydantic import BaseModel
class WeatherVariables(BaseModel):
temp_c: float
humidity: float
wind_speed_kmph: float
wind_bearing_degree: float
visibility_km: float
pressure_millibars: float
current_weather_condition: float
在 WeatherVariables 类中,定义变量及其类型,如前述代码所示。用于训练模型相同的变量将用于推理。我们在这里定义这些输入变量为 temp_c、humidity、wind_speed_kmph、wind_bearing_degree、visibility_km、pressure_millibars 和 current_weather_condition。这些变量的数据类型定义为 float。我们将导入 WeatherVariables 类并在 fastAPI 服务中使用定义的输入变量。让我们看看如何使用 WeatherVariables 类中定义的变量在 fastAPI 服务中使用 Weather_api.py 文件。
Weather_api.py
此文件用于定义 fastAPI 服务。所需的模型工件被导入并用于提供 API 端点以推理模型,用于实时或生产中的预测:
-
我们首先按照以下方式导入所需的包:
import uvicorn from fastapi import FastAPI from variables import WeatherVariables import numpy import pickle import pandas as pd import onnxruntime as rt我们导入了所需的包,例如
uvicorn(一个 ASGI 服务器实现包)、fastapi、numpy、pickle、pandas和onnxruntime(用于反序列化和推理onnx模型)。注意
我们之前在
variables.py文件中导入了WeatherVariables类。我们将使用此文件中定义的变量为fastAPI服务获取输入数据。 -
接下来,我们创建一个
app对象。您将注意到fastAPI与 Flask 网络框架(如果您曾经使用过 Flask)在语法上有一些相似之处。例如,在下一步中,我们使用
FastAPI()函数创建app对象。创建app对象的方式类似于我们在Flask示例中做的那样:从 Flask 导入Flask,然后使用Flask函数以app = Flask()的方式创建app对象。您将会注意到我们在使用fastAPI构建 API 端点时存在这样的相似性:app = FastAPI() # Load model scalar pickle_in = open("artifacts/model-scaler.pkl", "rb") scaler = pickle.load(pickle_in) # Load the model sess = rt.InferenceSession("artifacts/svc.onnx") input_name = sess.get_inputs()[0].name label_name = sess.get_outputs()[0].name -
在创建
app对象后,我们将导入在端点中进行推理所需的必要模型工件。使用Pickle反序列化数据缩放文件model-scaler.pkl。此文件用于训练模型(在 第四章,机器学习管道),现在我们将使用它来在模型推理之前缩放传入的数据。我们将使用之前训练的支持向量机分类器模型,该模型被序列化到名为scv.onnx的文件中(我们可以像 图 8.3 所示那样访问和下载该文件)。 -
使用
ONNX运行时将序列化的模型加载到推理会话(input_name和label_name)中,以进行机器学习模型的预测。接下来,我们可以转向定义 API 端点的核心部分,以推断机器学习模型。首先,我们使用包装函数@app.get('/')向索引路由发出一个GET请求:@app.get('/') def index(): return {'Hello': 'Welcome to weather prediction service, access the api docs and test the API at http://0.0.0.0/docs.'}为索引路由定义了一个名为
index()的函数。它返回指向文档链接的欢迎信息。此信息旨在指导用户访问和测试 API 端点。 -
接下来,我们将定义核心 API 端点
/predict,该端点用于推断机器学习模型。使用包装函数@app.post('/predict')发出POST请求:@app.post('/predict') def predict_weather(data: WeatherVariables): data = data.dict() # fetch input data using data varaibles temp_c = data['temp_c'] humidity = data['humidity'] wind_speed_kmph = data['wind_speed_kmph'] wind_bearing_degree = data['wind_bearing_degree'] visibility_km = data['visibility_km'] pressure_millibars = data['pressure_millibars'] current_weather_condition = data['current_weather_condition']为
/predict端点启动了一个名为predict_weather()的函数。在函数内部,我们创建了一个名为data的变量,该变量将捕获输入数据;这个变量捕获通过POST请求获取的JSON数据,并指向WeatherVariables。一旦我们发出POST请求,传入数据中的所有变量都将映射到variables.py文件中的WeatherVariables类中的变量。 -
接下来,我们将数据转换为字典,从字典中获取每个输入变量,并将它们压缩成一个名为
data_to_pred的numpy数组变量。我们将使用这个变量来缩放数据并推断机器学习模型:data_to_pred = numpy.array([[temp_c, humidity, wind_speed_kmph, wind_bearing_degree,visibility_km, pressure_millibars, current_weather_condition]]) # Scale input data data_to_pred = scaler.fit_transform(data_to_pred.reshape(1, 7)) # Model inference prediction = sess.run( [label_name], {input_name: data_to_pred.astype(numpy.float32)})[0]使用之前加载的缩放器通过
fit_transform()函数对数据 (data_to_pred) 进行重塑和缩放。 -
接下来,执行模型推理步骤,这是关键步骤,通过将缩放数据推断到模型中完成,如前面的代码所示。从模型推断出的预测随后作为输出返回到
prediction变量:if(prediction[0] > 0.5): prediction = "Rain" else: prediction = "No_Rain" return { 'prediction': prediction }最后,我们将模型推理转换为人类可读的格式,根据机器学习模型的预测建议
rain或no_rain,并将prediction返回给/predict端点的POST调用。这标志着weather_api.py文件的结束。当通过传递输入数据发出POST请求时,服务以0或1的形式返回模型预测。根据模型预测,服务将返回rain或not_rain。当你得到这样的预测时,你的服务正在运行,并且足够健壮,可以满足生产需求。
Requirement.txt
此文本文件包含运行 fastAPI 服务所需的所有软件包:
numpy
fastapi
uvicorn
scikit-learn==0.20.3
pandas
onnx
onnxruntime
这些软件包应该安装在你希望运行 API 服务的环境中。我们将使用 numpy、fastapi(一个用于创建健壮 API 的机器学习框架)、uvicorn(一个 ASGI 服务器)、scikit-learn、pandas、onnx 和 onnxruntime(用于反序列化和推理 onnx 模型)来运行 FastAPI 服务。为了以标准化的方式部署和运行 API 服务,我们将使用 Docker 在 Docker 容器中运行 FastAPI 服务。
接下来,让我们看看如何为服务创建 Dockerfile。
使用 Docker 开发微服务
在本节中,我们将使用 Docker 以标准化的方式打包 FastAPI 服务。这样,我们可以在大约 5 分钟内将 Docker 镜像或容器部署到您选择的部署目标。
Docker 有许多优点,例如可复制性、安全性、开发简单性等。我们可以使用 Docker Hub 上的官方 fastAPI 镜像(tiangolo/uvicorn-gunicorn-fastapi)。以下是 Dockerfile 的一个片段:
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7
COPY ./app /app
RUN pip install -r requirements.txt
EXPOSE 80
CMD ["uvicorn", "weather_api:app", "--host", "0.0.0.0", "--port", "80"]
首先,我们使用 Docker Hub 上的官方 fastAPI Docker 镜像,通过使用 FROM 命令并指向镜像 – tiangolo/uvicorn-gunicorn-fastapi:python3.7。该镜像使用 Python 3.7,与 fastAPI 兼容。接下来,我们将 app 文件夹复制到 Docker 镜像/容器内的 app 目录中。在将文件夹 app 复制到 Docker 镜像/容器内之后,我们将使用 RUN 命令安装文件 requirements.txt 中列出的必要软件包。
由于 uvicorn 服务器(ASGI 服务器)默认使用端口 80,我们将为 Docker 镜像/容器 EXPOSE 端口 80。最后,我们将使用命令 CMD "uvicorn weather_api:app –host 0.0.0.0 –port 80" 在 Docker 镜像/容器内启动服务器。此命令指向 weather_api.py 文件以访问服务的 fastAPI 应用程序对象,并在镜像/容器的端口 80 上托管。
恭喜,你几乎完成了。现在我们将测试微服务的就绪状态,并查看它是否以及如何工作。
测试 API
要测试 API 的就绪状态,我们将执行以下步骤:
-
让我们从构建 Docker 镜像开始。为此,先决条件是安装 Docker。转到您的终端或命令提示符,将存储库克隆到您希望的位置,并访问文件夹
08_API_Microservices。执行以下 Docker 命令以构建 Docker 镜像:build command will start building the Docker image following the steps listed in the Dockerfile. The image is tagged with the name fastapi. After successful execution of the build command, you can validate whether the image is built and tagged successfully or not using the docker images command. It will output the information as follows, after successfully building the image:(base) 用户 ~ docker images
REPOSITORY 标签 镜像 ID 创建时间 大小
fastapi latest 1745e964f57f 56 秒前 1.31GB
-
在本地运行 Docker 容器。现在,我们可以从之前创建的 Docker 镜像启动一个正在运行的 Docker 容器。要运行 Docker 容器,我们使用
RUN命令:fastapi Docker image. The name of the running container is weathercontainer and its port 80 is mapped to port 80 of the local computer. The container will run in the background as we have used -d in the RUN command. Upon successfully running a container, a container ID is output on the terminal, for example, 2729ff7a385b0a255c63cf03ec9b0e1411ce4426c9c49e8db 4883e0cf0fde567. -
使用样本数据测试 API 服务。我们将检查容器是否成功运行。要检查这一点,请使用以下命令:
fastapi is mapped and successfully running on port 80 of the local machine. We can access the service and test it from the browser on our local machine at the address 0.0.0.0:80.NoteIf you have no response or errors when you run or test your API service, you may have to disable CORS validation from browsers such as Chrome, Firefox, and Brave or add an extension (for example, go to the Chrome Web Store and search for one) that will disable CORS validation for running and testing APIs locally. By default, you don't need to disable CORS; do it only if required.You will see the message that follows:Figure 8.6 – FastAPI service running on local port 80FastAPI uses the OpenAPI (read more: [`www.openapis.org/`](https://www.openapis.org/), [`swagger.io/specification/`](https://swagger.io/specification/)) Specification to serve the model. The `0.0.0.0:80/docs` and it will direct you to a Swagger-based UI (it uses the OAS) to test your API. -
现在,使用您选择的数据测试
/predict端点(通过选择端点并点击尝试它按钮),如图 图 8.6 所示:![图 8.7 – FastAPI 服务的请求体输入图 8.7 – FastAPI 服务的请求体输入
-
点击
POST调用并测试端点。输入由服务中的模型推断,模型预测Rain或No_Rain是POST调用的输出,如图 图 8.7 所示:
![图 8.8 – POST 调用(/predict 端点)的输出
图 8.8 – POST 调用的输出(/predict 端点)
/predict API 的POST调用成功执行将导致输出模型预测,如图 图 8.6 所示。运行在 Docker 容器中的模型在POST调用中将天气条件输出为Rain。恭喜你,你已经成功启动了一个fastAPI容器并对其进行了测试。这个练习应该已经让你具备了构建、部署和测试基于 ML 的 API 服务以供你使用的能力。
摘要
在本章中,我们学习了 API 设计和生产中微服务部署的关键原则。我们简要介绍了 API 设计方法的基础,并了解了 FastAPI。对于我们的业务问题,我们在动手实现将 ML 模型作为 API 提供服务部分通过 FastAPI 和 Docker 进行了实际实施。利用本章获得的实际知识,你可以设计和开发健壮的 API 服务来服务于你的 ML 模型。为 ML 模型开发 API 服务是将 ML 模型推向生产的一个步骤。
在下一章中,我们将深入探讨测试和安全性的概念。我们将使用 Locust 实现一种测试方法来测试 API 服务的健壮性。让我们开始吧!
第九章:测试和确保你的机器学习解决方案安全
在本章中,我们将深入探讨机器学习(ML)解决方案的测试和安全方面。您可以期待获得关于测试您机器学习解决方案的鲁棒性和可扩展性的各种测试类型的入门知识,以及确保您的机器学习解决方案所需的知识。我们将探讨对机器学习解决方案的多种攻击以及防御您的机器学习解决方案的方法。
在本章中,我们将通过执行我们之前一直在工作的天气预测业务用例的负载测试和安全测试来通过示例学习。我们将从反思测试和确保你的机器学习解决方案的需求开始,然后继续探索本章中的其他以下主题:
-
理解测试和确保你的机器学习应用程序的需求
-
通过设计测试你的机器学习解决方案
-
通过设计确保你的机器学习解决方案安全
理解测试和确保你的机器学习应用程序的需求
数据驱动和基于机器学习的解决方案的日益普及导致企业必须处理不断增长的工作负载,使它们面临额外的复杂性和漏洞。
网络安全是 AI 开发者和采用者面临的最令人担忧的风险。根据德勤发布的调查(www2.deloitte.com/us/en/insights/focus/cognitive-technologies/state-of-ai-and-intelligent-automation-in-business-survey.html),2020 年 7 月,62%的采用者认为网络安全风险是一个重大或极端威胁,但只有 39%的人表示他们认为自己有准备应对这些风险。
在本节中,我们将探讨确保基于机器学习的系统和解决方案安全的需求。我们将反思一些机器学习系统更广泛面临的挑战,如偏差、伦理和可解释性。我们还将研究在机器学习生命周期的每个阶段与机密性、完整性和可用性相关的挑战,这些挑战将使用机器学习测试和设计安全的指南来研究。
通过设计测试你的机器学习解决方案
除了执行常规的软件开发测试,如单元测试、集成测试、系统测试和验收测试之外,机器学习解决方案还需要额外的测试,因为数据与机器学习模型都随时间动态变化。以下是一些设计测试的概念;将这些概念应用于您的用例可以确保产生健壮的机器学习解决方案。
数据测试
测试数据的目的是确保数据对于机器学习模型训练来说质量足够高。数据质量越好,为给定任务训练的模型就越好。那么我们如何评估数据的质量呢?可以通过检查以下五个数据因素来完成:
-
准确性
-
完整性(无缺失值)
-
一致性(在预期的数据格式和数量方面)
-
相关性(数据应满足预期的需求和需求)
-
及时性(最新或最新数据)
基于这些因素,如果一家公司能够在接收或创建每个数据集时管理其数据质量,则数据质量得到保证。以下是一些您的团队或公司可以用来作为数据质量保证措施的数据步骤:
-
细致的数据目录和输入数据的控制:数据目录(以所需格式或模式记录和存储数据)和控制功能的组合可以确保输入数据的高质量。数据目录和控制可以通过监控数据因素,如数据格式和模式、值分布和异常、完整性和一致性来实现,这有助于提供良好的输入数据质量。
-
精心管理数据管道以避免重复数据:当重复数据由相同的数据源生成,并且由不同的人使用相同的逻辑时,管理血缘、真实性和数据完整性可能会变得复杂。这可能会在多个系统或数据库中产生级联效应。尽可能避免重复数据会更好。
-
强制执行数据治理的完整性:在当今世界,维护数据完整性变得至关重要。没有强制执行数据完整性的心态可能会对一个组织造成损失。数据最终可能会变得不完整、延迟或过时,导致严重的数据质量问题。
-
维护端到端的可追溯性和血缘关系:通过智能使用元数据和数据本身,可以实现数据血缘和可追溯性。使用两者,我们可以记录关键信息,如每个数据集的唯一键、为每条记录添加时间戳以及记录数据变更。确保数据血缘和端到端可追溯性被启用,可以给我们提供重现模型和调试错误和管道的可能性。
模型测试
模型测试需要涵盖以下服务器问题:
-
评估机器学习模型的准确性或关键指标
-
在随机数据点上测试
-
测试任务的可接受损失或性能
-
使用真实数据进行模型鲁棒性的单元测试
这些测试可以分为两个阶段:预训练和后训练。在流程中实施这些测试可以产生适合生产的稳健模型。让我们看看预先设计和后训练测试可以做什么。
预训练测试
在我们进入训练阶段之前,可以通过测试来捕捉缺陷。这些缺陷可能存在于数据、管道或参数中。图 9.1建议将预训练和后训练测试作为开发高质量模型所提出的流程的一部分:
图 9.1 – 开发高质量模型所提出的流程
这里有一些使用预训练测试来检测和避免预训练缺陷的方法:
-
通过处理任何数据泄漏、边缘情况和优化以使管道时间效率和资源效率来消除数据管道债务
-
确保您的模型输出形状与数据集中的标签匹配
-
检查输出范围以确保它们符合我们的预期(例如,检查分类模型的输出是一个分布,其类概率之和为 1)
-
检查您的训练和验证数据集是否存在标签泄漏
-
确保 ETL 管道以所需格式输出或获取数据
预训练测试不需要参数运行,但它们在运行模型训练之前捕捉错误非常有用。
训练后测试
训练后测试使我们能够调查模型性能和模型预测背后的逻辑,并在将模型部署到生产之前预见模型中可能存在的任何缺陷。训练后测试使我们能够检测模型性能和功能中的缺陷。训练后测试包括模型性能评估测试、不变性测试和最小功能测试。以下是一篇推荐的阅读材料,以了解更多关于训练后测试的信息:超越准确性:使用 CheckList 对 NLP 模型进行行为测试 (homes.cs.washington.edu/~marcotcr/acl20_checklist.pdf)
部署和推理测试
部署测试包括测试持续集成/持续交付(CI/CD)管道交付、集成测试以及测试部署是否成功。测试已部署的模型至关重要,这就是推理测试介入以压力或负载测试已部署模型并测试其在实时数据上的性能的原因。
在下一节中,我们将对之前部署的模型进行负载测试(针对一个用例)。
实践部署和推理测试(一个业务用例)
当您的服务(无论是 API 还是 ML)准备就绪,您即将向用户提供服务,但您对它实际上可以处理多少用户以及当许多用户同时访问时它将如何反应没有任何头绪时,这就是负载测试有用之处,可以基准测试您的服务可以服务多少用户,并验证该服务是否能够满足业务需求。
我们将对之前部署的服务进行负载测试(在第七章,构建健壮的 CI 和 CD 管道)。将使用Locust.io进行负载测试。locust.io是一个开源的负载测试工具。为此,我们将使用pip安装locust,并使用 locust.io SDK 编写一个 Python 脚本来测试一个端点。让我们从安装locust开始:
-
安装
locust:转到您的终端并执行以下命令:pip, locust will be installed – it takes around a minute to install. After installation is successful it's time to curate the Python script using the locust.io SDK to test an endpoint. -
精炼
load_test.py脚本:前往您的首选 IDE 并开始精炼脚本,或者遵循预先制作脚本中的步骤。要访问预先制作的脚本,请前往之前克隆的 Engineering MLOps 仓库,访问09_Testing_Security文件夹,然后转到load_test.py文件。让我们揭开load_test.py中的代码之谜——首先,所需的库如下导入:import time import json from locust import HttpUser, task, between我们导入了
time、json和locust库,然后从locust中导入了以下所需的功能:HttpUser(一个可以访问不同端点的用户代理)、task和between。 -
创建一个
test_data变量,包含用于负载测试中推断机器学习模型的样本测试数据。定义我们将在负载测试中使用的headers:test_data = json.dumps({"data": [[8.75, 0.83, 70, 259, 15.82, 1016.51, 1.0]]}) headers = {'Content-Type': 'application/json'} -
接下来,我们将通过扩展
HttpUser来实现负载测试的核心功能,作为MLServiceUser类(您可以取任何名字)的一部分。HttpUser是一个用户代理,可以访问不同的端点:class MLServiceUser(HttpUser): wait_time = between(1, 5) @task def test_weather_predictions(self): self.client.post("", data=test_data, headers=headers)我们使用
between()函数创建了一个wait_time变量,该变量指定了完成测试一个端点后切换到测试下一个端点所需的时间。因此,我们在between(1,5)函数中将wait_time指定为1到5秒。下一个部分是定义测试端点的任务的核心。对于此,我们使用
@task包装器或装饰器来开始定义我们的任务,以使用自定义函数测试我们选择的端点。定义一个自定义函数def test_weather_predictions(),并使用之前定义的test_data和headers向端点发送post请求。现在,我们已经准备好运行负载测试了! -
运行
locust.io服务器:前往您的终端并切换到您有load_test.py文件的位置(例如,在本书中使用的克隆仓库的09_Testing_Security文件夹中),然后运行以下命令来启动一个locust.io服务器:Locust -f load_test-py执行上一条命令将在端口
8089启动locust服务器。我们可以在由locust.io渲染的 Web 界面上执行负载测试。要访问 Web 服务,打开您选择的浏览器并访问以下 Web 地址:http://0.0.0.0:8089/,如图 图 9.2 所示:图 9.2 – 访问 Locust.io Web 服务
-
运行负载测试:打开 Web 服务将提示您指定选项,如用户数量、生成速率和主机(要测试的端点)。根据您的需求指定要模拟的用户数量和生成速率(每秒将生成多少用户),以验证您的端点是否能够满足您的业务/用户需求,例如,50 个用户和 50 的生成速率。
-
最后,输入您想要进行负载测试的端点或主机,并点击开始 swarming以开始执行负载测试。在第七章 构建健壮的 CI/CD 管道中,我们部署了一个端点。建议测试已部署的端点。
-
前往您的 Azure ML 工作区,访问端点部分,访问名为dev-webservice的已部署端点,并将端点 Web 地址复制并粘贴到主机文本框中。
-
接下来,点击开始 swarming以开始对端点进行负载测试。这将启动负载测试并打开一个新页面,您可以在其中实时监控您的负载测试,如图图 9.3所示:
图 9.3 – 实时监控负载测试
-
分析负载测试结果:您可以在实时监控统计数据、图表、故障和异常。例如,在图 9.3中,我们正在监控带有测试数据的
POST请求的负载测试。监控的项目包括请求数量(77459)、失败次数(0)、平均响应时间(75ms)以及其他信息。检查是否存在故障以及平均响应时间是否在满足您的业务/用户需求的有效范围内或没有速度瓶颈是很重要的。如果您没有失败的请求,并且平均响应时间在所需范围内,则您的端点已通过负载测试并准备好供用户使用。在负载测试之后或期间,您可以通过图表查看负载测试性能,包括每秒总请求数、响应时间和随时间推移的用户数量等关键信息。我们可以在图 9.4和图 9.5中实时查看这些信息:
图 9.4 – 显示每秒总请求数和响应时间的图表
在图 9.4中,我们可以注意到,当locust.io的模拟用户发起请求时,每秒请求数量在 18-22 之间,某些情况下响应时间在 70 到 500 毫秒之间变化,最小和最大响应时间之间的差异为 430 毫秒。平均请求时间为 75 毫秒(如图图 9.3所示)。
请注意,这种性能可能或可能不适合特定的用例,这取决于您的业务或用户需求。更稳定的响应时间更可取;例如,最小和最大响应时间之间的响应时间变化不超过 50ms 可能更适合稳定性能。为了实现这种性能,建议根据需要部署到高端基础设施上,例如 GPU 或高端 CPU,而不是在 Azure 容器实例上的 CPU 上部署。同样,在图 9.5中,我们可以看到响应时间与用户数量的关系:
![图 9.5 – 显示每秒总请求次数和用户数量的图表
![img/B16572_09_05.jpg]
图 9.5 – 显示每秒总请求次数和用户数量的图表
我们可以看到,每秒产生的用户数量为 50,如(图 9.2)中所述。随着时间的推移,产生率保持恒定,响应时间在 70-500ms 之间变化,平均响应时间为 75ms。
- 文档或下载结果:负载测试成功执行后,您可以使用测试报告记录或向相关利益相关者(QA/产品经理)展示负载测试的结果。要下载或访问测试报告,请访问如图图 9.6所示的
.csv文件:
![图 9.6 – 下载测试结果
![img/B16572_09_06.jpg]
图 9.6 – 下载测试结果
根据您的需求下载所需的统计数据或故障报告,并请注意,您可以通过点击下载报告来访问完整的测试报告,如图图 9.7所示:
![图 9.7 – 下载测试结果
![img/B16572_09_07.jpg]
图 9.7 – 下载测试结果
提供了包含关键信息的全面测试报告,例如端点推断的平均请求时间和最小/最大请求时间,这些信息也以可视化的图表形式呈现,如图图 9.7所示。您还可以下载此完整报告以向您的相关利益相关者展示。
恭喜您,您已经进行了手动负载测试以验证您的端点,并检查您的机器学习服务是否能够以高效的方式满足您的业务或用户需求。
通过设计确保机器学习解决方案的安全
由于人工智能在提供智能应用方面的日益普及,确保您的机器学习应用安全比以往任何时候都更重要。在设计和发展机器学习系统时,如果不考虑安全性,可能会因暴露系统给黑客而造成损失,导致操纵、数据泄露和不合规。鲁棒性和安全性在确保人工智能系统值得信赖方面发挥着重要作用。为了构建值得信赖的机器学习应用,考虑安全性是至关重要的,以确保不留任何遗漏。
图 9.8 展示了一个通过设计创建安全机器学习应用的框架。该框架针对机器学习生命周期的关键区域,确保在这些特定阶段中的机密性、完整性和可用性。让我们反思机器学习生命周期的每个区域,并针对每个区域解决机密性、完整性和可用性问题:
![图 9.8 – 通过设计确保机器学习生命周期的框架
![img/B16572_09_08.jpg]
图 9.8 – 通过设计确保机器学习生命周期的框架
在查看不同类型的攻击的同时,让我们反思机器学习生命周期的每个区域,并解决每个区域的机密性、完整性和可用性问题。
攻击类型
我们将探讨一些最常见针对机器学习系统的攻击。从高层次来看,黑客的攻击可以分为四个类别:中毒、输入攻击和规避、逆向工程和后门攻击。让我们看看攻击者是如何通过这些攻击渗透机器学习系统的。
中毒
在中毒攻击中,黑客或攻击者试图破坏 AI 模型。中毒攻击可以在任何阶段发生(训练、部署或实时推理)。它们通常发生在训练和推理阶段。让我们看看中毒攻击是如何以三种典型方式实施的:
-
数据集中毒:训练数据集包含模型训练所依据的知识。攻击者可以通过渗透训练数据集来操纵这种知识。在这里,攻击者将错误标记或错误的数据引入训练数据集,从而扭曲整个学习过程。这是直接中毒模型的一种方式。训练数据集可以在数据收集和整理阶段中毒,由于训练数据集可能来自多个来源,可能很大,而且攻击者可以在数据分布中渗透,因此可能很难注意到或检测到它。
-
算法中毒发生在攻击者干预用于训练模型的算法时。这可以简单到渗透超参数或篡改算法架构。例如,让我们以联邦学习(旨在保护个人数据的隐私)为例,在多个私有数据子集(如来自多家医院的医疗数据,同时保护患者的机密信息)上完成模型训练。从每个子集中衍生出多个模型,然后组合成一个最终模型。在这个过程中,攻击者可以操纵任何数据子集并影响最终生成的模型。攻击者还可以从伪造数据创建一个假模型,并将其与从多个私有数据子集的训练中产生的模型连接起来,以生成一个偏离高效执行任务或服务于攻击者动机的最终模型。
-
模型中毒发生在攻击者用替代模型替换已部署模型时。这种攻击与典型的网络攻击相同,其中包含模型的电子文件可能被修改或替换。
输入攻击和规避
当攻击者以某种方式修改输入到机器学习系统,导致系统故障(或给出错误预测)时,就会发生输入或规避攻击。这些扰动或变化可能很难检测,因为这些变化非常微妙或微小。
例如,输入攻击在计算机视觉算法中很受欢迎。这可以通过仅更改输入图像中的几个像素来实现。结果,系统可能会以它不应该的方式识别图像,或者做出错误的预测。这种微小的变化可以有效地操纵预测,导致系统采取错误的行为。因此,ML 系统表现得像它应该的那样,而输出被操纵。
ML 系统高度容易受到输入攻击。因此,拥有一个异常检测器来监控传入数据可以非常方便,以避免传入数据中的这种扰动。无论输入数据如何,大多数分类模型都会从它们的训练中选择一个有效类别。保护 ML 系统的另一种方法是在将图像发送到最终图像分类器之前,使用代理二进制模型对输入进行预处理,该模型告诉你,例如,输入图像是人的图像还是动物的图像。
逆向工程
对于一个 AI 系统的用户来说,它可能是一个黑盒或是不透明的。在 AI 系统中,接受输入以生成输出而不透露内部情况(无论是逻辑还是算法)是很常见的。训练数据集,它实际上包含了所有训练系统的知识,通常也保持机密。从理论上讲,这使得外部人士无法预测特定输出产生的原因或 AI 系统在算法、训练数据或逻辑方面的内部情况。然而,在某些情况下,这些系统可能容易受到逆向工程的影响。逆向工程攻击的攻击者或黑客的目标是复制作为服务部署的原始模型,并利用它为自己谋利。
在一篇题为《针对循环神经网络的后门提取攻击》的论文中(arxiv.org/pdf/2002.00123.pdf),该论文于 2020 年 2 月发表,研究人员对使用公开可用的学术数据集训练的 RNN 和 LSTM 进行了模型提取攻击实验。研究人员通过模型提取攻击有效地复制了 ML 系统的功能。他们证明,高精度的模型提取攻击可以有效地提取,主要是通过复制或配置目标模型中的损失函数或架构。
在另一个例子中,2018 年,马克斯·普朗克信息学研究所的研究人员展示了他们如何通过一系列输入-输出查询从不可见模型中推断信息。
后门攻击
在后门攻击中,攻击者可以在训练或推理阶段将他们选择的模式嵌入到模型中,并使用预先准备好的输入来推断部署的模型,从而产生意外的输出或触发 ML 系统。因此,后门攻击可以在训练和推理阶段发生,而逃避和中毒攻击可以在训练或推理的单个阶段发生。
毒化攻击可以用作后门攻击的一部分,在某些情况下,学生模型可以通过迁移学习从教师模型中学习到一些后门。
后门攻击可能会引起完整性挑战,尤其是在训练阶段,如果攻击者成功利用毒化攻击渗透训练数据并触发模型或系统的更新。此外,后门攻击可能旨在降低性能,耗尽或重定向可能导致系统故障的资源,或者尝试从人工智能系统中引入特殊的行为和输出。
摘要
在本章中,我们通过设计测试和安全性的关键原则进行了学习。我们探讨了测试机器学习解决方案的各种方法以确保其安全性。为了获得全面的理解和动手经验,我们实施了对之前部署的机器学习模型(来自第七章,构建健壮的 CI/CD 管道)进行负载测试,以预测天气。有了这个,您就准备好应对各种测试和安全场景,这些场景将会出现在您的面前。
在下一章中,我们将深入探讨在生产环境中部署和维护健壮的机器学习服务的秘密。这将使您能够在生产环境中部署健壮的机器学习解决方案。让我们深入探讨。
第十章:生产发布的基本要素
在本章中,您将了解持续集成和持续交付(CI/CD)管道、生产环境的基本要素以及如何设置生产环境以向最终用户提供之前测试和批准的机器学习(ML)模型。我们将为 CI/CD 管道的生产环境设置所需的基础设施,配置生产部署的过程,配置管道执行触发器以实现完全自动化,并学习如何管理生产发布。本章将涵盖 CI/CD 管道和生产环境的基本要素,因为管道是产品,而不是模型。
通过了解 CI/CD 管道的基础知识,您将能够为您的用例或业务开发、测试和配置自动化的 CI/CD 管道。我们将涵盖与生产部署相关的一系列主题,然后深入探讨在生产环境中监控机器学习模型的基础知识。
在本章中,我们将涵盖以下主题:
-
设置生产基础设施
-
在 CI/CD 管道中设置我们的生产环境
-
测试我们的生产就绪管道
-
配置管道触发器以实现自动化
-
管道发布管理
-
向持续监控服务迈进
让我们从设置构建 CI/CD 管道所需的基础设施开始。
设置生产基础设施
在本节中,我们将设置所需的基础设施以服务于我们的业务用例(预测天气条件——图尔库港是否下雨,以规划和优化港口资源)。我们将设置一个自动扩展的 Kubernetes 集群,以将我们的 ML 模型以 Web 服务的形式部署。Kubernetes 是一个开源的容器编排系统,用于自动化软件应用程序的部署、扩展和管理。许多云服务提供商提供基于 Kubernetes 的基础设施即服务。同样,Microsoft Azure 提供了一个名为 Azure Kubernetes Service(AKS)的基于 Kubernetes 的基础设施即服务。我们将使用 AKS 来编排我们的基础设施。
在 Azure 上部署自动扩展的 Kubernetes 集群有多种方式。我们将探讨以下两种方式,以了解基础设施部署的不同视角:
-
Azure 机器学习工作区门户
-
Azure SDK
让我们先看看最简单的方法;那就是使用 Azure 机器学习工作区为生产部署 Azure Kubernetes 集群。
Azure 机器学习工作区
在本节中,我们将使用 Azure 机器学习工作区提供 Azure Kubernetes 集群。请执行以下步骤:
-
前往 Azure 机器学习工作区,然后转到计算部分,该部分提供了创建不同类型计算选项。选择推理集群并点击创建,如下截图所示:![图 10.1 – 部署推理集群
图 10.1 – 部署推理集群
-
点击创建按钮将显示您可以使用来创建 Kubernetes 服务的各种计算选项。您将被提示选择一个区域,这是您的计算将被部署的位置,以及一些配置,以便您可以根据核心、RAM 和存储来部署。选择一个合适的选项(建议您选择Standard_D2_v4作为此实验的成本最优选择),如下截图所示:![图 10.2 – 选择合适的计算选项
图 10.2 – 选择合适的计算选项
-
选择合适的计算选项后,您将被提示输入
'prod-aks'(意味着生产 Azure Kubernetes 服务),将集群用途设置为生产(因为我们正在为生产设置),选择集群的节点数量,并选择网络配置的基本选项。为了简单起见,省略启用 SSL 配置。然而,根据您的需求,建议在生产中启用 SSL 连接,以提高安全性:![图 10.3 - 配置设置图 10.3 - 配置设置
-
点击创建按钮以部署用于生产的 Kubernetes 集群。创建和部署用于生产的计算大约需要 15 分钟:![图 10.4 – 部署的 Kubernetes 集群
图 10.4 – 部署的 Kubernetes 集群
-
一旦您的 AKS 集群已部署,您将看到一个运行中的 Kubernetes 集群,其名称与您为计算提供的名称(例如,
prod-aks)相匹配,如前一个截图所示。
Azure 机器学习 SDK
在 Azure 上创建和部署 Kubernetes 集群的另一种方法是使用 Azure 机器学习 SDK。您可以使用名为create_aks_cluster.py的预置脚本,该脚本位于10_Production_Release文件夹中。运行create_aks_cluster.py脚本的前提是您的 Azure 机器学习工作区的config.json(可以从 Azure 机器学习工作区下载)文件,如下截图所示:
![图 10.5 – 从您的 Azure 机器学习工作区获取配置文件
图 10.5 – 从您的 Azure 机器学习工作区获取配置文件
前往您的 Azure 机器学习工作区,并点击与create_aks_cluster.py文件相同的目录(10_Production_Release)中的config.json文件,如下所示:
├──10_Production_Release
├── create_aks_cluster.py
├── config.json
通过这种方式,您现在可以运行脚本 (create_aks_cluster.py) 来创建用于生产部署的 AKS 计算资源。让我们看看 create_aks_cluster.py 脚本:
-
从
azureml.coreSDK 或库中导入必要的函数。例如Workspace、Model、ComputeTarget、AksCompute等函数将用于配置您的 AKS 集群:from azureml.core import Workspace from azureml.core.model import Model from azureml.core.compute import ComputeTarget from azureml.core.compute_target import ComputeTargetException from azureml.core.compute import AksCompute, ComputeTarget -
通过导入必要的函数,您可以通过连接到您的 Azure Machine Learning 工作区并创建
ws对象来开始使用它们。这样做是通过使用Workspace函数并将它指向您的config.json文件来完成的,如下所示:ws = Workspace.from_config() print(ws.name, ws.resource_group, ws.location, sep = '\n') -
默认情况下,
from_config()函数会在您执行create_aks.py文件相同的目录中查找config.json文件。如果您的config.json文件在其他位置,请在from_config()函数中指定该文件的位置。在成功执行workspace.from_config()函数后,您将看到工作区的名称、资源组和位置被打印出来。 -
接下来,我们将为生产部署创建一个 AKS Kubernetes 集群。首先为您的 AKS 集群选择一个名称(将其引用到
aks_name变量),例如prod-aks。脚本将检查是否已存在具有所选名称的集群。我们可以使用try语句通过ComputeTarget()函数检查是否已存在具有所选名称的 AKS 目标。它接受workspace对象和aks_name作为参数。如果找到具有所选名称的集群,它将打印找到的集群并停止执行。否则,将使用ComputeTarget.create()函数创建一个新的集群,该函数接受具有默认配置的provisioning配置:# Choose a name for your AKS cluster aks_name = 'prod-aks' # Verify that cluster does not exist already try: aks_target = ComputeTarget(workspace=ws, name=aks_name) print('Found existing cluster, use it.') except ComputeTargetException: # Use the default configuration (can also provide parameters to customize) prov_config = AksCompute.provisioning_configuration() # Create the cluster aks_target = ComputeTarget.create(workspace = ws, name = aks_name, provisioning_configuration = prov_config) if aks_target.get_status() != "Succeeded": aks_target.wait_for_completion(show_output=True)
在成功执行前面的代码后,将创建一个具有所选名称的新集群(即 prod-aks)。通常,创建新集群需要大约 15 分钟。一旦集群创建完成,您可以在 Azure Machine Learning 工作区中找到它,正如我们在 图 10.4 中所看到的。现在我们已经为增强生产环境 CI/CD 管道设置了先决条件,让我们开始设置它!
在 CI/CD 管道中设置我们的生产环境
执行以下步骤以在 CI/CD 管道中设置生产环境:
-
前往您之前工作的 Azure DevOps 项目,并重新访问 Pipelines | Releases 部分,以查看您的 Port Weather ML Pipeline。我们将通过创建生产阶段来增强此管道。
-
点击 编辑 按钮开始,然后在 DEV TEST 阶段下点击 添加,如图所示:![Figure 10.6 – 添加新阶段
Figure 10.6 – 添加新阶段
-
点击
production或PROD并保存,如图所示:![Figure 10.7 – 添加并保存生产阶段 (PROD)Figure 10.7 – 添加并保存生产阶段 (PROD)
-
将创建一个新的名为PROD的生产阶段。现在,你可以在生产阶段配置作业和流程。要为PROD配置作业,点击PROD阶段中的 1 个作业,0 个任务链接(如前述截图所示,在PROD阶段),你将被导向任务部分,你可以在这里将作业添加到PROD阶段。在这个阶段,我们将从我们的 Azure 机器学习工作区部署模型,因此我们将使用我们在第七章,构建健壮的 CI 和 CD 流水线中之前使用的 AzureML 模型部署模板来连接它。点击代理作业部分右侧的**+**号来添加一个任务,如下所示:![图 10.8 – 添加 AzureML 模型部署任务
![图片 B16572_10_08.jpg]
图 10.8 – 添加 AzureML 模型部署任务
-
搜索
mlops_ws并指向模型工件作为你的模型源。我们这样做是因为我们将使用我们在第四章,机器学习流水线中训练的模型工件。 -
接下来,从 Azure DevOps 仓库指向你的推理配置文件,如下截图所示。推理配置文件代表用于部署的定制环境的配置设置。我们将使用与
inferenceConfig.yml文件相同的推理Config.yml文件。 -
接下来,我们将配置
prod-aks),命名你的部署或网络服务(例如,prod-webservice),并从与流水线连接的 Azure DevOps 仓库中选择部署配置文件,如下所示:![图 10.10 – 配置你的部署信息![图片 B16572_10_10.jpg]
AksDeploymentConfig.yml computeType: AKS autoScaler: autoscaleEnabled: True minReplicas: 1 maxReplicas: 3 refreshPeriodInSeconds: 10 targetUtilization: 70 authEnabled: True containerResourceRequirements: cpu: 1 memoryInGB: 1 appInsightsEnabled: False scoringTimeoutMs: 1000 maxConcurrentRequestsPerContainer: 2 maxQueueWaitMs: 1000 sslEnabled: False -
选择
AksDeploymentConfig.yml文件作为我们的部署配置文件。现在,点击保存按钮来设置PROD环境。
通过这些,你已经成功设置了生产环境并将其与你的 CI/CD 流水线集成以实现自动化。现在,让我们通过执行它来测试流水线。
测试我们的生产就绪流水线
恭喜你成功设置了生产流水线!接下来,我们将测试其鲁棒性。一种很好的方法是创建一个新的版本,观察并研究生产流水线是否成功将模型部署到生产环境(包含流水线的生产 Kubernetes 集群设置)。按照以下步骤测试流水线:
-
首先,创建一个新的版本,转到流水线 | 发布部分,选择你之前创建的流水线(例如,Port Weather ML 流水线),然后点击屏幕右上角的创建发布按钮以启动一个新的发布,如下所示:![图 10.11 – 创建一个新的发布
![图片 B16572_10_11.jpg]
图 10.11 – 创建一个新的发布
-
在屏幕右上角选择你想要在流水线中部署的工件(例如,
Learn_MLOps repo,_scaler和support-vector-classifier模型,并选择它们的版本。建议第一次测试 PROD 部署时使用版本 1),然后点击屏幕右上角的创建按钮,如图所示。完成此操作后,将启动一个新的版本,如图所示:![Figure 10.12 – New release’s execution![img/B16572_10_12.jpg]
图 10.12 – 新版本执行
-
在执行流水线后,DEV TEST和PROD阶段将被部署(例如,Release-5,如图所示)。在流水线发布进行中时,你可以通过监控任何阶段(DEV TEST 或 PROD)的每个步骤的日志来检查每个阶段的每个步骤,直到流水线成功部署。你还可以检查以前版本的日志。
-
在成功完成版本发布后,DEV TEST和PROD阶段将分别使用 CI 和 CD 进行部署。你必须确保流水线是健壮的。接下来,我们可以通过添加自定义触发器进一步自定义流水线,这些触发器将自动化流水线而无需人工监督。在没有人工监督的情况下自动化 CI/CD 流水线可能会有风险,但可能具有优势,例如实时持续学习(监控和重新训练模型)和更快的部署。了解如何在没有人工监督的情况下自动化 CI/CD 流水线是很有用的。请注意,在许多情况下并不推荐这样做,因为错误的空间很大。在某些情况下,它可能是有用的——这完全取决于你的用例和机器学习系统目标。现在,让我们看看全自动化触发器。
配置流水线触发器以实现自动化
在本节中,我们将基于我们已经连接到流水线的工件配置三个触发器。我们将设置的触发器如下:
-
Git 触发器:用于对 master 分支进行代码更改。
-
Artifactory 触发器:用于创建或训练新模型或工件时。
-
计划触发器:每周周期性触发。
让我们详细看看这些流水线触发器。
设置 Git 触发器
在团队中,当代码库中某个分支发生代码更改时,通常会设置一个部署触发器。例如,当对master分支或develop分支进行代码更改时,CI/CD 流水线会被触发,分别将应用程序部署到 PROD 或 DEV TEST 环境。当向master或develop分支提交合并请求时,QA 专家或产品经理会接受合并请求以与相应的分支合并。在 master 或 develop 分支上做出代码更改后,会生成一个触发器以在流水线中创建一个新的版本。按照以下步骤为实验的 master 分支创建触发器,如图所示:
-
进入 管道 | 发布 部分,选择您的管道(例如,Port Weather ML 管道)。然后,点击 编辑:![图 10.13 – 设置持续部署触发器(Git 触发器)
图 10.13 – 设置持续部署触发器(Git 触发器)
您将被引导到一个门户,您可以在其中编辑您的管道(例如,Port Weather ML 管道),以便您可以为您的工件配置持续部署触发器。
-
要为 master 分支设置 Git 触发器(当 master 分支发生更改时,将触发新发布),点击 触发器 图标(雷声图标)并将开关按钮从禁用状态移动到启用状态。这将启用持续部署触发器。
-
最后,添加一个分支过滤器并指向您想要设置触发器的分支 – 在这种情况下,是 master 分支 – 如前图所示。保存您的更改以设置 Git 触发器。
通过实施这些步骤,您已设置了一个持续部署触发器,以便在 master 分支发生更改时启动新发布。
设置 Artifactory 触发器
对于机器学习应用程序,Artifactory 触发器非常有用。当团队中的数据科学家训练了新的模型或工件(文件)时,将那些模型部署到测试环境,并在有希望或优于先前模型或触发器的情况下最终部署到生产环境是有用的。按照以下步骤设置一个持续部署触发器,以便在训练新模型时为管道创建新发布,如图中所示:
-
进入 管道 | 发布 部分,选择您的管道(例如,Port Weather ML 管道)。然后,点击 编辑:![图 10.14 – 为工件触发器设置 CD(SVC 模型)
图 10.14 – 为工件触发器设置 CD(SVC 模型)
点击 编辑 按钮后,您将被引导到一个门户,您可以在其中编辑您的管道,如图中所示。
-
要为您的模型设置工件触发器,点击您选择模型,例如 支持向量机分类器(SVC),并启用 持续部署触发器。在前面的截图,已为模型(SVC)启用了一个触发器。每当在连接到您的 Azure Machine Learning 工作区的模型注册表中训练并注册新的 SVC 模型时,将通过管道触发新发布以部署新模型。
-
最后,保存您的更改以设置 SVC 模型的工件触发器。您已设置了一个持续部署触发器,以便在您的 Azure Machine Learning 工作区上训练并注册新的 SVC 模型时启动新发布。该管道将检索新模型并将其部署到开发测试和产品环境中。
通过实施这些步骤,您已设置了一个持续部署触发器,当在您的 Azure Machine Learning 工作区中创建或注册新工件时,将启动新的管道发布。
设置计划触发器
现在,我们将为管道设置一个特定时间的时间触发计划。这种触发器对于通过定期的新发布保持系统健康和更新非常有用。计划触发器在设定的时间间隔创建新发布。我们将为每周星期一上午 11:00 设置一个计划触发器。在此时间,将触发一个新发布,将 SVC 模型的最新版本部署到开发测试和 PROD 环境。按照以下步骤设置计划触发器:
-
前往管道 | 发布部分并选择您的管道(例如,Port Weather ML 管道)。然后,点击编辑,如图所示:![图 10.15 – 设置计划触发器
图 10.15 – 设置计划触发器
点击编辑按钮后,您将被引导到一个门户,您可以在那里编辑您的管道。
-
要为管道设置计划触发器,请点击计划设置并启用计划发布触发器。然后,选择您希望触发发布的日期和时间。例如,在先前的屏幕截图中,每周星期一上午 11:00 已启用触发器。
-
最后,保存您的更改以设置管道的计划触发器。
通过实施这些步骤,您已设置了一个持续部署触发器,在设定的时间间隔内启动新的管道发布。
恭喜您设置 Git、工件和计划触发器。这些触发器使管道实现完全自动化。管道已设置,现在可以成功测试和部署模型。您还可以选择通过添加人工或质量保证(QA)专家来部分自动化管道,以在每个管道阶段获得批准。例如,在测试阶段之后,QA 专家可以进行批准,以便在测试阶段一切顺利时开始生产部署。作为 QA 专家,监控您的 CI/CD 管道至关重要。在下一节中,我们将探讨在管理管道发布时的最佳实践。
管道发布管理
CI/CD 管道中的发布允许您的团队完全自动化,并以更快的速度、更低的风险向客户交付软件。发布允许您在生产的多个阶段测试和交付软件,或设置带有批准和按需部署的半自动化流程。监控和管理这些发布至关重要。我们可以通过从管道 | 发布访问管道并选择我们的 CI/CD 管道(例如,Port Weather ML Pipeline)来管理发布,如图所示:
![图 10.16 – 管道发布管理
图 10.16 – 管道发布管理
在这里,您可以跟踪所有版本及其历史记录,并对每个版本执行操作,例如重新部署、放弃、检查日志等。您可以看到以下截图中的版本。通过点击单个版本(例如,版本 4),我们可以检查在版本中部署了哪些模型和工件以及版本是如何触发的(手动或使用自动触发器)。它提供了管道的端到端可追溯性。这些信息对于 ML 系统的治理和合规至关重要:
![图 10.17 – 检查版本
![img/B16572_10_17.jpg]
图 10.17 – 检查版本
预防胜于治疗。正如我们在失败后进行事件审查一样,在部署新服务或模型后进行发布后审查有助于通过预防可能的失败。对部署后的发布进行彻底分析可以使我们理解以下关键问题的答案:
-
在发布过程中,哪些是有效的,哪些是无效的?
-
发布过程中是否遇到了任何障碍?
-
是否存在可以解决并使下一个版本更具可解释性的不明确流程?
在发布后彻底理解这些问题可以帮助您改进和迭代您的策略,并发展更好的发布管理实践。
向持续监控迈进
通过这样,我们已经建立了一个完全自动化且稳健的流程。到目前为止,我们已经成功地在 MLOps 工作流中实现了部署部分或模块(正如我们在第一章,MLOps 工作流基础中讨论的那样)。实时监控已部署的 ML 模型和服务对于理解系统的性能至关重要,因为这有助于最大化其商业影响。ML 项目未能为业务带来价值的一个原因是因为它们在决策过程中缺乏信任和透明度。在当今时代,将信任融入 AI 系统至关重要,尤其是如果我们希望适应不断变化的环境、监管框架和动态的客户需求。持续的监控将使我们能够监控 ML 系统的性能,并将信任融入 AI,以最大化我们的商业价值。在下一章中,我们将学习 MLOps 工作流中的监控模块以及它是如何促进持续监控的。
摘要
在本章中,我们介绍了 CI/CD 管道和生成环境的基本要素。我们进行了一些实际操作来搭建生产基础设施,然后在管道的生产环境中设置了流程以进行生产部署。我们测试了准备就绪的生产管道以检验其鲁棒性。为了将事情提升到下一个层次,我们使用各种触发器完全自动化了 CI/CD 管道。最后,我们探讨了发布管理实践和能力,并讨论了持续监控 ML 系统的必要性。一个关键的观点是管道是产品,而不是模型。比起构建最佳模型,更应专注于构建一个强大且高效的管道。
在下一章中,我们将探讨 MLOps 工作流程监控模块,并深入了解这个颠覆性的可解释监控框架。
第三部分:生产环境中监控机器学习模型
在本部分,读者将了解生产环境中监控机器学习系统的原理和流程。这将使他们能够构建 CI/CD 管道以监控部署,并使他们能够设置和促进机器学习模型的持续交付和持续监控。
本节包含以下章节:
-
第十一章, 监控您的 ML 系统的关键原则
-
第十二章, 模型服务和监控
-
第十三章, 持续学习的 ML 系统治理
第十一章:监控你的 ML 系统的关键原则
在本章中,我们将学习那些对于在生产环境中监控你的机器学习(ML)模型至关重要的基本原理。你将学习如何使用可解释监控框架构建可信赖且可解释的人工智能解决方案。可解释监控框架可用于构建功能监控管道,以便你在生产环境中监控 ML 模型,分析应用程序和模型性能,并治理 ML 系统。监控 ML 系统的目标是实现信任、透明度和可解释性,以增加业务影响。我们将通过观察一些现实世界的例子来了解这一点。
理解本章中提到的原则将使你具备构建针对你的用例或公司的端到端监控系统的知识。这将帮助你参与业务、技术以及公众(客户和法律)利益相关者,以便你能够高效地实现你的业务目标。这还将帮助你获得优势,并采用系统的方法来治理你的 ML 系统。使用本章中的框架,你可以为你的利益相关者和 ML 系统启用信任、透明度和可解释性。
在本章中,我们将涵盖以下主要内容:
-
理解监控 ML 系统的关键原则
-
在 MLOps 工作流程中的监控
-
理解可解释监控框架
-
启用服务的持续监控
让我们开始吧!
理解监控 ML 系统的关键原则
在当今数据驱动产品日益增长的需求以及适应不断变化的环境和监管框架的背景下,将信任融入 AI 系统至关重要。ML 项目未能为业务带来价值的一个原因就是决策过程中缺乏信任和透明度。许多黑盒模型擅长达到高精度,但在解释已做决策背后的原因时却变得过时。在撰写本文时,有关信任和可解释性的担忧的新闻正在浮出水面,如下图所示:
![图 11.1 – 模型信任和可解释性的组成部分]
![img/image001.jpg]
图 11.1 – 模型信任和可解释性的组成部分
这张图片展示了现实生活中重要领域的担忧。让我们通过一些现实生活中的例子来探讨这些担忧如何转化为模型可解释性的关键方面,例如模型漂移、模型偏差、模型透明度和模型合规性。
模型漂移
我们生活在一个动态变化的世界。因此,机器学习模型执行任务或进行预测的环境和数据也在不断演变,考虑这种变化是至关重要的。例如,COVID-19 大流行给我们带来了一个意想不到的现实。许多商业运营已经转向虚拟,这场大流行给我们带来了一个许多人都认为的新常态。许多小企业已经破产,由于失业率的上升,个人面临着极端的财务短缺。这些人(小企业主和个人)以前从未如此大规模地向银行和机构申请过贷款和财务救济。银行和机构已经部署并使用的欺诈检测算法在贷款和财务救济申请方面没有看到这种速度和真实性。
所有这些特征的变化(例如申请人的收入、他们的信用历史、申请人的位置、他们请求的金额等),由于一个原本有资格贷款但之前没有申请过贷款的申请人失去了工作,可能会扭曲模型的权重/感知(或混淆模型)。这对模型来说是一个重要的挑战。为了处理这种动态变化的环境,考虑模型漂移并持续从中学习至关重要。
Drift 与环境的改变相关,指的是预测机器学习模型性能的下降以及变量之间关系的退化。以下是与模型和数据相关的四种模型变化类型:
-
数据漂移:这是指独立变量的属性发生变化。例如,在先前的例子中,由于季节性、新产品或为满足消费者需求而进行的更改,数据发生变化,如 COVID-19 大流行。
-
特征漂移:这是指特征(的)属性随时间变化。例如,温度随着季节的变化而变化。在冬天,温度比夏天或秋天的温度要低。
-
模型漂移:这是指依赖变量的属性发生变化。例如,在上面的例子中,这是欺诈检测分类发生变化的地方。
-
上游数据变化:这是指数据管道经历操作数据变化时的情况,例如当某个特征不再生成时,导致缺失值。一个例子是客户薪资价值的变化(从美元到欧元),其中美元价值不再生成。
为了更清晰地说明,我们将在下一章中学习更多关于 drift 的知识,并开发 drift 监控器(第十二章,模型服务和监控)。
模型偏差
无论你是否喜欢,机器学习已经影响了你生活中的许多决策,比如获得下一份工作的短名单或从银行获得抵押贷款批准。甚至执法机构也在使用它来缩小潜在的犯罪嫌疑人以预防犯罪。ProPublica 是一个新闻机构(使用机器学习预测未来的罪犯 - www.propublica.org/article/machine-bias-risk-assessments-in-criminal-sentencing)。2016 年,ProPublica 的机器学习显示了一些案例,其中模型倾向于将黑人女性预测为比白人男性风险更高,而所有之前的记录都显示并非如此。这类案例可能代价高昂,并具有破坏性的社会影响,因此需要避免。在另一个案例中,亚马逊构建了一个用于招聘人员的 AI,但由于它歧视女性(据《华盛顿邮报》报道),不得不关闭它。这类偏见可能代价高昂且不道德。为了避免这些,需要监控人工智能系统,以便我们能够对其建立信任。
模型偏差是一种由于数据集(用于模型训练)中某些特征比其他特征更频繁地表示和/或加权而产生的错误。一个失真或有偏差的数据集可能导致模型用例的结果偏差、低准确度水平和分析错误。换句话说,这是由于机器学习算法做出不正确假设而产生的错误。高偏差可能导致预测不准确,并可能导致模型错过特征与预测的目标变量之间的相关关系。一个例子是上述由亚马逊构建的用于招聘人员的 AI,但它对女性存在偏见。我们将在“可解释监控框架”部分了解更多关于模型偏差的内容,我们将探讨“偏差和威胁检测”。
模型透明度
人工智能在本质上是非确定性的。特别是机器学习在其生命周期中持续演变、更新和重新训练。人工智能几乎影响着所有行业和领域。随着其日益普及和重要决策使用机器学习,建立与确定性系统相同的信任水平变得至关重要。毕竟,数字系统只有在它们能够被信任执行其任务时才有用。模型透明度有明确的需求——许多首席执行官和商业领袖都在鼓励我们了解人工智能的商业决策及其商业影响。最近,TikTok 的首席执行官发表声明称:
"我们相信所有公司都应该向监管机构披露他们的算法、审核政策和数据流"(来源:TikTok)。
公司这样的开放和透明度可以建立我们作为社会对人工智能的信任,并使采用和合规更加顺畅。
模型透明性是建立对人工智能系统信任的追求,以确保公平性、减少或消除偏差、提供问责制(审计系统推导结果的端到端过程),以及证明模型输出和系统决策的合理性。
模型合规性
模型合规性已成为重要议题,因为不遵守政府和社会的规定可能造成巨大的成本。以下标题是由《华盛顿邮报》报道的:
"摩根大通就联邦抵押贷款歧视诉讼达成 5500 万美元和解"
不合规对摩根大通来说变成了一笔昂贵的交易。将监管合规性付诸实践越来越重要,以避免不必要的罚款和对社会的损害。以下是一些在公司内实现模型合规性的驱动因素:
-
问责文化:对机器学习系统进行端到端审计对于监控合规性至关重要。MLOps 可以在促进审计和编辑使用人工智能做出的运营和业务决策中发挥关键作用。
-
伦理优先:构建对社会有价值并赢得我们信任的负责任的人工智能系统需要人工智能预测具有包容性、公平性和伦理性。拥有一个伦理框架可以帮助公司将其客户与他们的价值观和原则联系起来,并确保人工智能决策是按照伦理做出的。欧洲委员会在这方面做得很好,提出了可信赖人工智能的伦理和指南。您可以在以下链接找到这些指南:
ec.europa.eu/digital-single-market/en/news/ethics-guidelines-trustworthy-ai。 -
合规性管道:拥有满足商业和政府规定的合规性管道可以为寻求确保实时合规性、审计和编辑的组织带来回报。MLOps 可以通过跟踪所有机器学习模型的库存来促进这一点,从而让利益相关者了解它们的工作方式,并以可视化的方式解释它们是如何工作的。这种方式的工作使人类能够监控、编辑并解释与法规的相关性,这对于业务利益相关者、数据科学家和监管者携手合作确保他们有透明和可解释的运营是高效的。
可解释人工智能
在理想情况下,企业应将模型透明度和合规性置于首位,以便业务能够动态适应不断变化的环境,如模型漂移,并在过程中处理偏差。所有这些都需要一个框架,使所有业务利益相关者(IT 和业务领导者、监管者、业务用户等)与人工智能模型保持联系,以便理解模型所做的决策,同时专注于提高模型透明度和合规性。这样的框架可以通过将可解释人工智能作为 MLOps 的一部分来实现。可解释人工智能使机器学习易于人类理解。
模型透明度和可解释性是两种使可解释人工智能成为可能的方法。机器学习模型基于它们训练的数据形成模式或规则。可解释人工智能可以帮助人类或业务利益相关者理解模型发现的这些规则或模式,并帮助验证由机器学习模型做出的业务决策。理想情况下,可解释人工智能应该能够服务于多个业务利益相关者,如下面的图所示:
![图 11.2 – 以业务驱动的可解释人工智能]
图 11.2 – 以业务驱动的可解释人工智能
黑盒模型在预测上可以达到高精度,但一旦它们无法解释为什么做出这些决策,就会变得过时。大多数黑盒模型不提供对模型性能的可见性,没有监控来捕捉潜在的偏差或漂移,也没有对模型行为的可解释性。为了解决这个问题,大量研究和开发正在进行中,以提供可解释人工智能方法,以提供模型透明度和模型可解释性。
将 MLOps 与可解释人工智能方法相结合可以使几乎所有的业务利益相关者理解和验证人工智能做出的业务决策,并帮助向内部和外部利益相关者解释它们。可解释人工智能没有一劳永逸的解决方案,因为每个用例都需要自己的可解释人工智能方法。有各种方法正在变得越来越受欢迎。我们将在以下小节中查看一些示例。
特征归因方法
特征归因方法显示了模型中的每个特征对每个实例预测的贡献程度。当你请求解释时,你会得到预测,以及特征归因信息。以下是一些特征归因方法:
-
SHapley Additive exPlanations(SHAP):一种解释任何机器学习模型输出的方法。它基于博弈论方法,解释任何机器学习模型的输出。特别是,它解释了每个特征对推动模型输出的贡献。
-
集成梯度:一种旨在通过模型特征来解释模型预测之间关系的技巧。它在论文《深度网络的公理化归因》中提出。它可以通过识别偏斜数据来解释特征重要性,并有助于调试模型性能。
-
Local Interpretable Model-Agnostic Explanation(LIME):这是一种模型无关的方法,用于解释预测。它侧重于局部解释;也就是说,解释反映了模型对预测数据实例的行为。例如,LIME 可以建议哪些因素或特征对模型预测结果很重要。这可以在以下图中看到:
![图 11.3 – 使用 LIME 解释单个预测]
图 11.3 – 使用 LIME 解释单个预测
在前面的图中,模型预测患者患有糖尿病。LIME 解释器突出了与糖尿病相关的症状,如干燥的皮肤、过多的尿液和模糊的视力,这些症状有助于“糖尿病”预测,而“无疲劳”则是反对的证据。使用解释器,医生可以从模型的预测中做出决定并得出结论,并为患者提供适当的治疗。
你可以在cloud.google.com/ai-platform/prediction/docs/ai-explanations/overview了解更多关于 AI 解释的信息。
非特征归因方法
非特征归因方法不关注特征如何影响你的模型预测。相反,它们关注模型推理中输入数据和输出数据之间的关系。以下是一些非特征归因方法:
-
Deeplift:这是通过比较每个神经元的激活与其参考激活并根据差异分配贡献分数来评估神经网络的。Deeplift 揭示了相关性和贡献。例如,假设我们正在使用猫和狗图像分类器来对猫和狗之间的图像进行分类。假设分类器使用 deeplift 方法预测输入图像是狗。在这里,我们可以将图像分类器神经网络中激活的神经元反向传播到它们的参考激活,然后根据差异为每个特征分配贡献分数。
-
自然语言解释(NLE):NLE 旨在通过融合部分依赖函数、梯度分析、上下文编码、个体条件期望、累积局部效应等技术,捕捉文本解释的输入输出关系。这些技术在解释分类或生成文本的语言模型方面非常有用。NLE 为用户提供易于理解和有用的理由,以决定是否信任模型的决策并采取行动。例如,你可能希望根据模型的推荐和解释购买产品。可以使用如 Microsoft Power BI 和 Qlik Sense 等工具来插入并研究 NLE。这些工具需要根据你的需求或用例进行定制。
除了前面提到的那些方法之外,还有其他方法。这个领域是 AI 领域研究的热点。许多研究人员和商业领袖都在追求解决可解释 AI 问题,向内部和外部利益相关者解释模型决策。为多个商业利益相关者提供可解释 AI 驱动的界面可以帮助他们回答关键的商业问题。例如,一位商业领袖需要能够回答“这些模型决策如何影响业务?”而对于 IT 和运营来说,了解“我如何监控和调试?”的答案至关重要。
为多个商业利益相关者回答这些问题,使员工和企业能够适应人工智能,并通过确保模型透明度和合规性,在优化模型偏差和漂移的同时适应不断变化的环境,从而最大化从人工智能中获得的价值。
可解释人工智能 = 模型透明度和可解释性
由于机器学习模型正成为一等公民,为了监控模型在这些领域的性能,我们可以使用可解释监控,它允许我们通过监控和解释其决策来分析和治理生产中的机器学习系统,使用的是可解释人工智能方法。可解释监控是可解释人工智能的混合体;它在生产中融合了操作(Ops)的可解释人工智能方法。可解释监控正成为 MLOps 工作流程的一个组成部分。我们将在下一节中探讨可解释监控如何为 MLOps 工作流程带来价值。
MLOps 工作流程中的监控
我们在第一章《MLOps 工作流程基础》中了解了 MLOps 工作流程。如图所示,监控模块是 MLOps 工作流程的一个组成部分,用于评估生产中机器学习模型的性能和衡量机器学习系统的商业价值。只有当我们从透明度和可解释性的角度理解模型的决策时,我们才能做到这两者(衡量由机器学习模型产生的性能和商业价值),以便向利益相关者和客户解释这些决策。
可解释监控使透明度和可解释性得以治理机器学习系统,从而驱动最佳商业价值:
![图 11.4 – MLOps 工作流程 – 监控
图 11.4 – MLOps 工作流程 – 监控
在实践中,可解释监控使我们能够监控、分析和治理机器学习系统,并且它与其他 MLOps 工作流程组件一起形成一个连续的循环。它还赋予人类参与循环的机会,以理解模型决策并即时教导模型(通过标记数据和重新训练模型)。可解释监控实现了持续学习,并且从长远来看,对一家公司来说可能非常有价值。以下图中可以看到,使用可解释监控实现的人机交互的持续学习流程:
![图 11.5 – 由可解释监控实现的持续学习
图 11.5 – 由可解释监控实现的持续学习
持续学习是系统在变化的环境中持续学习的能力,同时建立之前学到的知识。为了促进持续学习,数据和建模必须携手合作,并得到人工的辅助(通常是一个 QA 分析师或系统管理员,如数据科学家或 ML 工程师)。可解释监控在持续学习系统中发挥着至关重要的作用,以增加收入、保持合规和负责任地构建 ML 系统。毕竟,只有具备持续学习能力并部署的模型才能带来商业价值。
理解可解释监控框架
在本节中,我们将详细探讨可解释监控框架(如图所示)以了解和了解可解释监控如何增强 MLOps 工作流程和 ML 系统本身:
图 11.6 – 可解释监控框架
可解释监控框架是一个模块化框架,用于监控、分析和治理 ML 系统,同时实现持续学习。所有模块协同工作,以实现透明和可解释的监控。让我们看看每个模块是如何工作的,以了解它们在框架中的贡献和功能。首先,让我们看看监控模块(前图中第一个面板)。
监控
监控模块专注于监控生产中的应用程序(服务 ML 模型)。在 ML 系统中存在多个因素,例如应用程序性能(遥测数据、吞吐量、服务器请求时间、失败的请求、错误处理等)、数据完整性和模型漂移,以及不断变化的环境。监控模块应从生产系统日志中捕获关键信息,以跟踪 ML 系统的鲁棒性。让我们看看监控模块三个功能的重要性及其功能:数据完整性、模型漂移和应用性能。
数据完整性
确保 ML 应用程序的数据完整性包括检查输入(ML 模型的输入数据)和输出(ML 模型预测)数据,以确保 ML 系统的完整性和鲁棒性。监控模块通过检查数据的量、种类、真实性和速度来确保数据完整性,以检测异常值或异常。检测异常值或异常可以防止 ML 系统性能不佳并容易受到安全攻击(例如,对抗性攻击)。数据完整性与高效的审计相结合,可以促进 ML 系统达到预期的性能,从而产生商业价值。
模型漂移
如果不测量模型漂移,模型的性能可能会很容易变得低于标准,并可能因不良的决策和客户服务而损害业务。例如,在类似 COVID-19 的黑天鹅事件期间,很难预见数据的变化或趋势。以下是一些登上头条的新闻:
-
由于购物习惯的巨大变化,Instacart 模型预测项在商店的可访问性准确性从 93%下降到 61%(
fortune.com/2020/06/09/instacart-coronavirus-artificial-intelligence/)。 -
银行家们怀疑,那些在好时光下训练的信用模型是否能够准确应对压力情景(
www.americanbanker.com/opinion/ai-models-could-struggle-to-handle-the-market-downturn)。 -
针对市场不确定性,交易算法失误。某些基金下降了 21%(
www.wired.com/story/best-ai-models-no-match-coronavirus)。 -
在 COVID-19 大流行之后,图像分类模型难以适应“新常态”:一个家庭在家前使用笔记本电脑现在可能意味着“工作”,而不是“休闲”。(
techcrunch.com/2020/08/02/ai-is-struggling-to-adjust-to-2020/)。
因此,监控模型漂移至关重要,无论是数据漂移、概念漂移还是任何上游数据的变化,以便适应不断变化的环境,并以最相关的方式服务于企业和客户,从而产生最大的商业价值。
应用性能
监控应用性能以预见和预防任何潜在故障至关重要,因为这确保了机器学习系统的鲁棒性。在这里,我们可以监控生产部署目标(例如,Kubernetes 或本地服务器)的关键系统日志和遥测数据。监控应用性能可以实时提供关键洞察,例如服务器的吞吐量、延迟、服务器请求时间、失败请求的数量或控制流错误等。监控应用没有固定的方法,而且根据你的业务用例,你的应用性能机制可以被定制和监控,以保持系统运行并产生商业价值。
在监控组件方面,我们监控了数据完整性、模型漂移和应用性能。在下一节中,我们将分析如何监控模型和应用程序的数据。
分析
在生产环境中实时分析你的机器学习系统对于理解你的机器学习系统的性能和确保其鲁棒性至关重要。人类在分析模型性能和检测细微异常和威胁方面发挥着关键作用。因此,在机器学习系统中引入人类可以极大地提高透明度和可解释性。我们可以分析模型性能以检测任何偏差或威胁,并了解为什么模型以某种模式做出决策。我们可以通过应用高级技术,如数据切片、对抗攻击预防技术,或通过理解局部和全局解释来实现这一点。让我们看看我们如何在实践中做到这一点。
数据切片
在机器学习(ML)改善商业和一般生活方面有许多成功的案例。然而,仍有改进数据工具以调试和解释模型的空间。一个关键的改进领域是理解为什么模型在某些数据部分或切片上表现不佳,以及我们如何平衡它们的整体性能。切片是数据集的一部分或子集。数据切片可以帮助我们了解模型在不同类型的子数据集上的表现。我们可以将数据集分成多个切片或子集,并研究模型在它们上的行为。
例如,让我们考虑一个假设的情况,我们训练了一个随机森林模型来分类一个人的收入是否高于或低于 50,000 美元。该模型是在 UCI 人口普查数据上训练的 (archive.ics.uci.edu/ml/datasets/Census-Income+%28KDD%29)。模型对数据切片(或子集)的结果可以在下表中看到。这张表表明,整体指标可能是可接受的,因为所有数据的整体对数损失都很低(见 All 行)。这是二分类问题中广泛使用的损失指标,表示预测概率与实际/真实值之间的接近程度;在二分类的情况下,它为 0 或 1。预测概率与实际值偏差越大,对数损失值就越高。然而,各个切片讲述了一个不同的故事:
![表 11.1 – UCI 人口普查数据切片
表 11.1 – UCI 人口普查数据切片
通过查看前表,我们可以得出结论,该模型的表现尚可。然而,如果我们比较男性和女性的表现,我们会看到模型仅在女性受试者上表现良好,其日志损失低于男性受试者的日志损失。另一方面,如果你查看教授-专业职业,你会看到净表现与男性受试者的表现相当,其日志损失分别为 0.45 和 0.41,而教授-专业的影响量则明显较小。对于学士、硕士和博士,模型表现不佳,因为其日志损失分别为 0.44、0.49 和 0.59。还应注意,如果一个切片及其对应项的日志损失低于可接受水平,这表明模型整体表现不佳,而不仅仅是特定数据切片。
数据切片使我们能够看到微妙的偏差和未见过的相关性,以了解为什么模型可能在数据子集上表现不佳。我们可以通过使用代表所有数据切片的平衡数据集(例如,使用合成数据或通过欠采样等)或调整模型的超参数以减少整体偏差来避免这些偏差并提高模型的整体性能。数据切片可以为机器学习系统提供模型公平性和性能的概述,并帮助组织优化数据和机器学习模型以达到最佳性能和合理的公平性阈值。数据切片可以通过提供数据和模型性能的透明度和可解释性来帮助建立对人工智能系统的信任。
备注
要全面了解数据切片和自动化数据切片方法,请参阅自动化数据切片用于模型验证:大数据-人工智能集成方法,链接为arxiv.org/pdf/1807.06068.pdf。
偏差和威胁检测
为了确保使用机器学习模型做出稳健和道德的决定,我们需要确保模型是公平和安全的。任何偏差和威胁都需要被监控和缓解,以避免不道德或偏颇的决定,这些决定可能有利于任何特定一方,以符合商业价值观和法律。
存在着不同类型的偏差,例如选择偏差(用于训练模型的训练数据不代表人口,例如少数群体)、框架偏差(用于收集数据的问题或调查是以某种观点或偏见为框架的)、系统性偏差(重复或一致的错误)、响应偏差(参与者由于跟随他们的主观偏见而回答错误的数据)或确认偏差(收集数据以验证自己的先入之见)。为了避免这些偏差并减轻它们,可以根据具体情况应用数据切片、基于切片的学习或平衡偏差-方差权衡等技术。
机器学习系统面临着需要监控和缓解的安全威胁。我们在第九章“测试和保障您的机器学习解决方案”中讨论了一些常见的威胁和威胁预防技术,包括对抗攻击、投毒攻击、隐私攻击或后门攻击等。
局部和全局解释
局部和全局解释提供了对模型性能的不同视角。局部解释为特定或单个输入的模型预测提供依据,而全局解释则提供了对模型预测过程的洞察,不受任何特定输入的影响。例如,让我们看看一个假设的案例,即使用循环神经网络(RNN)模型对客户评论进行情感分析。以下图表显示了使用 RNNVis 工具对 RNN 模型情感分析的全局解释(整个过程):
图 11.7 – 使用 RNNVis 对 RNN 模型的整体解释(理解隐藏状态、层等如何影响模型输出和预测过程)
来源:blog.acolyer.org/2019/02/25/understanding-hidden-memories-of-recurrent-neural-networks/
例如,这里共聚类可视化显示了具有积极和消极情感的单词云。使用全局解释,我们可以模拟模型的预测过程,并理解与参数或模型架构(例如隐藏状态和层)相关的相关性。全局解释提供了可解释性的两个视角:高级模型过程和预测解释。另一方面,局部解释提供了对单个预测的洞察。如果我们希望全面理解模型的表现并验证它,这两种解释都是有价值的。
在分析组件中,我们可以使用我们探索的技术来分析模型的表现,例如数据切片、偏差和威胁检测以及局部和全局解释。在下一节中,我们将学习如何管理和控制机器学习系统,以有效地引导它实现运营或业务目标。
管理
机器学习系统的有效性取决于其治理方式,以实现最大化的商业价值。系统治理的很大一部分涉及质量保证和控制,以及模型审计和报告,以确保其具有端到端的可追踪性并符合法规。基于对模型性能的监控和分析,我们可以控制和治理机器学习系统。治理是通过智能警报和行动来最大化商业价值的。让我们来看看警报和行动、模型质量保证和控制以及模型审计和报告是如何协调机器学习系统治理的。
警报和行动
治理机器学习系统涉及监控和分析机器学习应用。在这里,系统开发者可以被告知系统何时表现出异常行为,如失败请求、缓慢的服务器响应时间、服务器异常、错误或高延迟。向系统开发者或管理员发出警报可以确保质量保证并防止系统故障。有两种不同类型的警报:系统性能警报和基于模型性能的警报。以下是一些系统性能警报的示例:
-
基于阈值的基于规则的针对失败请求的警报
-
基于阈值的基于规则的针对服务器响应时间的警报
-
基于阈值的基于规则的针对服务器异常的警报
-
基于阈值的基于规则的针对可用性的警报
当模型经历漂移或异常特征分布或偏差时,会生成模型性能警报。当记录此类事件时,系统管理员或开发者会通过电子邮件、短信、推送通知和语音警报被提醒。这些警报操作(自动化或半自动化)可以用来减轻系统性能下降。根据具体情况和需求,可以采取一些可能的行动,例如以下内容:
-
在经历高模型漂移时部署替代模型
-
重新训练一个模型
-
训练一个新的模型
-
重新启动机器学习系统
-
重新部署机器学习系统
模型质量保证和控制
对于使用机器学习系统的用户来说,一个模型的质量保证和控制机制可以非常有益,如果我们希望防止许多可能的事故,并确保机器学习系统的定期和健康监控和功能。建议有一个模型质量保证和控制框架或机制。为此,以下图所示的机器学习系统质量保证框架可以为您组织启用该机制。它是一个模块化框架,用于监控机器学习系统的三个重要方面:
![图 11.8 – 模型质量保证框架
图 11.8 – 模型质量保证框架
质量保证专家可以帮助您的公司或组织实施测试机制,以验证用于训练的数据是否已清理,确保用于模型推断的数据不含有对那个机器学习系统的威胁,并监控数据漂移以理解和验证不断变化的环境。通过以下方式,质量保证或测试工程师,连同产品经理一起,可以监控和测试数据:
-
理解和验证训练、测试和推断数据中的统计关系(例如,平均值、中位数、众数等)。
-
开发测试来验证上述统计和关系(使用脚本)。
-
使用特征选择、降维等技术评估特征分布。
-
重新训练并审查所有模型的性能。
-
定期使用新的数据集监控所有模型的性能。
-
如果模型库存中的另一个模型(性能)比现有模型更准确,则发出警报。
-
定期进行测试。
模型审计和报告
如果您希望为监管机构和法律合规性提供足够的信息,则模型审计和报告至关重要。对模型进行端到端可追溯性确保了极大的透明度和可解释性,这可以为组织或公司带来透明的治理机制。模型审计和报告的目标是评估模型性能,并据此实现机器学习系统治理。在以下图表中,我们可以看到从审计和报告中生成的模型透明度图表的整体概述:
![图 11.9 – 模型 QA 框架
图 11.9 – 模型透明度图表
基于审计和报告的模型评估将确保组织拥有健康、透明和稳健的治理机制,并使他们能够实现端到端可追溯性,以符合监管机构的要求。拥有这样的机制将帮助组织节省大量时间和资源,并使与监管机构的互动更加高效。
启用服务的持续监控
如果我们希望在生产中监控机器学习系统,则可解释性监控框架非常有用。在下一章中,我们将为我们在前几章中工作的业务用例启用可解释性监控框架。我们将为已部署的系统启用持续监控。然后,我们将监控已部署到生产的机器学习应用程序,分析传入数据和模型性能,以治理机器学习系统,为用例产生最大的商业价值。
摘要
在本章中,我们学习了监控机器学习系统的关键原则。我们探讨了常见的监控方法以及可解释监控框架(包括监控、分析和治理阶段)。然后,我们深入探讨了可解释监控的概念。
在下一章中,我们将深入探讨可解释监控框架的实战应用。利用这个框架,我们将构建一个监控管道,以便持续监控生产环境中的机器学习系统,用于业务场景(例如预测图尔库港的天气)。
下一章非常注重实践,所以请系好安全带,做好准备!
第十二章:模型服务和监控
在本章中,我们将反思在生产环境中服务和监控机器学习(ML)模型的需求,并探讨为模型用户或消费者提供不同服务 ML 模型的方法。然后,我们将重新审视第十一章中讨论的可解释监控框架,即监控您的 ML 系统的主要原则,并将其应用于我们使用 MLOps 预测天气的业务用例中。可解释监控框架的实施是实践性的。我们将推断部署的 API,并使用漂移(如数据漂移、特征漂移和模型漂移)来监控和分析推理数据,以衡量 ML 系统的性能。最后,我们将探讨一些概念,以管理 ML 系统,确保 ML 系统的稳健性能,以驱动持续学习和交付。
让我们从反思在生产环境中监控 ML 的需求开始。然后,我们将继续在本章中探讨以下主题:
-
在生产环境中服务、监控和维护模型
-
探索服务机器学习模型的不同模式
-
实施解释监控框架
-
管理您的 ML 系统
在生产环境中服务、监控和维护模型
部署一个模型或 ML 系统而不监控它是没有意义的。监控性能是 ML 系统最重要的方面之一。监控使我们能够以定性和定量的方式分析和绘制 ML 系统对利益相关者的业务影响。为了实现最大的业务影响,ML 系统的用户需要以最方便的方式提供服务。之后,他们可以消费 ML 系统并产生价值。在前几章中,我们开发和部署了一个 ML 模型来预测港口的天气条件,这是我们一直在解决的实际实施业务用例的一部分。在本章中,我们将重新审视我们在第十一章中讨论的可解释监控框架,即监控您的 ML 系统的主要原则,并将其应用于我们的业务用例中。在图 12.1中,我们可以看到可解释监控框架及其一些组件,如绿色高亮所示:
图 12.1 – 要实施的解释监控框架的组件
我们将为以下领域实现可解释监控:数据完整性、模型漂移、应用性能、偏差和威胁检测、局部和全局解释、警报和操作、模型 QA 和控制以及模型审计和报告。这些组件在我们使用案例中是最重要的,以理解可解释监控的实施。我们将省略数据切片,因为我们数据中的人口统计或样本(例如,性别、年龄组等)没有太多多样性。通过使用其他组件的信息,我们可以评估模型的表现及其公平性。在本章中,我们将实现监控和分析模块的组件:数据完整性、模型漂移、应用性能、偏差和威胁检测以及局部和全局解释。其余组件的实现将在第十三章中介绍,持续学习的 ML 系统治理。在我们继续到实现过程之前,让我们看看模型如何为用户消费提供服务。
探索 ML 模型的不同服务模式
在本节中,我们将考虑如何为用户(无论是人类还是机器)提供模型以高效地消费 ML 服务。模型服务是一个关键领域,ML 系统需要成功实现以发挥其商业影响,因为在这个领域的任何延迟或错误都可能对服务用户造成高昂的成本。鲁棒性、可用性和便利性是在提供服务模型时需要考虑的关键因素。让我们看看 ML 模型可以以哪些方式提供服务:这可以是批量服务或按需模式(例如,当需要查询以获取预测时)。在按需模式下,模型可以服务于机器或人类用户。以下是将模型提供给用户的示例:
图 12.2 – 向用户提供服务模型
在典型场景(按需模式)中,模型作为服务提供给用户消费,如图图 12.2所示。然后,机器上的外部应用程序或人类使用他们的数据向预测或机器学习服务发出查询。机器学习服务在收到请求后,使用负载均衡器将请求路由到机器学习应用程序内的可用资源(如容器或应用程序)。负载均衡器还管理机器学习服务内的资源,以按需编排和生成新的容器或资源。负载均衡器将查询从用户重定向到机器学习应用程序内运行的容器中的模型以获取预测。获取预测后,负载均衡器将返回到机器上的外部应用程序,或请求查询的人类,或模型预测内的查询。这样,机器学习服务能够为其用户提供服务。机器学习系统与模型存储或注册表协同工作,以保持其与最新或性能最佳的模型同步,以便以最佳方式为用户提供服务。与用户进行查询的典型场景相比,还有另一种用例,即模型作为批量服务提供。
将模型作为批量服务提供
批量处理或服务应用于大量或批次的输入数据(即不是单个观察值,而是成组的观察值)。在存在大量数据需要推断的情况下,模型通常以批量模式提供服务。一个例子是当模型一次性处理产品或服务的所有消费者或用户的数据。或者,工厂在固定时间线上的数据批次可能需要被处理以检测机器中的异常。与按需模式相比,批量模式更节省资源,通常在可以承受一定延迟的情况下使用:
图 12.3 – 批量推断
批量处理的一个关键优势是,与基于 REST API 的服务不同,批量服务可能需要更轻量或更少的基础设施。对于数据科学家来说,编写批量作业比部署在线 REST 服务更容易。这是因为数据科学家只需要在机器上训练一个模型或反序列化一个训练好的模型,并对一批数据进行批量推理。批量推理的结果可以存储在数据库中,而不是发送响应给用户或消费者。然而,一个主要的缺点是高延迟且不是实时。通常,批量服务可以一次处理数百或数千个特征。可以使用一系列测试来确定最佳批量大小,以达到可接受的延迟。典型的批量大小可以是 32、64、128 或 2 的 518 次方。批量推理可以定期安排,并可以服务于许多延迟不是问题的用例。以下将讨论一个这样的例子。
一个现实世界的例子
一个现实世界的例子是银行从一批文本文档中提取信息。银行每天从其合作伙伴机构接收数千份文件。人类代理不可能阅读所有这些文件并突出显示文档中列出的操作中的任何红旗。批量推理用于一次性从银行接收的所有文档中提取命名实体和红旗。然后,批量推理或服务的成果存储在数据库中。
将模型提供给人类用户
在处理来自人类用户的请求之前,检查用户是否有足够的权限使用模型至关重要。此外,在大多数情况下,了解请求的上下文也很有帮助。收集请求的上下文将使模型能够产生更好的预测。收集上下文后,我们可以将其转换为模型可读的输入,并推断模型以获得预测。
在实践中,以下是向人类用户提供按需模型的关键步骤:
-
验证或授权请求。
-
分析和收集上下文信息(例如,历史数据、用户体验数据或任何其他用户个人数据)。
-
将任何上下文信息转换为模型可读的输入或模式。
-
使用输入数据(包括请求和上下文信息)推断模型以做出预测或获取输出。
-
根据上下文解释输出结果。
-
将输出传递给用户。
一个现实世界的例子
考虑一个聊天机器人服务于人类客户预订机票。它执行上下文推理以服务于人类用户。
将模型提供给机器
我们可以根据用例使用REST API 或基于流的服务的机器或外部应用程序。通常,机器推理数据需求要么是预先确定的,要么在标准模式内。一个定义良好的拓扑和数据模式,无论是 REST API 还是流式服务,都将有效。对机器或人类的需求式服务因情况而异,因为在某些场景中,需求可能会变化(例如,在一天中的特定时间,用户服务的需求可能很高,如下午)。为了处理服务的高需求,自动扩展(在云上)可以帮助按需生成更多资源,并杀死任何空闲资源以释放更多资源。然而,自动扩展不是缩放的万能解决方案,因为它不能单独处理需求上的突然或特殊峰值:
![图 12.4 – 需求式服务的消息代理
图 12.4 – 需求式服务的消息代理
如图 12.4所示的方法在处理高量需求峰值时资源效率高。为了处理突然的峰值,可以使用如 Apache Kafka 或 Spark 这样的消息代理。消息代理运行进程以向队列写入和从队列读取:一个进程用于在队列中写入消息,另一个进程用于从该队列读取。服务模型定期连接到消息代理以处理队列中的输入数据批次,并对批次中的每个元素进行预测。在处理输入数据批次并生成预测后,预测被写入输出队列,然后根据用户请求推送给用户。
一个现实世界的例子
考虑一个拥有数百万用户的社交媒体公司。该公司使用单个或公共机器学习模型作为推荐系统,向用户推荐新闻文章或帖子。由于请求量很大,为了服务众多用户,它不能依赖于基于 REST API 的机器学习系统(因为它同步)。流式解决方案更好,因为它为公司提供异步推理,以便实时服务其用户。当用户登录到其机器上的应用程序或账户(例如社交媒体公司服务器上的应用程序)时,运行在其机器上的应用程序通过流式服务推断机器学习模型(即推荐系统),以提供用户新闻源的推荐。同样,成千上万的用户同时登录。流式服务可以无缝地服务所有这些用户。请注意,这不可能通过 REST API 服务实现。通过为推荐系统模型使用流式服务,社交媒体公司能够实时服务其大量用户,避免出现重大延迟。
实施可解释监控框架
要实现可解释监控框架,回顾一下到目前为止所讨论的内容,特别是关于实现假设用例的内容是值得的。以下是关于我们用例实现回顾,包括问题和解决方案:
-
问题背景:您在芬兰图尔库港的一家货运公司的小团队中担任数据科学家,与另外三名数据科学家一起工作。90% 的进入芬兰的商品通过货运在国家的各个港口抵达。对于货运来说,天气条件和物流有时可能具有挑战性。雨天可能会扭曲港口的运营和物流,从而影响供应链运营。提前预测雨天条件可以使我们优化人力资源、物流和运输资源,以实现港口供应链运营的高效。从业务角度来看,提前预测雨天条件可以使港口通过高效规划和调度人力资源、物流和运输资源,将运营成本降低约 20%。
-
任务或解决方案:作为数据科学家,您被要求开发一个机器学习驱动的解决方案,以提前 4 小时预测芬兰图尔库港的天气状况。这将使港口能够优化其资源,从而实现高达 20% 的成本节约。为了开始,您将获得一个包含 10 年时间线的图尔库港历史天气数据集(数据集可通过本书的 Git 仓库访问)。您的任务是构建一个持续学习驱动的机器学习解决方案,以优化图尔库港的运营。
到目前为止,我们已经开发了机器学习模型并将它们作为 REST API 端点部署在 Kubernetes 集群中,地址为 20.82.202.164:80/api/v1/service/weather-prod-service/score(您的端点地址将不同)。
接下来,我们将为该端点复制一个真实的推断场景。为此,我们将使用我们在 第四章 的 机器学习管道 部分中分割并注册的测试数据集。前往您的 Azure ML 工作区,从 数据集 部分或与您的工作区连接的 Blob 存储下载 test_data.csv 数据集(该数据集已注册为 test_dataset),如图 12.5 所示:
![图 12.5 – 下载验证数据集(之前已分割并注册)
![img/image0051.jpg]
图 12.5 – 下载验证数据集(之前已分割并注册)
准备使用 REST API 端点或机器学习服务推断 test_data.csv 数据。前往 12_Model_Serving_Monitoring 文件夹,并将下载的数据集 (test_data.csv) 放入文件夹中。接下来,访问 inference. py 文件:
import json
import requests
import pandas as pd
data = pd.read_csv('test_data.csv')
data = data.drop(columns=['Timestamp', 'Location', 'Future_weather_condition'])
url = 'http://20.82.202.164:80/api/v1/service/weather-prod-service/score'
headers = {'Content-Type':'application/json'}
for I in range(len(data)):
inference_data = data.values[i].tolist()
inference_data = json.dumps(""dat"": [inference_data]})
r = requests.post(url, data=inference_data, headers=headers)
print(str(i)+str(r.content))
在前面的代码中,我们执行以下步骤:
-
在
inference.py文件中,首先导入必要的库,例如json、requests和pandas。 -
接下来,导入用于与端点推断的
test_data.csv数据集。 -
删除推理中不必要的列,如
Timestamp、Location和Future_weather_condition(我们将通过查询端点来预测这个最终列)。 -
下一步,指向端点的 URL(您可以通过导航到 Azure ML 工作区 | 端点 | Weather-prod-service | 消费)来。为了简单起见,因为我们没有为该服务设置身份验证或密钥,所以我们有 application/JSON 的标题,没有密钥或身份验证。
-
最后,我们将通过端点推断数组中的每个元素来遍历数据数组。要运行脚本,只需将
'url'替换为您的端点,然后在终端(从文件夹位置)运行以下命令以执行脚本:>> python3 inference.py
运行脚本将花费大约 10-15 分钟来推断推理数据中的所有元素。之后,我们可以监控推理并分析推断数据的结果。让我们从数据完整性开始监控和分析。
监控您的机器学习系统
监控模块专门用于监控生产中的应用(即,提供机器学习模型)。动作监控模块具有以下三个功能:
-
数据完整性:
-
注册目标数据集
-
创建数据漂移监控器
-
执行数据漂移分析
-
执行特征漂移分析
-
-
模型漂移
-
应用性能
让我们更详细地查看这些功能。
数据完整性
要监控推理数据的数据完整性,我们需要监控数据漂移和特征漂移,以查看是否有任何异常变化或任何新的模式:
-
数据漂移:这是指独立变量的属性发生变化的情况。例如,由于季节性或新产品的添加、消费者需求或习惯的变化,数据可能会发生变化,就像在 COVID-19 大流行期间所发生的那样。
-
特征漂移:这是指特征(的)属性随时间变化的情况。例如,由于季节变化或季节性,温度在夏季比冬季或秋季的温度要暖和。
要监控漂移,我们将测量基线数据集与目标数据集之间的差异。第一步是定义基线数据集和目标数据集。这取决于用例;我们将使用以下数据集作为基线数据集和目标数据集:
-
基线数据集:这是训练数据集。
-
目标数据集:这是推理数据集。
我们将使用之前用于训练模型的训练数据集作为基线数据集。这是因为用于推理的模型非常了解训练数据集中的模式。训练数据集非常适合比较推理数据随时间的变化。我们将收集推理过程中收集的所有推理数据并将其编译到推理数据集中,并将这两个数据集(即基线数据集和目标数据集)进行比较,以评估目标数据集的数据和特征漂移。
注册目标数据集
训练数据集已在第四章的机器学习管道部分注册,在数据摄取和特征工程部分。我们需要在 Azure ML 工作区的数据集部分内注册推理数据集。
推理数据是使用 azureml.monitoring SDK(modelDataCollector 函数)收集的结果。通过在评分文件(在 score.py 中,正如我们在第六章的部署您的 ML 系统的关键原则中做的那样)中使用 modelDataCollector 函数启用监控功能,我们将推理数据以时间序列数据集的形式存储在 Blob 存储中。在连接到您的 Azure ML 工作区的 Blob 存储中,推理数据存储在 modeldata 容器中。在 modeldata 容器中,推理数据(包括输入和输出)以 CSV 文件的形式存储,这些文件被分在文件夹内。这些文件按照年份、月份和日期(在生产中记录推理数据时)进行结构化。在分区文件夹内,推理数据存储在名为 inputs.csv 和 outputs.csv 的 CSV 文件中。我们需要注册这些 input.csv 文件以监控数据漂移和特征漂移。按照以下步骤注册 input.csv 文件:
-
前往数据集部分,点击创建数据集。然后,选择从数据存储选项,如图 12.6 所示:![图 12.6 – 注册推理数据集
图 12.6 – 注册推理数据集
-
为数据集命名(例如,
Inputs-Inference-Dataset),选择数据集类型为表格型,并在描述字段中写入适当的描述,描述数据集的目的。点击下一步以指定数据存储选择。选择modeldata数据存储,如图 12.7 所示:![图 12.7 – 数据存储选择(输入-推理数据注册)图 12.7 – 数据存储选择(输入-推理数据注册)
-
在选择
input.csv文件后。您可以在您的support vectorclassifier 模型文件夹中找到它,该文件夹位于您的服务名称(例如,prod-webservice)文件夹内。然后,进入子文件夹(默认、inputs 以及按日期结构化的文件夹),并进入您当前日期的文件夹以找到input.csv文件。选择input.csv文件,如图 12.8 所示:![图 12.8 – 选择 input.csv 文件的路径(输入-推理数据注册)图 12.8 – 选择 input.csv 文件的路径(输入-推理数据注册)
-
在选择
input.csv文件后,点击/**/inputs*.csv(如图 12.9 所示)。这是一个重要的步骤,将动态引用inputs文件夹中的所有input.csv文件。如果不引用所有input.csv文件,我们将路径限制为仅一个input.csv文件(如图 12.8 所示之前已选择)。通过引用所有input.csv文件,我们将所有输入数据(inputs.csv文件)编译到目标数据集中(例如,Inputs-Inference-Data):![图 12.9 – 引用路径以动态访问所有 input.csv 文件图 12.9 – 引用路径以动态访问所有 input.csv 文件
-
点击下一步按钮进入设置和预览:![图 12.10 – 设置和预览(推理数据集注册)]
图 12.10 – 设置和预览(推理数据集注册)
如图 12.10 所示,我们可以配置设置并预览数据集。通过选择 列标题 下拉菜单并选择 从所有文件合并标题 来指向正确的列名。检查正确的列名(例如,Temperature_C 和 Humidity)。在选择了适当的列名后,点击 下一步 按钮进入下一个窗口。通过选择您想要监控的所有列及其数据类型,选择正确的模式,如图 12.11 所示:
![图 12.11 – 模式选择(推理数据集注册)]
图 12.11 – 模式选择(推理数据集注册)
确保你在 $aml_dc_scoring_timestamp 列中选择 时间戳 和 日期 属性,因为这些属性包含推理的时间戳。这一步很重要。只有时间序列格式的数据集才能用于计算漂移(通过 Azure 漂移模型);否则,我们无法计算漂移。通过选择所有列来选择正确的模式后,点击 下一步 以确认所有必要的详细信息(例如数据集名称、数据集版本、其路径等)。
-
点击创建按钮以创建数据集。当您的数据集创建成功后,您可以从 Azure ML 工作区的数据集部分查看数据集。转到数据集部分以确认您的数据集已创建。识别并点击您创建的数据集。点击后,您将能够查看您已注册的推理数据集的详细信息,如图图 12.12所示:
![图 12.12 – 查看已注册的推理数据集
图 12.12 – 查看已注册的推理数据集
您可以在图 12.12中看到您已注册数据集的所有基本属性。需要注意的是,相对路径是动态的,它指向引用所有的input.csv文件。所有输入文件的引用结果将显示在input.csv文件中,随着在 Blob 存储的数据存储中每天创建新的input.csv文件,这些文件的数量将持续增加。恭喜您注册了推理数据。接下来,我们将配置数据漂移监控器。
创建数据漂移监控器
为了监控数据漂移和特征漂移,我们将使用 Azure ML 工作区内置的漂移监控功能,作为我们 Azure ML 工作区上的Data Drift Monitor功能的一部分:
-
前往您的 workspace 并访问数据集部分。然后,选择数据集监控器(目前处于预览模式,因为此功能仍在测试中)。点击创建,如图图 12.13所示:![图 12.13 – 创建数据漂移监控器
图 12.13 – 创建数据漂移监控器
-
在选择创建按钮后,系统将提示您创建一个新的数据漂移监控器。选择您所需的靶数据集。
-
在注册靶数据集部分,我们将
inputs.csv文件注册为Input-InferenceData。选择您的推理数据集作为靶数据集,如图图 12.14所示:![图 12.14 – 选择靶数据集图 12.14 – 选择靶数据集
-
在选择您的靶数据集后,系统将提示您指向您的基线数据集,这应该是您的训练数据集(它被用来训练您的已部署 ML 模型)。选择您的基线数据集,如图图 12.15所示:![图 12.15 – 选择基线数据集和配置监控设置
图 12.15 – 选择基线数据集和配置监控设置
-
在选择基线数据集后,系统将提示您设置监控设置,例如数据漂移监控器的名称(例如,
weather-Data-Drift)、运行数据漂移作业的计算目标、数据漂移作业的频率(例如,每天一次)以及监控漂移的阈值(例如,60)。您还将被要求提供一个电子邮件地址,以便在数据漂移超过设定的阈值时接收通知。 -
在配置设置后,创建一个数据漂移监控器。转到您新创建的数据漂移(在数据集部分,点击数据集监控器以查看您的漂移监控器),如图图 12.16所示:![Figure 12.16 – 数据漂移概述(目前为空)
![img/image016.jpg]
图 12.16 – 数据漂移概述(目前为空)
当您访问您的数据漂移监控器时,您会看到没有数据。这是因为我们还没有计算任何漂移。为了计算漂移,我们需要一个计算资源。
-
转到计算部分,访问计算集群选项卡,创建一个新的计算资源(例如,drift-compute – Standard_DS_V2 machine),如图图 12.17所示:![Figure 12.17 – Creating a compute cluster to compute data drift
![img/image0171.jpg]
图 12.17 – 创建计算集群以计算数据漂移
-
在创建计算集群后,返回您的数据漂移监控器(例如,Weather-Data-Drift)。接下来,我们将计算数据漂移。
-
点击分析现有数据并提交一个运行以分析任何现有推断数据,如图图 12.18所示:![Figure 12.18 – Submitting run to analyze any data drift
![img/image018.jpg]
图 12.18 – 提交运行以分析任何数据漂移
-
选择开始和结束日期以及计算目标(即之前创建的,即drift-compute)。然后,点击提交以运行漂移计算。通常需要大约 10 分钟来分析和计算数据漂移。您可以在 Azure ML 工作区的实验部分跟踪您运行的进度。
数据漂移分析:在成功完成运行后,数据漂移已经被计算。使用如图图 12.19所示的漂移概述,我们可以监控和分析您的 ML 模型在生产中的性能。我们可以通过特征查看数据漂移幅度和漂移分布:
![Figure 12.19 – Data Drift magnitude trend
![img/image019.jpg]
图 12.19 – 数据漂移幅度趋势
Azure ML 服务测量模型漂移的方式是使用一个独立的漂移模型(由 Azure 维护),该模型查看基线并比较推断数据。这种比较结果是一个简单的百分比或数据变化的程度。
在图 12.19中,漂移幅度趋势表明我们对模型进行了 3 天的推断(即03/23/21,04/03/21,和04/04/21)。
分析显示,这三次的数据漂移低于 70%的阈值(这是红线,表示阈值)。03/23/21的数据漂移大约为 50%;04/03/21大约为 44%;04/04/21为 40%。这给我们提供了一个关于模型接收到的推断数据变化趋势的线索。同样,我们可以监控特征漂移。
- 特征漂移分析:你可以通过滚动到特征详情部分并选择一个你喜欢的特征来评估单个特征及其漂移。例如,我们可以看到Temperature_C随时间分布的特征,如图图 12.20所示:
![图 12.20 – 特征漂移趋势(Temperature_C)
图 12.20 – 特征漂移趋势(Temperature_C)
为了监控特征随时间的变化,我们可以选择一些我们喜欢的特征指标。例如,平均值、最小值、最大值、欧几里得距离或Wasserstein 距离,这些指标可用于分析特征漂移。选择一个你喜欢的指标(例如,平均值)。我们选择了平均值指标来评估温度漂移,如图图 12.20所示。平均值指标从 14 变为 8,随着时间的推移发生了变化;这显示了Temperature_C特征漂移的变化。这种变化是预期的,因为季节性变化会导致温度的变化。我们还可以监控特征分布的变化,如图图 12.21所示:
![图 12.21 – 特征分布趋势
图 12.21 – 特征分布趋势
如果漂移剧烈或异常,我们需要检查被推断到系统中的输入数据的质量。对特征漂移的了解使我们能够理解周围不断变化的数据和世界。同样,我们可以监控模型漂移,以了解模型性能随数据和世界的变化。
模型漂移
监控模型漂移使我们能够监控我们的模型在生产中的性能。模型漂移是依赖变量属性发生变化的地方。例如,在我们的案例中,这是天气(即下雨或不下雨)的分类结果。正如我们在创建数据漂移监控器部分设置数据漂移一样,我们也可以设置模型漂移监控器来监控模型输出。以下是设置模型漂移的高级步骤:
-
注册一个新的数据集(例如,
Outputs.csv文件。输出数据集可以从数据集部分创建。在创建输出推理数据集时,选择重要的列(例如,未来天气条件)并将数据集转换为表格和时间序列格式(漂移只能在时间序列数据中计算)通过选择带有时间戳的列。 -
从数据集部分创建一个新的监控器(例如,模型漂移监控器),然后点击数据集监控器。选择要监控的特征(例如,未来天气条件)并设置你想要监控的阈值。
-
在概述中分析模型漂移(如图图 12.22所示):
![图 12.22 – 提交运行以分析数据漂移
图 12.22 – 提交运行以分析数据漂移
如果您的模型漂移超过了设定的阈值,那么这可能是一个迹象,表明您应该重新训练或训练模型比较结果,这可以简单地表示为数据变化的百分比或程度。当数据漂移超过阈值(例如,70%)时,我们可以通过电子邮件通知管理员或产品所有者,或者采取部署另一个模型或重新训练现有模型等行动。使用智能操作,我们可以管理机器学习系统以产生最大价值。我们将在下一章中探讨管理机器学习系统的方法(第十三章,持续学习的机器学习系统管理)。到目前为止,我们已经实现了数据漂移、特征漂移和模型漂移的设置。接下来,让我们监控机器学习系统的应用程序性能。
应用性能
您已将机器学习服务以 REST API 端点形式部署,用户可以消费这些端点。我们可以使用 Azure Application Insights(由 Azure Monitor 启用)来监控这些端点。为了监控应用程序性能,访问应用洞察仪表板,如图 图 12.23 所示。转到您的 Azure ML 服务工作区中的 端点 部分,并选择您的机器学习模型部署在其上的 REST API 端点。点击 Application Insights url 以访问与您的 REST API 端点连接的应用洞察端点:
图 12.23 – 应用洞察概览
从 应用洞察概览 部分中,我们可以监控和分析您的机器学习服务的关键应用性能信息。此外,我们还可以从 概览 部分监控失败请求、服务器响应时间、服务器请求和可用性等信息,如图 图 12.24 所示:
图 12.24 – 应用洞察概览
基于这些指标和这些信息,我们可以监控应用性能。理想情况下,我们不应该有任何失败请求或长的服务器响应时间。为了更深入地了解应用性能,我们可以访问应用仪表板(通过点击屏幕顶部的按钮),如图 图 12.25 所示:
图 12.25 – 具有更详细性能评估的应用仪表板
从应用程序仪表板中,我们可以更详细地监控应用程序的性能。例如,我们可以监控应用程序的使用情况、可靠性和其他信息。在用途方面,唯一会话和用户是监控应用程序能够服务的唯一用户数量的关键信息。此外,平均可用性信息有助于评估服务对我们用户的可用性。有了这些信息,如果需要更多资源来服务用户,我们可以做出扩展决策。
我们可以通过评估诸如失败请求的数量、服务器异常和依赖性故障等信息来监控应用程序的可靠性。我们可以使用诸如平均服务器响应时间和 CPU 利用率等信息来监控响应性。理想情况下,应用程序不应有任何故障,如果有任何故障,我们可以通过访问事务搜索或日志,如图12.26所示,进行更深入的检查:
![Figure 12.26 – Accessing the logs to understand any errors or failures
![img/image026.jpg]
图 12.26 – 访问日志以了解任何错误或故障
我们可以更仔细地查看应用程序的日志,以了解任何故障或错误,以便调试应用程序并维护应用程序的健康运行。一个功能性的机器学习应用程序会导致用户满意和最大的商业影响。因此,监控应用程序可以揭示潜在的故障并维护应用程序,以便以最有效的方式为用户提供服务。
分析您的机器学习系统
在生产环境中实时监控和分析您的机器学习系统对于理解机器学习系统的性能和确保其稳健性以产生最大化的商业价值至关重要。人类在分析模型性能和检测细微异常和威胁中扮演着关键角色。我们可以通过应用高级技术,如数据切片、对抗攻击预防技术,或通过理解局部和全局解释来分析模型性能,以检测任何偏差或威胁,并理解模型为何以某种模式做出决策。
数据切片
对于我们的用例,我们将省略数据切片,因为我们没有太多关于人口统计学或数据样本(例如,性别、年龄组等)的多样性。为了衡量模型的公平性,我们将专注于偏差检测。
偏差和威胁检测
为了确定生产中的模型偏差,我们可以使用偏差-方差权衡方法。这使得监控和分析模型偏差或任何可能的威胁变得简单。不言而喻,可能存在更好的方法来监控偏差,但这里的想法是保持简单,因为有时简单更好、更高效。
我们模型平均预测值与我们试图预测的正确值之间的差异是偏差。方差是模型对给定数据点或值的估计的变异性,它告诉我们我们的数据分布。分析部署模型的推理数据的偏差和方差揭示了偏差为 20.1,方差为 1.23(你可以在machinelearningmastery.com/calculate-the-bias-variance-trade-off/上了解更多关于偏差和方差分析的内容)。这意味着我们的模型具有高偏差和低方差;因此,使用推理数据训练或重新训练我们的模型以平衡偏差-方差可能是一个好主意。
本地解释和全局解释
本地解释和全局解释提供了对模型性能的不同视角。本地解释为特定或单个输入的模型预测提供了合理性,而全局解释则提供了对模型预测过程的洞察,不受任何特定输入的影响。我们在探索图 12.19中的监控漂移时,之前已经研究了全局解释。我们可以进一步调查特征分布,如图图 12.21所示,以详细了解本地解释。
分析你的 ML 系统以公平性、偏差以及本地和全局解释,为我们提供了对模型性能的关键洞察,我们可以利用这些信息来治理我们的 ML 系统。
管理你的 ML 系统
系统治理的大部分工作涉及质量保证和控制、模型审计以及报告,以确保端到端的可追踪性和符合法规。ML 系统的有效性(即其产生预期或意图结果的能力)取决于其治理方式,以实现最大商业价值。到目前为止,我们已经监控并分析了我们的部署模型用于推理数据:
图 12.27 – 管理你的 ML 系统的组件
ML 系统的有效性可以通过基于监控和警报采取的智能行动来确定。在下一章中,我们将探讨 ML 系统治理,包括警报和行动、模型 QA 和控制以及模型审计和报告。
摘要
在本章中,我们学习了向用户提供服务 ML 模型以及监控它们以实现最大商业价值的关键原则。我们探讨了为模型用户或消费者提供 ML 模型的不同方式,并为一个假设的商业用例实现了可解释监控框架并部署了一个模型。我们进行了可解释监控框架的动手实现,以衡量 ML 系统的性能。最后,我们讨论了治理 ML 系统的必要性,以确保 ML 系统的稳健性能。
我们将在下一章和最后一章进一步探讨 ML 系统的治理和持续学习概念!
第十三章:治理持续学习的机器学习系统
在本章中,我们将反思机器学习(ML)解决方案中持续学习的必要性。适应是机器智能的核心。适应得越好,系统就越好。持续学习专注于外部环境并适应它。为机器学习系统启用持续学习可以带来巨大的好处。我们将探讨在探索持续学习和研究可解释监控框架的治理组件时,成功治理机器学习系统所需的内容,该框架帮助我们控制和治理机器学习系统以实现最大价值。
我们将深入探讨通过启用警报和操作功能来实现治理的实战实施。接下来,我们将探讨确保模型质量和控制部署的方法,以及我们将学习生成模型审计和报告的最佳实践。最后,我们将了解使模型重新训练和维护 CI/CD 管道的方法。
让我们先反思一下持续学习的必要性,然后继续探讨本章中的以下主题:
-
理解持续学习的必要性
-
使用可解释监控来治理机器学习系统
-
启用模型重新训练
-
维护 CI/CD 管道
理解持续学习的必要性
当我们在第一章,“MLOps 工作流程基础”中开始时,我们了解到为什么人工智能在组织中的采用受到阻碍。其中一个原因是机器学习系统中缺乏持续学习。是的,持续学习!我们将在本章中解决这个挑战,并确保我们能够在本章结束时学会如何启用这种功能。现在,让我们来看看持续学习。
持续学习
持续学习建立在持续从数据、人类专家和外部环境中学习的原则之上。持续学习使终身学习成为可能,其核心是适应。它使机器学习系统能够随着时间的推移变得智能,以适应手头的任务。它是通过监控和学习环境和协助机器学习系统的人类专家来做到这一点的。持续学习可以是一个强大的机器学习系统附加功能。它可以让你随着时间的推移实现人工智能系统的最大潜力。持续学习非常值得推荐。让我们来看一个例子:
![图 13.1 – 贷款发放官员 – 传统系统与由人类辅助的机器学习系统
图 13.1 – 贷款发放场景 – 传统系统与由人类辅助的机器学习系统
与组织中的传统流程(完全依赖人类员工)相比,部署一个模型(由持续学习驱动)具有几个优势。例如,在前面的图表中,我们可以看到银行贷款审批流程的两个案例。第一种场景是由人类专家(例如在传统银行设置中)驱动的。第二种场景是使用机器学习系统自动化或增强流程,以筛选申请、谈判、提供贷款申请最终审批(在此过程中,人类专家审查机器学习系统的决策并批准或拒绝它),以及批准贷款。传统设置的审批时间为一周,而机器学习系统(与人类专家合作)的审批时间为 6 小时。
由于机器学习系统在人类助理的帮助下持续学习和改进,因此它对银行来说更快且更具可持续性。人类员工在公司或工作中有固定的雇佣期限。当他们离开时,他们的领域专业知识也随之消失,培训新员工或为同一任务招聘新员工是昂贵的。另一方面,随着时间推移,与人类专家合作或由人类专家辅助的机器学习模型能够随着时间的推移不断学习并保留知识(就时间而言)。与传统的、人类员工不断变化的方法相比,机器学习系统(与人类专家一起)获得的持续学习可以永久保留。从长远来看,持续学习可以为机器学习系统和业务释放巨大价值。
持续学习的需求
以下图表展示了为什么需要持续学习以及它如何增强您的机器学习系统以最大化您的商业价值:
![图 13.2 – 持续学习的益处
图 13.2 – 持续学习的益处
让我们详细探讨持续学习的益处:
-
适应性:在大多数直接应用中,数据漂移可能随着数据的持续流入而保持不变。然而,许多应用具有动态变化的数据漂移,例如推荐系统或异常检测系统,其中数据持续流动。在这些情况下,持续学习对于适应和准确预测至关重要。因此,适应数据和环境的不断变化性质是很重要的。
-
可扩展性:由 IDC 发布的白皮书(
www.seagate.com/files/www-content/our-story/trends/files/idc-seagate-dataage-whitepaper.pdf)指出,到 2025 年,数据生成的速度将增长到每年 160 ZB,我们将无法存储所有这些数据。该论文预测,我们只能存储 3%到 12%的数据。数据需要即时处理;否则,由于存储基础设施无法跟上产生的数据,数据将会丢失。这里的诀窍是只处理一次传入的数据,只存储必要的信息,然后丢弃其余部分。 -
相关性:ML 系统的预测需要具有相关性并适应不断变化的环境。持续学习是保持 ML 系统在变化的环境和环境中高度相关和有价值的必要条件。
-
性能:持续学习将使 ML 系统具有高性能,因为它通过适应不断变化的数据和环境来使 ML 系统保持相关性。换句话说,更具相关性将提高 ML 系统的性能,例如,在准确性或其他指标方面,通过提供更有意义或更有价值的预测。
由于这些原因,在 ML 系统中需要持续学习,否则我们无法达到 ML 系统所能提供的最大价值。换句话说,项目注定会失败。持续学习是 AI 项目成功的关键。作为可解释监控的一部分,有效的治理策略可以促进持续学习。持续学习的一个重要部分是模型重新训练,这样我们才能应对不断变化的数据并做出相关决策。为此,我们可以将可解释监控和模型重新训练结合起来,以实现持续学习:
可解释监控 + 模型重新训练 = 持续学习
接下来,我们将深入探讨持续学习的应用。现在,让我们探讨如何将有效的管理制度引入 ML 系统。
可解释的监控 – 管理制度
在本节中,我们将实现我们在第十一章“监控您的 ML 系统的关键原则”中学习到的治理机制,应用于我们一直在工作的业务案例。我们将深入研究管理 ML 系统的三个组成部分,如下面的图所示:
图 13.3 – 管理您的 ML 系统的组件
机器学习系统的有效性取决于它们如何被管理以最大化商业价值。为了实现端到端的可追踪性和符合法规,系统治理需要质量保证和监控、模型审计和报告。我们可以通过监控和分析模型输出来规范和规则机器学习系统。智能警告和行为指导治理以优化商业价值。让我们看看机器学习系统的治理是如何通过警告和行为、模型质量保证和控制、模型审计和报告来编排的。
警报和操作
警报是通过执行计划检查来检测条件生成的。一旦满足条件,就会生成警报。基于生成的警报,我们可以执行操作。在本节中,我们将了解这些元素以及它们是如何编排来管理机器学习系统的。
什么是警报?
警报是一个在后台运行的计划任务,用于监控应用程序以检查是否检测到特定条件。警报由以下三个因素驱动:
-
计划:我们应该多久检查一次条件?
-
条件:需要检测什么?
-
操作:当检测到条件时,我们应该做什么?
我们可以根据应用程序性能创建警报来监控以下方面:
-
基于阈值的可用性警报
-
基于阈值的失败请求警报
-
基于阈值的响应时间警报
-
基于阈值的服务器异常警报
-
基于数据漂移阈值的警报
-
基于模型漂移阈值的警报
-
基于错误或异常的警报
管理机器学习系统的一个重要领域是处理错误,因此让我们将注意力转向错误处理。
处理错误
在应用程序中,潜在的错误总是可能的。我们可以通过解决我们机器学习应用程序的所有可能的边缘情况来预见它们。使用以下图表中显示的框架,我们可以解决这些错误。这个框架的目的是识别边缘情况和自动调试方法来处理可能的错误。这将使机器学习服务保持运行:
图 13.4 – 调试和调查错误的框架
如前图所示,我们首先识别可能存在错误的地方,并选择一个资源来处理该错误。选择资源后,我们通过检查资源的高利用率以及资源饱和度(资源饱和是指其容量已完全利用或超过设定的阈值)来检查错误。在出现任何问题的情况下,我们通过检查日志和制定解决方案来处理任何错误。最终,我们通过使用预先编写的脚本来处理任何问题(例如,通过重启资源或重新加载一个函数或文件,以使资源在健康状态下运行)来自动化调试。
通过解决所有可能的边缘情况并制定自动错误处理或调试,我们可以使我们的应用程序无故障,以服务于我们的用户。拥有无故障的应用程序可以确保用户在使用机器学习应用程序时获得无缝的体验和价值。一旦你识别出错误,通过调查或创建自动调试过程来解决它。毕竟,预防胜于治疗。因此,检查所有可能的边缘情况并在事先解决它们是有益的。
我们可以通过使用异常处理功能来处理潜在的错误。异常处理是一种编程技术,用于处理需要特殊关注的情况。在 Python 中,实现广泛的错误类型的异常处理很容易。我们可以使用 try、except、else 和 finally 功能来处理错误和异常,如下图所示:
![图 13.5 – 处理异常和边缘情况
图 13.5 – 处理异常和边缘情况
在 try 子句中遇到异常之前,所有语句都会被执行。在 try 子句中找到的异常会被 except 块捕获和处理。else 块允许你编写只有在 try 子句中没有异常时才能运行的代码。使用 finally,无论之前是否遇到过异常,都可以运行应该始终运行的代码部分。
这里列出了一些可能常见的异常或错误,需要注意:
这些边缘情况或错误很常见,可以通过在应用程序中使用 try 和 exception 技术来解决。策略是减轻用户可能会觉得你的机器学习系统非常基础或天真的情况;例如,一个在聊天中发送错误信息的聊天机器人。在这种情况下,错误的代价很高,用户可能会失去对机器学习系统的信任。
我们将为我们一直在实施的业务用例实现一些自定义异常和错误处理,并根据生成的警报执行操作。让我们开始吧:
-
在您的 Azure DevOps 项目中,前往我们的
13_Govenance_Continual_Learning。从那里,访问score.py文件。我们将首先导入所需的库。这次,我们将使用applicationinsights库来跟踪与端点连接的 Application Insights 的自定义事件或异常:import json import numpy as np import os import pickle import joblib import onnxruntime import logging import time from azureml.core.model import Model from applicationinsights import TelemetryClient from azureml.monitoring import ModelDataCollector from inference_schema.schema_decorators import input_schema, output_schema from inference_schema.parameter_types.numpy_parameter_type import NumpyParameterType如前述代码所示,我们已经从
applicationinsights库中导入了TelemetryClient函数。我们将使用TelemetryClient函数来访问连接到我们端点的 Application Insights。将 Application Insights 的仪表化密钥提供给TelemetryClient函数。 -
此 Instrumentation Key 可从您的 Application Insights 访问,它应连接到机器学习应用程序,如下面的截图所示:
图 13.6 – 从 Application Insights 获取仪表化密钥
-
在获取您的
TelemetryClient函数后,如下述代码所示。在这里,我们在tc变量中创建了一个TelemetryClient对象,用于跟踪自定义事件:def init(): global model, scaler, input_name, label_name, inputs_dc, prediction_dc, tc init function to monitor whether a FileNotFound error occurs when we load the scaler and model artifacts. If a file is not found, the tc.track_events() function will log the error message that's generated by the exception and tag the custom code 101. -
同样,我们将在
run函数中实现一些其他自定义事件 – 即,ValueNotFound、OutofBoundsException和InferenceError–:@input_schema('data', NumpyParameterType(np.array([[34.927778, 0.24, 7.3899, 83, 16.1000, 1016.51, 1]]))) @output_schema(NumpyParameterType(np.array([0]))) def run(data): try: inputs_dc.collect(data) except Exception as e: try and except to collect incoming data using the model data collector function. This collects the incoming data and stores it in the blob storage connected to the Azure ML service. If the incoming data contains some anomalous data or a missing value, an exception is raised. We will raise a ValueNotFound error using the track_event function so that we can log the exception message and custom code (in this case, a random or custom number of 201 is given to track the error). After collecting the incoming data, we will attempt to scale the data before inference:try:
缩放传入数据
data = scaler.transform(data)
except Exception as e:
在此情况下,
try和except可能很有用,因为我们正在尝试使用在init函数中加载的缩放器文件来缩放数据。如果缩放数据不成功,则会引发异常。在这里,我们使用track_event函数在 Application Insights 上跟踪异常。如果生成异常,我们将生成一个名为ScalingError的自定义事件。在 Application Insights 上记录一个异常消息和错误代码301。同样,处理评分文件的最重要步骤 – 模型推理 – 需要细致入微地进行。现在,我们将再次使用try和except来确保推理成功且没有任何异常。让我们看看我们如何处理这种情况下的异常。请注意,我们正在访问model.run函数的元素编号2。这导致模型推理时出现错误,因为我们正在引用列表中的错误或不存在的元素:try: # model inference result = model.run([label_name], {input_name: data.astype(np.float32)})[2] # this call is saving model output data into Azure Blob prediction_dc.collect(result) if result == 0: output = "Rain" else: output = "No Rain" return output except Exception as e: track_event() function to generate a custom event called InferenceError. This will be logged on Application Insights with an error message and a custom error code of 401. This way, we can log custom errors and exceptions on Application Insights and generate actions based on these errors and exceptions.
现在,让我们看看如何使用错误日志在 Application Insights 中调查这些错误并为其生成操作。
设置操作
我们可以根据之前创建的异常事件(在 处理错误 部分中)设置警报和操作。在本节中,我们将根据我们生成的警报设置一个电子邮件通知形式的操作。每当在 Application Insights 中生成异常或警报时,我们都会通过电子邮件收到通知。然后,我们可以进行调查并解决它。
通过访问应用洞察(Application Insights),我们可以设置一个动作(电子邮件)来接收警报,该应用洞察应连接到您的机器学习系统端点。您可以通过 Azure ML 工作区访问应用洞察。让我们开始吧:
-
前往
端点并检查应用洞察。一旦您访问了应用洞察仪表板,点击事务搜索,如下面的截图所示,以检查您的自定义事件日志(例如,推理异常):![图 13.7 – 检查自定义事件日志图 13.7 – 检查自定义事件日志
-
您可以通过日志检查在异常和错误发生时生成的自定义事件,然后为这些自定义事件设置警报和动作。要设置警报和动作,请转到监控 > 警报部分并点击新建警报规则,如下面的截图所示:![图 13.8 – 设置新的警报规则
图 13.8 – 设置新的警报规则
-
在这里,您可以根据警报创建动作的条件。要设置条件,请点击添加条件。您将看到一个可以用来创建条件的信号或日志事件的列表。选择InferenceError,如下面的截图所示:![图 13.9 – 配置条件
图 13.9 – 配置条件
-
选择您选择的信号或事件后,您将可以配置其条件逻辑,如下面的截图所示。通过设置一个阈值来配置条件。在这种情况下,我们将提供一个阈值为
400,因为错误会引发一个值为401(因为我们为InferenceError事件提供了一个自定义的值为401)。当发生推理异常时,它会引发一个值高于400的InferenceError(确切地说是401):![图 13.10 – 配置条件逻辑和阈值图 13.10 – 配置条件逻辑和阈值
-
设置阈值后,您将需要配置其他动作,例如运行自动化运行手册、Azure Function、逻辑应用或安全 Webhook,如下面的截图所示。目前,我们不会提示这些动作,但了解我们有这些动作是好的,因为我们可以运行一些脚本或应用程序作为备份机制来自动化错误调试:![图 13.11 – 自动化调试的动作(可选)
图 13.11 – 自动化调试的动作(可选)
这样,我们就可以通过预先配置的脚本或应用程序来自动化调试,以防发生错误或防止错误。毕竟,预防胜于治疗!
-
最后,我们将创建一个条件。点击审查和创建以创建条件,如前面的截图所示。一旦创建了此条件,您将在创建警报规则面板中看到它,如下面的截图所示。接下来,通过点击添加动作组然后创建动作组来设置一个动作:![图 13.12 – 创建动作组
图 13.12 – 创建动作组
-
提供一个电子邮件地址,以便您可以接收通知,如下面的截图所示。在这里,您可以在警报规则名称字段中命名您的通知,并提供设置电子邮件警报动作所需的信息:![图 13.13 – 配置电子邮件通知
图 13.13 – 配置电子邮件通知
在提供所有必要信息,包括电子邮件后,点击审查 + 创建按钮来配置动作(基于错误的电子邮件)。最后,提供如警报规则名称、描述和严重性之类的警报规则详细信息,如下面的截图所示:
![图 13.14 – 配置电子邮件通知
图 13.14 – 配置电子邮件通知
-
点击
InferenceError)。有了这个,您已经创建了一个警报,现在是时候测试它了。转到13_Govenance_Continual_Learning文件夹,访问test_inference.py脚本(将 URL 替换为您的端点链接)。然后,通过运行以下命令来运行脚本:python3 test_inference.py -
运行脚本将输出错误。在执行一些推理后停止脚本。在错误发生后的 5-10 分钟内,您将通过电子邮件收到错误通知,如下面的截图所示:
![图 13.15 – 生产中的错误电子邮件通知
图 13.15 – 生产中的错误电子邮件通知
恭喜您 – 您已成功设置了一个错误的电子邮件动作警报!这样,您就可以在发现错误时进行调查,以便解决它并使系统恢复正常运行。
接下来,让我们看看如何确保我们有模型的质量保证,并且可以控制它们以最大化商业价值。
模型问答和控制
数据的演变或动态变化导致预测错误率增加。这可能是由于业务和外部环境的变化导致的数据漂移,或者可能是由于数据中毒攻击。预测错误率的增加导致在重新训练(手动或自动)时必须重新评估机器学习模型,从而发现比之前更准确的新算法。以下是一些使用新数据测试机器学习模型的指南:
-
通过重新训练模型并评估其性能来启用持续学习。
-
在定期间隔内评估所有模型在新的数据集上的性能。
-
当替代模型开始提供比现有模型更好的性能或更高的准确性时,发出警报。
-
维护包含最新性能细节和报告的模型注册表。
-
维护所有模型的端到端血缘,以便重现它们或向利益相关者解释其性能。
模型审计和报告
建立 MLOps 的定期审计和报告系统是一种良好的做法,因为它使组织能够端到端地跟踪其运营,并遵守法律,在需要时向利益相关者解释其运营。我们可以确保机器学习系统符合在社会和政府层面已经建立和审议的惯例。为了审计和报告 MLOps,建议审计员检查以下图像所示的审计基础:
![Figure 13.16 – ML Operations 审计报告的基本要素]
![img/B16572_13_016.jpg]
Figure 13.16 – ML Operations 审计报告的基本要素
数据审计
数据是驱动许多机器学习系统决策的因素。因此,审计员在审计和报告中需要考虑数据,检查训练数据,测试数据,推断数据,并监控数据。这是至关重要的,并且对于 MLOps 来说,拥有端到端的可追溯性以跟踪数据的使用(例如,哪个数据集用于训练哪个模型)是必要的。拥有类似“数据 Git”的机制,可以对数据进行版本控制,可以使得审计员能够引用、检查和记录数据。
模型审计(公平性和性能)
机器学习系统的审计员需要具备黑客心态,以识别模型可能失败的不同方式以及无法给出公平预测的情况。首先,审计员会检查训练数据,并使用可解释人工智能技术将其与推理数据进行比较。这有助于审计员对每个模型及其每个预测在个体层面上做出公平的判断。为了对每个模型进行公平性和性能评估,我们可以使用数据切片技术,这可以揭示对评估有价值的宝贵信息。因此,审计员请求所需人口统计数据和数据切片的数据切片结果是有价值的。为了进行集体评估,我们可以比较模型并评估其性能。这可以揭示关于公平性和性能评估的另一个信息角度。
如果进行模型审计,它将评估模型的输入(训练数据)、模型本身及其输出。需要评估数据的一致性和训练数据中可能存在的偏差。例如,如果简历筛选模型是在候选人收到工作邀请和工人晋升的先前或历史决策上训练的,我们想确保训练数据没有受到过去招聘人员和经理的隐含偏见的影响。与竞争模型进行基准测试、执行统计测试以确保模型从训练推广到未知结果,以及使用最先进的技术以允许模型可解释性,都是模型评估过程的一部分。
项目和治理审计
审计算法是否需要深入了解 AI 模型?当然不是。对 AI 系统进展的审计就像项目管理审计一样。是否有明确的期望成果目标?如果政府实体在特定环境中实施了 AI,这是一个很好的、直接的问题。此外,如果外部开发者被应用于 AI 系统,在开发者离开后,是否有可行的框架来管理模型?为了减少对专业知识的需要,公司必须对概念创建有广泛的文档记录,并拥有熟悉该模型的员工。因此,审计开发和治理实践从长远来看是有益的。
审计数据考虑因素、模型公平性和性能,以及 ML 系统的项目管理与治理,可以提供一个全面的 MLOps 视图。使用错误警报和操作,我们可以及时调查错误,使系统恢复正常运行,在某些情况下,我们甚至可以进行自动化调试以自动化错误解决和 MLOps。最后,通过进行模型质量保证、控制和审计,我们可以确保 MLOps 的有效治理。接下来,我们将探讨如何启用模型重新训练,以便我们的 ML 系统具有持续学习的能力。
启用模型重新训练
到目前为止,我们已经讨论了什么是模型漂移以及如何识别它。那么,问题来了,我们应该如何应对它?如果一个模型的预测性能由于环境变化而下降,解决方案是使用代表当前情况的新训练集重新训练模型。你的模型应该重新训练多少次?你如何选择你的新训练计划?以下图表显示了基于模型重新训练功能触发的构建模块,该模块基于监控模块的结果。有两种方式可以触发模型重新训练功能。一种是通过手动操作,另一种是通过自动化模型重新训练功能。让我们看看我们如何启用这两种方式:
![图 13.17 – 在 MLOps 工作流程中启用模型重新训练
![img/B16572_13_017.jpg]
图 13.17 – 在 MLOps 工作流程中启用模型重新训练
手动模型重新训练
产品负责人或质量保证经理有责任确保手动模型重新训练成功。手动模型触发步骤包括评估模型漂移,如果它超过了一个阈值(你需要确定一个漂移阈值,以触发模型重新训练),那么他们必须通过使用新的数据集(这可以是之前的训练数据集和最新的推理数据)来训练模型来触发模型训练过程。这样,产品负责人或质量保证经理对整个过程有完全的控制权,并且知道何时以及如何触发模型重新训练,以从机器学习系统中获得最大价值。
自动化模型重新训练
如果你想要完全自动化 MLOps 管道,自动化模型漂移管理可以是一个重新训练生产模型的理想方法。自动化模型漂移管理是通过配置监控应用程序诊断和模型性能的批量作业来完成的。然后,你必须激活模型重新训练。自动化模型漂移管理的关键部分是设置将自动触发重新训练模型功能的阈值。如果漂移监控阈值设置得太低,你可能会面临需要频繁重新训练的风险,这会导致高昂的计算成本。如果阈值设置得太高,你可能会面临不够频繁地重新训练的风险,导致生产模型次优。确定正确的阈值比看起来要复杂,因为你必须确定你需要多少额外的训练数据来反映这一新现实。即使环境已经改变,用一个非常小的训练集替换现有模型也是没有意义的。一旦你确定了阈值,你就可以有作业(例如,作为 CI/CD 管道的一部分)定期比较实时数据集的特征分布与训练数据上的特征分布(正如我们在第十二章,模型服务和监控中所做的那样)。当检测到大的偏差(或超过定义的阈值)时,系统可以安排模型重新训练并自动部署新模型。这可以通过使用工作调度程序(例如,Jenkins 或 Kubernetes 作业或 CI/CD 管道 cron 作业)来完成。这样,你可以完全自动化 MLOps 管道和模型重新训练部分。
注意,在数据流入量低或你偶尔进行批量推理(例如,每 6 个月一次)的情况下重新训练模型是没有意义的。你可以在推理之前或在你需要的时候定期训练模型。
维护 CI/CD 管道
如您所忆,在第十章“生产发布要素”中,我们提到模型不是产品;管道才是产品。因此,在设置自动化或半自动化 CI/CD 管道后,监控我们管道的性能至关重要。我们可以通过检查 Azure DevOps 中的发布来实现这一点,如下面的截图所示:
![图 13.18 – 维护 CI/CD 管道发布
![img/B16572_13_018.jpg]
图 13.18 – 维护 CI/CD 管道发布
检查的目标是保持 CI/CD 管道处于健康和稳健的状态。以下是一些保持 CI/CD 管道健康和稳健的指南:
-
如果构建失败,团队应实施立即修复的政策。
-
集成自动化验收测试。
-
需要提交拉取请求。
-
对每个故事或功能进行同行代码审查。
-
定期审计系统日志和事件(建议)。
-
定期向所有团队成员公开报告指标(例如,通过 slackbot 或电子邮件通知)。
通过实施这些实践,我们可以避免高失败率,并使 CI/CD 管道对所有团队成员来说都稳健、可扩展和透明。
摘要
在本章中,我们学习了 ML 解决方案持续学习的核心原则。我们通过实际错误处理和配置使用电子邮件通知提醒开发者的操作,学习了可解释监控(治理组件)。最后,我们探讨了启用模型重新训练以及维护 CI/CD 管道的方法。这样,您已经具备了自动化和治理 MLOps 的关键技能,以应对您的用例。
恭喜您完成这本书!MLOps 的世界正在不断进化,变得越来越好。您现在已经准备好利用 MLOps 来帮助您的业务繁荣。希望您在完成动手实践 MLOps 实现的过程中享受阅读和学习。走出舒适区,成为您希望看到的改变。祝您在 MLOps 的努力中一切顺利!