亚马逊AWS官方博客

手把手教你玩转 Kubeflow on EKS(三)

本文为手把手教你玩转Kubeflow on EKS 系列文章的第三篇。

1. 前言

Amazon SageMaker 是一个完全托管的服务,涵盖了 ML 的整个工作流,可以标记和准备数据、选择算法、训练模型、调整和优化模型以便部署、预测和执行操作,可以帮助开发人员和数据科学家快速构建、训练和部署机器学习 (ML) 模型。SageMaker 完全消除了机器学习过程中每个步骤的繁重工作,让开发高质量模型变得更加轻松。

 

许多客户希望使用 Amazon SageMaker 全面管理的机器学习功能,但也希望平台和基础设施团队继续使用 Kubernetes 来编排和管理管道。SageMaker提供了用于Kubeflow Pipeline (KFP)的Amazon SageMaker组件和SageMaker Operator,帮助客户轻松实现SageMaker和Kubeflow的无缝集成。借助SageMaker Operator和Pipeline,Amazon EKS 用户可以访问完全托管的,Kubeflow 原生提供的 SageMaker 机器学习工具和引擎。这样就无需手动管理和优化Amazon EKS 中的 机器学习基础设施,同时仍可通过 Amazon EKS 控制整体编排。使用适用于 Kubernetes 的 SageMaker Operator和Pipeline,企业可以在 Amazon EKS中使用完全托管的机器学习服务,而无需迁移工作负载。

 

Amazon SageMaker 组件

AWS宣布了用于Kubeflow管道的Amazon SageMaker组件,Amazon SageMaker Componets提供了一系列Kubeflow Pipeline组件可以在Kubernetes中启动计算密集型作业,并集成了Kubeflow Pipeline的编排优点。这些组件可以利用Kubeflow Pipeline在Amazon SageMaker中创建和监视培训、调优、端点部署和批处理转换作业。通过Kubeflow Pipeline和SageMaker的集成,您可以将数据处理和训练任务从Kubernetes集群转移到Amazon SageMaker来优化机器学习管理服务。同时来自Amazon SageMaker的作业参数、状态、日志和输出仍然可以通过Kubeflow Pipelinee UI来访问。您可以创建一个完全使用这些组件构建的Kubeflow管道,或者根据需要结合SageMaker的优势将单个组件集成到Kubeflow Pipeline中。以下是Amazon SageMaker提供的Kubeflow Pipeline组件,用于将Amazon SageMaker的下面6个关键特性集成到Kubeflow的ML工作流中。

  • 模型训练:训练组件允许您直接从Kubeflow管道工作流提交Amazon SageMaker训练工作。
  • 超参数优化:超参数优化组件允许您直接从Kubeflow管道工作流向Amazon SageMaker提交超参数调优作业。
  • 模型部署:部署组件使您能够通过Kubeflow管道工作流在Amazon SageMaker中部署模型
  • 批处理转换组件:批处理转换组件使您能够从Kubeflow管道工作流中运行针对Amazon SageMaker中的整个数据集的推理作业
  • Ground Truth:Ground Truth组件允许您直接从Kubeflow管道工作流提交Amazon SageMaker Ground Truth 标记作业。
  • Workteam:Workteam组件允许您直接从Kubeflow管道工作流创建Amazon SageMaker私有Workteam作业

Kubeflow Pipelines

Kubeflow PipelineKubeflow Pipeline是使用Kubeflow Pipeline SDK构建的可重用的端到端ML工作流,是Kubeflow的核心组件之一。Pipelines是 Kubeflow 端到端的机器学习工作流服务,实现了一个工作流模型。所谓工作流,或者称之为流水线(Pipeline),可以将其当做一个有向无环图(DAG)。其中的每一个节点,在 Kubeflow Pipelines 的语义下被称作组件(component)。组件在图中作为一个节点,其会处理真正的逻辑,每一个组件负责的功能不同,比如预处理,数据清洗,模型训练等等。每个组件都是以 Docker 镜像的方式被打包,以容器的方式被运行的。

 

Kubeflow Pipelines 平台的功能包括:

  • 能够运行和追踪实验的管理控制台
  • 能够执行多个机器学习步骤的工作流引擎 ,实现任务编排(Argo Workflow)
  • 用来自定义工作流的 SDK,用于与笔记本交互创建Kubeflow Pipeline 的DSL
  • DSL compiler: 将Python代码转换成YAML静态配置文件

