机器学习解决方案架构手册第二版-二-

73 阅读1小时+

机器学习解决方案架构手册第二版(二)

原文:annas-archive.org/md5/0af95f3eb3657d22b97e00830e661a6d

译者:飞龙

协议:CC BY-NC-SA 4.0

第六章:Kubernetes 容器编排基础设施管理

虽然为简单的机器学习任务建立个人使用的本地数据科学设置可能看起来很简单,但为多个用户创建一个强大且可扩展的数据科学环境(满足多样化的机器学习任务并有效跟踪机器学习实验)则面临着重大挑战。为了克服大量用户带来的可扩展性和控制挑战,公司通常实施机器学习平台。构建机器学习平台的方法有很多,包括使用开源技术自行构建或使用完全托管的云机器学习平台。

在本章中,我们将探讨开源选项,特别是 Kubernetes,这是一个不可或缺的开源容器编排平台,它是构建开源机器学习平台的关键基础。Kubernetes 提供了丰富的功能,能够无缝管理和编排大规模容器。通过利用 Kubernetes,组织可以高效地部署和管理机器学习工作负载,确保高可用性、可扩展性和资源利用率优化。

我们将深入研究 Kubernetes 的核心概念,了解其网络架构和基本组件。此外,我们还将探索其强大的安全特性和细粒度的访问控制机制,这对于保护机器学习环境和敏感数据至关重要。通过实际练习,你将有机会构建自己的 Kubernetes 集群,并利用其力量部署容器化应用程序。

具体来说,我们将涵盖以下主题:

  • 容器简介

  • Kubernetes 概述和核心概念

  • Kubernetes 网络

  • Kubernetes 安全性和访问控制

  • 实践实验室 - 在 AWS 上构建 Kubernetes 基础设施

技术要求

在本章的实践部分,你将继续使用 AWS 账户中的服务。我们将使用多个 AWS 服务,包括 AWS 弹性 Kubernetes 服务EKS)、AWS CloudShell 和 AWS EC2。本章中使用的所有代码文件都位于 GitHub 上:github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/tree/main/Chapter06

容器简介

要理解 Kubernetes,我们首先需要了解容器,因为它们是 Kubernetes 的核心构建块。容器是一种操作系统虚拟化形式,并且是软件部署和基于微服务架构的现代软件的非常流行的计算平台。容器允许您将计算机软件打包并运行,同时具有隔离的依赖关系。与 Amazon EC2 或VMware虚拟机等服务器虚拟化相比,容器更轻量级、更便携,因为它们共享相同的操作系统,并且每个容器中不包含操作系统镜像。每个容器都有自己的文件系统、共享的计算资源以及运行在其内部的自定义应用程序的进程空间。

容器技术的概念可以追溯到 20 世纪 70 年代的chroot 系统Unix Version 7。然而,在接下来的二十年里,容器技术在软件开发社区中并没有引起太多关注,一直处于休眠状态。虽然它在 2000 年到 2011 年期间取得了一些进展,但直到 2013 年Docker的引入才使容器技术迎来了复兴。

您可以在容器内运行各种应用程序,例如数据处理脚本等简单程序或数据库等复杂系统。以下图表说明了容器部署与其他类型部署的不同之处。在裸金属部署中,所有不同的应用程序共享相同的宿主操作系统。如果宿主操作系统出现问题,所有应用程序都会在同一台物理机器上受到影响。

在虚拟化部署中,多个虚拟操作系统可以共享相同的宿主操作系统。如果一个虚拟操作系统出现问题,只有在该虚拟操作系统上运行的应用程序会受到影響。每个虚拟操作系统都会有一个完整的安装,因此会消耗大量资源。在容器部署中,容器运行时在单个宿主操作系统上运行,允许共享一些公共资源,同时仍然为运行不同应用程序的不同环境提供隔离。容器比虚拟操作系统轻得多,因此资源效率更高,速度更快。请注意,容器运行时也可以在虚拟化环境的虚拟操作系统上运行,以托管容器化应用程序:

图 6.1 – 裸金属、虚拟化和容器部署之间的差异

图 6.1:裸金属、虚拟化和容器部署之间的差异

容器被打包成 Docker 镜像,这些镜像包含了运行容器及其中的应用程序所必需的所有文件(例如安装文件、应用程序代码和依赖项)。构建 Docker 镜像的一种方法就是使用Dockerfile – 这是一个纯文本文件,它提供了如何构建 Docker 镜像的规范。一旦创建了 Docker 镜像,它就可以在容器运行时环境中执行。

以下是一个示例Dockerfile,用于构建基于Ubuntu操作系统(FROM指令)的运行环境,并安装各种Python包,如python3numpyscikit-learnpandasRUN指令):

