在研究代码示例时,在 [第 2 章] B17649_02_ePub.xhtml#idTextAnchor032) 、使用 SageMaker Autopilot 自动化机器学习模型开发,以及 [第 3 章](B17649_03_ePub.xhtml#idTextAnchor048
无论一个 ML 从业者利用 CRISP-DM 方法还是 AutoML 方法,一旦他们产生了一个最佳的 ML 模型,他们的职责范围就结束了。在他们的任务完成之后,ML 从业者简单地将模型移交给负责在生产中部署和管理模型的各个团队。这种移交在整个流程中造成了脱节,并在尝试自动化整个流程时带来了进一步的挑战。更重要的是,这种脱节经常会影响整个交付时间表,并导致整个项目的成功完成延迟。
本章的主要目标是强调一种方法来弥补模型部署中的这种明显的差距,并使用持续集成和持续交付 ( CI/CD )方法来进一步自动化该过程。我还将向您介绍敏捷、跨职能团队的概念,向您展示 ML 从业者如何更好地与应用开发和运营团队互动,在本章结束时,您将看到这种方法如何一致地创建生产级 ML 模型并部署它们。为此,我们将关注以下主题:
- 介绍 CI/CD 方法
- 利用 CI/CD 实现 ML 自动化
- 在 AWS 上创建 CI/CD 管道
技术要求
本章将使用以下资源:
- web 浏览器(为了获得最佳体验,建议您使用 Chrome 或 Firefox 浏览器)。
- 访问您在 [第三章] B17649_03_ePub.xhtml##_idTextAnchor048
- 如果你选择不使用 AWS Cloud9 服务,可以访问一个集成开发环境 ( IDE )。
- 我们将再次在 AWS 免费层的使用限制内工作,以避免超出不必要的成本。
- 本章的配套 GitHub 存储库中提供了源代码示例、访问策略文档和 Jupyter 笔记本(https://GitHub . com/packt publishing/Automated-Machine-Learning-on-AWS/tree/main/chapter 04)。
介绍 CI/CD 方法
CI/CD 模式已经成为一种非常流行的方法来自动化软件的开发和发布。这种实践背后的主要思想是进行增量的、可靠的、频繁的软件代码变更,然后将这些变更自动地、无缝地部署到生产中。
虽然这种实践已经存在了几年,并被许多 DevOps 工程师采用,但这种实践正在以 MLOps 或机器学习操作的形式开始在 ML 从业者社区中获得牵引力。然而,在深入研究如何将这种方法应用于 ML 之前,让我们先从 CI 开始熟悉一下这个过程的具体步骤。
介绍 CI/CD 的 CI 部分
在高层次上,CI/CD 的 CI 部分包括四个关键阶段;图 4.1 显示了这些阶段的高级概述: ![Figure 4.1 – An overview of the stages in CI ]
图 4.1–CI 阶段概述
从图 4.1 中可以看出,CI 阶段包括以下几个关键阶段:
- 源工件
- 资产构建
- 集成测试
- 释放;排放;发布
让我们回顾一下这个流程(或管道)的步骤。
创建或更新源工件
除了启动整个流程之外,源工件阶段并不真正执行 CI 流程中的特定任务。本质上,这个阶段充当了一个存储库,开发人员在其中存储源代码或组成生产应用的软件片段。向这个存储库中添加新的软件工件(比如新特性)或者更新现有的软件工件(比如错误修复)会触发整个管道的开始。
例如,当应用开发人员进行代码更改、添加新功能或修复应用错误时,他们会将这些更新添加到共享版本控制系统中(如 GitHub、Bitbucket 或 AWS CodeCommit)。这些保存的更改被称为提交,每个提交都有一个相关的描述或消息来解释为什么要进行特定的更改。这些提交总结了所有变更的历史,以便其他贡献者可以理解对代码做了什么以及为什么。一旦创建了提交,开发人员就可以打开一个拉请求 ( PR )。PRs 是开发人员协作的核心,因为他们在团队成员之间就提议的变更展开讨论,并请求其他开发人员审查并将更新拉入他们的代码库分支。一旦这些添加被批准,它们就被合并到存储库的主分支中,以启动或触发更新的应用的构建。
注意
软件开发人员不会简单地向存储库添加随机特性或更新;他们必须首先在本地或基于云的开发环境中测试新代码,以验证新代码是否有效。这个过程通常被称为单元测试。
构建管道资产
管道的下一个阶段是编译或构建各种软件工件(及其依赖关系)的地方。从本质上来说,这些资产在高层次上是将源代码构件构建到特定于当前版本的资产中的结果,或者换句话说,是特定于管道的当前执行的资产。例如,构建阶段将 C++代码编译成发布二进制文件,或者构建阶段可用于构建 Docker 容器映像。
测试管道资产
一旦构建了管道资产,管道的下一个阶段不仅要测试这些资产的功能,还要测试它们是否适合到整体架构或应用中。正是在这个阶段,开发人员利用测试脚本、自动化测试,甚至测试架构(称为测试或 QA 环境】来执行系统测试。这一步的主要目标是验证构建的资产一旦被部署到生产环境中,将会正确运行。通过测试整个系统,应用开发人员可以确信,一旦部署到生产环境中,解决方案的整体完整性得到了维护。
批准发布
一旦测试了整个系统或应用的完整性,CI 阶段的最后一部分就是批准它投入生产。过程的这个阶段可以由一个人(或者团队)来批准测试的结果,或者在频繁的代码变更的情况下,可以是自动化的。
一旦发布被批准,管道的 CI 阶段就完成了,然后发布可以进入生产部署的 CD 阶段。让我们回顾一下裁谈会阶段需要什么。
介绍 CI/CD 的 CD 部分
管道的 CD 阶段只是 CI 阶段的延续,由四个单独的阶段组成,专注于生产应用的运营任务。构成 CI/CD 管道 CD 阶段的四个阶段如下:
- 资产部署
- 操作
- 监视
- 运营反馈 图 4.2 显示了这四个阶段的概况: ![Figure 4.2 – An overview of the stages in CD ]
图 4.2–CD 中各阶段的概述
让我们看看这些阶段需要什么。
将版本部署到生产环境中
当将构建并测试的软件部署到生产环境中时,该过程有两个主要部分。第一个组件是部署过程,而第二个组件是部署策略。
例如,一个部署策略可能包括将一个重复的应用部署到生产环境中,并在一段时间后,将新的使用请求重定向到新的版本,同时最终逐步淘汰旧的版本。这种策略通常被称为蓝/绿部署。
另一方面,部署过程是将新版本投入生产的底层机制。这一过程因正在部署的软件或编译资产的类型而异。例如,如果部署的资产是一个容器映像,那么部署过程可能涉及到通过容器编排解决方案(比如 Kubernetes)来下载和运行容器映像。
管理和监控解决方案
为了确保解决方案按预期方式运行,有多个任务通常在运营阶段执行,这些任务也可能与应用监控任务重叠。因此,通常情况下,运营和监控任务由基础架构或 IT 团队同时执行。例如,这些任务可能包括更新底层操作系统补丁,或者通过监控应用性能来确保体系结构自动扩展以应对使用量的增加。
生产反馈报告
反馈阶段也是管理和监控任务的延伸;然而,它还涉及解析各种日志和报告仪表板,以隔离生产应用中的任何故障、错误或问题。例如,这个阶段可能涉及从适用的日志中查找应用错误,并生成一个错误报告。然而,如果信息没有反馈给应用开发人员,简单地对错误进行编目是没有用的。
因此,CI/CD 流程不会在此阶段结束。因此,在下一节中,我们将了解如何使用该反馈报告来结束循环,并确保 CI/CD 流程名副其实。
结束循环
图 4.3 显示了为什么 CI/CD 方法对于将增量的、可靠的和频繁的软件代码变更部署到生产中是有效的: ![Figure 4.3 – Creating a continuous process ]
图 4.3–创建一个连续的过程
正如图 4.3 所强调的,向开发人员提供产品反馈,本质上是封闭循环,创建一个连续的过程,开发人员可以通过这个过程解决报告中的错误,修复源代码,并更新工件库。在更新工件存储库时,会触发 CI/CD 管道的新版本变更,从而将修复部署到产品中。
因此,正如您所看到的,CI/CD 方法本质上提供了一种将新软件、软件更新或软件修复部署到生产环境中的连续机制。此外,很明显,CI/CD 管道的成功实现需要多个不同的团队,从软件开发人员到基础设施和 it 团队。
这就引出了一个问题,为 ML 实现 CI/CD 方法会解决一开始强调的部署限制吗?
在下一节中,我们将通过探索 CI/CD 方法如何适应 ML 用例来回答这个问题。
通过 CI/CD 实现 ML 自动化
如果你还记得第一章 、*中的[、] B17649_01_ePub.xhtml##_idTextAnchor015 ![Figure 4.4 – A realistic overview of the ML process ]
图 4.4–ML 流程的真实概述
然而,由于本章的重点是解决典型的 ML 过程和 AutoML 方法的局限性,特别是在弥补模型部署的差距时,这些过程之间有几个相似之处。因此,如果您采用以部署为中心的方法(图 4.3 ),而不是以实验为中心的方法(图 1.2 ),那么将优化模型部署到产品中的过程与将软件代码变更部署到产品中的过程完全相同。
采取以部署为中心的方法
图 4.5 显示了如果我们使用软件发布 CI/CD 方法,对 ML 流程采取以部署为中心的方法,那么结果管道将会是什么样子: ![Figure 4.5 – Model deployment using CI/CD ]
图 4.5–使用 CI/CD 的模型部署
正如图 4.5 所示,通过将模型部署视为变更发布,我们可以使用 CI/CD 方法将过程自动化。为了进一步详细说明这是如何工作的,让我们回顾一下这个过程的每一步。
构建模型工件
有几个组件可以被认为是模型工件。例如,有算法代码本身,以及利用算法代码进行训练和评估的各种例程。因此,与处理软件代码发布的 CI/CD 管道不同,在 CI/CD 管道的 ML 版本中没有代码编译。
然而,我们可以将类似的方法应用于我们在 [第 3 章] B17649_03_ePub.xhtml##_idTextAnchor048)中使用的方法,通过自动运行实现复杂模型开发的自动化。通过创建一个包含相关模型工件的容器映像,我们可以train.py
文件来捕获模型训练和测试运行时。然后,我们构建了一个Dockerfile
深度学习容器来捕获图像构建指令,以便我们可以使用sm-docker-build
CLI ( 命令行界面
因此,通过将模型工件存储在管道存储库中,我们可以开始管道发布周期,并从模型工件编译或构建容器映像。
构建数据工件
准备训练数据并不是软件发布流程中的一个实际阶段。然而,如果我们将任务视为构建或编译适当的模型训练数据,并提供合适的运行时工件来预处理数据,那么数据构建任务就可以被认为是管道构建任务。
注意
您可能还记得上一节,当在源代码存储库中添加或更新代码时,会触发 CI/CD 发布管道。这一事实突出了使用 CI/CD 方法部署 ML 模型的潜在局限性。由于训练数据通常不被归类为源代码,更新原始数据或训练数据不会触发发布管道。
建筑模型
用正确的预处理数据以及正确的参数训练模型可以再次被视为构建或编译优化的模型。因此,通过改变我们对模型训练和优化的视角,就像数据处理步骤一样,通过提供合适的运行时工件来执行训练过程,我们可以将模型训练任务视为管道构建任务。
批准模型发布
正如软件发布管道一样,无论我们是批准一个用于生产的软件发布,还是评估一个经过训练的模型的性能,这两项任务本质上都是一样的。在经过训练的模型的情况下,根据业务标准对其性能进行评估,以确定它是否可以被视为生产级的。如果模型满足业务标准,它就可以发布到生产中。
将模型部署为 pagemaker 端点
一旦模型被评估并被批准用于生产,它就可以很容易地被部署为 SageMaker 托管的端点。SageMaker 端点本质上是一个端点地址,它可以表示多个模型,或者多个模型版本(称为变体)。这意味着 SageMaker 端点可以内在地支持蓝/绿部署策略。
将一个经过训练的模型的新版本发布到一个现有的生产端点意味着 SageMaker 将自动开始将新的请求重定向到新的模型版本,同时系统地逐步淘汰旧的模型。
因此,将 SageMaker 端点合并到 CI/CD 管道中为 ML 从业者提供了与软件工程师相同的部署策略。
管理 pagemaker 端点
将发布的模型部署为 SageMaker 托管端点的另一个令人信服的原因是,sage maker 端点是一个 AWS 托管服务的事实;因此,没有必要管理任何底层操作系统补丁。
此外,托管端点可以配置为根据使用请求的数量自动扩大和缩小。
因此,将模型部署任务卸载给 SageMaker 可以极大地减少生产中管理已部署模型的操作开销。
使用 Amazon SageMaker 模型监视器监视模型的性能
与使用日志、仪表板和报告向开发人员提供反馈的软件发布管道不同,SageMaker 端点可以集成到 Amazon SageMaker 模型监视器中,以自动验证生产模型是否正在执行其预期目的。 Amazon SageMaker Model Monitor 将生产模型的响应与基线进行统计比较,以自动确定它是否偏离了其预期目的。如果检测到这些约束违反中的任何一个,ML 从业者可以得到警告,以便在管道的下一个版本中解决它们,从而关闭反馈循环,并使整个部署过程连续进行。
注意
如果启用了端点数据捕获(https://docs . AWS . Amazon . com/sage maker/latest/DG/Model-Monitor-data-capture . html)并创建了一个基线(https://docs . AWS . Amazon . com/sage maker/latest/DG/Model-Monitor-create-baseline . html),则 Amazon SageMaker 模型监视器能够自动执行管道的监视任务。
正如您所看到的,通过使用以部署为中心的方法,可以使用 CI/CD 方法来解决一开始强调的模型部署限制。但是 ML 实验在这个方法论中处于什么位置呢?
在下一节中,我们将探讨如何将寻找最佳模型及其参数的过程整合到 CI/CD 管道中。
创建 MLOps 方法
在第一部分介绍 CI/CD 方法中,我注意到软件开发人员不仅仅是简单地向代码库中添加新特性或随机更新。他们必须执行单元测试,以确保在将更改部署到生产环境之前,更新能够正常工作。
这一结果符合执行 ML 实验的总体目标。ML 实验的目标是在将它部署到生产中之前,获得最佳候选模型及其相关参数。将 ML 实验整合到开发和运营中 DevOps 方法论是一个 MLOps 方法论的基础;图 4.6 提供了该过程的概述: ![Figure 4.6 – An MLOps process overview ]
图 4.6–MLOps 流程概述 图 4.6 清楚地显示了 ML 从业者如何采用两阶段方法,使用 MLOps 方法实现 ML 流程的自动化。通过使用 AutoML 方法来自动化 ML 实验,并生成最佳候选工件,可以将结果工件提交到源存储库中,以使用 CI/CD 管道触发生产级部署。
因此,现在我们有了关于 CI/CD 方法如何运作以及如何将 ML 集成到流程中的必要背景,我们现在可以将这些技术应用到年龄计算器用例中。然而,在开始动手示例之前,在下一节中,我们将回顾 AWS 为创建 CI/CD 管道提供的各种功能。
在 AWS 上创建 CI/CD 管道
AWS 提供了一整套开发人员工具,解决了托管代码、构建和部署 pipeline 资产的许多需求。为了在 AWS 上创建 CI/CD 管道,我们将利用 AWS 开发人员工具链中的三个主要服务。为了进一步简化管道的构建和自动化,我们将利用 AWS 开发套件中的两个附加服务。
注意
要了解更多关于 AWS 可用开发工具的信息,您可以参考产品页面(https://aws.amazon.com/products/developer-tools/)。
让我们回顾一下构成 CI/CD 管道的重要服务。
使用 AWS CI/CD 工具链
构成 CI/CD 渠道的三个核心组件如下:
- 存储各种管道工件的组件
- 构建各种管道资产的组件流程
- 自动化管道执行的组件
为了便于创建这三个核心组件,AWS 提供了专门的服务来匹配每个组件所需的功能,即:
- AWS 代码提交
- AWS 代码构建
- AWS 代码管道
虽然还有其他 CI/CD 管道组件和相关的 AWS 服务,但我们将重点关注这三个组件,为 ML 发布自动化提供必要的功能。
AWS 代码提交
code commit(https://aws.amazon.com/codecommit/)是一个基于云的源代码和版本控制服务。本质上,它是 GitHub 的 AWS 管理的替代品。我们将使用 CodeCommit 来存储所有不同的管道和 ML 模型工件。
注意
如果你不熟悉源代码和版本控制的概念,AWS 在他们的网站上提供了一个概述(https://aws.amazon.com/devops/source-control/)。
AWS 代码构建
CodeBuild(https://aws.amazon.com/codebuild/)是 CI/CD 管道的持续集成阶段的核心。该服务负责将各种工件编译或构建成可用的管道资产。在 ML 发布自动化的情况下,CodeBuild 构建所需的模型训练和服务运行时,以及执行数据处理、模型训练和模型评估过程。
AWS 代码管道
code pipeline(https://aws.amazon.com/codepipeline/)处理 CI/CD 管道的持续部署阶段。该服务包含管道的结构,并负责将经过训练的模型作为 SageMaker 托管的端点发布到产品中的自动化任务。
现在我们已经对核心 AWS 服务及其用途有了一个简要的概述,在下一节中,我将重点介绍一些额外的 AWS 功能来构建服务基础设施。
使用附加的 AWS 开发工具
我们将利用另外两个 AWS 开发工具,虽然这些服务对 CI/CD 实现的成功并不重要,但它们使开发整个解决方案变得更加容易。例如,我们将使用 AWS 云开发套件 ( CDK )来编写整个解决方案。因此,不仅管道工件作为代码获得和管理,管道本身和相关的 AWS 基础设施也是如此。这使得整个解决方案成为一个云原生应用。
注意
在后面的章节中,你将会看到将整个解决方案创建为一个云原生应用如何进一步简化 ML 自动化的端到端流程。正如你将看到的,CDK 框架(https://aws.amazon.com/cdk/)将在加强这一进程中发挥重要作用。如果你不熟悉使用 CDK 来编写云原生解决方案,强烈建议阅读 https://docs.aws.amazon.com/cdk/api/latest/的 CDK 文档(),参考 https://github.com/aws-samples/aws-cdk-examples 的 CDK GitHub 资源库()中的示例,并查看 AWS CDK 官方研讨会(【https://cdkworkshop.com/】)。
为了确保实践示例的一致性和易用性,我们将利用 AWS 基于云的 I DE 服务,名为cloud 9(https://AWS . Amazon . com/cloud 9/)。虽然可以在本地 IDE 上运行实践示例,但 Cloud9 已经预装了所有相关的工具、编程库和实用程序。
我们现在对 CI/CD 流程有了一个概述,它如何应用于将 ML 模型自动发布到产品中,以及我们可以用来将解决方案构建为云原生应用的 AWS 服务。因此,让我们通过一个实际操作的例子将我们所学的知识应用到年龄计算器用例中。
为生产 ML 模型创建云原生 CI/CD 管道
作为对成功实现针对年龄计算器用例的 CI/CD 管道的指导,我们将执行以下任务:
- 准备开发环境
- 创建管道工件存储库
- 开发应用构件
- 部署管道应用
- 创建 ML 模型工件
- 执行自动化 ML 模型部署
此外,在我们使用前面的步骤构建解决方案时,我将把各种任务分成两个单独的类别。一个类别将围绕应用开发团队执行的各种任务,另一个类别将包含通常由 ML 从业者执行的任务。我这样做的主要目的是强调跨职能团队的角色。 ML 从业者和 DevOps 工程团队之间的有效协调为成功的模型部署奠定了基础。这种在基础层次上共同工作的过程,从而建立一个跨职能的团队,是成功的模型部署的主要成功标准。
在本节结束时,您将看到,决定生产级 ML 模型成功实现的不仅仅是所使用的工具链,甚至是管道本身的执行;相反,关键要素是一个跨职能团队。
现在,让我们从创建 Cloud9 开发环境开始。
小费
以下代码示例的参考文件可以在本章的配套 GitHub 资源库(https://GitHub . com/packt publishing/Automated-Machine-Learning-on-AWS/tree/main/chapter 04/)中找到。
准备开发环境
首先,我们将从 DevOps 工程师的角度出发,通过为应用开发准备 Cloud9 环境来看待这项任务。以下步骤将引导您完成这一过程:
- 登录你一直使用的 AWS 账户,打开你支持的 AWS 地区的 Cloud9 管理控制台(https://console.aws.amazon.com/cloud9)。
- 点击创建环境按钮,创建一个 Cloud9 环境。
- 出现提示时,提供名称和可选描述。然后,点击下一步按钮。图 4.7 显示了一个命名环境的例子: ![Figure 4.7 – Naming the Cloud9 environment ]
图 4.7–命名 Cloud9 环境
- 在
t3.small
实例上,它不符合空闲层的条件。 - On the Review page, confirm the settings and click Create environment. After a few minutes, you will be redirected to the IDE web interface. 小费 为了熟悉 IDE 以及如何使用各种面板,请查看 AWS 网站上的基本教程文档(https://docs . AWS . Amazon . com/cloud 9/latest/user-guide/tutorial-tour-IDE . html)。
- 既然 Cloud9 workspace 已经准备好了,我们将需要提供对我们将要使用的各种 AWS 服务的适当的访问。要配置权限,点击 IDE 右上角的 A 图标并选择 Manage EC2 Instance 。图 4.8 显示了流程的一个例子: ![Figure 4.8 – Manage EC2 Instance ]
图 4.8–管理 EC2 实例
- 将打开一个新的 web 浏览器选项卡,将您带到 EC2 管理控制台,显示 Cloud9 EC2 实例。通过点击实例名称旁边的复选框来选择您的 Cloud9 实例。然后点击动作按钮,从下拉菜单中选择安全选项。安全菜单展开后,选择修改 IAM 角色。图 4.9 显示了扩展菜单设置的示例: ![Figure 4.9 – The EC2 instance security menus ]
图 4.9–EC2 实例安全菜单
- 当修改 IAM 角色页面打开时,单击创建新的 IAM 角色链接,在新的浏览器选项卡中打开 IAM 管理控制台。图 4.10 显示了修改 IAM 角色页面示例: ![Figure 4.10 – Modify IAM role ]
图 4.10-修改 IAM 角色
- 在 IAM 管理控制台的中,点击创建角色按钮来创建一个新的实例管理员角色。
- 在创建角色页面,选择常用用例部分下的 EC2 ,然后点击下一步:权限按钮。图 4.11 显示了选择 EC2 用例的示例: ![Figure 4.11 – The EC2 common use case ]
图 4.11–EC2 常见用例
- 使用
administrator
中提供的搜索栏作为搜索词。您将看到列出了包含administrator
的各种策略。选中管理员访问旁边的复选框,然后点击下一步:标签按钮。图 4.12 显示了选择管理员访问策略的示例: ![Figure 4.12 – Selecting the AdministratorAccess policy ]
图 4.12–选择管理员访问策略
- 点击下一步:查看按钮,跳过添加标签(可选)部分。
- 在审核页面,输入一个合适的角色名称,点击创建角色按钮。图 4.13 显示了一个提供角色名称的例子: ![Figure 4.13 – Providing a role name ]
图 4.13–提供角色名称
- 一旦创建了角色,您可以关闭 IAM 控制台并从步骤 8 返回到修改 IAM 角色选项卡。
- 点击刷新图标,使用下拉菜单选择您在步骤 13 中创建的角色。图 4.14 显示了页面外观的一个例子: ![Figure 4.14 – Selecting the IAM role ]
图 4.14–选择 IAM 角色
- 点击保存按钮。
- 返回到显示 Cloud9 工作区的浏览器选项卡,点击右上角的齿轮图标,连接新创建的角色。
- 在工作区首选项选项卡中,选择 AWS 设置选项,禁用 AWS 管理临时凭证开关。图 4.15 显示了最终 AWS 设置页面的示例: ![Figure 4.15 – Disabling AWS managed temporary credentials ]
图 4.15–禁用 AWS 管理的临时凭证
既然已经建立了开发环境,我们可以继续下一个任务,创建管道工件存储库。
创建管道工件库
使用开发环境,我们现在将创建一个 CodeCommit 存储库来存储各种管道,并最终存储 ML 模型工件。尽管创建 CodeCommit 存储库有多种方法,但我们将使用 AWS CLI,它已经在 Cloud9 workspace 中安装和配置好了。以下步骤将引导我们完成这一过程:
- 使用终端窗格(Cloud9 工作区的底部),运行以下 CLI 命令以确保 CLI 区域设置正确。确保将
<REGION>
替换为您当前使用的 AWS 区域:$ aws configure set region <REGION>
- 使用以下命令创建一个名为
abalone-cicd-pipeline
的 CodeCommit 存储库:$ aws codecommit create-repository --repository-name abalone-cicd-pipeline --repository-description "Automated ML on AWS using CI/CD"
- 接下来,我们捕获新创建的存储库的 URL,以便克隆它。运行以下命令创建
CLONE_URL
参数:$ CLONE_URL=$(aws codecommit get-repository --repository-name abalone-cicd-pipeline --query "repositoryMetadata.cloneUrlHttp" --output text)
- 运行下面的命令,在 Cloud9 工作区中本地克隆空的存储库:
$ git clone $CLONE_URL
现在,您应该会在 Cloud9 工作区的左侧导航窗格中看到abalone-cicd-pipeline
文件夹。现在我们有了项目存储库,我们可以继续下一个任务,构建应用工件。
开发应用工件
在我们开始编写整个解决方案之前,我们需要配置应用环境。下一组步骤将配置环境以使用 AWS CDK。
创建和配置 CDK 项目
如果参考 cdk 文档(https://docs . AWS . Amazon . com/CDK/latest/guide/getting _ started . html),在使用 CDK 之前需要配置某些先决条件。幸运的是,AWS 通过在 Cloud9 IDE 中预配置这些先决条件来提供帮助。因此,在构建应用之前,我们需要做的就是更新到 CDK 的最新版本,并按照以下步骤设置环境变量:
注意
在撰写本文时,AWS CDK 的最新版本是 2.3.0 (build beaa5b2) 。为了维护本例中代码的功能,我们将使用 2.3.0 版的 CDK:
- 在构建编码的 CDK 应用之前,运行下面的命令来确保我们安装了一致版本的 CDK:
$ npm install -g aws-cdk@2.3.0 --force
- Run the following command to confirm that version 2.3.0 is the current version of the CDK:
注意 请务必记住 CDK 的版本,因为在后面的步骤中将需要此信息。$ cdk --version
- 接下来,我们运行以下命令集来配置一些 CDK 环境变量,比如我们的 AWS 帐户和我们当前使用的 AWS 区域:
$ export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query "Account" --output text) $ echo "export CDK_DEFAULT_ACCOUNT=$(aws sts get-caller-identity --query "Account" --output text)" >> ~/.bashrc $ export CDK_DEFAULT_REGION=$(aws configure get region) $ echo "export CDK_DEFAULT_REGION=$(aws configure get region)" >> ~/.bashrc
- 创建一个空的 CDK 项目,并通过运行以下命令将 Python 指定为项目的编程语言:
$ cd abalone-cicd-pipeline && cdk init --language python
- 由于 CDK Python 项目将与工件存储库接口,我们可以使用以下命令为项目创建主分支:
$ git add –A $ git commit -m "Started CDK Project" $ git branch main $ git checkout main
- 接下来,我们可以通过运行以下命令来配置 Python 环境:
$ source .venv/bin/activate $ python -m pip install --upgrade pip pylint boto3 $ pip install -r requirements.txt
随着 CDK 项目的创建和配置,我们现在可以继续构建应用构件了。
创建应用
既然我们已经准备好了 CDK 项目的环境,在这个阶段,跨团队的协作对项目的持续成功至关重要。作为应用开发人员,我们现在需要与 ML 从业者团队合作,评估应用的以下关键元素:
- 我们需要了解最终的应用是什么样的。在这种情况下,最终的应用将是一个生产级的 ML 模型,作为 SageMaker 托管的端点进行部署。
- 我们还需要理解 ML 从业者团队将会贡献什么作为他们的管道工件。在这种情况下,ML 从业者团队将交付一个客户 SageMaker 容器映像,例如我们在第三章中使用的容器映像。
- 我们将需要理解如何构建或编译这些工件。本质上,我们需要理解构建运行时逻辑需要什么。在这种情况下,ML 从业者将希望使用 SageMaker 来处理训练数据,训练 ML 模型,并根据用例的业务标准评估其性能。
- 我们需要理解 ML 从业者工件需要什么依赖关系。例如,模型数据处理和训练组件将需要访问原始源数据。
- 同样重要的是,我们需要评估相关的 AWS 服务以及创建和更新应用工件的各个团队需要什么样的安全性和访问需求。
一旦我们捕获、审查了这些需求,并且所有团队成员都签署了这些需求,我们就可以继续构建应用了。我们将要开发的整个应用的第一部分是最后一部分,SageMaker 托管端点。
注意
通过关注管道的最后一部分——在本例中,是生产级模型——来开始应用开发过程,这似乎是违反直觉的。在大多数情况下,通过关注结果来开始自动化工作流的开发是一个很好的实践。通过这种方式,您可以从最终结果开始逆向工作,理解并开发最终产生最终结果的必要代码。
编码 pagemaker 端点
由于这可能是你第一次使用 CDK,不同构造的代码已经在本章的配套 GitHub 库中为你提供了。使用以下步骤将 SageMaker 端点构造添加到 CDK 环境中:
- 使用 cloud 9 工作区内的终端窗口,运行以下命令来克隆配套的 GitHub 存储库:
$ cd ~/environment/ && git clone https://github.com/PacktPublishing/Automated-Machine-Learning-on-AWS src
- 使用以下命令将预建的
abalone_endpoint_stack.py
文件复制到abalone_cicd_pipeline
文件夹:$ cd ~/environment/abalone-cicd-pipeline $ cp ~/environment/src/Chapter04/cdk/abalone_endpoint_stack.py abalone_cicd_pipeline/
- 使用 Cloud9 工作区的左侧导航面板,展开
abalone-cicd-pipeline
文件夹,然后展开abalone_cicd_pipeline
文件夹以显示abalone_endpoint_stack.py
文件。 - 双击
abalone_endpoint_stack.py
文件,这样我们可以查看代码。
既然abalone_endpoint_stack.py
文件已经在 Cloud9 编辑器中打开,我们就可以遍历代码来回顾我们是如何构建托管端点的。打开文件后,您将看到的第一件事是,我们需要为我们的构造和aws_sagemaker
模块导入必要的 CDK 模块。然后我们为EndpointStack()
初始化一个 Python 类作为cdk.Stack
构造;因此,我们实际上是用相关的 SageMaker 端点资源实例化了一个新的 CloudFormation 堆栈。
注意
如果您不熟悉什么是 CloudFormation 堆栈,或者 CDK 如何将 AWS 资源初始化为堆栈构造的组件,您可以参考 AWS 文档了解堆栈(https://docs . AWS . Amazon . com/AWS cloud formation/latest/user guide/stacks . html)和构造(https://docs . AWS . Amazon . com/CDK/latest/guide/constructs . html)。
接下来,我们为 CloudFormation 堆栈定义参数,比如存放我们的数据的 S3 桶的名称或bucket_name
参数。正如你将在本章后面看到的,这些参数将作为流水线执行的输出提供给堆栈。
在声明了各种 CloudFormation 堆栈参数之后,我们使用来自aws_sagemaker
库的CfnModel()
模块实例化了训练模型的表示。在这里,我们定义了必要的参数来告诉 SageMaker 关于训练好的模型,以便它可以作为 SageMaker 端点来托管。
注意
关于表示一个训练好的模型所需的不同参数的更多信息,你可以参考CfnModel
文档(https://docs . AWS . Amazon . com/CDK/API/latest/python/AWS CDK . AWS sage maker/cfn model . html)。
在定义模型之后,我们指定实际托管训练模型所需的必要配置参数。这是使用来自aws_sagemaker
库的CfnEndpointConfig()
模块完成的。在这里,我们定义托管模型的计算资源的类型和数量。您可以看到,我们还指定了data_capture_config
参数来告诉 SageMaker 在哪里存储进入托管模型的推理请求负载,以及来自托管模型的推理响应输出。通过这种方式,我们实际上记录了端点的使用情况,这样我们就可以在生产中监控模型。
最后,我们使用CfnEndpoint()
模块定义端点本身。这里,我们为端点定义一个名称,并指定要使用的端点配置。
接下来,我们将构建运行时逻辑,以从管道执行中检索特定的CfnParamater()
值。
配置部署参数
为了向EndpointStack()
构造提供所需的CfnParamater()
参数,如前面的步骤所示,我们需要在一个名为params.json
的 JSON 文件中捕获和存储管道执行参数。您将会看到,一旦我们定义了实际的管道结构,这个文件就会作为端点 CloudFormation 堆栈的输入。以下步骤显示了如何复制运行时脚本以供查看:
- 使用 Cloud9 工作区内的终端,通过运行以下命令创建一个文件夹来存储预构建的脚本:
$ cd ~/environment/abalone-cicd-pipeline/ $ mkdir –p artifacts/scripts/ $ cp ~/environment/src/Chapter04/scripts/deploy.py artifacts/scripts/
- 使用 Cloud9 工作区的左侧导航面板,展开新创建的
artifacts
文件夹。 - 现在,展开
scripts
文件夹,双击deploy.py
进行查看。
随着deploy.py
文件在 Cloud9 编辑器面板中打开,我们可以回顾一下如何从正在运行的管道中获取执行参数并创建params.json
文件。
在为脚本导入必要的 Python 库之后,您将从下面的代码片段中看到,在我们设置了日志记录并配置了全局环境参数之后,我们为 Python 配置了 AWS SDK 以访问 SageMaker 和 CodePipeline SDK 客户端:
...
logger = logging.getLogger()
logging_format = "%(levelname)s: [%(filename)s:%(lineno)s] %(message)s"
logging.basicConfig(format=logging_format, level=os.environ.get("LOGLEVEL", "INFO").upper())
codepipeline_client = boto3.client("codepipeline")
sagemaker_client = boto3.client("sagemaker")
pipeline_name = os.environ["PIPELINE_NAME"]
model_name = os.environ["MODEL_NAME"]
role_arn = os.environ["ROLE_ARN"]
...
设置日志记录对于我们验证脚本是如何执行的,并确保它正确运行是很重要的,如果不是,日志记录错误将允许我们进行故障排除和调试。
接下来,我们创建了两个 Python 函数,即get_execution_id()
和get_model_artifact()
函数。在__main__
程序中使用这些函数来从 CodePipeline 获得唯一的管道执行 ID,以及从 SageMaker 模型注册中心获得经过训练的 ML 模型的名称。
然后,__main__
程序获取由get_execution_id()
和get_model_artifact()
函数返回的参数来填充params.json
文件。我们将使用管道执行 ID 进行资产版本控制。正如您将在后面看到的,我们将把这个 ID 附加到各种资产上,特别是发布版本,以便从源代码到发布版本跟踪模型的血统。
既然我们已经有了查询管道所必需的 Python 代码,并且已经检索了将它们提供给部署构造所必需的执行参数,那么我们基本上已经创建了运行管道的持续部署阶段所必需的工件。接下来,我们可以处理管道的持续集成阶段所需的工件。
配置构建工件
当我们继续逆向工作的方法时,在下一步,我们将创建构建、训练和评估 ML 模型所需的工件。以下步骤将带您了解如何做到这一点:
- 使用 Cloud9 工作区内的终端,运行以下命令将预构建的
build.py
脚本复制到scripts
文件夹:$ cd ~/environment/abalone-cicd-pipeline/ $ cp ~/environment/src/Chapter04/scripts/build.py artifacts/scripts/
- 使用 Cloud9 工作区的左侧导航面板,双击
build.py
进行查看。
正如您在build.py
文件中看到的,deploy.py
脚本导入了必要的 Python 库,设置了日志记录,并且还为定义了相同的get_execution_id()
和get_model_artifact()
Python 函数。我们还创建特定的 Python 函数来启动 ML 过程的适当阶段。例如,为了训练 ML 模型,我们调用handle_training()
函数。这个函数对 SageMaker 进行必要的 API 调用,以启动训练作业。正如您所看到的,我们对预处理训练和验证数据集的handle_data()
函数以及评估已训练的 ML 模型性能的handle_evluation()
函数应用了相同的方法。
我们还创建了一个名为handle_status()
的新函数,它充当 ML 过程中每一步的包装器。下面的代码片段展示了handle_status()
Python 函数:
...
def handle_status(task=None, job_name=None):
if task == "preprocess" or task == "evaluate":
status = sagemaker_client.describe_processing_job(ProcessingJobName=job_name)["ProcessingJobStatus"]
while status == "InProgress":
time.sleep(60)
logger.info(f"Task: , Status: {status}")
status = sagemaker_client.describe_processing_job(ProcessingJobName=job_name)["ProcessingJobStatus"]
return status
elif task == "train":
status = sagemaker_client.describe_training_job(TrainingJobName=job_name)["TrainingJobStatus"]
while status == "InProgress":
time.sleep(60)
logger.info(f"Task: , Status: {status}")
status = sagemaker_client.describe_training_job(TrainingJobName=job_name)["TrainingJobStatus"]
return status
...
正如您从代码片段中看到的,根据管道执行的当前阶段,由参数task
表示,handle_status()
函数将调用适当的句柄函数来获取与 ML 流程的特定任务或阶段相关联的 SageMaker 作业的状态。例如,为了训练 ML 模型,handle_status()
函数从task
参数中确定它需要获得 SageMaker 训练作业的状态,并记录它拥有的任务是当前正在运行还是正在进行中。
最后,我们有如下代码片段所示的__main__
函数,作为脚本的主要执行点:
...
if __name__ == "__main__":
task = sys.argv[1]
execution_id = get_execution_id(name=pipeline_name, task=task)
logger.info(f"Executing task")
if task == "preprocess":
job_name = handle_data(model_name=model_name, execution_id=execution_id)
status = handle_status(task=task, job_name=job_name)
elif task == "train":
job_name = handle_training(model_name=model_name, execution_id=execution_id)
status = handle_status(task=task, job_name=job_name)
elif task == "evaluate":
job_name = handle_evaluation(model_name=model_name, execution_id=execution_id)
status = handle_status(task=task, job_name=job_name)
else:
error = "Invalid argument: Specify 'preprocess', 'train' or 'evaluate'"
logger.error(error)
sys.exit(255)
if status == "Completed":
logger.info(f"Task: , Final Status: {status}")
sys.exit(0)
else:
error = f"Task: {task}, Failed! See CloudWatch Logs for further information"
logger.error(error)
sys.exit(255)
...
从前面的代码片段中可以看出,__main__
函数将当前的管道阶段作为输入,并为该阶段调用适当的处理函数。例如,如果管道当前正在执行训练阶段,__main__
函数根据任务输入确定它需要调用handle_training()
函数来启动 SageMaker 训练作业,然后调用handle_status()
函数来跟踪和管理该训练作业的执行。
注意
有关创建 SageMaker 处理作业的各种参数的更多信息,请参考 AWS SDK for Python 文档(https://boto 3 . Amazon AWS . com/v1/documentation/API/latest/reference/services/sage maker . html # sage maker。Client.create_processing_job)和 SageMaker 训练作业(https://boto 3 . Amazon AWS . com/v1/documentation/API/latest/reference/services/sage maker . html # sage maker。Client.create_training_job)。
虽然在这一点上看起来不太直观,但是通过创建build.py
和deploy.py
脚本,我们已经产生了基本的机制,通过这些机制,管道将执行持续集成和持续部署过程。例如,通过执行build.py
脚本,管道可以构建、训练和评估生产级 ML 模型。并且,通过执行deploy.py
脚本,管道可以处理来自集成的相关参数,通过端点 CDK 构造将模型部署到生产中。
然而,在进入下一章之前,将当前正在进行的工作提交给源代码库是一个很好的实践。以下步骤将带您了解如何检查您的进度:
- 使用 Cloud9 工作区内的终端,运行以下命令,将我们所做的更改添加到工作目录:
$ cd ~/environment/abalone-cicd-pipeline/ $ git add -A
- 现在,运行命令将这些更改提交到存储库历史:
$ git commit -m "Checkpoint"
- 最后,我们可以通过运行下面的命令将变更推送到源代码库:
$ git push --set-upstream origin main
因此,现在这些内在的工件已经被创建并提交到存储库中,我们可以在下一章继续开发管道本身。
总结
在这一章中,我们向您介绍了 CI/CD 流程的概念,这是一种缩小构建生产级 ML 和将模型投入生产之间差距的方法。利用这种方法,ML 从业者不仅仅是将训练好的模型交给平台团队,而是将模型工件集成到整个过程中。
虽然我们还没有展示 ML 从业者如何将这些模型工件贡献到过程中,但是我们已经通过引入和建立 AWS CDK 项目建立了一个编码过程的模式。通过使用 CDK,我们实际上演示了一种逆向工作的方法,即工程团队如何将一个经过训练的模型部署为 SageMaker 托管的端点 CDK 构造。我们还展示了工程团队如何构建基本的机制,这些机制将最终自动地将模型训练和评估程序集成到流程中。
在下一章中,我们将继续构建 CI/CD 管道,添加模型工件,并将训练好的模型自动部署到生产中。
文章列表
- AWS自动化机器学习-一、AWS 上的自动化机器学习入门
- AWS自动化机器学习-七、使用 AWS 步骤函数构建 ML 工作流
- AWS自动化机器学习-三、使用 AutoGluon 技术自动化复杂的模型开发
- AWS自动化机器学习-九、使用 Amazon Managed Workflows 为 Apache AirFlow 构建 ML 工作流
- AWS自动化机器学习-二、使用 SageMaker 自动驾驶器自动化机器学习模型开发
- AWS自动化机器学习-五、自动化 ML 模型的持续部署
- AWS自动化机器学习-八、使用 Apache Airflow 实现机器学习过程的自动化
- AWS自动化机器学习-六、使用 AWS 步骤函数自动化机器学习过程
- AWS自动化机器学习-十、机器学习软件开发生命周期(MLSDLC)简介
- AWS自动化机器学习-十一、MLSDLC 的持续集成、部署和训练
- AWS自动化机器学习-四、机器学习的持续集成和持续交(CI/CD)
- AWS自动化机器学习-第一部分:自动机器学习过程和 AWS 上的 AutoML 的基础知识
- AWS自动化机器学习-第三部分:优化以源代码为中心的自动化机器学习方法
- AWS自动化机器学习-第二部分:通过持续集成和持续交付(CI/CD)实现机器学习过程的自动化
- AWS自动化机器学习-第五部分:自动化 AWS 上的端到端生产应用
- AWS自动化机器学习-第四部分:优化以数据为中心的自动化机器学习方法
- AWS自动化机器学习-零、前言