Kubeflow Pipelines 的目标在于:

  • 端到端的任务编排: 支持编排和组织复杂的机器学习工作流,该工作流可以被直接触发,定时触发,也可以由事件触发,甚至可以实现由数据的变化触发;
  • 简单的实验管理: 帮助数据科学家尝试众多的想法和框架,以及管理各种试验。并实现从实验到生产的轻松过渡;
  • 通过组件化方便重用: 通过重用 Pipelines 和组件快速创建端到端解决方案,无需每次从 0 开始的重新构建。

Kubeflow Pipeline与SageMaker端到端集成方案概述

在本方案中会演示如何在notebook笔记本中安装Pipeline SDK,构建和编译Kubeflow Pipeline,在Kubeflow Pipeline中调用SageMaker超参数优化组件进行超参数优化,训练模型和创建模型,调用SageMaker部署组件在Amazon SageMaker中批量推理和部署模型端点。

 

如上图所示,整个端到端的Pipeline包含以下组件:

  1. SageMaker超参数优化:在Kubeflow Pipeline中调用Amazon SageMaker超参数优化,根据指定的算法和超参数范围,在数据集上运行多个训练作业来查找模型的最佳版本
  2. SageMaker模型训练:在Kubeflow Pipeline中调用Amazon SageMaker创建训练作业后,Amazon SageMaker 将启动 ML 计算实例,并使用前面超参数优化的参数来训练模型,训练会使用KMeans算法对mnist数据集进行分类
  3. SageMaker模型创建:在模型训练任务完成以后,在Kubeflow Pipeline中调用Amazon SageMaker根据训练任务创建模型
  4. SageMaker批量转换:在Kubeflow Pipeline中调用Amazon SageMaker使用使用批量转换,获取整个数据集的推理结果
  5. SageMaker部署推理端点:在Kubeflow Pipeline中调用Amazon SageMaker创建终端节点,将模型部署到 Amazon SageMaker,以便从模型获取预测

 

2.Kubeflow Pipelines与SageMaker端到端集成演示

1)先决条件

首先需要在 EKS 集群中配置 AWS credentials ,演示需要不同级别的IAM权限。

  1. 创建一个用户sagemakeruser
  2. 使用sagemakeruser用户的ak和sk创建Kubernetes的secrets资源aws-secret,我们将在Kubeflow Pipeline执行期间使用它来调用AWS API。
  3. 为Sagemaker创建一个IAM执行角色,以便EKS 工作节点可以承担此角色以执行Sagemaker操作。

通常在生产环境中,根据权限最小化原则,最好是根据操作分配细粒度的权限,并利用诸如IAM Role for Service Account这样的工具来确保对AWS资源的访问,但本文为简单起见,我们将为 EKS 工作节点分配AmazonSageMakerFullAccess IAM策略。

 

在终端运行下列命令创建 IAM 权限:

aws iam create-user --user-name sagemakeruser aws iam attach-user-policy --user-name sagemakeruser --policy-arn arn:aws-cn:iam::aws:policy/AmazonSageMakerFullAccess aws iam create-access-key --user-name sagemakeruser > /tmp/create_output.json

设置环境变量:

export AWS_ACCESS_KEY_ID_VALUE=$(jq -j .AccessKey.AccessKeyId /tmp/create_output.json | base64)
export AWS_SECRET_ACCESS_KEY_VALUE=$(jq -j .AccessKey.SecretAccessKey /tmp/create_output.json | base64)

在EKS cluster中创建secret资源:

cat <<EOF | kubectl apply -f -
apiVersion: v1
kind: Secret
metadata:
  name: aws-secret
  namespace: Kubeflow
type: Opaque
data:
  AWS_ACCESS_KEY_ID: $AWS_ACCESS_KEY_ID_VALUE
  AWS_SECRET_ACCESS_KEY: $AWS_SECRET_ACCESS_KEY_VALUE
EOF

运行下列命令创建 Sagemaker执行角色,给创建角色分配AmazonSageMakerFullAccess和AmazonS3FullAccess的权限

TRUST="{ \"Version\": \"2012-10-17\", \"Statement\": [ { \"Effect\": \"Allow\", \"Principal\": { \"Service\": \"sagemaker.amazonaws.com\" }, \"Action\": \"sts:AssumeRole\" } ] }"
aws iam create-role --role-name eksworkshop-sagemaker-kfp-role --assume-role-policy-document "$TRUST"
aws iam attach-role-policy --role-name eksworkshop-sagemaker-kfp-role --policy-arn arn:aws-cn:iam::aws:policy/AmazonSageMakerFullAccess
aws iam attach-role-policy --role-name eksworkshop-sagemaker-kfp-role --policy-arn arn:aws-cn:iam::aws:policy/AmazonS3FullAccess
aws iam get-role --role-name eksworkshop-sagemaker-kfp-role --output text --query 'Role.Arn'

