机器学习不仅仅关乎模型。ML工作流包括数据寻源和准备数据、构建ML模型、训练和评估模型、将模型部署到生产环境以及生产后持续监控。Amazon SageMaker可帮助用户更快地构建、训练、部署和维护模型。
但是,与构建模型相关的工作通常是规模更大的工作流的一部分,此工作流跨越了多个支持全局应用程序的工程团队和服务。Kubernetes用户(包括EKS客户)通过编写配置文件来部署工作负载,Kubernetes将这些配置文件与Kubernetes集群中的可用计算资源相匹配。虽然Kubernetes为用户提供了控制权和可移植性,但在Kubernetes集群上运行ML工作负载却会带来独特挑战。例如,底层基础设施需要额外的管理:针对利用率、成本和性能进行优化、符合适用的安全和法规要求,以及确保高可用性和可靠性等等。这些无差别的繁重工作占用了宝贵的时间和资源,延缓了将新的ML应用投入市场的速度。
如何控制编排和工作流,同时又免于管理集群中的底层ML基础设施及服务?
Amazon SageMaker Operator可以帮助数据科学家以及开发人员利用Kubernetes接口来创建和管理SageMaker任务,如机器学习的模型训练、超参优化、批量转换以及实时推理等。
如图所示,SageMaker Operator可以让开发与运维人员通过Kubectl命令行或者Kubernetes API接口调用的方式来管理和使用SageMaker服务,它就像翻译器一样,在Kubernetes平台与AWS SageMaker服务之间搭建了一座桥梁,让那些已经很很熟悉Kubernetes的开发、运维人员在无需投入过多精力的情况下,即可快速地使用SageMaker服务。
应用场景
SageMaker Operator可以让那些已经很了解Kubernetes平台的开发人员以非常熟悉和友好的方式来使用SageMaker服务,它非常适用于以下一些场景。
1、 项目团队已经非常熟悉Kubernetes平台的接口和标准,由于项目需求,希望引进机器学习部分。由于人员数量有限,团队不希望再去单独维护一套机器学习平台,而是在充分利用已有的能力的基础上,适当引进第三方的工具和服务,快速地进行业务创新,降低学习和使用的成本,大幅度提升效率。
2、 项目团队已在Kubernetes平台的基础上很好的实现了DevOps,很多业务模块都已经做到了持续集成与持续发布。机器学习部分只是整个业务系统中的一个模块,团队希望能够能将机器学习模块与其它业务模块统一进行工程化的管理,最终实现业务流程的全自动化。
技术原理
与其它第三方应用的Kubernetes Operator实现机制一样,SageMaker Operator由Kubernetes CRD和Controller两部分组成。如图所示,在安装好SageMaker Operator之后,SageMaker Operator会向Kubernetes平台新注册一些与SageMaker服务相关CRD,同时以Pod的方式在Kubernetes Worker Node上运行SageMaker Operator Controller。当开发人员需要创建机器学习的任务时,首先需要在yaml文件中定义与CRD资源相关的关键配置参数,然后通过kubectl提交命令创建CRD资源,在CRD资源资源成功创建后,SageMaker Controller可以从Kubernetes API Server监听到与该CRD相关的信息,之后解析参数并调用SageMaker服务,完成机器学习任务的创建。
Operator是Kubernetes中一个重要概念,它可以让开发人员在Kubernetes的基础上进行高级的抽象和封装,从而可以更加容易地安装和管理复杂的应用。除了SageMaker Operator,很多公司和开源机构都会按照Kubernetes的标准把封装自己的Operator。Kubernetes Operator概念相对抽象,技术实现细节也比较复杂,若想对它更深入的了解,我们首先需要理解Kubernetes资源创建的机制和流程,同时也需要理解Kubernetes CRD和Controller等一些重要的概念,本文不会就Kubernetes Operator的技术细节做过多的展开,关于更多有关Kubernetes Operator的介绍,请参考以下链接:
- Kubernetes CRD
- Kubernetes Controller
- Kubernetes Operator
实验演示
下文我们将演示一个具体的例子,从而更好地说明如何如何利用AWS SageMaker Operator来实现机器学习任务的创建和管理。在该方案中,我们会用到以下服务:
- AWS S3:AWS对象存储服务,用于存放训练数据集以及机器学习模型。
- AWS EKS:AWS Kubernetes托管服务,用于运行SageMaker Operator以及其它与Kubernetes相关的应用。
- AWS SageMaker:AWS机器学习托管服务,用于实现数据处理、模型训练、模型优化以及模型部署等机器学习任务的自动化创建和管理。Operator会自动解析参数并调用SageMaker服务完成机器学习任务的创建。
- AWS IAM:AWS安全管理服务,用于控制SageMaker Operator以及SageMaker对AWS资源的访问权限。
- AWS CloudWatch:AWS日志管理服务,用于记录SageMaker机器学习任务的日志同时将日志以事实的方式推送至AWS EKS。
实验内容
搭建EKS集群,配置IAM权限,安装SageMaker Operator。
- 通过kubectl命令创建SageMaker机器学习训练任务,提交任务后可以在SageMaker界面上看到机器训练任务,任务结束后确认模型会自动上传至S3。
- 通过kubectl命令创建SageMaker机器学习部署的任务,提交任务后可以在SageMaker界面上看到机器学习部署任务,SageMaker会自动创建虚拟机并加载模型。
实验步骤
1、EKS集群搭建
EKS是AWS的Kubernetes托管集群,我们可以通过图形界面或者命令行的方式实现集群的创建。在本实验中,我们在ap-southeast-1区域部署Kubernetes集群,该集群会包含一个Worker Node Group,该Node Group内有三个c5.xlarge的计算实例。在默认情况下,节点会采用高可用的方式均匀地部署在该区域的多个可用区内,如果有定制化需求,我们也可以通过指定命令行参数或者编写配置文件来指定可用区。
1.1 运行命令,创建集群。
eksctl create cluster --region --name= --nodes-min=3 --nodes-max=5 --node-type=c5.xlarge --ssh-access —ssh-public-key
1.2 运行命令,查看Kubernetes节点的工作状态。
kubectl get node
2、创建OpenID Connect Provider
OpenID Connect Provider可以将Kubernetes内的Service Account与AWS IAM的角色进行关联。在上文中我们提到过,SageMaker Operator Controller会以Pod的方式运行在EKS节点上,该Pod在监听到资源的创建信息后会调用SageMaker服务,而成功调用SageMaker的前提是该Pod要具备相应的权限。我们知道Kubernetes内Pod的权限分配一般是要通过Service Account传入的,所以OpenID Connect Provider的作用便是将集群外的IAM角色与集群内的Service Account进行关联。
2.1 运行命令获取OIDC ID。
请将${CLUSTERNAME}替换成实际的EKS集群名称,将${AWSREGION}替换成实际的Region。
aws eks describe-cluster --name ${CLUSTER_NAME} --region ${AWS_REGION} \
--query cluster.identity.oidc.issuer --output text
命令运行成功或会返回如下类似的结果:
https://oidc.eks.${AWS_REGION}.amazonaws.com/id/D48675832CA65BD10A532F597OIDCID
2.2 创建名为trust.json的文件。
文件模板如下所示。请将
{
"Version": "2012-10-17",
"Statement": [
{
"Effect": "Allow",
"Principal": {
"Federated": "arn:aws:iam:::oidc-provider/oidc.eks..amazonaws.com/id/"
},
"Action": "sts:AssumeRoleWithWebIdentity",
"Condition": {
"StringEquals": {
"oidc.eks..amazonaws.com/id/:aud": "sts.amazonaws.com",
"oidc.eks..amazonaws.com/id/:sub": "system:serviceaccount:sagemaker-k8s-operator-system:sagemaker-k8s-operator-default"
}
}
}
]
}
使用上一步创建成功的trust.json文件,并运行下面命令创建IAM角色,将
aws iam create-role --role-name --assume-role-policy-document file://trust.json --output=text
命令运行成功后会返回如图所示的结果:
2.3 运行下列命令,将SageMaker FullAccess的权限赋予上一步所创建的角色。
aws iam attach-role-policy --role-name --policy-arn arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
在完成角色的创建和权限的配置后,请记录角色的ARN,在后面创建SageMaker Operator时,我们需要为SageMaker Operator配置该角色,从而确保SageMaker Operator Controller具备操作SageMaker的权限。
3、安装SageMaker Operator
SageMaker Operator的安装方式很灵活,我们可以直接通过yaml文件进行部署或者通过Helm的方式进行安装部署,本次实验中我们通过yaml的方式进行部署。在上文提到过,SageMaker Operator由CRD和Controller两部分组成,其中Controller会以Pod的形式运行在EKS Worker Node上。
3.1 运行命令下载用于安装SageMaker Operator的yaml文件。
wget https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-**for**-k8s/master/release/rolebased/installer.yaml
3.2 下载完yaml文件后,进入文件内。
找到eks.amazonaws.com/role-arn参数项,将该参数对应的值更新为2.3步所创建角色的ARN。
3.3 运行下列命令安装SageMaker Operator
kubectl apply -f installer.yaml
上文曾提到,SageMaker Operator由CRD与Controller两部分组成,当SageMaker Operator安装成功后,SageMaker Operator会向Kubernetes集群内注册新的CRD,同时以Pod的形式在Kubernetes Worker Node上运行SageMaker Operator Controller。
3.4 运行下列命令查看新创建的CRD。
kubectl get crd | grep sagemaker
3.5 运行下列命令查看新创建的SageMaker Operator Controller。
kubectl -n sagemaker-k8s-operator-system get pods
4 安装SageMaker Operator日志插件
SageMaker日志插件是SageMaker Operator中的一个可选项,SageMaker的任务在运行过程中会将日志推送至CloudWatch的日志组中,而SageMaker Operator日志插件则可实时地将CloudWatch日志收集到Kubernetes集群上,从而让开发人员通过kubectl命令查看SageMaker任务的日志。SageMaker Operator日志插件的安装是可选项,若安装则可以方便用户对日志进行管理,不安装也不会影响到任务自身的创建。
4.1 运行命令,安装SageMaker日志插件
export os="linux"
wget https://amazon-sagemaker-operator-for-k8s-us-east-1.s3.amazonaws.com/kubectl-smlogs-plugin/v1/${os}.amd64.tar.gz
tar xvzf ${os}.amd64.tar.gz
# Move binaries to a directory in your homedir.
mkdir ~/sagemaker-k8s-bin
cp ./kubectl-smlogs.${os}.amd64/kubectl-smlogs ~/sagemaker-k8s-bin/.
# This line will add the binaries to your PATH in your .bashrc.
echo 'export PATH=$PATH:~/sagemaker-k8s-bin' >> ~/.bashrc
# Source your .bashrc to update environment variables:
source ~/.bashrc
4.2 运行下列命令验证插件是否安装成功。
kubectl smlogs
5、创建机器学习训练任务
接下来,我们将创建一个SageMaker机器学习模型训练的任务,这里我们以SageMaker内置算法xgboost为例,对MINIST数据集进行模型的训练和部署。
5.1 运行命令,生成数据集并将数据集上传至S3存储桶。
请将
`wget https://raw.githubusercontent.com/aws/amazon-sagemaker-operator-for-k8s/master/scripts/upload_xgboost_mnist_dataset/upload_xgboost_mnist_dataset \
chmod +x upload_xgboost_mnist_dataset \
./upload_xgboost_mnist_dataset --s3-bucket --s3-prefix xgboost-mnist`
查看S3存储桶,可以发现训练、测试和验证数据集都已成功上传至S3存储桶上。
5.2 运行命令创建SageMaker角色。
在创建SageMaker任务前,需要为SageMaker创建好角色,从而确保SageMaker可以顺利运行相关的任务。
export assume_role_policy_document='{
"Version": "2012-10-17",
"Statement": [{
"Effect": "Allow",
"Principal": {
"Service": "sagemaker.amazonaws.com"
},
"Action": "sts:AssumeRole"
}]
}'
aws iam create-role --role-name --assume-role-policy-document file://<(echo "$assume_role_policy_document")
aws iam attach-role-policy --role-name --policy-arn arn:aws:iam::aws:policy/AmazonSageMakerFullAccess
5.3 准备机器学习训练任务yaml文件。
在该文件中,需要配置与SageMaker训练任务相关的重要参数。关于机器学习训练任务yaml文件的模板请参考如下,请将变量部分替换成实际的参数,关键参数解释请参考模板中的备注信息。
apiVersion: sagemaker.aws.amazon.com/v1
kind: TrainingJob // CRD类型
metadata:
name: xgboost-mnist
spec:
roleArn: // 上一步创建的SageMaker role
region: // EKS集群所在的region
algorithmSpecification:
trainingImage: // SageMaker XGboost镜像的存放位置,请参考SageMaker官方文档查看具体的镜像位置。
trainingInputMode: File
outputDataConfig:
s3OutputPath: // 测试数据集存放位置
inputDataConfig:
- channelName: train
dataSource:
s3DataSource:
s3DataType: S3Prefix
s3Uri: // 训练数据集存放位置
s3DataDistributionType: FullyReplicated
contentType: text/csv
compressionType: None
- channelName: validation
dataSource:
s3DataSource:
s3DataType: S3Prefix
s3Uri: < //验证数据集存放位置
s3DataDistributionType: FullyReplicated
contentType: text/csv
compressionType: None
resourceConfig:
instanceCount: 1 // SageMaker实例数量
instanceType: ml.m4.xlarge //SageMaker实例类型
volumeSizeInGB: 5 // SageMaker 根卷大小
hyperParameters: // 超参设置,不同的算法会有不同的参数。
- name: max_depth
value: "5"
- name: eta
value: "0.2"
- name: gamma
value: "4"
- name: min_child_weight
value: "6"
- name: silent
value: "0"
- name: objective
value: multi:softmax
- name: num_class
value: "10"
- name: num_round
value: "10"
stoppingCondition:
maxRuntimeInSeconds: 86400
5.4 运行命令,创建SageMaker训练任务。
`kubectl apply -f train.yaml`
5.5 运行命令,查看SageMaker训练任务状态。
`$ kubectl describe trainingjob xgboost-mnist
$ kubectl get trainingjob xgboost-mnist`
5.6 进入AWS控制台,查看AWS SageMaker训练任务状态。
5.7 任务训练结束后,模型会被自动存放至S3。
进入S3控制台,可以查看到模型以及成功上传。
6、模型部署
模型训练结束后,我们将创建模型部署任务,SageMaker Operator会自动调用SageMaker服务完成模型的部署。
6.1 创建模型部署yaml文件。
在该文件中,我们需要配置与SageMaker模型部署任务相关的重要参数。关于模型部署任务的yaml文件的模板请参考如下,请将变量部分替换成实际的参数,关键参数解释请参考模板中的备注信息。
apiVersion: sagemaker.aws.amazon.com/v1
kind: HostingDeployment //CRD类型
metadata:
name: hosting-deployment
spec:
region: // EKS集群所在区域
productionVariants:
- variantName: AllTraffic
modelName: xgboost-model
initialInstanceCount: 1 // 部署实例类型数量
instanceType: ml.r5.large //部署实例类型
initialVariantWeight: 1
models:
- name: xgboost-model
executionRoleArn: // 上一步创建的SageMaker role
containers:
- containerHostname: xgboost
modelDataUrl: //模型存放地址
image: // SageMaker XGboost Docker
Image地址,请参考SageMaker官方文档查看镜像具体存放位置。
6.2 运行命令查看模型部署任务状态
kubectl get hostingdeployments
6.3 进入AWS控制台,查看SageMaker模型部署任务。
在上面实验中,我们举了模型训练和部署的例子,除了这两种任务,SageMaker Operator还支持参数优化、批量转换以及模型部署配置等其它任务,我们可以根据项目中的实际需求灵活选择相对应的任务。
总结
利用SageMaker Operator,项目团队可以使用所熟悉的Kubernetes命令以及接口管理复杂机器学习任务与流程,无需在已有的基础设施和平台上做出改动便可以快速地启动与机器学习相关的项目,从而极大程度地提升效率、降低成本。
在真实项目中,机器学习部分往往只是整个业务系统的一个模块,因此在设计方案时也需要系统性的考虑,除了机器学习流程本身,还需要考虑CI/CD、监控运维、安全控制、服务集成等多方面的因素。AWS可以做到服务之间的高度集成,在实际生产中,我们完全可以在上面实验案例的基础上进一步扩展,集成新的服务,从而构建一个端到端的解决方案。