FROM ubuntu:20.04
ENV DEBIAN_FRONTEND=noninteractive
RUN apt-get update && apt-get install -y --no-install-recommends \
wget \         
python3-pip \         
python3-dev \         
build-essential \         
libffi-dev \         
libssl-dev \         
nginx \         
ca-certificates \    
&& rm -rf /var/lib/apt/lists/*
RUN pip --no-cache-dir install numpy scipy scikit-learn pandas flask unicor 

要从此Dockerfile构建 Docker 镜像,你可以使用Docker build - < Dockerfile命令,这是一个作为 Docker 安装的一部分提供的实用工具。

现在我们已经了解了容器,接下来,让我们深入了解 Kubernetes。

Kubernetes 及其核心概念概述

在计算环境中手动管理和编排少量容器和容器化应用程序相对容易管理。然而,随着容器和服务器数量的增加,这项任务变得越来越复杂。Kubernetes 应运而生,这是一个专门设计来应对这些挑战的强大开源系统。Kubernetes(通常简称为 K8s,由将“ubernete”替换为数字 8 而来)首次于 2014 年推出,为在服务器集群中高效管理大规模容器提供了一个全面的解决方案。

Kubernetes 遵循分布式架构,由一个主节点和服务器集群内的多个工作节点组成。在这里,服务器集群指的是 Kubernetes 管理的机器和资源集合,而节点是集群中的单个物理或虚拟机。

主节点,通常被称为控制平面,在管理整个 Kubernetes 集群中扮演主要角色。它接收有关内部集群事件、外部系统和第三方应用程序的数据,然后处理这些数据,并据此做出和执行决策。它由四个基本组件组成,每个组件在整体系统中都扮演着独特的角色:

  • API 服务器:API 服务器充当与 Kubernetes 集群所有交互的中心通信枢纽。它提供了一个 RESTful 接口,用户、管理员和其他组件可以通过该接口与集群交互。API 服务器处理请求的认证、授权和验证,确保对集群资源的访问既安全又受控。

  • 调度器:调度器组件负责确定工作负载或 Pod 在集群内可用工作节点中的最佳放置位置。

  • 控制器:控制器管理器负责监控集群的整体状态,并管理各种后台任务以维护所需的系统状态。

  • etcd:etcd 是一个分布式键值存储,作为集群的可靠数据存储,确保对关键配置和状态信息的持续和一致访问。它存储集群的当前状态、配置细节和其他必要数据,为整个系统提供可靠的真实来源。

最后,工作节点是运行容器化工作负载的机器。

下图展示了 Kubernetes 集群的核心理念组件:

图 6.2 – Kubernetes 架构

图 6.2:Kubernetes 架构

主节点暴露了 API 服务器 层,它允许对集群进行程序化控制。一个 API 调用的例子可能是将一个网络应用程序部署到集群中。控制平面还跟踪和管理所有配置数据在 etcd 中,它负责存储所有集群数据,例如要运行的容器镜像数量、计算资源规范以及运行在集群上的网络应用程序的存储卷大小。Kubernetes 使用 控制器 来监控 Kubernetes 资源当前的状态,并采取必要的行动(例如,通过 API 服务器请求更改)将当前状态移动到所需状态,如果两个状态之间存在差异(例如运行容器的数量差异),则进行操作。主节点中的控制器管理器负责管理所有的 Kubernetes 控制器。Kubernetes 随带一套内置控制器,例如 调度器,它负责在出现更改请求时将 Pods(部署的单位,我们将在后面详细讨论)调度到工作节点上。

其他例子包括 作业控制器,它负责运行和停止一个或多个 Pod 以完成任务,以及 部署控制器,它负责根据部署清单部署 Pods,例如网络应用程序的部署清单。

要与 Kubernetes 集群控制平面交互,你可以使用 kubectl 命令行工具、Kubernetes Python 客户端(github.com/kubernetes-client/python),或者直接通过 RESTful API 访问。你可以在 kubernetes.io/docs/reference/kubectl/cheatsheet/ 找到支持的 kubectl 命令列表。

Kubernetes 架构的核心由几个基本的技术概念构成。这些概念对于理解和有效地使用 Kubernetes 是必不可少的。让我们详细看看一些关键概念。

命名空间

命名空间将工作机器集群组织成虚拟子集群。它们被用来提供不同团队和项目拥有的资源的逻辑分离,同时仍然允许不同命名空间之间的通信。命名空间可以跨越多个工作节点,并且可以用来将一组权限分组在单个名称下,以便授权用户访问命名空间中的资源。可以对命名空间实施资源使用控制,例如 CPU 和内存资源的配额。命名空间还使得当资源位于不同的命名空间中时,可以以相同的名称命名资源,以避免命名冲突。默认情况下,Kubernetes 中有一个 default 命名空间。根据需要,你可以创建额外的命名空间。如果没有指定命名空间,则使用默认命名空间。

Pod

Kubernetes 以一个称为 Pod 的逻辑单元来部署计算。所有 Pod 必须属于一个 Kubernetes 命名空间(无论是默认命名空间还是指定的命名空间)。一个或多个容器可以被组合成一个 Pod,并且 Pod 中的所有容器作为一个单一单元一起部署和扩展,并共享相同的环境,例如 Linux 命名空间和文件系统。每个 Pod 都有一个唯一的 IP 地址,该地址由 Pod 中的所有容器共享。Pod 通常作为工作负载资源创建,例如 Kubernetes Deployment 或 Kubernetes Job。

图 6.3 – 命名空间、Pod 和容器

图 6.3:命名空间、Pod 和容器

前面的图示展示了 Kubernetes 集群中命名空间、Pod 和容器之间的关系。在这个图中,每个命名空间包含其自己的 Pod 集合,并且每个 Pod 可以包含一个或多个在其中运行的容器。

Deployment

Kubernetes 使用 Deployment 来创建或修改运行容器化应用程序的 Pod。例如,要部署一个容器化应用程序,你需要创建一个配置清单文件(通常以 YAML 文件格式),该文件指定了详细信息,例如容器部署名称、命名空间、容器镜像 URI、Pod 副本数量以及应用程序的通信端口。使用 Kubernetes 客户端工具(kubectl)应用 Deployment 后,将在工作节点上创建运行指定容器镜像的相应 Pod。以下示例创建了一个具有所需规范的 nginx 服务器 Pod 的 Deployment:

apiVersion: apps/v1 # k8s API version used for creating this deployment
kind: Deployment # the type of object. In this case, it is deployment
metadata:
name: nginx-deployment # name of the deployment
spec:
selector:
matchLabels:
app: nginx # an app label for the deployment.  This can be used to look up/select Pods
replicas: 2 # tells deployment to run 2 Pods matching the template
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2 # Docker container image used for the deployment
ports:
- containerPort: 80 # the networking port to communicate with the containers 

下面的图示展示了将前面的部署清单文件应用到 Kubernetes 集群中,并创建两个 Pod 来托管两个 nginx 容器副本的过程:

图 6.4 – 创建 Nginx 部署

图 6.4:创建 nginx 部署

在 Deployment 之后,一个 Deployment 控制器会监控已部署的容器实例。如果一个实例宕机,控制器将用工作节点上的另一个实例替换它。

Kubernetes Job

Kubernetes 作业是一个控制器,用于创建一个或多个 Pod 来运行一些任务,并确保作业成功完成。如果由于节点故障或其他系统问题导致多个 Pod 失败,Kubernetes 作业将重新创建 Pod 以完成任务。Kubernetes 作业可用于运行面向批处理的任务,例如在大量推理请求上运行批数据处理脚本、ML 模型训练脚本或 ML 批推理脚本。作业完成后,Pod 不会终止,因此您可以访问作业日志并检查作业的详细状态。以下是一个运行训练作业的示例模板:

apiVersion: batch/v1
kind: Job # indicate that this is the Kubernetes Job resource
metadata:
name: train-job
spec:
template:
spec:
containers:
- name: train-container
imagePullPolicy: Always # tell the job to always pull a new container image when it is started
image: <uri to Docker image containing training script>
command: ["python3",  "train.py"]  # tell the container to run this command after it is started
restartPolicy: Never
backoffLimit: 0 

注意,此配置包含一个名为restartPolicy的参数,它控制容器退出并失败时 Pod 的重新启动方式。有三个配置:

  • OnFailure:只有当 Pod 失败时才重新启动 Pod,而不是成功时。这是默认设置。

  • Never:在任何情况下都不重新启动 Pod。

  • Always:无论 Pod 的退出状态如何,总是重新启动 Pod。

您可以使用此参数来控制是否希望在容器失败时重新启动训练。

Kubernetes 自定义资源和操作符

Kubernetes 提供了一系列内置资源,例如 Pod 或 Deployment,以满足不同的需求。它还允许您创建自定义资源CR)并像管理内置资源一样管理它们,您可以使用相同的工具(例如kubectl)来管理它们。当您在 Kubernetes 中创建 CR 时,Kubernetes 为资源的每个版本创建一个新的 API(例如,<自定义资源名称>/<版本>)。这也被称为扩展Kubernetes API。要创建 CR,您创建一个自定义资源定义CRDYAML文件。要在 Kubernetes 中注册 CRD,您只需运行kubectl apply -f <CRD yaml 文件名称>来应用文件。之后,您就可以像使用任何其他 Kubernetes 资源一样使用它。例如,要管理 Kubernetes 上的自定义模型训练作业,您可以定义一个 CRD,其中包含算法名称、数据加密设置、训练镜像、输入数据源、作业失败重试次数、副本数量和作业存活探测频率等规范。

Kubernetes 操作符是一个在自定义资源上操作的控制器。操作符监视 CR 类型并采取特定操作以使当前状态与所需状态相匹配,就像内置控制器一样。例如,如果您想为之前提到的训练作业 CRD 创建一个训练作业,您将创建一个操作符来监控训练作业请求并执行特定于应用程序的操作以启动 Pod 并在整个生命周期中运行训练作业。以下图显示了与操作符部署相关的组件:

图 6.5 – Kubernetes 自定义资源和它与操作符的交互

图 6.5:Kubernetes 自定义资源和它与操作符的交互

部署操作员的最常见方式是部署 CR 定义和相关控制器。控制器在 Kubernetes 控制平面外部运行,类似于在 Pod 中运行容器化应用程序。

服务

Kubernetes 服务在 Kubernetes 集群内各种组件和应用程序之间实现可靠和可扩展的通信中发挥着关键作用。

由于集群中的应用程序通常是动态的,并且可以扩展或缩减,因此服务提供了一种稳定和抽象的端点,其他组件可以使用它来访问这些应用程序的运行实例。

在其核心,Kubernetes 服务是一个抽象层,它将一组 Pod 作为单个、定义良好的网络端点暴露出来。它充当负载均衡器,将进入的网络流量分发到服务后面的可用 Pod。这种抽象允许应用程序与服务交互,而无需了解底层 Pod 或其 IP 地址的详细信息。

Kubernetes 上的网络

Kubernetes 在 Kubernetes 集群中的所有资源之间运行一个扁平的私有网络。在集群内部,所有 Pod 都可以在集群范围内相互通信,无需网络地址转换NAT)。Kubernetes 为每个 Pod 分配其自己的集群私有 IP 地址,这个 IP 地址既是 Pod 自身看到的,也是其他人看到的。单个 Pod 内部的全部容器都可以到达本地主机上每个容器的端口。集群中的所有节点也有各自分配的 IP 地址,并且可以无需 NAT 与所有 Pod 进行通信。以下图显示了 Pod 和节点的不同 IP 分配,以及来自不同资源的通信流程:

图 6.6 – IP 分配和通信流程

图 6.6:IP 分配和通信流程

有时,你可能需要运行相同应用程序容器(例如nginx应用程序的容器)的一组 Pod,以实现高可用性和负载均衡,例如。而不是分别通过每个 Pod 的私有 IP 地址调用每个 Pod 以访问 Pod 中运行的应用程序,你希望调用一个用于该组 Pod 的抽象层,并且这个抽象层可以动态地将流量发送到它后面的每个 Pod。在这种情况下,你可以创建一个 Kubernetes 服务作为一组逻辑 Pod 的抽象层。Kubernetes 服务可以通过匹配 Pod 的app标签来动态选择其后面的 Pod,这是通过 Kubernetes 的一个名为selector的功能实现的。以下示例显示了创建名为nginx-service的服务规范,该服务将流量发送到具有nginx标签的 Pod,并在端口9376上。服务也分配了其自己的集群私有 IP 地址,因此它可以在集群内部被其他资源访问:

apiVersion: v1
kind: Service
metadata:
name: nginx-service
spec:
selector:
app: nginx
ports:
- protocol: TCP
port: 80
targetPort: 9376 

除了使用selector自动检测服务后面的 Pod 之外,您还可以手动创建一个Endpoint,并将固定的 IP 地址和端口映射到服务,如下例所示:

apiVersion: v1
kind: Endpoints
metadata:
name: nginx-service
subsets:
- addresses:
- ip: 192.0.2.42
ports:
- port: 9376 

虽然节点、Pod 和服务都被分配了集群私有 IP,但这些 IP 在集群外部是不可路由的。要从集群外部访问 Pod 或服务,您有以下几种选择:

  • 从节点或 Pod 访问:您可以使用kubectl exec命令连接到正在运行的 Pod 的 shell,并通过 shell 访问其他 Pod、节点和服务。

  • Kubernetes 代理:您可以在本地机器上运行kubectl proxy --port=<端口号>命令来启动 Kubernetes 代理以访问服务。一旦代理启动,您就可以访问节点、Pod 或服务。例如,您可以使用以下方案访问服务:

    http://localhost:<port number>/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE NAME>:<PORT NAME> 
    
  • NodePortNodePort在所有工作节点上打开一个特定的端口,并将发送到任何节点 IP 地址上此端口的任何流量转发到端口后面的服务。节点的 IP 地址需要从外部源可路由。以下图显示了使用NodePort的通信流程:图 6.7 – 通过 NodePort 访问 Kubernetes 服务

    图 6.7:通过 NodePort 访问 Kubernetes 服务

    NodePort使用简单,但有一些限制,例如每个服务一个NodePort,使用固定的端口范围(300032767),并且您需要知道各个工作节点的 IP 地址。

  • 负载均衡器:当您使用像 AWS 这样的云提供商时,负载均衡器是一种将服务暴露给互联网的方式。使用负载均衡器,您将获得一个可访问互联网的公网 IP 地址,并将发送到该 IP 地址的所有流量都会转发到负载均衡器后面的服务。负载均衡器不是 Kubernetes 的一部分,它由 Kubernetes 集群所在的云基础设施提供(例如,AWS)。以下图显示了从负载均衡器到服务和 Pod 的通信流程:图 6.8 – 通过负载均衡器访问 Kubernetes 服务

    图 6.8:通过负载均衡器访问 Kubernetes 服务

    负载均衡器允许您选择要使用的确切端口,并且可以支持每个服务多个端口。但是,它确实需要为每个服务配置一个单独的负载均衡器。

  • Ingress:Ingress 网关是集群的入口点。它充当负载均衡器,并根据路由规则将传入流量路由到不同的服务。图 6.9 – 通过 Ingress 访问 Kubernetes 服务

    图 6.9:通过 Ingress 访问 Kubernetes 服务

Ingress 与负载均衡器和 NodePort 不同,它充当代理来管理集群的流量。它与 NodePort 和负载均衡器协同工作,将流量路由到不同的服务。Ingress 方式越来越普遍地被使用,尤其是在与负载均衡器结合使用时。

除了从集群外部管理网络流量外,Kubernetes 网络管理的另一个重要方面是控制集群内不同 Pods 和服务之间的流量。例如,你可能希望允许某些流量访问一个 Pod 或服务,同时拒绝来自其他来源的流量。这对于基于微服务架构的应用程序尤为重要,因为可能有多个服务或 Pods 需要协同工作。这样的微服务网络也被称为 服务网格。随着服务数量的增加,理解和管理工作量变得具有挑战性,例如 服务发现网络路由网络指标故障恢复Istio 是一款开源的服务网格管理软件,它使得在 Kubernetes 上管理大型服务网格变得简单,并提供以下核心功能:

  • Ingress:Istio 提供了一个 Ingress 网关,可以用来将服务网格内部的服务暴露给互联网。它充当负载均衡器,管理服务网格的入站和出站流量。网关只允许流量进入/离开一个网格——它不进行流量路由。要将流量从网关路由到服务网格内的服务,你需要创建一个名为 VirtualService 的对象来提供路由规则,将入站流量路由到集群内部的不同目的地,并且创建虚拟服务与网关对象之间的绑定来连接两者。

  • 网络流量管理:Istio 提供基于规则的简单网络路由,以控制不同服务之间的流量和 API 调用。当 Istio 安装后,它会自动检测集群中的服务和端点。Istio 使用名为 VirtualService 的对象来提供路由规则,将入站流量路由到集群内部的不同目的地。Istio 使用名为 gateway 的负载均衡器来管理网络网格的入站和出站流量。gateway 负载均衡器只允许流量进入/离开一个网格——它不进行流量路由。要从网关路由流量,你需要创建虚拟服务与 gateway 对象之间的绑定。

    为了管理 Pod 进出流量,一个 Envoy 代理组件(也称为sidecar)被注入到 Pod 中,并拦截并决定如何路由所有流量。管理 sidecar 和服务的流量配置的 Istio 组件称为PilotCitadel组件负责服务到服务和最终用户身份验证。Gallery组件负责隔离其他 Istio 组件与底层 Kubernetes 基础设施。以下图显示了 Kubernetes 上 Istio 的架构:

    图 6.10 – Istio 架构

    图 6.10:Istio 架构

Istio 还支持安全和可观察性,这对于构建生产系统至关重要:

  • 安全:Istio 为服务间通信提供身份验证和授权。

  • 可观察性:Istio 捕获集群内所有服务通信的指标、日志和跟踪。指标示例包括网络延迟、错误和饱和度。跟踪示例包括网格内的调用流程和服务依赖。

Istio 可以处理各种部署需求,例如负载均衡和服务间认证。它甚至可以扩展到其他集群。

安全性和访问管理

安全性是构建 Kubernetes 上生产级系统的关键考虑因素。作为一名计划将 Kubernetes 作为 ML 基础平台的从业者,了解 Kubernetes 的各种安全方面非常重要。

Kubernetes 有许多内置的安全功能。这些安全功能允许您实现细粒度的网络流量控制和访问控制到不同的 Kubernetes API 和服务。在本节中,我们将讨论网络安全、身份验证和授权。

API 身份验证和授权

Kubernetes API 的访问可以为用户和 Kubernetes 服务帐户(服务帐户为在 Pod 中运行的过程提供身份)进行身份验证和授权。

用户在 Kubernetes 外部处理,并且 Kubernetes 有多种用户身份验证策略:

  • X.509 客户端证书:一个签名证书被发送到 API 服务器进行身份验证。API 服务器通过与证书颁发机构验证来验证用户。

  • 使用 OpenID Connect 进行单点登录OIDC):用户通过 OIDC 提供者进行身份验证,并接收一个包含用户信息的载体令牌(JSON Web TokenJWT))。用户将载体令牌传递给 API 服务器,API 服务器通过检查令牌中的证书来验证令牌的有效性。

  • HTTP 基本身份验证:HTTP 基本身份验证要求将用户 ID 和密码作为 API 请求的一部分发送,并验证用户 ID 和密码是否与 API 服务器关联的密码文件匹配。

  • 身份验证代理:API 服务器从 HTTP 头中提取用户身份,并使用证书颁发机构验证用户。

  • 身份验证网关:用于处理 API 服务器身份验证的外部服务。

服务帐户用于为在 Pod 中运行的进程提供身份。它们在 Kubernetes 中创建和管理。默认情况下,服务帐户需要位于命名空间内。每个命名空间还有一个 默认 服务帐户。如果 Pod 未分配服务帐户,则默认服务帐户将被分配给 Pod。服务帐户有一个相关的身份验证令牌,以 Kubernetes Secret 的形式保存,并用于 API 身份验证。Kubernetes Secret 用于存储敏感信息,如密码、身份验证令牌和 SSH 密钥。我们将在本章后面更详细地介绍 Secrets。

用户或服务帐户经过身份验证后,请求需要授权以执行允许的操作。Kubernetes 使用控制平面中的 API 服务器授权经过身份验证的请求,并且它有几种授权模式:

  • 基于属性的访问控制ABAC):通过策略授予用户访问权限。请注意,每个服务帐户都有一个相应的用户名。以下示例策略允许 joe 用户访问所有命名空间中的所有 API。

    {
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
    "user": "joe",
    "namespace": "*",
    "resource": "*",
    "apiGroup": "*"
    }
    } 
    

    以下策略允许 system:serviceaccount:kube-system:default 服务帐户访问所有命名空间中的所有 API:

    {
    "apiVersion": "abac.authorization.kubernetes.io/v1beta1",
    "kind": "Policy",
    "spec": {
    "user": "system:serviceaccount:kube-system:default",
    "namespace": "*",
    "resource": "*",
    "apiGroup": "*"
    }
    } 
    
  • 基于角色的访问控制RBAC):根据用户的角色授予访问权限。RBAC 使用 rbac.authorization.k8s.io API 组进行授权。RBAC API 与四个 Kubernetes 对象一起工作:RoleClusterRoleRoleBindingClusterRoleBinding

RoleClusterRole 包含一组权限。权限是 累加的,这意味着没有拒绝权限,并且您需要显式添加权限到资源。Role 对象是命名空间级别的,用于在命名空间内指定权限。ClusterRole 对象是非命名空间级别的,但可以用于为特定命名空间或集群范围权限授权。请参阅以下插图:

图片

图 6.11:Role 与 ClusterRole

以下 .yaml 文件为默认命名空间中核心 API 组的所有 Pod 资源提供获取、观看和列表访问权限:

apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
namespace: default
name: pod-reader
rules:
- apiGroups: [""]
  resources: ["pods"]
  verbs: ["get", "watch", "list"] 

以下策略允许对集群中所有 Kubernetes 节点的获取、观看和列表访问:

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
name: nodes-reader
rules:
- apiGroups: [""]
  resources: ["nodes"]
  verbs: ["get", "watch", "list"] 

RoleBindingClusterRoleBinding 将定义在 RoleClusterRole 对象中的权限授予具有对 RoleClusterRole 对象引用的用户或一组用户。以下策略将 joe 用户绑定到 pod-reader 角色:

apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: read-pods
namespace: default
subjects:
- kind: User
name: joe
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: pod-reader
apiGroup: rbac.authorization.k8s.io 

以下 RoleBinding 对象将服务帐户 SA-name 绑定到 ClusterRole secret-reader

apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: read-secrets-global
subjects:
- kind: ServiceAccount
name: SA-name
namespace: default
roleRef:
kind: ClusterRole
name: secret-reader
apiGroup: rbac.authorization.k8s.io 

Kubernetes 有一个内置功能用于存储和管理敏感信息,如密码。您不必直接在 Pod 中以纯文本形式存储这些敏感信息,而是可以将这些信息作为 Kubernetes Secrets 存储,并使用 Kubernetes RBAC 提供对这些 Secrets 的特定访问权限。默认情况下,Secrets 以未加密的纯文本 Base64 编码字符串的形式存储,并且可以为 Secrets 启用静态数据加密。以下策略显示了如何创建用于存储 AWS 访问凭证的 secret:

apiVersion: v1
kind: Secret
metadata:
name: aws-secret
type: Opaque
data:
AWS_ACCESS_KEY_ID: XXXX
AWS_SECRET_ACCESS_KEY: XXXX 

在 Pod 中使用密钥的方式有几种:

  • 作为 Pod 规范模板中的环境变量:

    apiVersion: v1
    kind: Pod
    metadata:
    name: secret-env-pod
    spec:
    containers:
    - name: mycontainer
    image: redis
    env:
    - name: SECRET_AWS_ACCESS_KEY
    valueFrom:
    secretKeyRef:
    name: aws-secret
    key: AWS_ACCESS_KEY_ID
    - name: SECRET_AWS_SECRET_ACCESS_KEY
    valueFrom:
    secretKeyRef:
    name: aws-secret
    key: AWS_SECRET_ACCESS_KEY
    restartPolicy: Never 
    

    容器内的应用程序代码可以像其他环境变量一样访问 Secrets。

  • 作为挂载在 Pod 上的卷中的文件:

    apiVersion: v1
    kind: Pod
    metadata:
    name: pod-ml
    spec:
    containers:
    - name: pod-ml
    image: <Docker image uri>
    volumeMounts:
    - name: vol-ml
    mountPath: "/etc/aws"
    readOnly: true
    volumes:
    - name: vol-ml
    Secret:
    secretName: aws-secret 
    

在前面的示例中,您将看到每个对应的密钥名称(如 SECRET_AWS_ACCESS_KEY)在 Pod 的 /etc/aws 文件夹中的文件,这些文件包含 Secrets 的值。

我们现在知道了容器是什么,以及它们如何在 Kubernetes 集群上部署。我们还了解了如何在 Kubernetes 上配置网络,以允许 Pods 之间相互通信,以及如何使用不同的网络选项将 Kubernetes 容器暴露给集群外部的访问。

Kubernetes 可以作为运行 ML 工作负载的基础基础设施。例如,您可以在 Kubernetes 上作为您的数据科学实验和模型构建环境,将 Jupyter 笔记本 运行为一个容器化应用程序。

如果您需要额外的资源,也可以将模型训练作业作为 Kubernetes Job 运行,然后将模型作为容器化的 Web 服务应用程序提供服务,或者作为 Kubernetes Job 在训练模型上运行批量推理。在接下来的动手练习中,您将学习如何使用 Kubernetes 作为运行 ML 工作负载的基础基础设施。

实践操作 - 在 AWS 上创建 Kubernetes 基础设施

在本节中,您将使用 Amazon EKS 创建一个 Kubernetes 环境,这是 AWS 上的托管 Kubernetes 环境,这使得设置 Kubernetes 集群变得更加容易。让我们首先看看问题陈述。

问题陈述

作为 ML 解决方案架构师,您被分配评估 Kubernetes 作为构建您银行一个业务单元的 ML 平台潜在基础设施平台的任务。您需要在 AWS 上构建一个沙盒环境,并证明您可以将 Jupyter 笔记本作为容器化应用程序部署,供您的数据科学家使用。

实验室说明

在这个动手练习中,您将使用 Amazon EKS 创建一个 Kubernetes 环境,Amazon EKS 是 AWS 上的 Kubernetes 管理服务,它可以自动创建和配置具有主节点和工作节点的 Kubernetes 集群。EKS 配置并扩展控制平面,包括 API 服务器和后端持久层。它还运行开源 Kubernetes,并与所有基于 Kubernetes 的应用程序兼容。

在创建 EKS 集群之后,您将探索 EKS 环境,检查其一些核心组件,然后您将学习如何部署一个容器化的 Jupyter Notebook 应用程序,并使其可通过互联网访问。

让我们完成以下步骤以开始:

  1. 启动 AWS CloudShell 服务。

    登录您的 AWS 账户,选择 俄勒冈 区域,并启动 AWS CloudShell。CloudShell 是一种 AWS 服务,它提供了一个基于浏览器的 Linux 终端环境,用于与 AWS 资源交互。使用 CloudShell,您可以使用 AWS 控制台凭据进行认证,并轻松运行 AWS CLIAWS SDK 和其他工具。

  2. 安装 eksctl 工具。

    按照 Unix 的安装说明在 github.com/weaveworks/eksctl/blob/main/README.md#installation 安装 eksctl。eksctl 工具是用于管理 EKS 集群的命令行工具。我们将在 步骤 3 中使用 eksctl 工具在 Amazon EKS 上创建一个 Kubernetes 集群:

  3. 运行以下命令以在您 AWS 账户内的 俄勒冈 区域启动创建 EKS 集群。设置完成大约需要 15 分钟:

    eksctl create cluster --name <cluster name> --region us-west-2 
    

    该命令将启动一个 cloudformation 模板,这将创建以下资源:

    • 在一个新的 Amazon 虚拟私有云VPC)内部包含两个工作节点的 Amazon EKS 集群。Amazon EKS 提供了完全管理的 Kubernetes 主节点,因此您在私有 VPC 内看不到主节点。

    • 在 CloudShell 的 /home/cloudshell-user/.kube/config 目录中保存的 EKS 集群配置文件。该 config 文件包含诸如 API 服务器 url 地址、管理集群的管理员用户名以及用于认证 Kubernetes 集群的客户端证书等详细信息。kubectl 工具使用 config 文件中的信息连接并认证到 Kubernetes API 服务器。

    • EKS 将工作节点组织成称为 nodegroup 的逻辑组。运行以下命令以查找 nodegroup 名称。您可以在 EKS 管理控制台中查找集群的名称。节点组的名称应类似于 ng-xxxxxxxx

      eksctl get nodegroup --cluster=<cluster name> 
      
  4. 安装 kubectl 工具。

    按照以下链接中的说明进行操作docs.aws.amazon.com/eks/latest/userguide/install-kubectl.html以在 Linux 上安装 kubectl。您需要知道 Kubernetes 服务器的版本才能安装相应的 kubectl 版本。您可以使用kubectl version --short命令找到 Kubernetes 服务器的版本。

  5. 探索集群。

    现在集群已启动,让我们稍微探索一下。尝试在 CloudShell 终端中运行以下命令并查看返回结果:

    表 6.1 – kubectl 命令

    图 6.12:kubectl 命令

  6. 部署 Jupyter 笔记本。

    让我们部署一个 Jupyter Notebook 服务器作为容器化应用程序。复制并运行以下代码块。它应该创建一个名为deploy_Jupyter_notebook.yaml的文件。我们将使用 Docker Hub 镜像仓库中的容器镜像:

    cat << EOF > deploy_Jupyter_notebook.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
    name: jupyter-notebook
    labels:
    app: jupyter-notebook
    spec:
    replicas: 1
    selector:
    matchLabels:
    app: jupyter-notebook
    template:
    metadata:
    labels:
    app: jupyter-notebook
    spec:
    containers:
    - name: minimal-notebook
    image: jupyter/minimal-notebook:latest
    ports:
    - containerPort: 8888
    EOF 
    

    现在,让我们运行以下命令来创建一个 Deployment:

    kubectl apply -f deploy_Jupyter_notebook.yaml. 
    

    通过执行kubectl get pods来检查 Pod 是否正在运行。

    通过运行kubectl logs <notebook pod 名称>来检查 Jupyter 服务器 Pod 的日志。找到包含http://jupyter-notebook-598f56bf4b-spqn4:8888/?token=XXXXXXX...的日志部分,并复制令牌(XXXXXX…)部分。我们将在步骤 8中使用此令牌。

    您还可以通过运行kubectl exec --stdin --tty <notebook pod 名称> -- /bin/sh使用交互式 shell 访问 Pod。运行ps aux以查看运行进程列表。您将看到一个与 Jupyter 笔记本相关的进程。

  7. 将 Jupyter 笔记本暴露给互联网。

    到目前为止,我们已经在 AWS VPC 中两个 EC2 实例之上的 Kubernetes Pod 中运行了一个 Jupyter 服务器,但我们无法访问它,因为 Kubernetes 集群没有向容器公开路由。我们将创建一个 Kubernetes 服务,将 Jupyter Notebook 服务器暴露给互联网,以便可以从浏览器访问。

    运行以下代码块以创建一个新 Service 的规范文件。它应该创建一个名为jupyter_svc.yaml的文件:

    cat << EOF > jupyter_svc.yaml
    apiVersion: v1
    kind: Service
    metadata:
    name: jupyter-service
    annotations:
    service.beta.kubernetes.io/aws-load-balancer-type: alb
    spec:
    selector:
    app: jupyter-notebook
    ports:
    - protocol: TCP
    port: 80
    targetPort: 8888
    type: LoadBalancer
    EOF 
    

    文件创建后,运行kubectl apply -f jupyter_svc.yaml以创建服务。应创建一个名为jupyter-service的新 Kubernetes 服务以及一个新的LoadBalancer对象。您可以通过运行kubectl get service来验证服务。注意并复制与jupyter-service服务关联的EXTERNAL-IP地址。

    EXTERNAL-IP地址粘贴到新的浏览器窗口中,并将您之前复制的令牌输入到密码或令牌字段中,以按以下截图所示登录。您应该看到一个 Jupyter Notebook 窗口出现:

    图 6.11 – Jupyter 登录屏幕

    图 6.13:Jupyter 登录屏幕

    以下图表显示了您在完成动手练习后创建的环境。

    图 6.12 – EKS 集群上的 Jupyter 笔记本部署

    图 6.14:EKS 集群上的 Jupyter Notebook 部署

恭喜你,你已经在 AWS 上成功创建了一个新的 Amazon EKS 集群,并在集群上部署了一个 Jupyter 服务器实例作为容器。我们将重用这个 EKS 集群进行下一章的内容。然而,如果你计划一段时间内不使用这个 EKS,建议关闭集群以避免不必要的费用。要关闭集群,请运行 kubectl delete svc <service name> 来删除服务。然后运行 eksctl delete cluster --name <cluster name> 来删除集群。

摘要

在本章中,我们介绍了 Kubernetes,这是一个强大的容器管理平台,是构建开源 ML 平台的基础设施基础。在本章中,你了解了容器和 Kubernetes 的工作原理。此外,通过利用 AWS EKS,你获得了在 AWS 上建立 Kubernetes 集群的实际经验。此外,我们探讨了将容器化的 Jupyter Notebook 应用程序部署到集群上的过程,从而创建了一个基本的数据科学环境。在下一章中,我们将转向探索与 Kubernetes 基础设施无缝集成的开源 ML 平台的选择。

加入我们的 Discord 社区

加入我们的社区 Discord 空间,与作者和其他读者进行讨论:

packt.link/mlsah

二维码

第七章:开源机器学习平台

在上一章中,我们介绍了如何使用 Kubernetes 作为运行机器学习任务的基础设施,例如运行模型训练作业或构建数据科学环境,如Jupyter Notebook服务器。然而,为了在大规模组织中进行这些任务并提高效率,您需要构建具有支持完整数据科学生命周期能力的机器学习平台。这些能力包括可扩展的数据科学环境、模型训练服务、模型注册和模型部署能力。

在本章中,我们将讨论机器学习平台的核心理念,并探讨可用于构建机器学习平台的额外开源技术。我们将从为支持大量用户进行实验而设计的数据科学环境技术开始。随后,我们将深入研究各种模型训练、模型注册、模型部署和机器学习管道自动化的技术。

简而言之,以下主题被涵盖:

  • 机器学习平台的核心理念

  • 构建机器学习平台的开源技术

机器学习平台的核心理念

机器学习平台是一个复杂的系统,包括运行不同任务的环境和编排复杂工作流程过程。此外,机器学习平台需要满足多种角色,包括数据科学家、机器学习工程师、基础设施工程师、运维团队以及安全和合规利益相关者。要构建机器学习平台,需要几个组件共同作用。

这些组件包括:

  • 数据科学环境:数据科学环境提供数据分析工具和机器学习工具,如 Jupyter 笔记本、数据源和存储、代码仓库和机器学习框架。数据科学家和机器学习工程师使用数据科学环境进行数据分析、运行数据科学实验以及构建和调整模型。数据科学环境还提供协作功能,允许数据科学家共享和协作代码、数据、实验和模型。

  • 模型训练环境:模型训练环境提供专门的基础设施,以满足特定的模型训练需求。虽然数据科学家和机器学习工程师可以直接在其本地 Jupyter 环境中执行小规模的模型训练任务,但他们需要为大规模模型训练提供单独的专用基础设施。通过利用专用训练基础设施,组织可以更好地控制模型训练过程管理和模型血缘管理流程。

  • 模型注册:训练好的模型需要在模型注册表中进行跟踪和管理。模型注册表作为集中式存储库,用于库存和管理模型,确保有效的血缘管理、版本控制、模型发现和全面的生命周期管理。当处理大量模型时,这一点尤为重要。数据科学家可以直接在他们的数据科学环境中进行实验时在注册表中注册模型。此外,模型可以作为自动化机器学习模型管道执行的一部分进行注册,从而实现模型到注册表的流畅和自动化集成。

  • 模型服务环境:为了将训练好的机器学习模型的预测结果服务于客户端应用程序,需要在实时操作的后端 API 端点内托管模型。该基础设施还应提供对批量转换功能的支持,允许在大批量中处理预测。有几种类型的模型服务框架可供满足这些要求。

  • 机器学习管道开发:为了有效地管理生命周期中各种机器学习组件和阶段,关键是要纳入能够使管道开发编排机器学习训练和预测工作流程的能力。这些管道在协调不同阶段,如数据准备、模型训练和评估等方面发挥着重要作用。

  • 模型监控:强大的模型监控对于保持生产中机器学习模型的高性能至关重要。持续的监控跟踪预测准确性、数据漂移、延迟、错误和异常等指标。监控使平台操作员能够在影响用户之前检测到生产模型退化。当监控指标超过定义的阈值时,会触发调查工作流程和必要的缓解措施。有效的监控还提供性能仪表板和所有部署模型的可见性。这促进了模型的持续改进,并允许主动替换表现不佳的模型。

  • 机器学习特征管理:在机器学习生命周期中,管理特征是一项关键能力。特征管理包括对机器学习特征的持续维护、监控和共享,以加速模型开发。这包括用于发现、血缘跟踪和特征数据治理的工具。集中式特征存储通过为组织内的团队提供高质量特征,实现了访问的民主化。它们提供了一个单一的真实来源,消除了特征工程努力的重复。

  • 持续集成CI)/持续部署CD)和工作流程自动化:最后,为了在机器学习平台上简化数据处理、模型训练和模型部署流程,建立 CI/CD 实践以及工作流程自动化能力至关重要。这些实践和工具显著提高了机器学习部署的速度、一致性、可重复性和可观察性。

除了这些核心组件之外,在构建端到端机器学习平台时,还需要考虑几个其他平台架构因素。这些因素包括安全性和身份验证、版本控制和可重复性,以及数据管理和治理。通过将这些额外的架构因素整合到机器学习平台中,组织可以增强安全性,对系统操作有更清晰的了解,并执行治理政策。在接下来的章节中,我们将探讨可用于构建端到端机器学习平台的多种开源技术。

用于构建机器学习平台的开源技术

通过在 Kubernetes 集群中部署独立的机器学习容器来单独管理机器学习任务,在处理大量用户和工作负载时可能会变得具有挑战性。为了解决这种复杂性并实现高效扩展,许多开源技术已成为可行的解决方案。这些技术包括 Kubeflow、MLflow、Seldon Core、GitHub、Feast 和 Airflow,它们为构建数据科学环境、模型训练服务、模型推理服务和机器学习工作流程自动化提供了全面的支持。

在深入探讨技术细节之前,让我们首先探讨为什么许多组织选择开源技术来构建他们的机器学习平台。对于许多人来说,吸引力在于能够根据特定的组织需求和流程定制平台,开放标准和可互操作组件防止了供应商锁定,并允许随着时间的推移采用新技术。利用流行的开源机器学习项目还可以利用丰富的人才库,因为许多从业者已经熟练掌握了这些技术。此外,开源允许内部团队完全控制平台路线图,减少了对供应商优先级的依赖。当高效执行时,开源堆栈可以为组织节省成本,因为与软件相关的没有许可费用。

使用开源技术构建机器学习平台具有显著优势。然而,考虑潜在的缺点也同样重要。可能出现的挑战包括集成复杂性、缺乏全面支持、安全漏洞以及与商业解决方案相比可能的功能限制。此外,维护开源平台的资源密集型特性,以及团队可能面临的学习曲线,可能会影响效率和总拥有成本。对文档质量、缺乏标准化以及更新和维护的责任的担忧,进一步强调了仔细考虑的必要性。在决定采用开源方法之前,您必须权衡这些因素,并考虑其具体要求、资源和专业知识。

考虑到这些因素,让我们探讨使用开源技术设计核心机器学习平台组件。

实施数据科学环境

Kubeflow 是一个基于 Kubernetes 的开源机器学习平台。它提供了一套专门设计的工具和框架,旨在简化机器学习工作的部署、编排和管理。Kubeflow 提供了诸如 Jupyter 笔记本用于交互式数据探索和实验、分布式训练能力和模型服务基础设施等功能。

Kubeflow 的核心功能包括:

  • 一个中央 UI 仪表板

  • 用于代码编写和模型构建的 Jupyter Notebook 服务器

  • 用于机器学习流程编排的 Kubeflow 管道

  • KFServing用于模型服务

  • 用于模型训练支持的训练操作员

下图说明了 Kubeflow 如何提供数据科学环境所需的各种组件。具体来说,我们将深入探讨其对 Jupyter Notebook 服务器的支持,因为它是数据科学环境的主要构建块。

图 7.1 – 基于 Kubeflow 的数据科学环境

图 7.1:基于 Kubeflow 的数据科学环境

Kubeflow 提供了一个具有内置身份验证和授权支持的多个租户 Jupyter Notebook 服务器环境。让我们详细讨论这些核心组件:

  • Jupyter Notebook:作为数据科学家,您可以利用 Kubeflow Jupyter Notebook 服务器,该服务器提供了一个平台,用于在 Jupyter 笔记本中编写和运行Python代码以探索数据和构建模型。使用 Kubeflow,您可以启动多个笔记本服务器,每个服务器都与一个单独的 Kubernetes 命名空间相关联,该命名空间对应于一个团队、项目或个人用户。每个笔记本服务器在Kubernetes Pod内部运行一个容器。默认情况下,Kubeflow 笔记本服务器提供了一系列托管在公共容器镜像仓库中的笔记本容器镜像供您选择。或者,您也可以创建定制的笔记本容器镜像以满足您的特定需求。为了确保标准和一致性,Kubeflow 管理员可以为用户提供标准镜像列表。在创建笔记本服务器时,您选择运行笔记本服务器的命名空间。此外,您还需要指定笔记本服务器的容器镜像的统一资源标识符URI)。您还可以灵活地指定资源需求,例如 CPU/GPU 的数量和内存大小。

  • 身份验证和授权:您通过 Kubeflow UI 仪表板访问笔记本服务器,该仪表板通过 Dex OpenID ConnectOIDC)提供者提供身份验证服务。Dex 是一个使用 OIDC 为其他应用程序提供身份验证的标识服务。Dex 可以与其他身份验证服务(如Active Directory服务)进行联合。每个笔记本都与一个默认的 Kubernetes 服务帐户(default-editor)相关联,可用于授权目的(例如,授予笔记本访问 Kubernetes 集群中各种资源的权限)。Kubeflow 使用 Istio 基于角色的访问控制RBAC)来控制集群内的流量。以下YAML文件通过将ml-pipeline-services服务角色附加到它,授予与 Kubeflow 笔记本关联的default-editor服务帐户访问 Kubeflow 管道服务的权限:

    apiVersion: rbac.istio.io/v1alpha1
    kind: ServiceRoleBinding
    metadata:
    name: bind-ml-pipeline-nb-admin
    namespace: kubeflow
    spec:
    roleRef:
    kind: ServiceRole
    name: ml-pipeline-services
    subjects:
    - properties:
    source.principal: cluster.local/ns/admin/sa/default-editor 
    
  • 多租户:Kubeflow 提供了多用户访问共享 Kubeflow 环境的能力,同时确保资源隔离。这是通过为每个用户创建单独的命名空间并利用 Kubernetes RBAC 和 Istio RBAC 来管理这些命名空间及其相关资源的访问控制来实现的。对于团队内部的协作工作,命名空间的所有者可以直接从 Kubeflow 仪表板 UI 授予其他用户的访问权限。使用管理贡献者功能,命名空间所有者可以指定哪些用户被授予访问命名空间及其资源的权限。

除了上述核心组件之外,Kubeflow 还提供了一种机制,用于将用户引入以访问不同的 Kubeflow 资源。要引入新的 Kubeflow 用户,您需要创建一个新的用户配置文件,这将自动为该配置文件生成一个新的命名空间。

以下 YAML 文件,一旦使用kubectl应用,就会创建一个名为test-user的新用户配置文件,其电子邮件地址为test-user@kubeflow.org,同时还会创建一个名为test-user的新命名空间:

apiVersion: kubeflow.org/v1beta1
kind: Profile
metadata:
name: test-user
spec:
owner:
kind: User
name: test-user@kubeflow.org 

您可以使用kubectl get profileskubectl get namespaces命令来验证配置文件和命名空间是否已创建。

用户创建并添加到 Kubeflow Dex 身份验证服务后,新用户可以登录到 Kubeflow 仪表板,并在新创建的命名空间下访问 Kubeflow 资源(如 Jupyter Notebook 服务器)。

在数据科学环境中使用 Kubeflow 会带来一些关键挑战,这些挑战在决定实施之前必须了解。在 Kubernetes 之上安装 Kubeflow,无论是在本地还是在 AWS 等云平台,都可能很复杂,通常需要大量的配置和调试。众多的组件使得安装变得非同寻常。Kubeflow 由许多松散耦合的组件组成,每个组件都有自己的版本。在不同版本之间协调这些多样化的组件,以无缝地作为一个集成平台工作,可能会遇到困难。Kubeflow 的文档不足。Kubeflow 文档经常指向较旧的组件版本。过时的文档使得新用户在文档和平台版本之间出现不匹配时,采用变得更加困难。尽管存在这些限制,但由于其对端到端管道的支持、对各种 ML 框架的丰富支持以及可移植性,Kubeflow 仍然是构建 ML 平台高度推荐的技术。

有了这些,我们已经了解了如何使用 Kubeflow 提供多租户 Jupyter Notebook 环境进行实验和模型构建。接下来,让我们看看如何构建模型训练环境。

构建模型训练环境

如前所述,在 ML 平台中,通常提供专门的模型训练服务和基础设施,以支持在 ML 管道中进行大规模和自动化的模型训练。

这个专门的培训服务应该可以从平台内的不同组件轻松访问,例如实验环境(如 Jupyter 笔记本)以及 ML 自动化管道。

在基于 Kubernetes 的环境中,根据您的训练需求,您可以选择两种主要的模型训练方法:

  • 使用Kubernetes 作业进行模型训练

  • 使用Kubeflow 训练操作员进行模型训练

让我们逐一详细地审视这些方法:

  • 使用 Kubernetes Jobs 进行模型训练:正如我们在第六章Kubernetes 容器编排基础设施管理中讨论的那样,Kubernetes Job 创建一个或多个容器并将它们运行到完成。这种模式非常适合运行某些类型的机器学习模型训练作业,因为机器学习作业运行一个训练循环直到完成,而不是无限期运行。例如,您可以将一个包含 Python 训练脚本和所有训练模型所需的依赖项的容器打包,并使用 Kubernetes Job 来加载容器并启动训练脚本。当脚本完成并退出时,Kubernetes Job 也会结束。以下示例 YAML 文件,如果使用kubectl apply命令提交,将启动一个模型训练作业:

    apiVersion: batch/v1
    kind: Job
    metadata:
    name: train-churn-job
    spec:
    template:
    spec:
    containers:
    - name: train-container
    imagePullPolicy: Always
    image: <model training uri>
    command: ["python", "train.py"]
          restartPolicy: Never
    backoffLimit: 4 
    

    要查询作业状态并查看详细的训练日志,您可以分别运行kubectl get jobs命令和kubectl logs <pod name>命令。

  • 使用 Kubeflow 训练操作符进行模型训练:Kubernetes Job 可以启动一个模型训练容器并在容器内运行训练脚本直到完成。由于 Kubernetes Job 的控制器没有关于训练作业的应用特定知识,它只能处理运行作业的通用 Pod 部署和管理,例如在 Pod 中运行容器、监控 Pod 和处理通用 Pod 故障。然而,某些模型训练作业,如集群中的分布式训练作业,需要特殊部署、监控和维护各个 Pod 之间状态化通信。这就是 Kubernetes 训练操作符模式可以应用的地方。

Kubeflow 提供了一系列预构建的训练操作符(例如TensorFlowPyTorchXGBoost操作符)用于复杂的模型训练作业。每个 Kubeflow 训练操作符都有一个自定义资源CR)(例如,TensorFlow 作业的TFJob CR),它定义了训练作业的特定配置,例如训练作业中的 Pod 类型(例如,masterworkerparameter server),或者运行策略以清理资源以及作业应运行多长时间。CR 的控制器负责配置训练环境、监控训练作业的特定状态以及维护期望的训练作业的特定状态。例如,控制器可以设置环境变量,使训练集群规范(例如,Pod 类型和索引)对容器内运行的训练代码可用。此外,控制器还可以检查训练过程的退出代码,如果退出代码指示永久性故障,则失败训练作业。以下 YAML 文件示例模板代表使用 TensorFlow 操作符(tf-operator)运行训练作业的规范:

apiVersion: "kubeflow.org/v1"
kind: "TFJob"
metadata:
name: "distributed-tensorflow-job"
spec:
tfReplicaSpecs:
PS:
replicas: 1
restartPolicy: Never
template:
spec:
containers:
- name: tensorflow
image: <model training image uri>
command:
Worker:
replicas: 2
restartPolicy: Never
template:
spec:
containers:
- name: tensorflow
image: <model training image uri>
command: 

在此示例模板中,规范将创建一个参数服务器副本(它聚合不同容器中的模型参数)和两个工作副本(它们运行模型训练循环并与参数服务器通信)。操作符将根据规范处理TFJob对象,将实际运行的服务和 Pods 中存储的TFJob对象保持与系统中的规范一致,并用期望状态替换实际状态。您可以使用kubectl apply -f <TFJob specs template>提交训练作业,并使用kubectl get tfjob命令获取TFJob的状态。

作为数据科学家,您可以使用kubectl实用工具提交 Kubernetes 训练作业或 Kubeflow 训练作业,或者从您的 Jupyter Notebook 环境中使用Python SDK。例如,TFJob对象有一个名为kubernet.tfjob的 Python SDK,Kubernetes 有一个名为kubernetes.client的客户端 SDK,用于从 Python 代码与 Kubernetes 和 Kubeflow 环境交互。您还可以使用我们将在后面的Kubeflow 管道部分中介绍的Kubeflow Pipeline组件调用训练作业。

使用 Kubernetes 作业进行机器学习训练需要安装和配置必要的机器学习软件组件,以便使用不同的框架训练不同的模型。您还需要构建日志和监控能力以监控训练进度。

采用 Kubeflow 训练操作符也带来了一系列挑战。包括 MPI 训练操作符在内的几个操作符仍处于成熟阶段,还不适合用于生产环境。虽然操作符提供了一些日志和指标,但获取跨 Pods 的广泛训练运行的全面视图仍然具有挑战性,需要集成多个仪表板。为各种具有碎片化功能和状态的机器学习框架提供单独的操作符,使得实现统一体验变得更加复杂。

运行训练操作符的学习曲线可能很高,因为它涉及到理解许多组件,例如训练 YAML 文件的开发、分布式训练作业配置和训练作业监控。

使用模型注册表注册模型

模型注册表是模型管理和治理的重要组件,它是模型训练阶段与模型部署阶段之间的关键链接,因为模型需要被适当地存储在受管理的存储库中,以便进行受控的模型部署。在机器学习平台中实现模型注册表有几种开源选项。在本节中,我们将探讨用于模型管理的 MLflow 模型注册表。

MLflow 模型注册表是领先的模型注册解决方案之一,在模型工件生命周期管理、版本支持以及 Docker、Amazon SageMaker 和 Azure ML 等部署目标方面具有强大的支持。它旨在管理机器学习生命周期的所有阶段,包括实验管理、模型管理、可复现性和模型部署。它具有以下四个主要组件:

  • 实验跟踪: 在模型开发过程中,数据科学家会使用不同的数据集、算法和配置运行多个训练作业作为实验,以找到最佳的工作模型。跟踪这些实验的输入和输出对于确保高效进展至关重要。实验跟踪会在运行您的机器学习代码时记录参数、代码版本、指标和工件,以便稍后可视化结果。

  • 机器学习项目: 项目将数据科学代码打包成可以在任何平台上复现运行的格式。

  • 模型: 模型为打包和部署机器学习模型提供了一个标准单元。

  • 模型注册表: 模型注册表在中央存储库中存储、注释、发现和管理模型。

MLflow 模型注册表组件提供了一个中央模型存储库,用于保存模型。它捕获模型细节,如模型血缘、模型版本、注释和描述,并捕获模型从预发布到生产的阶段转换(因此模型状态的状态被清楚地描述)。

要在团队环境中使用 MLflow 模型注册表,您需要设置一个带有数据库作为后端和模型工件存储的 MLflow 跟踪服务器。MLflow 提供 UI 和 API 与其核心功能进行交互,包括模型注册表。一旦模型在模型注册表中注册,您就可以通过 UI 或 API 添加、修改、更新、过渡或删除模型。

下图显示了 MLflow 跟踪服务器及其相关模型注册表的架构设置:

图 7.2 – MLflow 跟踪服务器和模型注册表

图 7.2:MLflow 跟踪服务器和模型注册表

MLflow 支持基本 HTTP 身份验证,以实现对实验和已注册模型的访问控制。MLflow 跟踪服务器也支持基本身份验证。然而,这些安全功能可能不足以满足企业需求,例如用户组管理和与第三方身份验证提供商的集成。组织通常需要实施单独的安全和身份验证控制来管理对资源的访问。

使用模型服务来提供模型

一旦模型被训练并保存,利用它来生成预测只需将保存的模型加载到机器学习包中并调用该包提供的适当模型预测函数即可。然而,对于大规模和复杂的模型服务需求,您需要考虑实施专门的服务器模型服务基础设施以满足这些需求。

在接下来的章节中,我们将探讨各种开源模型服务框架,这些框架可以帮助解决这些需求。

Gunicorn 和 Flask 推理引擎

GunicornFlask 常用于构建自定义模型服务 Web 框架。以下图显示了使用 Flask、Gunicorn 和 Nginx 作为模型服务服务的构建块的一个典型架构。

图 7.3 – 使用 Flask 和 Gunicorn 的模型服务架构

图 7.3:使用 Flask 和 Gunicorn 的模型服务架构

Flask 是一个基于 Python 的微型网络框架,用于快速构建 Web 应用。它轻量级,几乎不依赖于外部库。使用 Flask,您可以定义不同的调用路由并将处理函数关联到不同的 Web 调用(例如健康检查调用和模型调用)。为了处理模型预测请求,Flask 应用将模型加载到内存中,并在模型上调用 predict 函数以生成预测。Flask 内置了网络服务器,但它扩展性不佳,因为它一次只能支持一个请求。

这就是 Gunicorn 可以帮助解决可扩展性差距的地方。Gunicorn 是一个用于托管 Web 应用的网络服务器,包括 Flask 应用。它可以并行处理多个请求并有效地将流量分配给托管 Web 应用。当它收到一个 Web 请求时,它将调用托管的 Flask 应用来处理请求,例如调用函数以生成模型预测。

除了作为 Web 请求提供预测请求之外,企业推理引擎还需要处理安全的 Web 流量(例如 SSL/TLS 流量),以及当有多个 Web 服务器时的负载均衡。这正是 Nginx 可以发挥重要作用的地方。Nginx 可以作为多个 Web 服务器的负载均衡器,并且可以更有效地处理 SSL/TLS 流量的终止,这样 Web 服务器就不必处理它。

基于 Flask/Gunicorn 的模型服务架构可以是托管简单模型服务模式的好选择。但对于更复杂的模式,例如托管不同版本的模型、A/B 测试(向不同的用户群体展示模型的两个变体并比较它们的响应)或大型模型服务,这种架构将有限制。Flask/Gunicorn 架构模式还需要自定义代码(如 Flask 应用)才能工作,因为它不提供对不同机器学习模型的内置支持。

接下来,让我们探索一些专门设计的模型服务框架,并看看它们与基于 Flask 的自定义推理引擎有何不同。

TensorFlow Serving 框架

TensorFlow Serving 是一个生产级、开源的模型服务框架,并提供了在 RESTFul 端点后服务 TensorFlow 模型的即用型支持。它管理模型服务的生命周期,并为单个端点后提供版本化和多个模型提供访问。此外,还内置了对金丝雀部署的支持。金丝雀部署 允许您将模型部署以支持部分流量。除了实时推理支持外,还有一个批量调度功能,可以批量处理多个预测请求并执行单个联合操作。使用 TensorFlow Serving,无需编写自定义代码来服务模型。

下图展示了 TensorFlow Serving 的架构:

图 7.4 – TensorFlow Serving 架构

图 7.4:TensorFlow Serving 架构

让我们更详细地讨论每个架构组件:

  • API 处理器 为 TensorFlow Serving 提供接口。它内置了一个轻量级的 HTTP 服务器,用于服务基于 REST 的 API 请求。它还支持 gRPC(一种 远程过程调用 协议)流量。gRPC 是一种更高效、更快的网络协议;然而,它比 REST 协议更复杂。TensorFlow Serving 有一个称为 可服务对象 的概念,它指的是处理任务的实际对象,例如模型推理或查找表。例如,训练好的模型表示为一个 可服务对象,它可以包含一个或多个算法和查找表或嵌入表。API 处理器使用可服务对象来满足客户端请求。

  • 模型管理器 负责管理可服务对象的生命周期,包括加载可服务对象、提供可服务对象服务以及卸载可服务对象。当需要可服务对象来执行任务时,模型管理器向客户端提供一个处理程序以访问可服务对象实例。模型管理器可以管理多个版本的可服务对象,允许逐步推出不同版本的模型。

  • 模型加载器 负责从不同来源加载模型,例如 Amazon S3。当加载新模型时,模型加载器会通知模型管理器新模型的可用性,模型管理器将决定下一步应该做什么,例如卸载旧版本并加载新版本。

TensorFlow Serving 可以扩展以支持非 TensorFlow 模型。例如,在其他框架中训练的模型可以被转换为 ONNX 格式,并使用 TensorFlow Serving 提供服务。ONNX 是一种用于表示模型以支持不同机器学习框架之间互操作性的通用格式。

The TorchServe serving framework

TorchServe是一个用于部署训练好的PyTorch模型的开源框架。类似于 TensorFlow Serving,TorchServe 通过其内置的 Web 服务器提供 REST API 来部署模型。它具有多模型部署、模型版本控制、服务器端请求批处理和内置监控等核心功能,能够大规模地部署生产工作负载。使用 TorchServe 部署 PyTorch 模型无需编写自定义代码。此外,TorchServe 还内置了 Web 服务器来托管模型。

下图展示了 TorchServe 框架的架构组件:

图 7.5 – TorchServe 架构

图 7.5:TorchServe 架构

推理 API负责处理来自客户端应用程序的预测请求,这些请求使用加载的 PyTorch 模型。它支持 REST 协议,并提供预测 API 以及其他支持 API,如健康检查和模型解释 API。推理 API 可以处理多个模型的预测请求。

模型工件被打包成一个单独的归档文件,并存储在 TorchServe 环境中的模型存储中。您可以使用名为torch-mode-archive命令行界面(CLI)命令来打包模型。

TorchServe 后端将从模型存储中加载归档模型到不同的工作进程中。这些工作进程与推理 API 交互,处理请求并发送响应。

管理 API 负责处理管理任务,如注册和注销 PyTorch 模型、检查模型状态以及扩展工作进程。管理 API 通常由系统管理员使用。

TorchServe 还提供了内置的日志记录和指标支持。日志组件记录访问日志和处理日志。TorchServe 指标收集系统指标列表,例如 CPU/GPU 利用率以及自定义模型指标。

KFServing 框架

TensorFlow Serving 和 TorchServe 是特定深度学习框架的独立模型部署框架。相比之下,KFServing是一个通用、多框架、支持不同机器学习模型的模型部署框架。KFServing 使用如 TensorFlow Serving 和 TorchServe 这样的独立模型部署框架作为后端模型服务器。它是 Kubeflow 项目的一部分,并为不同的模型格式提供了可插拔的架构:

图 7.6 – KFServing 组件

图 7.6:KFServing 组件

作为一种通用、多框架的模型服务解决方案,KFServing 为不同类型的模型提供了多个开箱即用的模型服务器(也称为预测器),包括 TensorFlow、PyTorchXGBoostscikit-learn 和 ONNX。使用 KFServing,您可以使用 REST 和 gRPC 协议来提供服务。要部署支持的模型类型,您只需定义一个指向数据存储中模型实体的 YAML 规范即可。此外,您还可以构建自己的自定义容器,在 KFServing 中提供服务。该容器需要提供模型服务实现以及一个网络服务器。以下代码展示了使用 KFServing 部署 tensorflow 模型的示例 YAML 规范:

apiVersion: "serving.kubeflow.org/v1alpha2"
kind: "InferenceService"
metadata:
name: "model-name"
spec:
default:
predictor:
tensorflow:
storageUri: <uri to model storage such as s3> 

KFServing 具有一个转换组件,允许在将输入有效载荷发送到预测器之前对其进行自定义处理,并在将响应发送回调用客户端之前对预测器的响应进行转换。有时,您需要为模型预测提供解释,例如哪些特征对预测有更强的影响,我们将在后面的章节中更详细地介绍。

KFServing 设计用于生产部署,并提供了一系列生产部署功能。其自动扩展功能允许模型服务器根据请求流量量进行扩展/缩减。使用 KFServing,您可以部署默认模型服务端点和金丝雀端点,在两者之间分配流量,并指定端点后面的模型修订版。对于运营支持,KFServing 还内置了监控功能(例如,监控请求数据和请求延迟)。

Seldon Core

Seldon Core 是另一个多框架模型服务框架,用于在 Kubernetes 上部署模型。与 KFServing 相比,Seldon Core 提供了更丰富的模型服务功能,例如用于 A/B 测试和模型集成的模型服务推理图。以下图显示了 Seldon Core 框架的核心组件:

图 7.7 – Seldon Core 模型服务框架架构

图 7.7:Seldon Core 模型服务框架架构

Seldon Core 为一些常见的机器学习库提供了打包的模型服务器,包括用于 scikit-learn 模型的 SKLearn 服务器、用于 XGBoost 模型的 XGBoost 服务器、用于 TensorFlow 模型的 TensorFlow Serving 以及基于 MLflow 的模型服务。您还可以为特定的模型服务需求构建自己的自定义服务容器,并使用 Seldon Core 进行托管。

以下模板展示了如何使用 Seldon Core 通过 SKLearn 服务器部署模型。您只需更改modelUri路径,使其指向云对象存储提供商上保存的模型,例如Google Cloud StorageAmazon S3 存储Azure Blob 存储。为了测试示例,您可以将以下modelUri值更改为 Seldon Core 提供的示例 - gs://seldon-models/sklearn/iris

apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
name: sklearn
spec:
name: sklearn-model
predictors:
- graph:
children: []
      implementation: SKLEARN_SERVER
modelUri: <model uri to model artifacts on the cloud storage>
name: classifier
name: default
replicas: 1 

Seldon Core 还支持一种高级工作流程,称为推理图,用于服务模型。推理图功能允许您在单个推理管道中拥有不同模型和其他组件的图。一个推理图可以由几个组件组成:

  • 用于不同预测任务的一个或多个 ML 模型

  • 不同使用模式(如 A/B 测试中对不同模型的流量分割)的流量路由管理

  • 用于组合多个模型结果的组件,例如模型集成组件

  • 用于转换输入请求(例如执行特征工程)或输出响应(例如,以JSON格式返回数组格式)的组件

要在 YAML 中构建推理图规范,您需要在seldondeployment YAML 文件中包含以下关键组件:

  • 一个预测因子列表,每个预测因子都有自己的componentSpecs部分,指定容器镜像等详细信息

  • 描述每个componentSpecs部分中组件如何相互连接的图

以下示例模板展示了自定义金丝雀部署的推理图,将流量分割为模型的两个不同版本 - 一个有 75%的流量,另一个有 25%的流量:

apiVersion: machinelearning.seldon.io/v1alpha2
kind: SeldonDeployment
metadata:
name: canary-deployment
spec:
name: canary-deployment
predictors:
- componentSpecs:
- spec:
containers:
- name: classifier
image: <container uri to model version 1>
graph:
children: []
      endpoint:
type: REST
name: classifier
type: MODEL
name: main
replicas: 1
traffic: 75
- componentSpecs:
- spec:
containers:
- name: classifier
image: <container uri to model version 2>
graph:
children: []
      endpoint:
type: REST
name: classifier
type: MODEL
name: canary
replicas: 1
traffic: 25 

一旦应用部署清单,Seldon Core 操作员负责创建用于服务 ML 模型所需的所有资源。具体来说,操作员将创建清单中定义的资源,向 Pod 添加编排器以管理推理图的编排,并使用如 Istio 等入口网关配置流量。

Triton 推理服务器

Triton 推理服务器是一种开源软件,旨在简化 AI 推理的过程。它为从各种深度学习和 ML 框架(包括 TensorRT、TensorFlow、PyTorch、ONNX、OpenVINO、Python 等)部署 AI 模型提供了一种灵活的解决方案。Triton 与广泛的设备兼容,支持在云环境、数据中心、边缘设备和嵌入式系统中进行推理。与 Seldon Core 相比,Triton 推理服务器更注重性能。它被设计为高度可扩展和高效,是高流量应用的理想选择。以下图展示了 Triton 推理服务器的核心组件:

包含文本、截图、图表、数字的图片,自动生成描述

图 7.8:Triton 推理服务器架构

Triton 推理服务器架构包括多个组件,它们协同工作以实现高效和可扩展的推理。其核心是后端,代表 Triton 支持的特定深度学习或机器学习框架。每个后端处理使用其相应框架训练的模型的加载和执行。Triton 推理服务器作为中央枢纽,接收和管理推理请求。它与客户端(如 Web 应用程序或服务)通信,并协调推理过程。模型仓库作为训练模型的存储位置。它包含与支持的各个后端兼容的模型序列化版本。当客户端请求时,服务器会访问并加载模型到内存中进行推理。

Triton 支持多种推理协议,包括 HTTP/REST 和 gRPC,允许客户端与服务器通信并发出推理请求。客户端可以使用这些协议指定输入数据和期望的输出格式。为了监控和优化性能,Triton 提供了指标和监控功能。这些指标包括 GPU 利用率、服务器吞吐量、延迟以及其他相关统计数据。监控这些指标有助于管理员优化资源利用并识别潜在的瓶颈。

Triton 还提供动态批处理功能。此功能允许通过将多个推理请求分组到一起成批处理来高效处理。这种批处理机制优化了资源利用并提高了整体推理性能。

总体而言,Triton 推理服务器架构旨在促进 AI 模型在多种框架和硬件平台上的高效部署和执行。它提供灵活性、可扩展性和可扩展性,使组织能够利用其首选框架,同时确保高性能的推理能力。

监控生产中的模型

由于各种因素,如数据模式的变化、用户行为的转变或不可预见的情况,模型性能可能会随时间恶化。为确保部署的机器学习模型持续有效,对它们在生产中的性能和行为进行持续监控至关重要。

模型监控涉及积极跟踪和分析已部署的机器学习模型的性能。这个过程包括收集不同指标和指标的数据,将它们与预定义的阈值或基线进行比较,并识别异常或与预期行为不符的情况。模型监控的两个关键方面是数据漂移和模型漂移:

  • 数据漂移:数据漂移指的是随时间变化的数据的统计属性发生变化的情况。这可能导致用于训练模型的数据与生产环境中遇到的数据之间产生脱节。数据漂移对机器学习模型的表现和可靠性有重大影响,因为它们可能难以适应数据中的新和演变模式。

  • 模型漂移:模型漂移指的是由于数据中潜在模式或关系的变化而导致机器学习模型性能随时间退化的情况。当模型训练期间做出的假设在生产环境中不再成立时,就会发生模型漂移。它可能导致准确性下降、错误增加和决策不佳。

为了支持模型监控工作,市场上提供了多种开源和商业产品。这些工具提供了监控模型性能、检测数据漂移、识别模型漂移以及生成洞察力以帮助组织采取必要纠正措施的能力。一些流行的例子包括 Evidently AI、Arize AI、Seldon Core、Fiddler 和 Author AI。

管理机器学习特征

随着组织越来越多地采用机器学习解决方案,它们认识到在整个机器学习生命周期中标准化和共享常用数据和代码的必要性。组织寻求集中管理的关键要素之一是机器学习特征,这些特征是常用数据属性,作为机器学习模型的输入。为了实现这些特征的标准化和重用,组织通常转向特征存储。

特征存储充当存储和管理机器学习特征的集中式仓库。它提供了一个专门的平台,用于组织、验证和在不同机器学习项目和团队之间共享特征。通过在单一位置整合特征,特征存储促进了一致性并促进了数据科学家和机器学习实践者之间的协作。

由于其众多益处,特征存储的概念在机器学习社区中受到了广泛关注。首先,它通过消除为每个机器学习项目重新创建和构建特征的需求来提高生产力。相反,数据科学家可以轻松地从存储中访问预先计算和验证的特征,节省时间和精力。此外,特征存储通过确保用于机器学习模型中特征的一致性和质量来提高模型性能。通过集中管理特征,组织可以实施数据治理实践,执行特征验证,并监控特征质量,从而实现更可靠和准确的机器学习模型。

市场上可用的开源特征存储框架包括 Feast 和 Hopsworks Feature Store,为组织提供了灵活的选项来管理他们的机器学习特征。让我们以 Feast 为例,深入了解特征存储是如何工作的。

Feast 是一个开源的特征存储库,它使组织能够管理、发现并为机器学习应用提供服务。由 Tecton 开发,Feast 旨在处理大规模、实时特征数据。它支持从各种来源获取特征,包括批处理管道和 Apache Kafka 等流系统。Feast 与 TensorFlow 和 PyTorch 等流行的机器学习框架良好集成,允许无缝集成到机器学习工作流程中。凭借特征版本控制、数据验证和在线离线服务功能,Feast 为特征管理提供了一个全面的解决方案。

包含文本、截图、图表、字体描述的图片,自动生成

图 7.9:Feast 特征存储

Feast 架构的核心是线上线下特征存储,它作为特征数据的集中存储。特征存储库将特征数据存储在分布式存储系统中,允许进行可扩展和高效的存储和检索特征值。

Feast 采用了解耦架构,其中特征数据的摄取和特征的服务是分离的。数据摄取组件负责从各种来源提取特征数据,例如数据仓库、数据库和流平台。然后它将特征数据转换并加载到特征存储中,确保数据质量和一致性。

特征服务组件负责在训练和推理期间为机器学习模型提供低延迟的特征数据访问。特征服务组件还支持在线和离线服务模式,允许实时和批量特征服务。

为了实现高效的数据发现,Feast 采用了一个特征注册表。特征注册表允许根据不同的特征组合和时间范围快速查找和检索特征值。

Feast 还通过其 SDK 和客户端库与流行的机器学习框架,如 TensorFlow 和 PyTorch 集成。这些集成使得 Feast 能够无缝集成到机器学习管道和工作流程中,使数据科学家和机器学习工程师能够轻松访问和利用模型中的特征数据。

总体而言,Feast 特征存储架构为管理和提供机器学习特征提供了一个强大且可扩展的解决方案。通过集中管理特征数据,Feast 使组织能够提高生产力、改善模型性能并促进机器学习开发中的协作。

自动化机器学习管道工作流程

为了自动化我们迄今为止讨论的核心机器学习平台组件,我们需要构建能够使用这些组件编排不同步骤的管道。自动化提高了效率、生产力和一致性,同时实现了可重复性和最小化了人为错误。有几种开源技术可用于自动化机器学习工作流程,Apache Airflow 和 Kubeflow Pipelines 是其中的突出例子。

Apache Airflow

Apache Airflow 是一个开源软件包,用于以编程方式创建、调度和监控多步骤工作流程。它是一个通用的工作流程编排工具,可以用于定义各种任务的流程,包括机器学习任务。首先,让我们探索一些核心的 Airflow 概念:

  • 有向无环图(DAG):DAG 定义了独立执行的任务,它们在管道中独立执行。执行顺序可以像图形一样可视化。

  • 任务:任务是在 Airflow 中执行的基本单元。在执行过程中,任务之间存在依赖关系。

  • 操作符:操作符是 DAG 组件,用于描述管道中的单个任务。操作符实现了任务执行逻辑。Airflow 提供了一系列操作符,用于常见任务,例如运行 Python 代码的 Python 操作符,或与 S3 服务交互的 Amazon S3 操作符。当实例化操作符时,会创建任务。

  • 调度:DAG 可以按需运行或按预定的时间表运行。

  • 传感器:传感器是一种特殊类型的操作符,旨在等待某个事件发生。然后,它们可以帮助触发下游任务的发生。

Airflow 可以在单台机器或集群上运行。此外,它还可以部署在 Kubernetes 基础设施上。以下图显示了多节点 Airflow 部署:

图 7.8 – Apache Airflow 架构

图 7.10:Apache Airflow 架构

主节点主要运行 Web 服务器调度器。调度器负责调度 DAG 的执行。它将任务发送到队列,工作节点从队列中检索任务并运行它们。元数据存储用于存储 Airflow 集群和进程的元数据,例如任务实例详情或用户数据。

您可以使用 Python 编写 Airflow DAG。以下示例代码展示了如何使用 Python 编写一个基本的 Airflow DAG,其中包含两个按顺序排列的 Bash 操作符:

from airflow import DAG
from airflow.operators.bash_operator import BashOperator
from datetime import datetime, timedelta
default_args = {
    'owner': myname,
}
dag = DAG('test', default_args=default_args, schedule_interval=timedelta(days=1))
t1 = BashOperator(
    task_id='print_date',
    bash_command='date',
    dag=dag)
t2 = BashOperator(
    task_id='sleep',
    bash_command='sleep 5',
    retries=3,
    dag=dag)
t2.set_upstream(t1) 

Airflow 可以连接到许多不同的来源,并为许多外部服务内置了操作符,例如 Amazon EMRAmazon SageMaker。它已被许多组织广泛采用,用于在生产环境中运行大规模工作流程编排作业,例如协调 ETL 作业和机器学习数据处理作业。AWS 甚至提供了一种管理的 Airflow 服务,以帮助减少运行 Airflow 基础设施的操作开销。

Airflow 也存在一些限制。Airflow 不提供 DAG 开发的 UI 设计器,这对于没有 Python 编程技能的用户来说可能是一个挑战,因为他们需要设计工作流。与 DAG 管道缺乏版本控制也带来了管理和理解管道演变变体的一些挑战。在 Kubernetes 上运行 Airflow 可能很复杂,这也是为什么许多组织选择托管服务的原因。然而,尽管存在这些限制,但由于其企业级能力、强大的社区支持和丰富的生态系统,Airflow 仍然成为了一个高度流行的流程编排工具。

Kubeflow Pipelines

Kubeflow Pipelines 是一个 Kubeflow 组件,它专为在 Kubernetes 上编写和编排端到端机器学习工作流而设计。首先,让我们回顾一下 Kubeflow Pipelines 的核心概念:

  • 管道:管道描述了一个机器学习工作流,工作流中的所有组件,以及组件在管道中的相互关系。

  • 管道组件:管道组件在管道中执行任务。管道组件的一个例子可以是数据处理组件或模型训练组件。

  • 实验:实验组织了机器学习项目的不同试验运行(模型训练),以便您可以轻松检查和比较不同的运行及其结果。

  • 步骤:管道中一个组件的执行称为步骤。

  • 运行触发器:您可以使用运行触发器启动管道的执行。运行触发器可以是周期性触发器(例如,每 2 小时运行一次),也可以是计划触发器(例如,在特定日期和时间运行)。

  • 输出工件:输出工件是管道组件的输出。输出工件的例子可以是模型训练指标或数据集的可视化。

Kubeflow Pipelines 作为 Kubeflow 安装的一部分被安装。它自带一个 UI,这是整体 Kubeflow 仪表板 UI 的一部分。Pipelines 服务管理管道及其运行状态,并将它们存储在元数据数据库中。有一个编排和工作流控制器来管理管道的实际执行和组件。以下图展示了 Kubeflow 管道中的核心架构组件:

图 7.9 – Kubeflow Pipelines 架构

图 7.11:Kubeflow Pipelines 架构

您可以使用 Python 中的 Pipeline SDK 编写管道。要创建和运行管道,请按照以下步骤操作:

  1. 使用 Kubeflow SDK 创建管道定义。管道定义指定了一组组件以及它们如何在图中连接在一起。

  2. 将定义编译成由 Kubeflow Pipelines 服务执行的静态 YAML 规范。

  3. 将规范注册到 Kubeflow Pipelines 服务中,并从静态定义中调用管道以运行。

  4. Kubeflow Pipelines 服务调用 API 服务器以创建运行管道的资源。

  5. 编排控制器执行各种容器以完成管道运行。

需要注意的是,使用 Kubeflow Pipelines 运行管道需要具备高度的 Kubernetes 熟练度,这对于没有深厚 Kubernetes 技能的人来说可能具有挑战性。在 Python 中构建工作流程可能是一项复杂的任务,涉及为每个组件编写 Dockerfile 或 YAML 文件,以及为工作流程和执行编写 Python 脚本。Kubeflow Pipelines 主要在 Kubeflow 环境中工作,与外部工具和服务的集成非常有限。它还缺少本地的管道版本控制功能。尽管存在这些挑战,但由于其对端到端机器学习管理的支持、工作流程可视化、可移植性和可重复性,Kubeflow Pipelines 仍然被广泛采用。

现在我们已经探讨了用于构建 ML 平台的各种开源工具,让我们深入了解使用这些开源框架和组件的端到端架构。

设计端到端 ML 平台

在单独讨论了几种开源技术之后,现在让我们深入了解它们的集成,看看这些组件是如何结合在一起的。架构模式和技术栈的选择可能根据具体需求和需求而有所不同。以下图表展示了 ML 平台架构的概念性构建块:

包含文本、截图、图表、设计的图片,自动生成描述

图 7.12:ML 平台架构

接下来,让我们深入了解不同的策略,以不同的开源技术组合来实现这种架构概念。

基于 ML 平台的策略

当使用开源技术设计 ML 平台时,一种有效的策略是利用 ML 平台框架作为基础平台,然后集成额外的开源组件以满足特定需求。这样的 ML 平台框架之一是 Kubeflow,它提供了一套强大的基础构建块,用于构建 ML 平台。通过利用 Kubeflow,您可以从其核心组件中受益,并通过集成互补的开源工具来扩展平台的功能。

这种策略通过无缝集成一系列开源 ML 组件到平台中,提供了灵活性和定制化。如果您的基础 ML 平台框架满足大部分需求,或者您可以在框架的限制内工作,您会选择这种方法。以下表格概述了关键 ML 平台组件及其相应的开源框架和工具:

ML 平台组件开源框架
代码仓库GitHub
实验和模型开发Kubeflow Jupyter Notebook
实验跟踪MLflow 实验跟踪器
特征存储Feast 特征存储
数据标注计算机视觉标注工具 (CVAT)
训练Kubeflow 训练操作符
数据和模型测试Deepchecks
模型仓库MLflow 模型仓库
机器学习管道开发Kubeflow 管道
模型推理Kubeflow KFServing(Seldon Core、TFServing、Triton)
Docker 镜像仓库Docker Hub
CI/CDGitHub Actions
漂移监控Deepchecks

表 7.1:机器学习平台组件及其对应的开源框架

通过将这些框架和工具纳入架构概念图,我们可以将结果图可视化如下:

包含文本、截图、图表、设计的图片,自动生成描述

图 7.13:基于 Kubeflow 的机器学习平台

使用此架构,数据科学家利用 Kubeflow Jupyter Notebook 进行实验和构建模型。实验运行和相关细节,如数据统计、超参数和模型指标,被跟踪并保存在 MLflow 实验跟踪组件中。

常见的机器学习功能存储在 Feast 特征存储中。当需要数据标注时,数据标注员可以使用如 计算机视觉标注工具CVAT)和 Label Studio 等开源数据标注工具来标注数据以供模型训练。数据科学家可以利用特征存储和标注数据集作为他们实验和模型构建的一部分。

GitHub 是数据科学家的代码仓库。他们将所有源代码,包括训练脚本、算法代码和数据转换脚本,保存在代码仓库中。模型训练和推理 Docker 镜像存储在 Docker Hub。可以将 Docker 镜像构建过程部署以创建用于训练和推理的新 Docker 镜像。

对于正式的模型训练,训练脚本从 GitHub 仓库拉取,训练 Docker 镜像从 Docker Hub 拉取到 Kubeflow 训练操作符以启动模型训练,包括训练数据集。可以使用 Deepchecks 进行数据验证和模型性能检查。一旦模型训练完成,模型工件以及任何元数据,如模型指标和评估图表,都存储在 MLflow 模型注册表中。

当是时候部署模型时,模型从 MLflow 模型注册表中检索并加载到 KFServing 以进行模型推理,包括模型推理 Docker 镜像和推理脚本。KFServing 提供了选择不同推理服务器(包括 Seldon Core、TFServing 和 Triton)的灵活性。

预测日志可以发送到模型监控组件以检测数据漂移和模型漂移。可以使用如 Evidently AI 等开源软件工具进行数据漂移和模型漂移检测。

为了编排各种任务,如数据处理、特征工程、模型训练和模型验证,可以开发 Kubeflow Pipelines。对于CI/CD持续集成/持续部署),可以使用 GitHub Actions 作为触发机制来启动不同的管道。

总体而言,这种方法允许您结合基础机器学习平台框架的优势和广泛开源组件提供的灵活性。

基于机器学习组件的策略

另一种方法是使用单个组件而不是依赖基础机器学习平台框架来构建机器学习平台。这种策略的优势在于为平台每个方面选择最佳组件,使组织能够遵守其现有的开源标准,如管道开发或笔记本 IDE 的核心组件。以下架构模式说明了这种方法。

包含文本、截图、图表、设计的图片,自动生成描述

图 7.14:基于组件的架构

在这种架构模式中,利用替代技术和工具进行管道开发、笔记本环境和训练基础设施管理。此外,Kubernetes 作为基础设施管理框架。这种方法允许组织利用与其独特需求和偏好相一致的具体技术和工具。

一个值得注意的方面是使用 Airflow 作为跨多个技术学科的标准编排和管道工具,包括机器学习和数据管理。Airflow 在组织中的广泛应用使其成为统一的管道管理工具,促进不同组件和工作流程之间的无缝集成。

此外,这种架构模式强调在 Kubernetes 之上构建定制的训练和推理基础设施。通过利用 Kubernetes,组织可以获得创建定制化训练和推理环境的灵活性,以满足其特定需求。

除了提供满足机器学习平台要求的免费开源工具外,考虑将商业组件集成到开源架构中也很重要。这些商业产品可以增强机器学习平台的具体方面,并提供额外的功能。

例如,当在 AWS 上部署此架构模式时,建议探索使用 Amazon Elastic Container Registry (ECR)作为 Docker 镜像仓库。Amazon ECR 提供了一个托管和安全的解决方案,用于存储和管理容器镜像,与 AWS 其他服务无缝集成。

在监控方面,有像 Fiddler 和 Author AI 这样的商业产品可以提供高级功能和见解。这些工具可以增强机器学习平台的监控能力,提供深入分析、模型可解释性和模型行为及性能的可视化。

总体而言,这种架构模式的优点包括能够为机器学习平台的不同方面选择替代技术和工具,利用 Airflow 作为统一的管道管理工具,以及在 Kubernetes 上构建定制的训练和推理基础设施。这些选择使组织能够创建一个量身定制且优化的机器学习平台,与他们的需求精确匹配,并允许进行高度定制的训练和推理过程。

摘要

在本章中,您已经了解了典型机器学习平台的核心架构组件及其功能。我们探讨了各种开源技术,如 Kubeflow、MLflow、TensorFlow Serving、Seldon Core、Triton 推理服务器、Apache Airflow 和 Kubeflow 流水线。此外,我们还讨论了使用开源框架和工具设计机器学习平台的多种策略。

虽然这些开源技术为构建复杂的机器学习平台提供了强大的功能,但重要的是要认识到构建和维护这样的环境需要大量的工程努力和专业知识,尤其是在处理大规模机器学习平台时。

在下一章中,我们将深入探讨专门为促进机器学习环境开发和运营而设计的完全托管机器学习解决方案。这些托管解决方案旨在简化构建和管理机器学习平台的复杂性,提供预配置和可扩展的基础设施,以及针对机器学习工作流程的额外功能。

留下评论!

喜欢这本书吗?通过留下亚马逊评论来帮助像您这样的读者。扫描下面的二维码,获取您选择的免费电子书。

图片

限时优惠

第八章:使用 AWS 机器学习服务构建数据科学环境

虽然一些组织选择使用开源技术构建自己的机器学习平台,但许多其他组织更喜欢利用完全托管的机器学习服务作为其机器学习平台的基础。在本章中,我们将深入了解 AWS 提供的完全托管的机器学习服务。具体来说,您将了解Amazon SageMaker以及为数据科学家构建数据科学环境的相关服务。我们将检查 SageMaker 的各个组件,如 SageMaker Studio、SageMaker Training 和 SageMaker Hosting。此外,我们将深入研究构建数据科学环境的架构框架,并提供一个动手练习,指导您完成该过程。

简而言之,本章将涵盖以下主题:

  • SageMaker 概述

  • 使用 SageMaker 构建的数据科学环境架构

  • 构建数据科学环境的最佳实践

  • 动手实验室 - 使用 AWS 服务构建数据科学环境

技术要求

在本章中,您需要访问 AWS 账户,并拥有以下 AWS 服务以进行动手实验室:

  • Amazon S3

  • Amazon SageMaker

  • Amazon ECR

您还需要从www.kaggle.com/ankurzing/sentiment-analysis-for-financial-news下载数据集。

本章中使用的示例源代码可在github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/tree/main/Chapter08找到。

SageMaker 概述

Amazon SageMaker 提供覆盖整个机器学习生命周期的机器学习功能,从初始实验到生产部署和持续监控。它满足各种角色,如数据科学家、数据分析师和 MLOps 工程师。以下图表展示了 SageMaker 的关键功能,这些功能支持不同角色的完整数据科学之旅:

计算机屏幕截图  自动生成的描述

图 8.1:SageMaker 功能

在 SageMaker 中,数据科学家可以访问一系列功能和服务的组合,以支持不同的机器学习任务。这些包括用于模型构建的 Studio 笔记本,用于可视数据准备的 Data Wrangler,用于大规模数据处理和转换的 Processing 服务,训练服务,用于模型调优的 Tuning 服务,以及用于模型托管的 Hosting 服务。有了这些工具,数据科学家可以处理各种机器学习职责,如数据准备、模型构建和训练、模型调优以及进行模型集成测试。

另一方面,数据分析师可以利用 SageMaker Canvas,这是一个用户友好的模型构建服务,几乎不需要编写代码。这个可视化界面使分析师能够轻松训练模型。此外,他们还可以使用 Studio 笔记本进行轻量级的数据分析和处理。

MLOps 工程师在管理和治理 ML 环境中扮演着至关重要的角色。他们负责自动化 ML 工作流程,并可以利用 SageMaker Pipelines、模型注册和端点监控来实现这一目标。此外,MLOps 工程师配置处理、训练和托管基础设施,以确保数据科学家交互式使用和自动化操作都能顺利进行。

在本章中,我们的重点将集中在专门针对数据科学家的数据科学环境中。随后,在下一章中,我们将深入探讨 ML 基础设施的治理、管理和自动化。

使用 SageMaker 的数据科学环境架构

数据科学家使用数据科学环境,通过不同的数据集和算法迭代不同的数据科学实验。这些环境需要诸如 Jupyter Notebook 等基本工具来编写和执行代码,数据处理引擎来处理大规模数据处理和特征工程,以及模型训练服务来大规模训练模型。此外,一个有效的数据科学环境还应包括用于管理和跟踪不同实验运行的工具,使研究人员能够有效地组织和监控他们的实验。为了管理诸如源代码和 Docker 镜像等工件,数据科学家还需要代码仓库和 Docker 容器仓库。

以下图表展示了使用 Amazon SageMaker 和其他支持服务的基本数据科学环境架构:

图 8.1 – 数据科学环境架构

图 8.2:数据科学环境架构

SageMaker 拥有多个数据科学环境,包括 Studio,这是数据科学家的主要开发环境,RStudio 为 R 用户设计,Canvas 为希望构建 ML 模型的无代码/低代码开发环境用户设计。您还可以访问 TensorBoard,这是一个用于监控和可视化模型指标(如损失和准确率)的流行工具。

现在,让我们探讨数据科学家如何利用 SageMaker 的不同组件来完成数据科学任务。

指导 SageMaker 用户

SageMaker 的主要用户界面是 SageMaker Studio,这是一个数据科学 集成开发环境IDE)。它提供了核心功能,如托管笔记本以运行实验,以及从单一用户界面访问不同的后端服务,如数据整理、模型训练和模型托管服务。它是数据科学家与 SageMaker 大多数功能交互的主要界面。它还提供了一个 Python SDK,用于从 Python 笔记本或脚本中以编程方式与其后端服务交互。以下图显示了 SageMaker Studio 的关键组件:

图 8.2 – SageMaker Studio 架构

图 8.3:SageMaker Studio 架构

SageMaker Studio 实现了域的概念来隔离用户环境。域代表一组用户配置文件,每个配置文件都配备了特定的配置,例如运行 Jupyter 笔记本时使用的 AWS IAM 角色、标签以及访问 SageMaker Canvas 的权限。在域内,每个 Studio 用户都可以通过用户配置文件访问不同的 Studio 应用程序,如 JupyterLab、代码编辑器或 Canvas。

要运行某些 Studio 应用程序,如 JupyterLab 和代码编辑器,您需要创建 SageMaker Studio 空间。SageMaker Studio 空间用于管理这些应用程序的存储和资源需求。每个空间与一个应用程序实例有一个 1:1 的关系,并包含诸如存储卷、应用程序类型和应用程序基于的镜像等资源。空间可以是私有的也可以是共享的。

要开始使用 SageMaker,第一步是将用户引入 SageMaker Studio。如果尚未存在,则通过创建 SageMaker 域来启动注册过程。对于单用户场景,SageMaker 提供了快速域设置选项。使用快速设置选项,SageMaker 会自动使用默认设置配置新域以实现快速设置。对于高级多用户场景,SageMaker 提供了高级域设置选项。使用高级设置,您可以配置域的各个方面以适应企业采用,例如认证方法、访问不同服务、网络配置和数据加密密钥。随后,在域内创建用户配置文件,并授予用户对这些配置文件的访问权限。一旦用户配置文件设置完成,用户可以通过在域中选择各自的用户配置文件来启动 Studio 环境。这使他们能够在 SageMaker Studio 中开始工作。

启动 Studio 应用程序

Studio 内部有多种应用程序可供使用,包括 JupyterLab、RStudio、Canvas 和代码编辑器。您还可以选择启动之前的 Studio 经典体验。

在 SageMaker Studio 环境中,启动 Jupyter notebook 是一个简单的过程。首先选择 JupyterLab 应用程序,然后创建一个 JupyterLab 空间。空间作为一个命名、自包含且持久的存储容器,可以附加到 JupyterLab 应用程序上。在空间创建过程中,您可以灵活地选择服务器实例类型和 JupyterLab 的 Docker 镜像。一旦空间成功创建,您就可以启动 JupyterLab 应用程序并在其中启动笔记本。JupyterLab 笔记本现在具有一个 AI 驱动的编程助手(Jupyternaut)功能,您可以使用它来提问编程问题。例如,您可以提问“如何导入 Python 库?”或“如何使用 SageMaker 训练模型?”。

类似地,在 SageMaker Studio 环境中启动 Canvas 应用程序也涉及在其中选择它。作为一个无代码机器学习工具,Canvas 提供了数据准备、模型训练、推理和工作流程自动化的功能。Canvas 主要面向数据分析师,他们可能在数据科学和机器学习方面背景有限,但它也证明对经验丰富的数据科学家很有价值,他们希望快速为各种数据集建立基线模型。用户可以利用 Canvas 的现成模型进行预测,而无需构建模型,或者选择创建针对特定业务问题的定制模型。现成模型涵盖了各种用例,如语言检测和文档分析。对于定制模型,Canvas 支持使用表格和图像数据构建多种模型类型,以进行个性化预测。

支持从本地或外部源导入数据,如 S3、Amazon Redshift 或 Databricks。此外,Canvas 通过 Data Wrangler 促进数据准备,并提供用于启动对话聊天的生成式 AI 基础模型。

基于 Code-OSS 和 Visual Studio Code Open Source 构建的代码编辑器,便于编写、测试、调试以及运行分析和机器学习代码。要启动代码编辑器,只需在 Studio 中选择应用程序并创建一个专用私有空间。此空间在单个 Amazon Elastic Compute Cloud (Amazon EC2) 实例上进行计算,并对应一个 Amazon Elastic Block Store (Amazon EBS) 存储卷。空间内的所有元素,包括代码、Git 配置文件和环境变量,都存储在这个统一的 Amazon EBS 存储卷上。

准备数据

准备和加工数据以用于模型训练是机器学习生命周期中优化模型性能的一个关键步骤。在 Studio 环境中,您可以直接在 Studio 笔记本中安装和使用您首选的库包来完成这项工作。SageMaker 还提供了一些数据整理和加工服务,以协助数据准备,包括 SageMaker Data Wrangler,以及与 Amazon EMR 和 Glue 集成的数据准备,用于大规模数据准备和处理。

使用 SageMaker Data Wrangler 交互式准备数据

SageMaker Data Wrangler 是一种完全托管的服务,帮助数据科学家和工程师准备和分析他们的数据以用于机器学习。它提供了一个图形用户界面,简化了数据准备任务,例如数据清洗、特征工程、特征选择和可视化。

要使用 Data Wrangler,您需要构建一个数据流,这是一个连接数据集、转换和分析的管道。当您创建并运行一个数据流时,Data Wrangler 会启动一个 EC2 实例来运行转换和分析。每个数据流都与一个 EC2 实例相关联。数据流通常从数据导入步骤开始。Data Wrangler 允许您从多个数据源导入数据,包括 Amazon S3、Athena、Amazon Redshift、Amazon EMR、Databricks、Snowflake,以及 软件即服务 (SaaS) 平台,如 Datadog、GitHub 和 Stripe。

数据导入后,您可以使用 Data Wrangler 清洗和探索数据,并使用内置的转换进行特征工程。您还可以使用预配置的可视化模板来理解数据和检测异常值。

您可以使用内置的报告来评估数据质量。以下图显示了 Data Wrangler 的流程和架构:

数据处理流程图  描述自动生成

图 8.4:SageMaker Data Wrangler 架构

当使用 Data Wrangler 时,第一步涉及从各种数据源导入样本数据以执行数据处理和转换。完成必要的转换步骤后,您可以选择导出一份食谱。然后,SageMaker Processing 可以执行这份食谱,根据定义的转换处理整个数据集。

此外,您还可以选择将转换步骤导出到笔记本文件中。这个笔记本文件可以用来启动 SageMaker Processing 作业,允许对数据进行处理和转换。结果输出可以指向 SageMaker Feature Store 或存储在 Amazon S3 以供进一步使用和分析。

交互式大规模数据准备

在处理大规模数据分析、转换和准备任务时,SageMaker 提供了与 Amazon EMR 和 AWS Glue 的内置集成。这种内置集成允许您管理和处理大规模交互式数据准备。通过利用 Amazon EMR,您可以处理和分析大量数据集,同时 AWS Glue 提供了一种无服务器能力,可以在大规模上准备数据,并提供对 Glue 数据目录的便捷访问。

在 Studio 笔记本环境中,您有发现和建立与现有 Amazon EMR 集群连接的能力。这使得他们能够交互式地探索、可视化和准备用于机器学习任务的大规模数据,利用 Apache Spark、Apache Hive 和 Presto 等强大工具。以下图显示了 SageMaker 与 EMR 的集成方式:

软件开发流程图  自动生成的描述

图 8.5:SageMaker 与 EMR 的集成

作为用户,您可以从您的 Studio 笔记本连接到现有的 EMR 集群。如果没有可用的 EMR 集群,您可以直接从 Studio 环境中通过选择系统管理员创建的预定义模板来自行配置一个。系统管理员使用 AWS 服务目录为数据科学家定义参数化模板。一旦您的笔记本连接到 EMR 集群,您就可以在笔记本单元格中运行 Spark 命令或代码。

AWS Glue 交互式会话是一种无服务器服务,它为您提供了收集、转换、清洗和准备数据的工具。SageMaker 与 Glue 交互式会话之间的内置集成允许您使用 Glue 作为后端,交互式地运行数据准备会话。

一个图例的图  自动生成的描述

图 8.6:SageMaker 与 AWS Glue 交互式会话的集成

要在 Studio 笔记本中使用 Glue 交互式会话,您在创建 Studio 笔记本时选择内置的 Glue PySpark 或 Glue Spark 内核。初始化后,您可以在 Studio 笔记本中浏览 Glue 数据目录、运行大型查询,并使用 Spark 交互式分析和准备数据。

EMR 和 Glue 都为大规模交互式数据处理提供了类似的功能。如果您正在寻找一种快速且无服务器的 Spark 会话运行方式,Glue 交互式会话是一个不错的选择。EMR 提供了更强大的功能和配置计算集群以进行优化的灵活性。

将数据处理为单独的任务

SageMaker Processing 为大规模数据处理提供独立的架构,例如为大型数据集提供数据清洗和特征工程作为独立的后端作业。它可以通过 SageMaker Python SDK 或 Boto3 SDK 直接从笔记本环境中访问。SageMaker Processing 使用 Docker 容器镜像来运行数据处理作业。提供了一些内置容器,例如 scikit-learn 容器和 Spark 容器。您还可以选择使用自己的自定义容器进行数据处理。以下图显示了 SageMaker Processing 架构:

图 8.3 – SageMaker Processing 架构

图 8.7:SageMaker Processing 架构

当 SageMaker Processing 作业启动时,处理容器从 Amazon ECR 中拉取并加载到 EC2 计算集群中。S3 中的数据被复制到连接到计算节点的存储中,以便数据处理脚本可以访问和处理。一旦处理过程完成,输出数据将被复制回 S3 输出位置。

SageMaker Processing 提供了多个处理器用于数据处理,包括 Spark 处理器、scikit-learn 处理器和通过引入您的容器实现的客户处理器。SageMaker Processing 还支持不同机器学习框架的处理器,包括 PyTorch、TensorFlow、MXNet、Hugging Face 和 XGBoost。如果您需要在处理脚本中使用库包,可以使用这些处理器之一。

创建、存储和共享特征

当数据科学家进行训练数据准备的特征工程时,他们通常需要为不同的模型任务重用相同的特征。此外,生成的特征可以用于训练和推理,以帮助减少训练-服务偏差。

Amazon SageMaker Feature Store 是一个用于分享和管理机器学习特征以用于机器学习开发和服务的服务。Feature Store 是一个集中存储特征及其相关元数据的地方,以便可以发现和重用特征。它具有在线组件和离线组件。在线存储用于低延迟实时推理用例,离线存储用于训练和批量推理。以下图显示了 Feature Store 的工作方式。如您所见,它与其他开源替代方案(如 Feast)的架构非常相似,主要区别在于它是完全托管的。

软件商店的图示  自动生成的描述

图 8.8:SageMaker Feature Store

首先,你需要阅读并处理原始数据。然后,数据通过流式传输或直接通过批量传输被摄入到在线和离线存储中。特征存储使用名为FeatureGroup的概念来存储和管理特征。FeatureGroup是一组通过特征存储中的模式定义的特征,描述了与记录相关的结构和元数据。你可以将特征组视为一个表格,其中每一列是一个特征,每一行都有一个唯一的标识符。

在线存储专门针对实时预测进行了优化,提供低延迟读取和高吞吐量写入。它非常适合需要快速访问特征数据进行实时推理的场景。另一方面,离线存储是为批量预测和模型训练而设计的。它作为一个只追加存储操作,允许存储和访问历史特征数据。离线存储在探索和模型训练过程中存储和提供特征特别有用。

训练机器学习模型

一旦你准备好了训练数据,你就可以开始训练模型。数据科学家可以使用 SageMaker 训练服务来处理需要专用训练基础设施和实例类型的模型训练。训练服务也适用于使用多个节点进行的大规模分布式训练。

要开始训练,你首先需要将你的训练数据存储在 Amazon S3、Amazon EFS 或 Amazon FSx 等存储中。你根据自己的具体需求选择不同的存储选项,例如成本和延迟。S3 是最常见的一种,适合大多数模型训练需求。使用 S3,你有多种模式将数据从 S3 摄入到训练基础设施中:

  • 文件模式:这是默认输入模式,SageMaker 将训练数据从 S3 下载到训练实例的本地目录。当完整数据集下载完毕后开始训练。使用此模式,训练实例必须有足够的本地存储空间来容纳整个数据集。

  • 管道模式:使用此模式,数据直接从 S3 数据源流式传输。这可以提供比文件模式更快的启动时间和更好的吞吐量。此模式还可以减小附加到训练实例的存储卷的大小。它只需要足够的空间来存储最终模型工件。

  • 快速文件模式:这种模式是管道模式的较新且更易于使用的替代品。在训练开始时,数据文件被识别但尚未下载。训练可以在整个数据集下载完毕之前开始。快速文件模式使用 POSIX 兼容的文件系统接口公开 S3 对象,就像文件在训练实例的本地磁盘上可用一样。它按需流式传输 S3 数据,这意味着你不需要将训练数据拟合到训练实例存储中。

除了 S3,您还可以将训练数据存储在 Amazon FSx for Lustre 中。当您对训练数据有高吞吐量和低延迟的数据检索需求时,您可以使用 FSx。使用 FSx,您可以通过低延迟的文件检索扩展到数百 GB 的吞吐量和数百万每秒输入/输出操作IOPS)。当启动训练作业时,它将 FSx 挂载到训练实例文件系统作为本地驱动器。FSx 允许训练作业运行得更快,因为它读取文件所需的时间更少,并且不需要像 S3 文件模式那样将数据复制到训练实例的本地存储。EFS 提供了与 FSx 类似的功能,但吞吐量较低,延迟较高。

如果您已经在 EFS 系统中有了数据,您可以直接使用 EFS 中的数据启动训练作业,无需数据迁移。这减少了训练启动时间。与 FSx 相比,EFS 成本较低,但吞吐量较低,延迟较高。

一旦训练数据已准备好在您选择的存储系统中,您可以使用 AWS Boto3 SDK 或 SageMaker Python SDK 启动训练作业。要运行训练作业,您需要提供配置细节,例如来自 ECR 的训练 Docker 镜像的 URL、训练脚本位置、框架版本、训练数据集位置以及 S3 模型输出位置,以及基础设施细节,例如计算实例类型和数量,以及网络细节。以下示例代码展示了如何使用 SageMaker SDK 配置并启动一个训练作业。

SageMaker 训练服务使用容器作为训练管理的关键技术。所有训练作业都在 SageMaker 训练基础设施上托管的容器内执行。以下图示展示了 SageMaker 训练服务的架构:

图 8.4 – SageMaker 训练服务架构

图 8.9:SageMaker 训练服务架构

SageMaker 为使用不同机器学习算法和机器学习框架进行模型训练提供了各种托管容器。首先,有一系列内置的容器化算法,用于不同的机器学习任务,如计算机视觉、自然语言处理、预测以及常见的表格回归和分类。使用这些内置算法,您只需提供训练数据位置。SageMaker 还提供了一系列托管框架容器,例如 scikit-learn、TensorFlow 和 PyTorch 的容器。使用托管框架容器,除了提供数据源和基础设施规范外,您还需要提供一个运行模型训练循环的训练脚本。

如果内置算法和框架容器不能满足您的需求,您可以为模型训练带来自己的自定义容器。这个容器需要包含模型训练脚本以及运行训练循环所需的所有依赖项。

默认情况下,SageMaker 跟踪所有训练作业及其关联的元数据,例如算法、输入训练数据集 URL、超参数和模型输出位置。训练作业还会向 AWS CloudWatch 发送系统指标和算法指标以进行监控。训练日志也会发送到 CloudWatch 日志以供检查和分析。这些元数据对于谱系追踪和可重复性至关重要。

调整机器学习模型

为了优化模型性能,您还需要尝试不同的超参数,例如梯度下降和模型训练的学习率。一个算法可能包含大量超参数,手动调整它们将是一项劳动密集型任务。SageMaker 调优服务与 SageMaker 训练作业协同工作,以自动调整模型训练超参数。该服务支持以下四种类型的超参数调优策略:

  • 网格搜索:网格搜索是一种穷举搜索技术,它系统地探索每个超参数在指定范围内的预定义超参数值集。它创建了一个所有可能组合的网格,并使用交叉验证或验证集评估每个配置的模型性能。网格搜索非常专注,但由于组合数量庞大,尤其是当超参数维度较高时,它可能非常低效。

  • 随机搜索:随机搜索是一种流行且有效的超参数优化技术,它为像网格搜索这样的穷举方法提供了一种替代方案。与网格搜索不同,后者在预定义的范围内评估所有可能的超参数组合,而随机搜索采取了一种更随机的策略。它不是系统地覆盖整个搜索空间,而是为每个超参数从定义的分布中随机采样超参数值。与网格搜索相比,随机搜索可能更有效率;然而,它可能并不总是能找到最佳的超参数组合。

  • 贝叶斯搜索:在这里,超参数搜索被处理为一个回归问题,其中回归的输入是超参数的值,输出是在使用输入值训练模型后模型性能指标。调优服务使用从训练作业中收集的值来预测下一组将产生模型改进的值。与随机搜索相比,贝叶斯搜索更有效率,因为它使用模型来关注最有希望的超参数搜索空间。

  • Hyperband:Hyperband 利用了 bandit 算法和连续减半的概念,使搜索过程更加有效和资源高效。它首先随机采样大量超参数配置,然后将它们分成多个“波段”或集合。在每个波段中,配置通过预定义的迭代次数进行评估,定期消除表现不佳的配置。然后,幸存下来的配置被提升到下一个波段,在那里它们将获得额外的迭代次数以微调其性能。这个过程持续进行,逐渐增加分配给有希望的配置的资源,同时有效地丢弃表现不佳的配置。Hyperband 被认为比其他方法更有效率,并且可以在更少的迭代中找到良好的超参数组合。

SageMaker 调优服务与 SageMaker 训练作业协同工作以优化超参数。它通过向训练作业发送不同的输入超参数值并选择返回最佳模型指标的超参数值来实现。以下图表展示了 SageMaker 调优服务的工作原理:

训练过程的图  自动生成的描述

图 8.10:SageMaker 调优架构

要使用 SageMaker 调优服务,你需要创建一个调优作业并指定配置细节,例如调优策略、要优化的目标指标、要调整的超参数及其范围、要运行的最大训练作业数以及并行运行的作业数。随后,调优作业将启动多个训练作业。根据调优策略,调优作业将传递不同的超参数到训练作业以执行。训练作业的训练指标将被调优作业用来确定使用哪些超参数以优化模型性能。

部署 ML 模型进行测试

数据科学家通常不会直接部署模型供客户端应用使用。然而,数据科学家有时需要测试使用 SageMaker 训练服务训练的模型的表现,并且他们需要将这些模型部署到 API 端点进行测试。这对于大型模型尤其必要,因为它们无法在笔记本实例中进行评估。SageMaker 提供了一个专门的服务用于模型托管,其架构如下所示:

服务器的图  自动生成的描述

图 8.11:SageMaker 托管架构

SageMaker 托管服务为不同的需求提供了多种模型推理选项,从实时推理到批量推理。以下是一些数据科学家用于模型托管评估和测试的可用选项:

  • 最常见的模型服务用例之一是在持续的基础上进行低延迟的实时预测。对于这个用例,你应该考虑 SageMaker 托管服务中的实时推理选项。SageMaker 实时推理提供了多种模型托管选项,包括单个模型托管、单个端点后单个容器中的多个模型托管,以及单个端点后使用不同容器的多个模型托管。

  • 有时,你有一些模型用于间歇性预测,在流量高峰之间的空闲期间。对于这种需求,你可以考虑 SageMaker 托管服务的无服务器选项。使用无服务器推理的关键好处是消除了基础设施配置和管理开销。它也更经济高效,因为你不需要在未使用时支付基础设施费用,与实时推理不同,无论是否有推理流量,都需要支付基础设施费用。然而,当模型首次被调用或调用之间存在较长的空闲时间以允许 SageMaker 无服务器推理启动实例时,可能会因为冷启动而出现延迟。

  • 有时,推理的负载大小可能非常大,生成预测需要很长时间。在这种情况下,由于负载大小大和推理时间延长,实时端点将无法工作。对于这种类型的用例,你可以考虑 SageMaker 托管的异步推理选项。异步推理将传入的请求排队,并异步处理它们(正如其名称所暗示的)。当使用异步推理时,输入数据和预测输出存储在 S3 中,而不是直接从端点 API 发送负载并获取响应。当预测完成时,你会从 AWS SNS 服务收到通知。

  • 另一种模型推理模式是批量推理。这是当你有大量推理要做,并且不需要为每个预测生成和返回单独预测时。例如,你可能需要为大量用户运行购买倾向模型,并将输出存储在数据库中以供下游使用。对于这种使用模式,你可以考虑 SageMaker 批量转换功能进行模型推理。批量推理也更经济高效,因为你只需要在运行批量作业时启动基础设施。

讨论了完成机器学习项目所涉及的各种任务后,从数据准备到使用不同的 SageMaker 功能进行模型部署,现在让我们简要谈谈自动化的必要性。数据科学家经常进行迭代实验和模型开发,涉及不同的数据集、新特征和多种训练脚本。跟踪每次运行的配置和模型指标变得至关重要。为了简化并自动化这些重复性任务,可以构建自动化管道,支持各种机器学习过程,如数据处理、模型训练和模型测试。

有几种自动化和编排工具可用,包括 SageMaker 的管道功能。它允许创建一个有向无环图DAG),以有效地编排和自动化机器学习工作流程。SageMaker 管道与第七章中讨论的开源工作流编排工具 Airflow 有相似之处。

此外,AWS Step Functions 作为构建自动化工作流编排的替代选项,提供了灵活性和可扩展性,以适应各种机器学习任务。通过利用这些工具,数据科学家可以提高他们在机器学习工作流程中的效率、可重复性和组织性。

构建数据科学环境的最佳实践

数据科学环境旨在让数据科学家使用广泛的机器学习框架和库进行快速实验。以下是在为数据科学家提供此类环境时需要遵循的一些最佳实践:

  • 使用 SageMaker 训练服务而不是 Studio 笔记本进行大规模模型训练:SageMaker Studio 笔记本旨在对小型数据集进行快速实验。虽然为某些大型模型训练作业配置大型 EC2 实例是可能的,但始终保持大型 EC2 实例运行以供笔记本使用并不经济。

  • 从数据科学家那里抽象出基础设施配置细节:在使用 SageMaker 时,有许多基础设施配置需要考虑,例如网络配置、IAM 角色、加密密钥、EC2 实例类型和存储选项。为了使数据科学家的生活更轻松,将这些细节抽象出来。例如,而不是让数据科学家输入特定的网络配置,将这些细节存储为环境变量或数据科学家可以选择的自定义 SDK 选项。

  • 创建自助服务配置:为了防止配置瓶颈,考虑构建自助服务配置能力以简化用户入职流程。例如,使用 AWS 服务目录创建一个用于自动化用户入职的机器学习产品。

  • 使用 Studio 笔记本本地模式进行快速模型训练作业测试:SageMaker 支持本地模式,这意味着你可以在 Studio 笔记本中模拟本地运行训练作业。使用 SageMaker 训练作业时,启动单独基础设施会有额外的开销。在本地运行这些测试可以帮助加快实验速度。

  • 设置安全措施:这有助于防止科学家犯诸如为模型训练使用错误的实例类型或忘记使用数据加密密钥等错误。你可以使用 AWS 服务控制策略来帮助进行安全措施管理。

  • 清理未使用的资源:定期审查并清理未使用的笔记本、端点和其它资源,以避免不必要的费用。

  • 使用 Spot 实例:为了成本优化,如果可能的话,考虑使用 Amazon EC2 Spot 实例进行训练作业。Spot 实例可以显著降低训练成本,同时保持高性能。然而,由于 Spot 实例可能会意外被回收,因此启用训练检查点非常重要,这样训练可以从最后一个检查点恢复,而不是从头开始重新训练。

  • 使用内置算法和托管容器进行训练:SageMaker 为不同的机器学习任务提供了一系列内置算法,并为不同的机器学习框架提供了托管训练容器。利用这些现有资源可以大幅减少所需的工程工作量,消除从头开始构建自己的算法的需求。

  • 构建可重复的机器学习实验、模型构建和模型测试的自动化管道:拥有自动化管道可以大大减少手动工作量并提高不同实验的跟踪。根据你的技术标准和偏好,考虑不同的编排技术选项。

通过遵循这些最佳实践,你可以充分利用 SageMaker Studio 的功能,简化你的机器学习工作流程,并确保平台的使用既经济高效又安全。

实践练习 - 使用 AWS 服务构建数据科学环境

本实验的主要目标是提供使用各种 SageMaker 工具的实用、动手经验。一旦你熟悉了本实验中的核心功能,你应该独立探索其他功能,例如代码编辑器和 RStudio。

问题陈述

作为一名机器学习解决方案架构师,你被分配在 AWS 上为股票研究部门的科学家们构建数据科学环境。股票研究部门的科学家们有几个自然语言处理问题,例如检测金融短语的情感。一旦为科学家们创建了环境,你还需要构建一个概念验证,向科学家们展示如何使用该环境构建和训练 NLP 模型。

数据集描述

数据科学家表示,他们喜欢使用 BERT 模型来解决情感分析问题,并计划使用金融短语数据集为模型建立一些初始基准:www.kaggle.com/ankurzing/sentiment-analysis-for-financial-news

实验说明

在这个实验中,您将首先建立 SageMaker 域和用户资料,以促进用户加入 SageMaker 工作室。此外,实验还包括通过 JupyterLab 笔记本直接和 SageMaker 训练作业服务学习如何训练深度学习模型。

最后一步将涉及使用 SageMaker 托管服务部署训练好的模型。您还将探索 SageMaker Canvas,以了解如何在不编写任何代码的情况下训练机器学习模型。实验结束后,您将能够将 SageMaker 用作数据科学工具,用于各种实验、模型训练和模型部署任务。SageMaker 还有许多其他功能。

让我们开始吧!

设置 SageMaker 工作室

按照以下步骤设置 SageMaker 工作室环境:

  1. 要创建 SageMaker 工作室环境,我们需要在相应的 AWS 区域设置一个域和一个用户资料。导航到 SageMaker 管理控制台,登录 AWS 管理控制台后,点击左侧的工作室链接。

  2. 在屏幕右侧,点击创建 SageMaker 域按钮。选择单用户设置选项,然后点击设置。创建域和默认用户资料可能需要几分钟时间。

要启动为新创建的用户创建的工作室环境,请再次点击工作室链接,选择您刚刚创建的用户资料,然后点击打开工作室以启动工作室。工作室环境出现可能需要几分钟时间。一旦一切准备就绪,您将看到一个类似于以下屏幕的界面:

图 8.12:工作室 UI

启动 JupyterLab 笔记本

现在,我们需要在 SageMaker 工作室 UI 中启动一个 JupyterLab 应用,以便我们有一个用于编写模型构建脚本和训练机器学习模型的 Jupyter Notebook 环境。继续以下步骤:

  1. 在左侧导航面板的应用程序部分下选择JupyterLab应用。

  2. 在右侧点击创建 JupyterLab 空间以创建 JupyterLab 的空间。在随后的弹出屏幕上为空间提供一个名称,然后点击创建空间

  3. 在下一屏幕上,将存储空间更改为20 GB,选择ml.g5.xLarge,并保持所有其他配置不变,然后点击运行空间

  4. 创建空间可能需要一些时间。一旦就绪,点击打开 JupyterLab以启动它,它将在一个单独的标签页中启动。

在 Jupyter 笔记本中训练 BERT 模型

在本节动手练习中,我们将使用 BERT 转换器训练一个金融情感分析 NLP 模型,这是我们在第三章探索机器学习算法中学到的。要开始,请从菜单下拉中选择文件 > 新建 > 笔记本来创建一个新的笔记本以编写我们的代码。当提示选择内核时,选择Python 3 (ipykernel)。您可以通过选择文件 > 重命名笔记本从菜单中重命名文件,使其具有更有意义的名称。从 Kaggle 下载数据集,网址为www.kaggle.com/ankurzing/sentiment-analysis-for-financial-news。请注意,您需要 Kaggle 账户才能下载。下载完成后,您应该看到一个archive.zip文件。使用您本地机器上的 unzip 工具解压文件。

接下来,让我们将data文件上传到 Studio 笔记本。在新的笔记本所在文件夹中创建一个名为data的新文件夹,并使用 Studio UI 中的文件上传实用程序(向上箭头图标)将文件上传到data目录。选择all-data.csv进行上传。

现在,让我们为我们的练习安装一些额外的包。在笔记本单元中运行以下代码块来安装转换器包。转换器包提供了一系列预训练的转换器,如 BERT。您将使用这些转换器来微调一个机器学习任务。请注意,一些代码块示例并不完整。您可以在github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/blob/main/Chapter08/bert-financial-sentiment.ipynb找到完整的代码示例:

!pip install transformers
!pip install ipywidgets 

在安装ipywidgets后重启笔记本内核。接下来,将一些库导入到笔记本中,并设置日志记录器以进行日志记录:

import logging
import os
import sys
import numpy as np
import pandas as pd
import torch
from torch.utils.data import DataLoader, TensorDataset
from transformers import AdamW, BertForSequenceClassification, BertTokenizer
from sklearn.preprocessing import OrdinalEncoder
from sklearn.model_selection import train_test_split
from types import SimpleNamespace
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler(sys.stdout)) 

现在,我们已经准备好加载data文件并处理它。以下代码块加载data文件并将数据分为训练集和测试集。我们将从文件中选择前两列,并命名为sentimentarticlesentiment列是标签列,它包含三个不同的唯一值(negativeneutralpositive)。由于它们是字符串值,我们将使用 scikit-learn 库中的OrdinalEncoder将它们转换为整数(0, 1, 2)。我们还需要确定文章列的最大长度。最大长度用于为转换器准备输入,因为转换器需要一个固定长度:

filepath = './data/all-data.csv'
data = pd.read_csv(filepath, encoding="ISO-8859-1",
header=None, usecols=[0, 1],
names=["sentiment", "article"])
ord_enc = OrdinalEncoder()
data["sentiment"] = ord_enc.fit_transform(data[["sentiment"]])
data = data.astype({'sentiment':'int'})
train, test = train_test_split(data)
train.to_csv("./data/train.csv", index=False)
test.to_csv("./data/test.csv", index=False)
MAX_LEN = data.article.str.len().max()  # this is the max length of the sentence 

接下来,我们将构建一个实用函数列表来支持数据加载和模型训练。我们需要以批量的形式向转换器模型提供数据。以下 get_data_loader() 函数将数据集加载到具有指定批量大小的 PyTorch DataLoader 类中。请注意,我们还会使用 BertTokenizer 类将文章编码为标记:

def get_data_loader(batch_size, training_dir, filename):
    logger.info("Get data loader")
    tokenizer = BertTokenizer.from_pretrained("bert-base-uncased", do_lower_case=True)
    dataset = pd.read_csv(os.path.join(training_dir, filename))
    articles = dataset.article.values
    sentiments = dataset.sentiment.values
    input_ids = []
    for sent in articles:
        encoded_articles = tokenizer.encode(sent, add_special_tokens=True)
        input_ids.append(encoded_articles)
...
       return tensor_dataloader 

以下 train() 函数将使用 BertForSequenceClassification 类运行训练循环。我们将使用预训练的 BERT 模型进行微调,而不是从头开始训练。我们将一次向 BERT 模型提供一批数据。请注意,我们也会检查服务器上是否有 GPU 设备。如果有,我们将使用 cuda 设备进行 GPU 训练,而不是使用 cpu 进行 CPU 训练。我们需要手动使用 .to(device) 函数将数据和 BERT 模型移动到同一目标设备,以便在目标设备上发生训练,同时数据驻留在同一设备上的内存中。我们在这里使用的优化器是 AdamW,它是梯度下降优化算法的一个变体。训练循环将运行指定数量的 epoch。一个 epoch 会遍历整个训练数据集一次:

def train(args):
    use_cuda = args.num_gpus > 0
    device = torch.device("cuda" if use_cuda else "cpu")
    # set the seed for generating random numbers
    torch.manual_seed(args.seed)
    if use_cuda:
        torch.cuda.manual_seed(args.seed)
    train_loader = get_data_loader(args.batch_size, args.data_dir, args.train_file)
    test_loader = get_data_loader(args.test_batch_size, args.data_dir, args.test_file)
    model = BertForSequenceClassification.from_pretrained(
        "bert-base-uncased",  
        num_labels=args.num_labels,
        output_attentions=False,  
        output_hidden_states=False,  )
... 
return model 

我们还希望在训练期间使用单独的测试数据集来测试模型的性能。为此,我们将实现以下 test() 函数,该函数由 train() 函数调用:

def test(model, test_loader, device):
    def get_correct_count(preds, labels):
        pred_flat = np.argmax(preds, axis=1).flatten()
        labels_flat = labels.flatten()
        return np.sum(pred_flat == labels_flat), len(labels_flat)

    model.eval()
    _, eval_accuracy = 0, 0
    total_correct = 0
    total_count = 0
...
    logger.info("Test set: Accuracy: %f\n", total_correct/total_count) 

现在,我们已经拥有了加载和处理数据、运行训练循环以及使用测试数据集测量模型指标所需的所有函数。有了这些,我们就可以启动训练过程。我们将使用 args 变量设置各种值,例如批量大小、数据位置和学习率,这些值将由训练循环和测试循环使用:

args = SimpleNamespace(num_labels=3, batch_size=16, test_batch_size=10, epochs=3, lr=2e-5, seed=1,log_interval =50, model_dir = "model/", data_dir="data/", num_gpus=1, train_file = "train.csv", test_file="test.csv")
model = train(args) 

一旦运行了前面的代码,你应该会看到每个批次和每个 epoch 的训练统计信息。模型也将被保存在指定的目录中。

接下来,让我们看看如何使用训练好的模型直接进行预测。为此,我们必须实现几个实用函数。以下 input_fn() 函数接收 JSON 格式的输入,并输出一个表示字符串输入及其相关掩码的输入向量。输出将被发送到模型进行预测:

def input_fn(request_body, request_content_type):
    if request_content_type == "application/json":
        data = json.loads(request_body)
        if isinstance(data, str):
            data = [data]
        elif isinstance(data, list) and len(data) > 0 and isinstance(data[0], str):
            pass
else:
            raise ValueError("Unsupported input type. Input type can be a string or a non-empty list. \
                             I got {}".format(data))

        tokenizer = BertTokenizer.from_pretrained("bert-base-uncased", do_lower_case=True)

        input_ids = [tokenizer.encode(x, add_special_tokens=True) for x in data]

        # pad shorter sentence
        padded =  torch.zeros(len(input_ids), MAX_LEN)
        for i, p in enumerate(input_ids):
            padded[i, :len(p)] = torch.tensor(p)

        # create mask
        mask = (padded != 0)

        return padded.long(), mask.long()
    raise ValueError("Unsupported content type: {}".format(request_content_type)) 

以下 predict_fn() 函数接收由 input_fn() 返回的 input_data,并使用训练好的模型生成预测。请注意,如果服务器上可用 GPU 设备,我们也会使用 GPU:

def predict_fn(input_data, model):
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)
    model.eval()
    input_id, input_mask = input_data
    input_id = input_id.to(device)
    input_mask = input_mask.to(device)
    with torch.no_grad():
        y = model(input_id, attention_mask=input_mask)[0]
    return y 

现在,运行以下代码以生成预测。将文章的值替换为不同的金融文本以查看结果:

import json
print("sentiment label : " + str(np.argmax(preds)))
article = "Operating profit outpaced the industry average"
request_body = json.dumps(article)
enc_data, mask = input_fn(request_body, 'application/json')
output = predict_fn((enc_data, mask), model)
preds = output.detach().cpu().numpy()
print("sentiment label : " + str(np.argmax(preds))) 

使用 SageMaker,您有不同选项来训练 ML 模型。对于快速实验和轻量级模型构建,Jupyter Notebook 环境对于许多模型训练任务来说已经足够。对于更资源密集型的 ML 训练任务,我们需要考虑为模型训练配置专用训练资源。在下一节中,让我们看看使用 SageMaker 训练服务训练 BERT 模型的另一种方法。

使用 SageMaker 训练服务训练 BERT 模型

在上一节中,您直接在基于 GPU 的 Jupyter 笔记本中训练了 BERT 模型。您不必配置基于 GPU 的笔记本实例,而是可以配置一个成本更低的基于 CPU 的实例,并将模型训练任务发送到 SageMaker 训练服务。要使用 SageMaker 训练服务,您需要对训练脚本进行一些小的修改,并创建一个单独的启动器脚本来启动训练。正如我们在训练 ML 模型部分所讨论的,在 SageMaker 中训练模型有三种主要方法。由于 SageMaker 为 PyTorch 提供了托管容器,我们将使用托管容器方法来训练模型。使用这种方法,您需要提供以下输入:

  • 以训练脚本作为入口点,以及依赖项

  • 训练作业将使用的 IAM 角色

  • 基础设施细节,如实例类型和数量

  • S3 中的数据(训练/验证/测试)位置

  • S3 中的模型输出位置

  • 模型训练的超参数

当训练作业启动时,SageMaker 训练服务将按顺序执行以下任务:

  1. 启动训练作业所需的 EC2 实例。

  2. 从 S3 下载数据到训练主机。

  3. 从 SageMaker ECR 注册表中下载适当的托管容器并运行容器。

  4. 将训练脚本和依赖项复制到训练容器。

  5. 运行训练脚本并将超参数作为命令行参数传递给训练脚本。训练脚本将从容器中的特定目录加载训练/验证/测试数据,运行训练循环,并将模型保存到容器中的特定目录。容器中将设置几个环境变量,以提供配置详细信息,例如数据和模型输出目录,给训练脚本。

  6. 一旦训练脚本成功退出,SageMaker 训练服务将从容器中复制保存的模型工件到 S3 中的模型输出位置。

现在,让我们创建以下训练脚本,命名为train.py,并将其保存在名为code的新目录中。请注意,训练脚本几乎与在 Jupyter 笔记本中训练 BERT 模型部分中的代码相同。我们在末尾添加了一个if __name__ == "__main__":部分。此部分包含读取命令行参数值和系统环境变量值的代码,例如 SageMaker 的数据目录(SM_CHANNEL_TRAINING)、模型输出目录(SM_MODEL_DIR)以及主机上可用的 GPU 数量(SM_NUM_GPUS)。以下代码示例并不完整。您可以在github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/blob/main/Chapter08/code/train.py找到完整的代码示例:

import argparse
import logging
import os
import sys
import numpy as np
import pandas as pd
import torch
from torch.utils.data import DataLoader, TensorDataset
from transformers import AdamW, BertForSequenceClassification, BertTokenizer
logger = logging.getLogger(__name__)
logger.setLevel(logging.DEBUG)
logger.addHandler(logging.StreamHandler(sys.stdout))
...
    train(parser.parse_args()) 

前面的脚本需要一些在托管训练容器中不可用的库包。您可以使用requirement.txt文件安装自定义库包。创建一个包含以下代码的requirement.txt文件,并将其保存在code目录中:

transformers==2.3.0 

接下来,让我们创建一个启动笔记本,用于使用 SageMaker 训练服务启动训练作业。启动笔记本将执行以下操作:

  • 将训练集和测试集上传到 S3 存储桶和文件夹中。

  • 使用 SageMaker SDK 设置 SageMaker PyTorch 估计器以配置训练作业。

  • 启动 SageMaker 训练作业。

code文件夹所在的文件夹中创建一个新的笔记本,命名为bert-financial-sentiment-launcher.ipynb,并将以下代码块逐个单元格地复制到笔记本中。当您被提示选择内核时,请选择Python 3 (ipykernel)内核。

以下代码指定了用于保存训练和测试数据集以及模型工件要使用的 S3 存储桶。您可以使用在设置 SageMaker Studio部分中创建的存储桶,当时配置了 Studio 域名。我们之前创建的训练集和测试集将被上传到该存储桶。get_execution_role()函数返回与笔记本关联的 IAM 角色,我们将使用它来稍后运行训练作业:

import os
import numpy as np
import pandas as pd
import sagemaker
sagemaker_session = sagemaker.Session()
bucket = <bucket name>
prefix = "sagemaker/pytorch-bert-financetext"
role = sagemaker.get_execution_role()
inputs_train = sagemaker_session.upload_data("./data/train.csv", bucket=bucket, key_prefix=prefix)
inputs_test = sagemaker_session.upload_data("./data/test.csv", bucket=bucket, key_prefix=prefix) 

最后,我们必须设置 SageMaker PyTorch 估计器和启动训练作业。请注意,您还可以指定 PyTorch 框架版本和 Python 版本来设置容器。为了简单起见,我们正在传递训练文件和测试文件的名字,以及最大长度作为超参数。train.py文件也可以修改为动态查找它们:

from sagemaker.pytorch import PyTorch
output_path = f"s3://{bucket}/{prefix}"
estimator = PyTorch(
    entry_point="train.py",
    source_dir="code",
    role=role,
    framework_version="1.6",
    py_version="py3",
    instance_count=1,  
    instance_type="ml.p3.2xlarge",
    output_path=output_path,
    hyperparameters={
        "epochs": 4,
        "lr" : 5e-5,
        "num_labels": 3,
        "train_file": "train.csv",
        "test_file" : "test.csv",
        "MAX_LEN" : 315,
        "batch-size" : 16,
        "test-batch-size" : 10
    }
)
estimator.fit({"training": inputs_train, "testing": inputs_test}) 

一旦训练作业完成,您可以通过 SageMaker 管理控制台访问训练作业的详细信息和元数据。训练作业还会将输出发送到 CloudWatch 日志和 CloudWatch 指标。您可以通过点击训练作业详情页面上的相应链接来导航到这些日志。

模型部署

在这一步,我们将部署训练好的模型到 SageMaker RESTful 端点,以便它可以与下游应用程序集成。我们将使用托管的 PyTorch 服务容器来托管模型。使用托管的 PyTorch 服务容器,您可以在将请求数据发送到模型进行推理之前提供推理脚本以处理数据,以及控制如何调用模型进行推理。让我们在code文件夹中创建一个新的脚本inference.py,其中包含以下代码块。如您所注意到的,我们使用了与在 Jupyter 笔记本中训练 BERT 模型部分相同的函数来生成预测。请注意,您需要使用这两个函数相同的函数签名,因为 SageMaker 将寻找确切的函数名和参数列表。您可以在github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/blob/main/Chapter08/code/inference.py找到完整的源代码:

import logging
import os
import sys
import json
import numpy as np
import pandas as pd
import torch
from torch.utils.data import DataLoader, TensorDataset
from transformers import BertForSequenceClassification, BertTokenizer
... 
def model_fn(model_dir):
    ...
    loaded_model = BertForSequenceClassification.from_pretrained(model_dir)
    return loaded_model.to(device)
def input_fn(request_body, request_content_type):
    ...
def predict_fn(input_data, model):
    device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
    model.to(device)
    model.eval()
    ...
    return y 

接下来,我们需要修改bert-financial-sentiment-launcher.ipynb文件以创建端点。您可以直接从 SageMaker 的estimator类部署训练好的模型。然而,在这里,我们想向您展示如何部署一个之前训练好的模型,因为这可能是最常见的部署场景:

from sagemaker.pytorch.model import PyTorchModel
model_data = estimator.model_data
pytorch_model = PyTorchModel(model_data=model_data,
                             role=role,
                             framework_version="1.6",
                             source_dir="code",
                             py_version="py3",
                             entry_point="inference.py")
predictor = pytorch_model.deploy(initial_instance_count=1, instance_type="ml.m4.xlarge") 

模型部署后,我们可以调用模型端点来生成一些预测:

predictor.serializer = sagemaker.serializers.JSONSerializer()
predictor.deserializer = sagemaker.deserializers.JSONDeserializer()
result = predictor.predict("The market is doing better than last year")
print("predicted class: ", np.argmax(result, axis=1)) 

尝试不同的短语,看看模型是否正确预测情感。您还可以通过导航到 SageMaker 管理控制台并点击端点来访问端点的详细信息。

为了避免端点的持续成本,让我们将其删除。在新的单元格中运行以下命令以删除端点:

predictor.delete_endpoint() 

恭喜您——您已经完成了基本数据科学环境的构建,并使用它来训练和部署了一个用于检测情感的 NLP 模型!如果您不想保留这个环境以避免任何相关成本,请确保关闭 SageMaker Studio 笔记本的任何实例。

接下来,让我们探索 SageMaker Canvas,看看如何使用它来构建无需任何编码的定制机器学习模型。

使用 SageMaker Canvas 构建机器学习模型

在这个实验室中,我们将使用 Canvas 的定制模型功能来训练一个客户流失分类模型。我们将完成从数据集创建/选择、模型训练、模型分析到预测生成和模型部署的全过程。

要开始,我们首先需要启动 SageMaker Canvas 环境。为此,返回您的 Studio 环境,在应用程序部分下选择Canvas,然后在右侧面板中点击运行 Canvas按钮。Canvas 环境变得可用需要 8-10 分钟。当 Canvas 状态变为运行中时,点击打开 Canvas,您将看到一个类似于图 8.13的屏幕。

图片

图 8.13:SageMaker Canvas

以下步骤将引导您完成剩余的实验:

  1. 在左侧面板中选择我的模型图标,以使用自定义数据集开始构建自定义模型。您应该看到一个类似于图 8.14的屏幕:图片

    图 8.14:Canvas 我的模型屏幕

  2. 点击新建模型按钮,为模型提供一个名称,选择预测分析作为问题类型,然后点击创建

  3. github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/blob/main/Chapter08/churn.csv下载数据集,并将其保存到您的本地计算机上。

  4. 选择数据集屏幕上,点击右上角的创建数据链接。为数据集提供一个名称。

  5. 在下一屏,点击从您的本地计算机选择文件,导航到您在步骤 4中下载的churn.csv文件以上传文件。文件上传后,点击创建数据集以继续。

  6. 在下一屏,检查您刚刚创建的数据集,并点击选择数据集以继续。

  7. 在下一屏,您将被要求选择一个预测的目标列。从数据集中选择已退出列。您还应该取消选中一些源列,例如姓氏和行号,因为它们与模型训练不相关。最后,选择快速构建来构建模型。

  8. 在下一屏,您将看到有关构建持续时间和构建类型的一些信息。现在您需要等待构建过程完成。完成后,您将看到一个类似于以下图所示的屏幕。您将能够查看各种训练指标,例如准确率、精确率和召回率。您还将能够看到不同源列对目标列的影响。图片

    图 8.15:模型训练结果

  9. 由于模型性能优化不是我们这里的主要目标,我们将点击预测以在下一屏生成一些预测。

  10. 在下一屏,选择单次预测选项,并更改一些字段的值,例如年龄、薪资和信用评分,通过点击更新来查看它们如何影响结果。

  11. 最后,我们将模型部署到端点,以便其他应用程序可以使用。要部署,您只需点击部署按钮来部署模型。您可以选择实例类型和模型的实例数量。部署成功后,将为其他应用程序提供部署 URL。

恭喜您完成实验室任务!您已经有效地使用 SageMaker Canvas,在没有编写任何代码的情况下,使用自定义数据集训练和部署了一个二元分类模型。这个无代码 ML 工具使得即使是缺乏先前 ML 知识的人也能迅速启动 ML 项目。您现在亲身体验了 Canvas 如何自动化为您执行众多任务,从算法选择和模型训练到模型部署。

摘要

在本章中,我们探讨了数据科学环境如何提供可扩展的基础设施,用于实验、模型训练和测试部署。您学习了使用 AWS 服务如 Amazon SageMaker、Amazon ECR 和 Amazon S3 构建完全托管的数据科学环境的核心架构组件。您练习了设置数据科学环境,并使用 SageMaker Studio 笔记本和 SageMaker 训练服务训练和部署了一个 NLP 模型。您还通过 SageMaker Canvas 获得了实际操作经验,以自动化从模型构建到模型部署的 ML 任务。

到目前为止,您应该能够讨论数据科学环境的关键组件,以及如何使用 AWS 服务构建一个并用于模型构建、训练和部署。在下一章中,我们将讨论如何通过自动化构建一个企业级 ML 平台以实现规模扩展。

加入我们的 Discord 社区

加入我们的社区 Discord 空间,与作者和其他读者进行讨论:

packt.link/mlsah

第九章:使用 AWS 机器学习服务设计企业级机器学习架构

许多组织选择构建企业级机器学习平台以支持众多快速发展的项目。这些平台旨在促进整个机器学习生命周期,并适应各种使用模式,同时强调自动化和可扩展性。作为一名从业者,我经常被要求提供创建此类企业级机器学习平台的架构指导。在本章中,我们将探讨设计企业级机器学习平台的基本要求。我们将涵盖一系列主题,例如工作流程自动化、基础设施可扩展性和系统监控。

在整个讨论过程中,你将深入了解那些能够开发自动化端到端机器学习工作流程并确保大规模无缝部署的技术解决方案的架构模式。此外,我们还将深入探讨企业级机器学习架构的必要组件,例如模型训练、模型托管、特征存储和模型注册,所有这些均针对满足企业级运营的需求而定制。

人工智能风险、治理和安全是企业级机器学习平台的另一些重要考虑因素,我们将在第十二章和第十三章中更详细地介绍它们。

简而言之,本章将涵盖以下主题:

  • 机器学习平台的关键考虑因素

  • 企业级机器学习平台的关键要求

  • 企业级机器学习架构模式概述

  • 采用 MLOps 进行机器学习工作流程

  • 构建和运营机器学习平台的最佳实践

技术要求

我们将继续使用 AWS 环境为本章的动手部分。本章中提到的所有源代码都可以在github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/tree/main/Chapter09找到。

机器学习平台的关键考虑因素

设计、构建和运营机器学习平台是复杂的任务,因为有许多不同的考虑因素,包括角色、关键机器学习流程工作流以及针对不同角色和工作流的各种技术能力要求。在本节中,我们将深入探讨这些关键考虑因素。让我们深入探讨吧!

机器学习平台的角色及其需求

在上一章中,我们讨论了为专注于实验和模型开发的数据科学家和机器学习工程师构建数据科学环境。在企业环境中,当需要机器学习平台时,涉及到的角色和各自的具体需求就更多了。从高层次来看,与机器学习平台相关的角色有两种:机器学习平台构建者和机器学习平台用户。

机器学习平台构建者

ML 平台构建者承担着构建数据和 ML 平台基础设施的关键责任。以下是构建基于云的 ML 平台所需的某些基本构建者类型:

  • 云基础设施架构师/工程师:这些专家设计整体云基础设施,选择合适的云服务并为 ML 平台搭建基础。

  • 安全工程师:安全工程师确保 ML 平台遵循行业标准的安全实践,保护敏感数据并防范潜在威胁。

  • ML 平台产品经理:ML 平台产品经理负责理解功能和非功能用户需求,定义 ML 平台的能力和实施路线图。

  • ML 平台工程师:ML 平台工程师负责设计、构建和维护支持组织内端到端 ML 生命周期的基础设施和系统。ML 平台工程师在确保数据科学家和 ML 实践者能够高效地在组织的 ML 平台上开发、部署和管理 ML 模型方面发挥着关键作用。他们负责平台设计,涵盖关键功能领域,如训练和托管,考虑到可扩展性、性能、安全性和与现有系统的集成。

  • 数据工程师:数据工程师负责构建数据管道、数据存储解决方案和数据处理框架,以确保 ML 任务的无缝数据访问和处理。

  • ML 平台测试员:ML 平台测试员负责测试平台的核心功能,以满足所需的预期功能和非功能需求。

平台用户和运维人员

平台用户和运维人员是 ML 平台的实际用户。他们使用 ML 平台执行从数据探索到模型监控的全生命周期 ML 任务。以下是一些关键的平台用户和运维人员类型:

  • 数据科学家/ML 工程师:数据科学家和 ML 工程师是 ML 平台的主要用户。他们使用平台来探索数据、构建和训练 ML 模型、执行特征工程以及评估模型性能。他们与 ML 平台工程师和运维工程师合作,将训练好的模型集成到生产系统中,优化模型推理性能,并确保模型在实际环境中可扩展且可靠。

  • 模型测试和验证人员:模型测试人员的主要职责是评估数据科学家使用机器学习平台开发的机器学习模型的性能和可靠性。具体来说,模型测试人员负责使用不同的数据集进行模型测试、计算和评估模型性能指标、检测过拟合/欠拟合以及测试边缘情况。模型验证人员负责验证模型是否符合业务目标、风险评估以及其他问题,如伦理考量。

  • 模型审批人:此个人或团队负责审查和批准将机器学习模型部署到生产或其他关键环境。模型审批人的主要职责是在模型部署之前确保开发的机器学习模型符合组织标准、业务需求和合规政策。他们还帮助确保所有必要的测试、部署后的运营和政策都到位。

  • 运维和支持工程师:此角色确保机器学习平台在组织内的平稳运行、维护和持续支持。他们的职责包括各种技术和运营方面,以保持机器学习平台的效率运行,并向用户提供帮助。一些关键功能包括平台维护和升级、性能监控和优化、事件管理、基础设施管理、安全和访问控制以及平台文档。

  • 人工智能风险/治理经理:人工智能风险/治理经理的主要职责是管理和减轻使用人工智能/机器学习系统可能带来的潜在风险。他们的角色对于确保人工智能技术得到负责任、道德地开发、部署和使用,并符合相关法规至关重要。他们帮助确保创建并遵守适当的流程、政策和技术标准。

你可能会想知道机器学习解决方案架构师在这个整体图景中处于什么位置。机器学习解决方案架构师在构建者、用户和操作者之间扮演着关键角色。他们作为这些群体之间的桥梁,提供有价值的见解和指导。首先,机器学习解决方案架构师与构建者合作,了解用户需求,并协助端到端架构设计。他们确保机器学习平台与用户和操作者的特定需求保持一致。其次,机器学习解决方案架构师向用户和操作者提供有关有效利用机器学习平台的建议。他们教育他们如何配置和利用平台以满足不同的需求和用例。

机器学习项目的常见工作流程

在运行机器学习项目时,不同的组织具有不同的工作流程和治理流程。然而,这些工作流程通常包括以下关键步骤:

  • 从不同来源收集和处理数据,使其可供数据科学家使用。

  • 使用数据子集进行数据探索性分析、形成假设、创建机器学习特征、进行实验以及使用不同技术和机器学习算法构建不同的机器学习模型。

  • 有时需要数据标注工作流程来标注用于监督机器学习任务(如文档分类或目标检测)的训练数据。

  • 使用完整数据集进行完整模型训练和调整。

  • 使用完整数据集训练的候选模型被提升到测试环境进行正式的质量保证。测试人员记录所有测试人员的测试细节,并验证模型是否满足预期的性能指标和其他评估标准,如延迟和可扩展性。模型验证者评估机器学习技术,对模型进行分析,并检查与业务成果的一致性。

  • 进行模型风险评估以确保风险项得到评估、缓解或接受。

  • 模型通过测试和验证步骤后,模型被发送给模型审批人员进行最终审查和批准以进行生产部署。

  • 模型在获得批准后部署到生产环境中。模型在模型注册表中注册,数据集进行版本控制和保留,任何代码工件也进行版本控制和存储,详细的训练配置细节也进行了文档记录。

  • 模型在生产中监控模型性能、数据漂移、系统问题和安全暴露及攻击。遵循事件管理流程来处理识别出的问题。

  • 在需要的时间表上,审计员执行端到端审计以确保所有流程和政策得到遵守,工件得到存储,系统和对模型的访问得到适当记录,文档符合所需标准,任何违规行为都会被标记并升级。

值得注意的是,这些步骤并不详尽。根据组织、风险和监管要求,组织可以执行更多步骤来满足这些要求。

不同角色的平台要求

机器学习平台涉及各种潜在的参与者和用户。以下表格概述了机器学习平台对于用户和操作者的基本需求。请注意,该表格不包括平台的建设者。

用户/操作员工具/能力要求
数据科学家访问各种机器学习库、工具和框架以进行模型开发和实验访问不同的数据集以执行不同的机器学习任务使用不同硬件的能力进行数据探索和模型训练工作流程自动化,包括数据检索和处理、特征工程、实验、模型构建和模型版本化以实现可重复性
模型测试和验证人员访问不同的测试数据集以进行模型测试和验证,以及访问用于数据可视化、模型评估、机器学习测试框架、偏差检测工具、模型可解释性工具和统计测试工具的各种库和工具
模型审批者访问模型文档、模型评估指标、合规清单和模型可解释性报告,以及访问审批工作流管理工具
运维和支持工程师访问机器学习平台内的所有基础设施组件,包括代码和容器存储库、库包、训练、托管、管道、日志记录、监控和警报、安全性和访问控制、备份和发现、性能测试和事件管理工具,以及访问平台自动化和管理工具
人工智能风险官访问人工智能风险评估工具、治理平台、模型可解释性和可解释性工具、偏差检测和公平性评估工具、人工智能风险报告和仪表板,以及人工智能法规和政策监控

表 9.1:面向不同用户和操作者的机器学习平台需求

总结来说,机器学习平台的成功在很大程度上取决于满足其用户/操作者的独特工具和能力需求。通过解决这些独特需求,机器学习平台可以有效地支持其用户和操作者自信地构建、部署和管理人工智能解决方案。

企业机器学习平台的关键需求

为了通过大规模机器学习实现业务效益,组织必须具备快速实验多种科学方法、机器学习技术和大量数据集的能力。一旦机器学习模型经过训练和验证,它们需要无缝过渡到生产部署。虽然传统企业软件系统和机器学习平台之间存在一些相似之处,例如可扩展性和安全担忧,但企业机器学习平台提出了独特的挑战。这些挑战包括需要与数据平台和高性能计算基础设施集成,以促进大规模模型训练。

让我们深入探讨企业机器学习平台的一些具体核心需求,以满足不同用户和操作者的需求:

  • 支持端到端机器学习生命周期:企业机器学习平台必须满足数据科学实验和生产级操作和部署的需求。在第八章使用 AWS 机器学习服务构建数据科学环境中,我们探讨了构建使用 AWS 机器学习服务的数据科学实验环境所需的基本架构组件。然而,为了促进无缝的生产级操作和部署,企业机器学习平台还应包括专门针对大规模模型训练、模型管理、特征管理和高度可用且可扩展的模型托管的特定架构组件。

  • 支持持续集成(CI)、持续训练(CT)和持续部署(CD):除了测试和验证代码和组件外,企业级机器学习平台的 CI 能力还扩展到包括数据和模型。机器学习的 CD 能力不仅限于部署单个软件组件;它还涉及管理与推理引擎相结合的机器学习模型。CT 是机器学习的一个独特方面,其中模型会持续监控,并在检测到数据漂移、模型漂移或训练数据变化时自动触发模型重新训练。数据漂移指的是数据发生变化,其中生产数据的统计特征与用于模型训练的数据不同。另一方面,模型漂移表示模型性能相对于模型训练阶段达到的性能有所下降。

  • 操作支持:企业级机器学习平台应提供监控不同管道工作流程状态、错误和指标、处理/训练作业、模型行为变化、数据漂移和模型服务引擎的能力。此外,基础设施级别的统计信息和资源使用情况持续监控,以确保高效的操作。自动警报机制是操作的关键组成部分,能够及时通知相关利益相关者任何问题或异常。此外,尽可能实施自动故障恢复机制,进一步增强了平台的安全性并最小化了停机时间,确保了平稳和可靠的机器学习操作。

  • 支持不同语言和机器学习框架:企业级机器学习平台使数据科学家和机器学习工程师能够使用他们偏好的编程语言和机器学习库。它应容纳流行的语言,如 Python 和 R,以及知名的机器学习框架,如 TensorFlow、PyTorch 和 scikit-learn。这种灵活性确保团队可以利用他们的专业知识,并在平台内利用最合适的工具进行高效和有效的模型开发。

  • 计算硬件资源管理:企业级机器学习平台应满足多样化的模型训练和推理需求,同时考虑成本因素。这包括提供对各种计算硬件的支持,例如 CPU 和 GPU,以优化性能和成本效益。此外,平台还应具备处理专用机器学习硬件的能力,如 AWS 的 Inferentia 和 Tranium 芯片,在相关情况下,以利用专用硬件加速器为特定机器学习工作负载带来的好处。

  • 与其他第三方系统和软件的集成:企业机器学习平台很少独立运行。它必须提供与各种第三方软件和平台(包括工作流程编排工具、容器注册库和代码仓库)的强大集成能力。这种无缝集成使得团队合作和互操作性变得顺畅,允许团队利用现有工具和工作流程,同时受益于机器学习平台的先进功能和能力。

  • 身份验证和授权:对于企业机器学习平台来说,确保对数据、文物和机器学习平台资源的安全访问是至关重要的。这需要提供各种级别的身份验证和授权控制。平台可能包括内置的身份验证和授权功能,或者它可以与外部身份验证和授权服务集成。

  • 数据加密:在金融服务和医疗保健等受监管的行业中,数据加密是一个关键要求。企业机器学习平台必须提供强大的能力来加密静态和传输中的数据,通常允许客户管理他们的加密密钥。这种数据保护水平确保敏感信息保持安全并符合行业法规,为在这些行业中处理机密数据提供了必要的保证。

  • 文物管理:在机器学习生命周期中,企业机器学习平台在各个阶段处理数据集并生成各种文物。这些文物可以是特征、代码、模型和容器。为确保可重复性和遵守治理和合规标准,平台必须具备跟踪、管理和版本控制这些文物的能力。通过有效管理和记录整个机器学习过程中所做的更改,平台保持了一个清晰且有序的记录,促进了结果的重复性,并为合规目的提供了可靠的审计轨迹。

  • 机器学习库包管理:对于许多组织来说,标准化和批准数据科学家使用的机器学习库包至关重要。通过建立一个包含预先批准包的中心库,可以强制执行跨库包使用的统一标准和政策。这种方法确保数据科学家在开发机器学习解决方案时使用经过审查和授权的库,促进可靠性、安全性和遵守组织指南。

  • 访问不同的数据存储:企业机器学习平台的一个基本功能是提供对各种数据存储的无缝访问,简化模型开发和训练过程。这种对多样化数据源的访问简化了数据科学家和机器学习工程师的工作流程,使他们能够高效地访问和利用平台内执行任务所需的必要数据。

  • 自助服务能力:为了提高运营效率并减少对中央团队的依赖,企业 ML 平台应包含自助服务能力,以支持用户入职、环境设置和管道提供等任务。通过使用户能够独立执行这些任务,平台简化了操作,使数据科学家和 ML 工程师能够更加自主和高效地工作。

  • 模型测试和验证:企业 ML 平台应提供全面的模型测试和验证功能,以支持对 ML 模型的彻底评估。这可能包括 A/B 测试基础设施、模型鲁棒性测试包、自动化测试管道、性能指标跟踪和错误分析工具以及可视化等功能。

在了解了企业 ML 平台的基本要求后,现在让我们探讨如何有效地利用 AWS ML 和 DevOps 服务,如 SageMaker、CodePipeline 和 Step Functions,来构建一个强大、企业级 ML 平台。

企业 ML 架构模式概述

在 AWS 上构建企业 ML 平台的第一步是创建不同的环境,以启用不同的数据科学和运营功能。以下图表显示了通常构成企业 ML 平台的核心环境。从隔离的角度来看,在 AWS 云的背景下,以下图表中的每个环境都是一个独立的 AWS 账户:

图 9.1 – 企业 ML 架构环境

图 9.1:企业 ML 架构环境

如我们在第八章中讨论的,使用 AWS ML 服务构建数据科学环境,数据科学家利用数据科学环境进行实验、模型构建和调整。一旦这些实验完成,数据科学家会将他们的工作提交到适当的代码和数据存储库。下一步是在受控和自动化的环境中使用数据科学家创建的算法、数据和训练脚本来训练和调整 ML 模型。这个受控和自动化的模型训练过程将有助于确保可扩展模型构建的一致性、可重复性和可追溯性。以下是由训练、托管和共享服务环境提供的核心功能和技术选项:

  • 模型训练环境:此环境管理模型训练的整个生命周期,从计算和存储基础设施资源分配到训练作业监控和模型持久化。为此,SageMaker 训练服务提供了一个合适的技术选项来构建训练基础设施。

  • 模型托管环境:此环境用于在 Web 服务端点或批量推理模式下提供训练好的模型。为此,你可以使用 SageMaker 托管服务。其他支持服务,如在线特征存储和 API 管理服务,也可以在模型托管环境中运行。可以存在多个模型托管环境,用于不同的阶段。例如,你可以有一个专门用于模型测试的测试托管环境,以及一个用于生产模型部署并服务于现实世界流量的生产托管环境。模型测试人员可以执行不同的测试,例如模型性能、鲁棒性、偏差、可解释性分析和模型托管测试。

  • 共享服务环境:共享服务环境托管常见服务,如工作流编排工具、CI/CD 工具、代码仓库、Docker 镜像仓库和私有库包工具。中央模型注册库也可以在共享服务环境中运行,用于模型注册和模型生命周期管理。服务提供能力,如通过基础设施即代码IaC)或 API 在不同环境中创建资源,也运行在这个环境中。任何服务票证工具,如 ServiceNow,以及服务提供工具,如服务目录,也可以托管在这个环境中。

除了核心的机器学习环境之外,还有其他支持环境,例如安全、治理、监控和日志记录,这些环境对于设计和构建企业级机器学习平台是必需的:

  • 安全和治理环境:安全和治理环境集中管理身份验证服务、用户凭证和数据加密密钥。安全审计和报告流程也运行在这个环境中。可以用于各种安全和治理功能的原生 AWS 服务,如 Amazon IAM、AWS KMS 和 AWS Config。任何定制的风险和治理工具也可以托管在这个环境中,以服务 AI 风险/治理经理。

  • 监控和日志环境:监控和日志环境集中聚合来自其他环境的监控和日志数据,以进行进一步的处理和报告。通常开发定制的仪表板和警报机制,以便轻松访问底层监控和日志数据中的关键指标和警报。

现在你已经对企业级机器学习平台构成的基本元素有了全面的了解,让我们更深入地探讨具体的核心领域。重要的是要认识到,在 AWS 上构建机器学习平台有各种模式和可用服务。

此外,虽然图 9.1展示了不同的 AWS 环境(即,AWS 账户)以托管不同的机器学习平台环境,但组织也可以选择将某些环境组合在单个 AWS 账户中,只要不同环境之间存在适当的边界,以确保基础设施、流程和安全管理上的隔离。此外,组织可以为托管不同用户或组的特定环境创建单独的 AWS 账户。例如,大型企业可以选择为每个业务部门创建一个数据科学环境,或者基于组织结构或工作负载分离创建单独的生产托管环境。在本章中,我们将主要关注探索一种企业模式来构建高效且可扩展的机器学习平台。

模型训练环境

在企业内部,模型训练环境是一个受控环境,具有关于其使用方式和谁可以使用它的明确流程和政策。通常,它应该是一个由机器学习运营团队管理的自动化环境,尽管可以启用自助服务以供数据科学家直接使用。

自动化模型训练和调优是模型训练环境的核心功能。为了支持广泛的使用案例,模型训练环境需要支持不同的机器学习和深度学习框架、训练模式(单节点和分布式训练)以及硬件(不同的 CPU、GPU 和定制硅芯片)。

模型训练环境管理着模型训练过程的生命周期。这可以包括身份验证和授权、基础设施配置、数据移动、数据预处理、机器学习库部署、训练循环管理和监控、模型持久化和注册、训练作业管理和谱系跟踪。从安全角度来看,训练环境需要提供针对不同隔离需求的安全功能,例如网络隔离、作业隔离和工件隔离。为了协助运营支持,模型训练环境还需要能够支持训练状态日志记录、指标报告以及训练作业监控和警报。在接下来的章节中,我们将讨论如何使用 Amazon SageMaker 作为企业管理的模型训练引擎。

使用 SageMaker 的模型训练引擎

SageMaker 训练服务为各种机器学习/深度学习库提供了内置的模型训练功能。此外,您还可以为定制模型训练需求带来自己的 Docker 容器。以下是 SageMaker Python SDK 支持的选项子集:

  • 训练 TensorFlow 模型:SageMaker 为 TensorFlow 模型提供了内置的训练容器。以下代码示例展示了如何通过 TensorFlow 估计器 API 使用内置容器训练 TensorFlow 模型:

    from sagemaker.tensorflow import TensorFlow
    tf_estimator = TensorFlow(
      entry_point="<Training script name>",
      role= "<AWS IAM role>",
      instance_count=<Number of instances),
      instance_type="<Instance type>",
      framework_version="<TensorFlow version>",
      py_version="<Python version>",)
    tf_estimator.fit("<Training data location>") 
    
  • 训练 PyTorch 模型:SageMaker 为 PyTorch 模型提供内置训练容器。以下代码示例展示了如何使用 PyTorch 估计器训练 PyTorch 模型:

    from sagemaker.pytorch import PyTorch
    pytorch_estimator = PyTorch(
      entry_point="<Training script name>",
      role= "<AWS IAM role>",
      instance_count=<Number of instances),
      instance_type="<Instance type>",
      framework_version="<PyTorch version>",
      py_version="<Python version>",)
    pytorch_estimator.fit("<Training data location>") 
    
  • 训练 XGBoost 模型:XGBoost 训练也通过内置容器支持。以下代码展示了使用 XGBoost 估计器训练 XGBoost 模型的语法:

    from sagemaker.xgboost.estimator import XGBoost
    xgb_estimator = XGBoost(
      entry_point="<Training script name>",
      hyperparameters=<dictionary of hyperparameters>,
      role=<AWS IAM role>,
      instance_count=<Number of instances>,
      instance_type="<Instance type>",
      framework_version="<Xgboost version>")
    xgb_estimator.fit("<train data location>") 
    
  • 使用 scikit-learn 训练模型:以下代码示例展示了如何使用内置容器训练 scikit-learn 模型:

    from sagemaker.sklearn.estimator import SKLearn
    sklearn_estimator = SKLearn(
      entry_point="<Training script name>",
      hyperparameters=<dictionary of hyperparameters>,
      role=<AWS IAM role>,
      instance_count=<Number of instances>,
      instance_type="<Instance type>",
         framework_version="<sklearn version>")
    Sklearn_estimator.fit("<training data>") 
    
  • 使用自定义容器训练模型:您还可以构建自定义训练容器,并使用 SageMaker 训练服务进行模型训练。以下代码示例展示了如何进行:

    from sagemaker.estimator import Estimator
    custom_estimator = Estimator (
      image_uri="<custom model inference container image uri>"
      role=<AWS IAM role>,
      instance_count=<Number of instances>,
      instance_type="<Instance type>")
    custom_estimator.fit("<training data location>") 
    

除了使用 SageMaker Python SDK 启动训练外,您还可以使用boto3库和 SageMaker CLI 命令来启动训练作业。

自动化支持

SageMaker 训练服务通过一组 API 进行暴露,可以通过与外部应用程序或工作流程工具集成来自动化,例如 SageMaker Pipelines、Airflow 和 AWS Step Functions。例如,它可以是端到端机器学习工作流程中基于 Airflow 的管道的步骤之一。一些工作流程工具,如 Airflow 和 AWS Step Functions,还提供了 SageMaker 特定的连接器,以便更无缝地与 SageMaker 训练服务交互。SageMaker 训练服务还提供 Kubernetes 操作符,因此它可以作为 Kubernetes 应用程序流程的一部分进行集成和自动化。

以下示例代码展示了如何通过 AWS boto3 SDK 的低级 API 启动训练作业:

import boto3
client = boto3.client('sagemaker')
response = client.create_training_job(
    TrainingJobName='<job name>',
    HyperParameters={<list of parameters and value>},
    AlgorithmSpecification={...},
    RoleArn='<AWS IAM Role>',
    InputDataConfig=[...],
    OutputDataConfig={...},
    ResourceConfig={...},
    ...
} 

关于使用 Airflow 作为工作流程工具,以下示例展示了如何在工作流程定义中将 Airflow SageMaker 操作符作为一部分使用。在这里,train_config包含训练配置细节,例如训练估计器、训练实例类型和数量以及训练数据位置:

import airflow
from airflow import DAG
from airflow.contrib.operators.sagemaker_training_operator import SageMakerTrainingOperator
default_args = {
    'owner': 'myflow',
    'start_date': '2021-01-01'
}
dag = DAG('tensorflow_training', default_args=default_args,
          schedule_interval='@once')
train_op = SageMakerTrainingOperator(
    task_id='tf_training',
    config=train_config,
    wait_for_completion=True,
    dag=dag) 

SageMaker 还内置了一个名为SageMaker Pipelines的工作流程自动化工具。可以使用 SageMaker Training Step API 创建训练步骤并将其集成到更大的 SageMaker Pipelines 工作流程中。

模型训练生命周期管理

SageMaker 训练管理模型训练过程的生命周期。它使用 Amazon IAM 作为验证和授权访问其功能的机制。一旦授权,它提供所需的架构,部署满足不同模型训练需求的软件堆栈,将数据从源移动到训练节点,并启动训练作业。一旦训练作业完成,模型工件将被保存到 S3 输出桶中,并且架构将被拆除。对于谱系追踪,捕获模型训练元数据,如源数据集、模型训练容器、超参数和模型输出位置。任何来自训练作业运行的日志都将保存到 CloudWatch 日志中,系统指标,如 CPU 和 GPU 利用率,将捕获到 CloudWatch 指标中。

根据整体端到端机器学习平台架构,模型训练环境也可以托管数据预处理、模型验证和模型训练后处理等服务,因为这些是端到端机器学习流程中的重要步骤。为此,有多种技术选项可用,例如 SageMaker 处理服务、AWS Glue 和 AWS Lambda。

模型托管环境

一个企业级的模型托管环境需要以安全、高效和可扩展的方式支持广泛的机器学习框架。它应该附带一系列预构建的推理引擎,这些引擎可以支持常见的模型,通过RESTful APIgRPC 协议直接提供。它还需要提供灵活性,以托管针对特定需求的定制构建的推理引擎。用户还应能够访问不同的硬件设备,如 CPU、GPU 和专用芯片,以满足不同的推理需求。

一些模型推理模式需要更复杂的推理图,例如流量分割、请求转换或模型集成支持。模型托管环境可以提供这种功能作为即插即用的特性,或者提供技术选项来构建自定义推理图。其他常见的模型托管功能包括概念漂移检测模型性能漂移检测。当生产数据的统计特性与用于模型训练的数据不符时,就会发生概念漂移。概念漂移的一个例子是,在生产环境中,一个特征的平均值和标准差与训练数据集相比发生了显著变化。当模型在生产中的准确性下降时,就会发生模型性能漂移。

模型托管环境中的组件可以通过其 API、脚本或 IaC 部署(如 AWS CloudFormation)参与自动化工作流程。例如,可以使用 CloudFormation 模板部署 RESTful 端点,或者作为自动化工作流程的一部分调用其 API。

从安全角度来看,模型托管环境需要提供身份验证和授权控制,以管理对控制平面(管理功能)和数据平面(模型端点)的访问。针对托管环境的访问和操作应记录下来,以供审计。为了支持操作支持,托管环境需要启用状态日志记录和系统监控,以支持系统可观察性和问题调试。

SageMaker 托管服务是一个完全托管的模型托管服务。类似于我们在本书中之前审查的 KFServing 和 Seldon Core,SageMaker 托管服务也是一个多框架模型托管服务。接下来,我们将更详细地探讨其为企业级模型托管提供的各种功能。

推理引擎

SageMaker 为多个 ML 框架提供内置推理引擎,包括 scikit-learn、XGBoost、TensorFlow、PyTorch 和 Spark ML。SageMaker 以 Docker 容器形式提供这些内置推理引擎。为了搭建一个 API 端点来服务模型,您只需提供模型工件和基础设施配置。以下是一个模型服务选项列表:

  • 服务 TensorFlow 模型:SageMaker 使用 TensorFlow Serving 作为 TensorFlow 模型的推理引擎。以下代码示例展示了如何使用 SageMaker 托管服务部署 TensorFlow Serving 模型,其中使用 Model 类从 S3 位置加载 TensorFlow 模型,并使用指定计算实例类型和数量的 deploy() 函数将其部署为 SageMaker 端点:

    from sagemaker.tensorflow.serving import Model
    tensorflow_model = Model(
        model_data=<S3 location of the TF ML model artifacts>,
        role=<AWS IAM role>,
       framework_version=<tensorflow version>
    )
    tensorflow_model.deploy(
      initial_instance_count=<instance count>, instance_type=<instance type>
    ) 
    
  • 服务 PyTorch 模型:SageMaker 托管在底层使用 TorchServe 来服务 PyTorch 模型。以下代码示例展示了如何部署 PyTorch 模型,其代码与部署 TensorFlow 模型的代码非常相似:

    from sagemaker.pytorch.model import PyTorchModel
    pytorch_model = PyTorchModel(
        model_data=<S3 location of the PyTorch model artifacts>,
        role=<AWS IAM role>,
        framework_version=<PyTorch version>
    )
    pytorch_model.deploy(
        initial_instance_count=<instance count>, instance_type=<instance type>
    ) 
    
  • 服务 Spark ML 模型:对于基于 Spark ML 的模型,SageMaker 使用 MLeap 作为后端来服务 Spark ML 模型。这些 Spark ML 模型需要序列化为 MLeap 格式,以便它们可以被 MLeap 引擎使用。以下代码示例展示了如何使用 SageMaker 托管服务部署 Spark ML 模型,其中使用 SparkMLModel 类指定模型配置,并使用 deploy() 函数将模型实际部署到 SageMaker 端点:

    import sagemaker
    from sagemaker.sparkml.model import SparkMLModel
    sparkml_model = SparkMLModel(
        model_data=<S3 location of the Spark ML model artifacts>,
        role=<AWS IAM role>,
        sagemaker_session=sagemaker.Session(),
        name=<Model name>,
        env={"SAGEMAKER_SPARKML_SCHEMA": <schema_json>}
    )
    sparkml_model.deploy(
        initial_instance_count=<instance count>, instance_type=<instance type>
    ) 
    
  • 服务 XGBoost 模型:SageMaker 为训练好的 XGBoost 模型提供 XGBoost 模型服务器。在底层,它使用 Nginx、Gunicorn 和 Flask 作为模型服务架构的一部分。入口 Python 脚本加载训练好的 XGBoost 模型,并可选择执行预处理和后处理数据:

    from sagemaker.xgboost.model import XGBoostModel
    xgboost_model = XGBoostModel(
        model_data=<S3 location of the Xgboost ML model artifacts>,
        role=<AWS IAM role>,
        entry_point=<entry python script>,
        framework_version=<xgboost version>
    )
    xgboost_model.deploy(
        instance_type=<instance type>,
        initial_instance_count=<instance count>
    ) 
    
  • 服务 scikit-learn 模型:SageMaker 为基于 scikit-learn 的模型提供内置服务容器。技术堆栈与 XGBoost 模型服务器类似,也是基于 Nginx、Gunicorn 和 Flask:

    from sagemaker.sklearn.model import SKLearnModel
    sklearn_model = SKLearnModel(
        model_data=<S3 location of the Xgboost ML model artifacts>,
        role=<AWS IAM role>,
        entry_point=<entry python script>,
        framework_version=<scikit-learn version>
    )
    sklearn_model.deploy(instance_type=<instance type>, initial_instance_count=<instance count>) 
    
  • 使用自定义容器服务模型:对于自定义创建的推理容器,您可以遵循类似的语法来部署模型。主要区别是必须提供自定义推理容器镜像的 uri,以指定自定义容器的位置。您可以在 docs.aws.amazon.com/sagemaker/latest/dg/adapt-inference-container.html 找到有关构建自定义推理容器的详细文档:

    from sagemaker.model import Model
    custom_model = Model(
        Image_uri = <custom model inference container image uri>,
        model_data=<S3 location of the ML model artifacts>,
        role=<AWS IAM role>,
        framework_version=<scikit-learn version>
    )
    custom_model.deploy(instance_type=<instance type>, initial_instance_count=<instance count>) 
    

SageMaker 托管提供推理管道功能,允许您创建一个线性序列的容器,在调用模型进行预测前后执行自定义数据处理。SageMaker 托管可以支持在模型多个版本之间进行流量拆分,以进行 A/B 测试。

可以使用 AWS CloudFormation 模板来配置 SageMaker 托管。同时,也支持 AWS CLI 用于脚本自动化,并且可以通过其 API 集成到自定义应用程序中。以下是一些不同端点部署自动化方法的代码示例:

  • 以下是一个用于 SageMaker 端点部署的 CloudFormation 代码示例。在这个代码示例中,你指定了计算实例、实例数量、模型名称以及用于托管模型的模型服务容器。你可以在这里找到完整的代码:github.com/PacktPublishing/The-Machine-Learning-Solutions-Architect-and-Risk-Management-Handbook-Second-Edition/blob/main/Chapter09/sagemaker_hosting.yaml

    Description: "Model hosting cloudformation template"
    Resources:
    Endpoint:
    Type: "AWS::SageMaker::Endpoint"
    Properties:
    EndpointConfigName:
    !GetAtt EndpointConfig.EndpointConfigName
    EndpointConfig:
    Type: "AWS::SageMaker::EndpointConfig"
    Properties:
    ProductionVariants:
    - InitialInstanceCount: 1
    InitialVariantWeight: 1.0
    InstanceType: ml.t2.large
    ModelName: !GetAtt Model.ModelName
    VariantName: !GetAtt Model.ModelName
    Model:
    Type: "AWS::SageMaker::Model"
    Properties:
    PrimaryContainer:
    Image: <container uri>
    ExecutionRoleArn: !GetAtt ExecutionRole.Arn
    ... 
    
  • 以下是一个用于 SageMaker 端点部署的 AWS CLI 示例,它包括三个主要步骤:创建模型、指定 SageMaker 端点配置以及将模型实际部署到 SageMaker 端点:

    Aws sagemaker create-model --model-name <value> --execution-role-arn <value>
    aws sagemaker Create-endpoint-config --endpoint-config-name <value> --production-variants <value>
    aws sagemaker Create-endpoint --endpoint-name <value> --endpoint-config-name <value> 
    

如果内置的推理引擎不符合你的要求,你应该考虑引入自己的 Docker 容器来托管你的机器学习模型。

认证和安全控制

SageMaker 托管服务使用 AWS IAM 作为控制平面 API(例如,创建端点的 API)和数据平面 API(例如,调用托管模型端点的 API)的访问控制机制。如果你需要支持数据平面 API 的其他认证方法,例如 OpenID ConnectOIDC),你可以实现一个代理服务作为前端来管理用户认证。一种常见的模式是使用 AWS API Gateway 作为 SageMaker API 的前端,以实现自定义认证管理以及其他 API 管理功能,如计费和节流管理。

监控和日志记录

SageMaker 提供了开箱即用的监控和日志记录功能,以协助支持操作。它监控系统资源指标(例如,CPU/GPU 利用率)和模型调用指标(例如,调用次数、模型延迟和失败)。这些监控指标以及任何模型处理日志都由 AWS CloudWatch 指标和 CloudWatch 日志捕获。

现在我们已经涵盖了机器学习平台训练、推理、安全和监控方面的内容,接下来我们将深入探讨如何实现 MLOps 以自动化机器学习工作流程。

采用 MLOps 进行机器学习工作流程

与广泛采用于传统软件开发和部署过程的 DevOps 实践类似,MLOps 实践旨在简化机器学习管道的构建和部署流程,同时增强数据科学家/机器学习工程师、数据工程和运维团队之间的协作。具体来说,MLOps 实践的主要目标是在整个机器学习生命周期中产生以下主要好处:

  • 流程一致性:MLOps 实践旨在在机器学习模型构建和部署过程中创建一致性。一致的流程可以提高机器学习工作流的效率,并确保机器学习工作流的输入和输出具有高度的确定性。

  • 工具和流程可重用性:MLOps 实践的核心目标之一是创建可重用的技术工具和模板,以加快新机器学习用例的采用和部署。这可以包括常见的工具,如代码和库存储库、打包和镜像构建工具、管道编排工具、模型注册表以及模型训练和模型部署的通用基础设施。从可重用模板的角度来看,这可以包括用于 Docker 镜像构建的通用可重用脚本、工作流编排定义以及用于模型构建和模型部署的 CloudFormation 脚本。

  • 模型构建可重复性:机器学习高度迭代,可能涉及大量使用不同数据集、算法和超参数的实验和模型训练运行。MLOps 流程需要捕获用于构建机器学习模型的所有数据输入、源代码和工件,并从这些输入数据、代码和工件中建立最终模型的模型血缘。这对于实验跟踪以及治理和控制目的都至关重要。

  • 交付可扩展性:MLOps 流程和相关工具能够并行运行大量机器学习管道,以实现高吞吐量的交付。不同的机器学习项目团队可以独立使用标准的 MLOps 流程和通用工具,而不会因资源竞争、环境隔离和治理方面的冲突而产生冲突。

  • 流程和操作可审计性:MLOps 使流程和机器学习管道的可审计性更高。这包括捕获机器管道执行的详细信息、不同步骤之间的依赖关系和血缘、作业执行状态、模型训练和部署细节、审批跟踪以及由人工操作员执行的操作。

现在我们已经熟悉了 MLOps 实践的预期目标和好处,让我们深入了解 AWS 上 MLOps 的具体操作流程和具体技术架构。

MLOps 架构的组件

MLOps 最重要的概念之一是自动化管道,它执行一系列任务,如数据处理、模型训练和模型部署。这个管道可以是步骤的线性序列,也可以是一个更复杂的有向无环图DAG),支持多个任务的并行执行。以下图表展示了 ML 管道的示例 DAG。

模型步骤描述自动生成图

图 9.2:样本 ML 管道流程

MLOps 架构还包括几个存储库,用于存储在管道执行过程中不同资产和元数据。以下图表列出了 MLOps 操作中的核心组件和任务:

图 9.2 – MLOps 组件

图 9.3:MLOps 组件

  • 代码存储库是 MLOps 架构组件,它不仅作为数据科学家和工程师的源代码控制机制,还可以作为触发不同管道执行的机制。例如,当数据科学家将更新的训练脚本检查到代码存储库中时,可以触发模型训练管道执行。

  • 特征存储库存储可重用的 ML 特征,可以是数据处理/特征工程作业的目标。特征存储库中的特征可以是适用情况下的训练数据集的一部分。特征存储库还用作模型推理请求的一部分。

  • 容器存储库存储用于数据处理任务、模型训练作业和模型推理引擎的容器镜像。它通常是容器构建管道的目标。

  • 模型注册库保存训练模型的清单,以及与模型相关的所有元数据,例如其算法、超参数、模型指标和训练数据集位置。它还维护模型生命周期的状态,例如其部署批准状态。

  • 管道存储库维护自动化管道的定义和不同管道作业执行的状态。

在企业环境中,当执行不同任务,如模型部署时,也需要创建任务票据,以便这些操作可以在一个共同的票据管理系统中被追踪。为了支持审计要求,需要追踪不同管道任务及其相关工件的历史。

MLOps 架构的另一个关键组件是监控。通常,您希望监控管道的执行状态、模型训练状态和模型端点状态。模型端点监控还可以包括系统/资源性能监控、模型统计指标监控、漂移和异常监控以及模型可解释性监控。可以在某些执行状态上触发警报,以调用所需的人类或自动化操作。

AWS 为实施 MLOps 架构提供了多种技术选项。以下图表显示了这些技术服务在企业 MLOps 架构中的位置:

图 9.3 – 使用 AWS 服务的 MLOps 架构

图 9.4:使用 AWS 服务的 MLOps 架构

如我们之前提到的,共享服务环境托管了用于流水线管理和执行的常用工具,以及如代码仓库和模型注册表等常用仓库。

在这里,我们使用 AWS CodePipeline 来编排整体的 CI/CD 流水线。AWS CodePipeline 是一个持续交付服务。我们在这里使用此服务,因为它可以与不同的代码仓库如 AWS CodeCommit、GitHub 仓库和 Bitbucket 等原生集成。

它可以从代码仓库中提取文件,并将它们提供给下游任务,例如使用 AWS CodeBuild 服务构建容器或训练模型训练环境中的模型。您可以根据不同的需求创建不同的流水线。流水线可以通过 API 或 CodePipeline 管理控制台按需触发,或者可以通过代码仓库中的代码更改触发。根据您的需求,您可以创建不同的流水线。在先前的图表中,我们可以看到四个示例流水线:

  • 用于构建用于训练、处理和推理的不同容器镜像的容器构建流水线

  • 用于为发布训练模型的模型训练流水线

  • 用于将训练好的模型部署到生产的模型部署流水线

  • 用于在数据科学环境中进行模型训练和部署测试的开发、训练和测试流水线

注意,虽然图 9.4只展示了四个不同的流水线,但实际上,根据具体需求,组织可以有更多流水线。此外,它们可以并行运行相同流水线的多个实例,以适应各种机器学习项目。例如,不同的训练作业流水线实例可以独立且并发运行,每个实例都专门用于使用不同的数据集和配置训练不同的机器学习模型。

代码仓库是 MLOps 环境中最重要的组件之一。它不仅被数据科学家/机器学习工程师和其他工程师用于持久化代码工件,而且还作为 CI/CD 流水线的触发机制。这意味着当数据科学家/机器学习工程师提交代码更改时,它可以自动启动 CI/CD 流水线。例如,如果数据科学家修改了模型训练脚本并希望在开发环境中测试自动化的训练流水线,他们可以将代码提交到开发分支以在开发环境中启动模型训练流水线。当它准备进行生产发布部署时,数据科学家可以将/合并代码到发布分支以启动生产发布流水线。

简而言之,在图 9.4的 MLOps 架构中,我们使用了:

  • 亚马逊弹性容器注册库ECR)作为中央容器注册服务。ECR 用于存储数据处理、模型训练和模型推理的容器。您可以为容器镜像添加标签,以指示不同的生命周期状态,如开发或生产。

  • SageMaker 模型注册库作为中央模型仓库。中央模型仓库可以位于共享服务环境中,因此可以被不同的项目访问。所有经过正式训练和部署周期的模型都应该在中央模型仓库中进行管理和跟踪。

  • SageMaker 特征存储提供了一个通用的特征仓库,供不同项目重用。它可以位于共享服务环境中,或成为数据平台的一部分。特征通常在数据管理环境中预先计算,并发送到 SageMaker 特征存储,以便在模型训练环境中进行离线模型训练,以及不同模型托管环境中的在线推理。

监控和日志记录

在监控方面,机器学习平台带来了一些独特的挑战。除了监控常见的软件系统相关指标和状态,如基础设施利用率和处理状态外,机器学习平台还需要监控模型和数据特定的指标和性能。此外,与传统的系统级监控相比,其直观性较强,而机器学习模型的透明度使得理解系统本身变得固有困难。现在,让我们更深入地了解机器学习平台监控的三个主要领域。

模型训练监控

模型训练监控提供了对训练进度的可见性,并有助于在训练过程中识别训练瓶颈和错误条件。它使操作流程,如训练作业进度报告和响应、模型训练性能进度评估和响应、训练问题故障排除以及数据和模型偏差检测以及模型可解释性和响应成为可能。具体来说,我们希望在模型训练期间监控以下关键指标和条件:

  • 通用系统和资源利用及错误指标:这些指标提供了对基础设施资源(如 CPU、GPU、磁盘 I/O 和内存)在模型训练中如何被利用的可见性。这些指标可以帮助您在满足不同模型训练需求时做出基础设施配置的决策。

  • 训练作业事件和状态:这提供了对训练作业进度的可见性,例如作业的开始和运行、完成以及失败详情。

  • 模型训练指标:这些是模型训练指标,例如损失曲线和准确率报告,有助于您了解模型的表现。

  • 偏差检测指标和模型可解释性报告:这些指标有助于您了解训练数据集或机器学习模型中是否存在偏差。模型可解释性也可以被监控和报告,以帮助您理解重要特征与不重要特征之间的区别。

  • 模型训练瓶颈和训练问题:这些提供了对训练问题(如梯度消失、权重初始化不良和过拟合)的可见性,以帮助确定所需的数据和算法以及训练配置更改。例如,CPU 和 I/O 瓶颈、负载不均和低 GPU 利用率等指标可以帮助确定更高效模型训练的基础设施配置更改。

AWS 提供了多个本地服务,用于在 AWS 上构建模型监控架构。以下图显示了为基于 SageMaker 的模型训练环境构建监控解决方案的示例架构:

图 9.4 – 模型训练监控架构

图 9.5:模型训练监控架构

此架构允许您监控训练和系统指标,并执行日志捕获和处理、训练事件捕获和处理以及模型训练偏差和可解释性报告。它有助于启用操作流程,如训练进度和状态报告、模型指标评估、系统资源利用率报告和响应、训练问题故障排除、偏差检测和模型决策可解释性。

在模型训练期间,SageMaker 可以向 AWS CloudWatch 发出模型训练指标,如训练损失和准确率,以帮助进行模型训练评估。AWS CloudWatch 是 AWS 监控和可观察性服务。它收集来自其他 AWS 服务的指标和日志,并提供仪表板以可视化和分析这些指标和日志。系统利用率指标(如 CPU/GPU/内存利用率)也报告给 CloudWatch 进行分析,以帮助您了解任何基础设施限制或低利用率。可以为单个指标或复合指标创建 CloudWatch 警报,以自动通知或响应。例如,您可以为低 CPU/GPU 利用率创建警报,以帮助主动识别训练作业的次优硬件配置。此外,当警报被触发时,它可以通过 AWS 简单通知服务SNS)发送自动通知(如短信和电子邮件),以支持通过 AWS 进行审查。

您可以使用 CloudWatch 日志收集、监控和分析训练作业发出的日志。您可以使用这些捕获的日志来了解训练作业的进度,并识别错误和模式,以帮助解决任何模型训练问题。例如,CloudWatch 日志可能包含错误,如模型训练时 GPU 内存不足或访问特定资源时的权限问题,以帮助您解决模型训练问题。默认情况下,CloudWatch 日志提供了一个名为 CloudWatch 日志洞察的 UI 工具,用于使用专门构建的查询语言交互式分析日志。或者,这些日志也可以转发到 Elasticsearch 集群进行分析和查询。这些日志可以在指定的日志和监控账户中聚合,以集中管理日志访问和分析。

SageMaker 训练作业还可以发送事件,例如训练作业状态从运行变为完成。您可以根据这些不同的事件创建自动通知和响应机制。例如,当训练作业成功完成或失败时,您可以向数据科学家发送通知,包括失败原因。您还可以自动对不同状态(如特定失败条件下的模型重新训练)的失败做出响应。

SageMaker Clarify 组件可以检测数据和模型偏差,并提供训练模型的模型可解释性报告。您可以在 SageMaker Studio UI 或 SageMaker API 中访问偏差和模型可解释性报告。

模型端点监控

模型端点监控提供了对模型服务基础设施性能的可见性,以及模型特定的指标,如数据漂移、模型漂移和推理可解释性。以下是一些模型端点监控的关键指标:

  • 通用系统和资源利用及错误指标:这些指标提供了对基础设施资源(如 CPU、GPU 和内存)用于模型服务利用情况的可见性。它们可以帮助您在为不同的模型服务需求提供基础设施时做出决策。

  • 数据统计监控指标:数据的统计性质可能会随时间变化,这可能导致从原始基准测试中降级 ML 模型性能。这些指标可以包括基本统计偏差,如均值和标准差的变化,以及数据分布的变化。

  • 模型质量监控指标:这些模型质量指标提供了对模型性能偏离原始基准的可见性。这些指标可以包括回归指标(如 MAE 和 RMSE)和分类指标(如混淆矩阵、F1、精确率、召回率和准确率)。

  • 模型推理可解释性:这为每个预测提供了模型可解释性,以帮助您了解哪些特征对预测所做的决策影响最大。

  • 模型偏差监控指标:类似于训练过程中的偏差检测,偏差指标帮助我们理解推理时的模型偏差。

模型监控架构依赖于许多相同的 AWS 服务,包括 CloudWatch、EventBridge 和 SNS。以下图表显示了基于 SageMaker 的模型监控解决方案的架构模式:

图 9.5 – 模型端点监控架构

图 9.6:模型端点监控架构

这种架构的工作原理与模型训练架构类似。CloudWatch 指标捕获端点指标,例如 CPU/GPU 利用率、模型调用指标(调用次数和错误数)以及模型延迟。这些指标有助于硬件优化和端点扩展等操作。

CloudWatch 日志捕获由模型服务端点发出的日志,帮助我们了解状态和解决技术问题。同样,端点事件,例如状态从 创建中 变为 服务中,可以帮助您构建自动通知管道以启动纠正措施或提供状态更新。

除了系统和相关状态监控之外,此架构还通过结合 SageMaker 模型监控器和 SageMaker Clarify 支持数据和模型特定的监控。具体来说,SageMaker 模型监控器可以帮助您监控数据漂移和模型质量。

对于数据漂移,SageMaker 模型监控器可以使用训练数据集创建基线统计指标,例如标准差、平均值、最大值、最小值和数据集特征的数据分布。它使用这些指标和其他数据特征,如数据类型和完整性,来建立约束。然后,它捕获生产环境中的输入数据,计算指标,将它们与基线指标/约束进行比较,并报告基线漂移。模型监控器还可以报告数据质量问题,例如数据类型错误和缺失值。数据漂移指标可以发送到 CloudWatch 指标进行可视化和分析,并且可以配置 CloudWatch 警报,在指标超过预定义阈值时触发通知或自动响应。

对于模型质量监控,它使用包含预测和真实标签的基线数据集创建基线指标(例如回归的 MAE 和分类的准确率)。然后,它捕获生产中的预测,摄取真实标签,并将真实标签与预测合并以计算各种回归和分类指标,然后再将它们与基线指标进行比较。类似于数据漂移指标,模型质量指标可以发送到 CloudWatch 指标进行分析和可视化,并且可以配置 CloudWatch 警报以进行自动通知和/或响应。以下图表显示了 SageMaker 模型监控器的工作原理:

图 9.6 – SageMaker 模型监控流程

图 9.7:SageMaker 模型监控流程

对于偏差检测,SageMaker Clarify 可以持续监控部署模型的偏差指标,并在指标超过阈值时通过 CloudWatch 发出警报。我们将在第十三章“偏差、可解释性、隐私和对抗攻击”中详细介绍偏差检测。

机器学习管道监控

需要监控机器学习管道的执行状态和错误,以便在需要时采取纠正措施。在管道执行期间,有管道级别的状态/事件以及阶段级别和动作级别的状态/事件。您可以使用这些事件和状态来了解每个管道和阶段的进度,并在出现问题时收到警报。以下图表显示了 AWS CodePipeline、CodeBuild 和 CodeCommit 如何与 CloudWatch、CloudWatch Logs 和 EventBridge 协同工作,以进行一般状态监控和报告,以及问题故障排除:

图 9.7 – 机器学习 CI/CD 管道监控架构

图 9.8:机器学习 CI/CD 管道监控架构

CodeBuild 可以发送指标,例如SucceededBuildsFailedBuildsDuration指标。这些 CodeBuild 指标可以通过 CodeBuild 控制台和 CloudWatch 仪表板访问。CodeBuild、CodeCommit 和 CodePipeline 都可以向 EventBridge 发出事件,以报告详细的状态变化并触发自定义事件处理,例如通知,或将事件记录到其他数据存储库以进行事件归档。所有三个服务都可以将详细日志发送到 CloudWatch Logs,以支持诸如故障排除或详细错误报告等操作。

Step Functions 还向 CloudWatch 提供一系列监控指标,例如执行指标(例如执行失败、成功、中止和超时)和活动指标(例如活动开始、计划中和成功)。您可以在管理控制台中查看这些指标,并设置阈值以设置警报。

服务提供管理

企业级机器学习平台管理的关键组成部分是服务提供管理。对于大规模的服务提供和部署,应采用自动化和受控的过程。在这里,我们将专注于提供机器学习平台本身,而不是提供 AWS 账户和网络,这些应在提前建立作为机器学习平台提供的基础环境。对于机器学习平台提供,有以下两个主要的提供任务:

  • 数据科学环境提供:为数据科学家提供数据科学环境主要包括提供数据科学和数据管理工具、实验存储以及数据源和预构建 ML 自动化管道的访问权限。

  • 机器学习自动化管道配置:机器学习自动化管道需要提前配置,以便数据科学家和 MLOps 工程师可以使用它们来自动化不同的任务,例如容器构建、模型训练和模型部署。

在 AWS 上自动提供服务配置有多种技术方法,例如使用配置脚本、CloudFormation 脚本和 AWS 服务目录。使用脚本,你可以在脚本中依次调用不同的 AWS CLI 命令来配置不同的组件,例如创建 SageMaker Studio 笔记本。CloudFormation 是 AWS 上基础设施部署的 IaC 服务。使用 CloudFormation,你可以创建模板来描述所需的资源和依赖关系,这些资源和依赖关系可以作为一个单独的堆栈启动。当模板执行时,堆栈中指定的所有资源和依赖关系将自动部署。以下代码显示了部署 SageMaker Studio 域的模板:

Type: AWS::SageMaker::Domain
Properties:
AppNetworkAccessType: String
AuthMode: String
DefaultUserSettings:
UserSettings
DomainName: String
KmsKeyId: String
SubnetIds:
- String
Tags:
- Tag
VpcId: String 

AWS 服务目录允许你创建不同的 IT 产品,以便在 AWS 上部署。这些 IT 产品可以包括 SageMaker 笔记本、CodeCommit 仓库和 CodePipeline 工作流定义。AWS 服务目录使用 CloudFormation 模板来描述 IT 产品。使用服务目录,管理员可以使用 CloudFormation 模板创建 IT 产品,按产品组合组织这些产品,并授权最终用户访问。然后,最终用户从服务目录产品组合中访问产品。

以下图显示了创建服务目录产品和从服务目录服务启动产品的流程:

图 9.8 – 服务目录工作流程

图 9.9:服务目录工作流程

对于大规模和受管理的 IT 产品管理,服务目录是推荐的方法。服务目录支持多种部署选项,包括单个 AWS 账户部署和中心辐射式跨账户部署。

中心辐射式部署允许你集中管理所有产品,并在不同的账户中使它们可用。对于我们的企业机器学习参考架构(图 9.4),我们可以使用中心辐射式架构来支持数据科学环境和机器学习管道的配置,如下所示:

图 9.9 – 企业机器学习产品管理的中心辐射式服务目录架构

图 9.10:企业机器学习产品管理的中心辐射式服务目录架构

在先前的架构中,我们在共享服务账户中设置了中央投资组合。所有产品,如创建新的 Studio 域、新的 Studio 用户配置文件、CodePipeline 定义和训练管道定义,都在中央枢纽账户中集中管理。一些产品与不同的数据科学账户共享,以创建数据科学家和团队的数据科学环境。一些其他产品与模型训练账户共享,以建立机器学习训练管道。

构建和运营机器学习平台的最佳实践

构建企业机器学习平台是一项多方面的任务。它通常需要大量时间,组织通常需要六个月或更长时间来实施其机器学习平台的初始阶段。未来多年需要持续努力,以纳入新的功能和改进。将用户和机器学习项目上线到新平台是另一个具有挑战性的方面,涉及对用户基础的广泛教育和提供直接的技术支持。

在某些情况下,可能需要对平台进行调整以确保顺利上线和成功利用。在与许多客户合作构建他们的企业机器学习平台的过程中,我已确定了一些关于构建和采用机器学习平台的最佳实践。

机器学习平台项目执行的最佳实践

  • 组建跨职能团队:将数据工程师、机器学习研究人员、DevOps 工程师、应用开发人员和业务领域专家汇集到综合团队中。这种技能和视角的多样性将丰富平台的设计和实施。

  • 制定治理需求和流程:在模型验证、可解释性、伦理审查和批准生产部署之前,尽早定义流程和需求。这将把负责任的 AI 实践嵌入到平台中。

  • 定义关键绩效指标 (KPIs) 以衡量成功:识别相关的业务 KPIs 并实施流程以积极监控和报告模型和平台对这些 KPIs 的影响。与利益相关者分享报告。

  • 选择试点机器学习工作负载:选择一些试点机器学习项目或工作负载首先在新平台上实施。从这些实际用例中学习,以验证和改进平台设计和功能。

  • 定义目标状态并分阶段执行:阐述企业机器学习平台的长远愿景和目标状态。然而,战略性地分阶段实施采用,以实现更快的学习。

机器学习平台设计和实施的最佳实践

  • 采用完全管理的内置功能:利用 SageMaker 的托管算法、容器和功能作为默认设置以减少开销并简化集成。仅在需要时使用自定义构建的功能。

  • 实施基础设施即代码:使用 CloudFormation 或 Terraform 通过代码提供、配置和管理 ML 基础设施。这实现了一致性和自动化。

  • 构建 CI/CD 管道:利用 CodePipeline、CodeBuild、CodeDeploy 和 SageMaker 实现持续集成和部署管道,以实现自动化工作流程。如有需要,考虑使用 GitHub Actions/Jenkins。

  • 自动化实验跟踪:配置 SageMaker 或第三方工具以自动记录模型训练元数据,如参数、指标和工件。这使调试、比较和可重复性成为可能。

  • 建立批准的库存储库:创建一个集中管理的存储库,用于存储训练、部署和推理代码中批准的库和包。这确保了一致性。

  • 设计可扩展性和峰值处理:通过自动扩展功能设计平台,以处理不同的使用模式和流量峰值。

  • 从一开始就优先考虑安全性:实施包括扫描、修补、加密和访问控制在内的安全最佳实践。制定事件响应计划。

  • 构建自助服务能力:早期开发自助服务功能,并不断演进以赋予用户权力,同时保持治理。

  • 集中模型存储库:使用单个集中存储库来存储模型,以提高协作、发现、合规性和高效的部署。

  • 建立中央特征存储库:实施一个集中特征存储库,用于共享、监控和管理特征工程工作和使用。

平台使用和操作最佳实践

  • 限制生产访问权限:仅允许必要的技术支持和操作人员访问生产系统。这降低了出错或未经授权更改的风险。

  • 优化成本:利用自动扩展、spot 实例、基于可用性的定价和其他功能来优化和降低云成本。

  • 监控和可观察性:使用 CloudWatch、SageMaker Debugger、Model Monitor 和其他工具积极监控模型准确性、数据漂移、系统性能等。

  • 建立变更管理:在部署前定义一个结构化的流程来管理、审查、批准和沟通平台/模型变更。

  • 事件管理流程:制定一个事件响应计划,包括检测、升级和及时解决生产问题和异常的程序。

  • 多可用区和区域部署:在多个可用区和区域部署模型和平台基础设施,以提高弹性和最小化延迟。

  • 发布管理:实施结构化的发布流程,以协调、审查和规划部署前的变更和新模型/平台版本。

  • 容量规划:根据路线图和工作负载主动评估和预测基础设施容量需求,并适当扩展。

  • 资源标记:一个设计合理的标记策略为机器学习平台提供了组织、发现、安全、自动化、合规性和改进的可视性。

实施一个健壮的企业级机器学习平台需要深思熟虑的策略和对人员、流程和技术之间的协调。通过汇集跨职能团队,建立负责任的 AI 治理,监控业务影响,并设计可扩展性、安全性和协作,组织可以加速他们的 AI 之旅。采用现代基础设施即代码、CI/CD 管道和云服务奠定了坚实的技术基础。然而,为了实现价值,平台必须与业务优先事项紧密集成,并持续提供值得信赖的 AI。通过围绕业务目标和用户进行的深思熟虑的计划和分阶段执行,公司可以转变为以 AI 驱动的企业。

关键在于在创新与治理之间取得平衡,通过自动化快速推进同时保持控制,并发展一个负责任地民主化 AI 能力,既服务于专家也服务于业务用户。这使 AI 在运营中得到可靠和可问责的嵌入,从而获得竞争优势。

摘要

在本章中,我们探讨了构建企业级机器学习平台的关键要求和最佳实践。我们讨论了如何设计一个支持端到端机器学习生命周期、流程自动化和环境分离的平台。回顾了架构模式,包括如何利用 AWS 服务在云上构建一个健壮的机器学习平台。

我们涵盖了不同机器学习环境的核心能力,例如训练、托管和共享服务。还讨论了平台设计、运营、治理和集成的最佳实践。你现在应该对什么是企业级机器学习平台以及如何在 AWS 上利用已验证的模式构建一个平台有了一个稳固的理解。

在下一章中,我们将更深入地探讨高级机器学习工程主题。这包括分布式训练技术以扩展模型开发,以及低延迟服务方法以优化推理。

加入我们的 Discord 社区

加入我们的 Discord 空间,与作者和其他读者进行讨论:

packt.link/mlsah

二维码