在输出脚本最后将得到生成的IAM角色的arn。请记录这个角色arn,因为在Kubeflow Pipeline创建步骤中需要设置,下面是输出的例子:

$ aws iam get-role --role-name eksworkshop-sagemaker-kfp-role --output text --query 'Role.Arn'
arn:aws:iam::371348455981:role/eksworkshop-sagemaker-kfp-role

最后,分配 sagemaker:InvokeEndpoint 权限给 EKS 工作节点IAM role

cat <<EoF > ~/environment/sagemaker-invoke.json
{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "sagemaker:InvokeEndpoint"
            ],
            "Resource": "*"
        }
    ]
}
EoF
aws iam put-role-policy --role-name $ROLE_NAME --policy-name sagemaker-invoke-for-worker --policy-document file://~/environment/sagemaker-invoke.json

2)创建Kubeflow Jupter笔记本

使用自定义镜像 (seedjeffwan/tensorflow-1.13.1-notebook-cpu:awscli-v2) 创建笔记本,如下图所示:

创建一个新的 Python 3 Notebook.运行以下命令从aws-samples克隆需要的文件和代码:

!git clone https://github.com/aws-samples/eks-Kubeflow-workshop.git

在Notebook笔记本中浏览到eks-workshop-notebook/notebooks/05_Kubeflow_Pipeline/05_04_Pipeline_SageMaker.ipynb. 打开该文件。

 

3)配置训练环境和下载训练数据
在notebook笔记本中安装加载Kubeflow Pipeline SDK,并创建S3存储桶存储Kubeflow Pipeline的数据;

注意:设置存储桶的region为:AWS_REGION = ‘cn-northwest-1’

下载训练数据和验证数据。将它们转换为KMeans所需的格式并上传到S3存储桶中。由于网络原因,可能存在数据集不能从http://deeplearning.net/data/mnist/mnist.pkl.gz 的情况,请手工下载,并上传到notebook笔记本:

注意:

如需手工下载数据集,需要:

注释#urllib.request.urlretrieve(“http://deeplearning.net/data/mnist/mnist.pkl.gz”, “mnist.pkl.gz”)

增加代码 :boto3.setup_default_session(region_name=’cn-northwest-1′)

如下图所示:

运行结果如下

Training data will be uploaded to: s3://yunpritrojsygzce1480922520076698-Kubeflow-Pipeline-data/mnist_kmeans_example/train_data
Test data will be uploaded to: s3://yunpritrojsygzce1480922520076698-Kubeflow-Pipeline-data/mnist_kmeans_example/test_data

4)构建Kubeflow Pipeline组件

Kubeflow Pipeline组件是独立的代码集,Pipeline组件的概念与函数的概念非常相似,每个组件都可以具有输入和输出(必须在组件规范中声明)。组件代码将传递给其输入的数据生成为其输出的数据。然后,管道通过将数据从某些组件的输出传递到其他组件的输入来将组件实例连接在一起,这与函数调用其他函数并在它们之间传递结果的方式非常相似。组件负责使用输入数据并生成输出数据

 

组件由一组输入参数,一组输出以及容器映像的位置组成。组件的容器映像是一个包,其中包含组件的可执行代码和运行该代码的环境的定义。Kubeflow管道由一组输入参数和一组任务组成。您可以在Kubeflow Pipelines用户界面中将管道的输入参数修改为:

  • 试用不同的超参数集
  • 重用管道的工作流程来训练新模型

在kubeflow中要从容器化程序创建组件,您需要以YAML格式编写组件规范,以描述Kubeflow Pipelines系统的组件。有关Kubeflow Pipelines组件的完整定义,请参见组件规范

 

本文使用已经构建好的容器镜像redbackthomson/aws-kubeflow-sagemaker 来创建Kubeflow Pipelines组件,从下图链接下载定义好的yaml格式的组件。执行代码单元格,会在Kubeflow Notebook中装载Kubeflow Pipelines SDK并装载可重用的Sagemaker Pipeline组件。

 

注意:由于网络原因,如遇到sagemaker组件yaml文件不能下载的情况,请多运行几遍,或者手工下载并加载sagemaker组件yaml文件

5)构建Kubeflow Pipeline

我们将使用Kubeflow Pipelines SDK 构建Pipeline。首先,我们定义工作流程的组成步骤及其相关性,对于每个组件指定一个Docker容器映像,以及要传递给容器端点的参数。在构建代码中需要指定存放训练模型和Pipeline包的S3存储桶位置,以及前面生成的Sagemaker执行角色。

注意:在notebook中运行创建Kubeflow Pipeline代码单元格之前,需要修改以下代码:

需要将SAGEMAKER_ROLE_ARN的值替换为我们在分配IAM权限期间创建的Sagemaker执行角色

将kmeans镜像替换为:image=’387376663083.dkr.ecr.cn-northwest-1.amazonaws.com.cn/kmeans:1′

将region替换为:region=’cn-northwest-1′

将训练实例类型替换:instance_type=’ml.m5.large’

6)编译和运行Kubeflow Pipeline

在Python中定义了管道之后,您必须先编译该管道才能将其提交给Kubeflow Pipelines服务,利用dsl-compile编译Pipeline代码并打包上传。

kfp.compiler.Compiler().compile(mnist_classification, 'mnist-classification-pipeline.zip')

执行Kubeflow Pipeline,Pipeline的运行结果会有两个链接,一个是Experiment的链接,另一个是正在运行的Kubeflow Pipeline链接。

点击上图 here 链接到 Experiments的UI界面,在Kubeflow 的控制台可以检查动态生成的图形,配置参数和日志以了解Pipeline执行步骤

通过 View Pipeline查看Pipeline的静态图详细信息

点击 Experiments, All runs, mnist-classification-Pipeline 检查Pipeline中的所有步骤

点击 sagemaker training job , 点击logs 查看执行日志细节

通过aws console打开SageMaker训练任务链接,可以看到超参数优化作业已经启动,

整个模型训练和部署过程大概需要十几分钟,您在Amazon Sagemaker中看到超参数训练工作成功执行,并在SageMaker中创建一个模型,然后运行批处理转换,最后部署推理模型。

 

下图可以看到超参数优化作业已经提交了9个超参数优化任务

在SageMaker超参数训练完成后,最佳训练任务的详细信息包括相关超参数信息

在训练任务完成后,Kubeflow Pipeline会启动批量转换任务,对验证数据进行批量推理,下图为批量转换任务详细信息

通过AWS Console检查SageMaker的终端节点已部署成功:

记下图中Sagemaker的输出端点,以便后继可以运行推理来验证我们的模型。

7)使用模型进行在线推理

现在,我们对这个SageMaker端点进行预测,通过调用AWS boto3 SDK,并将代码中端点名称更改为在前面步骤中输出的sagemaker端点名称

 

region_name替换成’cn-northwest-1′

 

如图所示,我们将得到推理结果:

8)清理

为了避免您的 AWS 账户在未来产生费用,到SageMaker console 手工删除本实验部署的 SageMaker端点和模型,并删除创建的 S3存储桶

!aws s3 rb s3://$S3_BUCKET –force

3.小结

在本文中,我们实现了一个Kubeflow pipeline通过集成Amazon Sagemaker实现端到端的机器学习过程,包括如何在kubeflow notebook笔记本中安装Pipeline SDK,构建和编译Kubeflow Pipeline,调用SageMaker超参数优化组件进行超参数优化,训练模型和创建模型,并在Amazon SageMaker中批量推理和部署模型端点。企业可以通过kubeflow Pipeline在 Amazon EKS中使用完全托管的机器学习服务SageMaker实现快速构建、训练和部署机器学习 (ML) 模型,而无需迁移工作负载。

4. 资料参考

https://eksworkshop.com/tags/opn401/

https://www.kubeflow.org/docs/

https://github.com/kubeflow/pipelines/tree/master/components/aws/sagemaker

https://medium.com/Kubeflow/Kubeflow-1-0-cloud-native-ml-for-everyone-a3950202751

https://cloud.google.com/blog/products/ai-machine-learning/getting-started-kubeflow-pipelines

本篇作者

贺杨

AWS解决方案架构师,具备17年IT专业服务经验,工作中担任过研发、开发经理、解决方案架构师等多种角色。在加入AWS前,拥有多年外企研发和售前架构经验,在传统企业架构和中间件解决方案有深入的理解和丰富的实践经验

Wei Su

AWS解决方案架构师,开源项目爱好者,致力于云原生应用推广、落地。具有15年以上的信息技术行业专业经验,担任过高级软件工程师,系统架构师等职位,在加入AWS之前曾就职于Bea, Oracle, IBM等公司。