写点什么

通过 Amazon SageMaker 与 Amazon Step Functions 实现机器学习的 CI/CD 方案

  • 2021 年 12 月 23 日
  • 本文字数:6062 字

    阅读完需:约 20 分钟

通过Amazon SageMaker与Amazon Step Functions实现机器学习的CI/CD 方案


在传统的机器学习工作流程当中,经常会面临两个问题:

(1)数据迭代迅速,需要定期对模型进行重新训练,每次训练完成后,都需要重新部署模型,如何实现训练与部署过程的的自动化,从而提升工作效率;

(2)算法团队不断地对算法进行开发与变更,并且需要尝试不同的特征工程,每次变更都需要做单元测试,如何将 Amazon SageMaker 与 CI/CD 工具整合,在提升开发效率的同时减少运维团队的工作负担。本文会介绍通过 Amazon SageMaker 与 Amazon Step Functions 进行模型自动训练与部署的方法,并会与 Amazon CodeCommit、Amazon CodeBuild、Jenkins 集成,实现机器学习的 CI/CD 方案。

相关技术介绍

在开始之前,请先对以下技术进行简单了解。

1.1 Amazon SageMaker

Amazon SageMaker 是一项完全托管的机器学习 PaaS 平台,它提供的功能完整的覆盖了整个机器学习生命周期。并且您不需要对用于训练和推理的实例进行维护,只需要根据工作负载指定相应的机型与数量即可,通过简单的 API 进行模型的一键训练与部署。

1.2 Amazon Step Functions

Amazon Step Functions 是一项云原生的 workflow 编排工具,在创建时不需要配置基础设施,只需要在工作流程当中指定要执行的步骤即可。Amazon Step Functions 为开发者提供了数据科学开发工具包,并且已经与 Amazon SageMaker 进行了集成,开发者可以通过面向对象编程的方式在 workflow 中定义 Amazon SageMaker 的步骤,因此可以将模型训练与部署的过程自动化。

1.3 Amazon CodeCommit 与 Amazon CodeBuild

Amazon CodeCommit 与 Amazon CodeBuild 是 Amazon CI/CD 系列当中的两个重要服务,Amazon CodeCommit 是一项完全托管的代码仓库服务,可以提供给用户近乎无限的代码存储空间,在使用习惯上和标准的 git 工具没有差异。Amazon CodeBuild 可编译源代码,运行单元测试,并构建可供部署的项目,并且也无需预置、管理和扩展自己的构建服务器,可以在构建请求高峰时实现自动扩展。

1.4 Jenkins

Jenkins 是一个自包含的开源自动化服务器,可用于自动化与构建,测试以及交付或部署软件有关的各种任务。它的开源社区非常活跃,整合了 1000 多种插件,为 CI/CD 的过程提供了极大的灵活性,并且也可以与 Amazon Code 系列集成,使得开发者可以轻松的集成两者的优势。

演练

2.1 流程架构图与过程简介



(1)在一台 Amazon EC2 上安装 Jenkins,配置好与 Amazon CodeCommit、Amazon CodeBuild 集成的插件;

(2)开发人员 push 代码到 Amazon CodeCommit 后触发 Jenkins pipeline,代码在 Amazon CodeBuild 中封装成 docker image,并推送到 ECR 当中(注:在本实验中,为了方便在 CI/CD 过程中对代码版本进行控制,会通过 BYOC 的方式在 Amazon SageMaker 中使用自定义算法,该方式需要自己编写 Dockerfile 并将算法 build 为 docker image,然后上传到 ECR 当中,详细介绍可参考将您的算法或模型与 Amazon SageMaker 结合使用

(3)触发 Amazon  Step Functions 执行 Amazon SageMaker 训练与部署的步骤;

(4)Amazon SageMaker 从 ECR 中加载 docker image 与 Amazon S3 中的数据进行训练;

(5)训练完成后对模型进行部署,暴露供推理使用的 endpoint。

2.2 前提条件

  (1)本文示例所使用的区域为 us-east-1;

  (2)在该区域使用 Ubuntu 18.04 的 AMI 创建一台 Amazon EC2,并确保与其绑定的 IAM Role 有 AdministratorAccess 权限,安全组放开 8080 端口供 Jenkins web 使用,后续章节有安装 Jenkins 的具体步骤; 

(3)为了模拟用户的开发环境,请先在本地或远程服务器配置好 git 工具与 y 与亚马逊云科技的 credentials,并确定其拥有 AdministratorAccess 权限。

2.3 实现过程

  (1)在 Amazon Step Functions 中定义使用 Amazon SageMaker 训练与部署模型的步骤




(2)打开 IAM console,找到 Amazon SageMaker 自动创建的新角色,添加 AdministratorAccess 权限;

(3)在 Terminal 中执行命令:


git clone https://github.com/micxyj/awsblog-lab-guide.git
复制代码


(4)进入下载好的文件夹,执行 unzip package.zip 命令进行解压,待解压完成后在 Jupyter notebook 左侧的工作目录中打开 sfn_deploy_byoc.ipynb 文件;

(5)按照该 notebook 中的步骤执行一遍即可;

(6)执行完成后,打开 Amazon Step Functions 控制台,会看到多出一个状态机,如下图所示:




2.3.2 在 Amazon EC2 上安装 Jenkins

在本实验中,Jenkins 只用来提供 pipeline 的作用,构建编译的步骤全部会由 CodeBuild 来完成。

(1)登陆 Amazon EC2,安装 Java 环境;


sudo apt-get updatesudo apt-get upgrade -ysudo apt-get install openjdk-8-jdk -y
复制代码


(2)根据 Jenkins 官方文档安装 Jenkins 2.235 版本;

(3)安装完成后,执行下列命令,记下初始密码;


sudo cat /var/lib/jenkins/secrets/initialAdminPassword
复制代码


(4)在浏览器输入 Jenkins server 的 URL,输入上一步的初始密码并点击 Continue;



(5)选择 Install suggested plugins 并等待插件安装完成;



(6)配置 Admin User 并选择 Save and Continue,接下来的步骤保持默认并点击继续完成配置;






(7)在 Jenkins 服务器上切换到 jenkins 用户,并配置后续实验所需的依赖包。


sudo su -sudo vim /etc/sudoers# 在文件中的User privilege specification下添加一行:jenkins ALL=(ALL) NOPASSWD: ALL,然后保存并关闭文件su jenkinssudo apt install python3-pippip3 install awscli --upgrade --uservim ~/.bashrc# 在文件中添加一行python路径:export PATH=$HOME/.local/bin:$PATH,然后保存并关闭文件source ~/.bashrc# 命令行输入aws configure,不需要设置access id与access key,在Default region name配置中输入us-east-1即可
复制代码

*左右滑动查看更多


2.3.3 创建 Amazon CodeCommit 与 Amazon CodeBuild

(1)打开 CodeCommit 控制台,点击创建存储库;



(2)输入存储库名称并点击创建;



(3)进入到 IAM 控制台中,选择并配置本地环境使用的 iam user 的 Amazon CodeCommit HTTPS Git 凭证;



点击生成凭证后将凭证下载到本地,供实验后续使用



(4)回到 CodeCommit 控制台,选择第二步中创建好的存储库,克隆 HTTPS URL,在本地执行 git clone;




一般第一次执行 git clone 会要求用户输入 Amazon CodeCommit HTTPS Git 的凭证,打开上一步下载好的凭证,输入用户名与密码即可,如果有报错,请查询 CodeCommit 问题排查

(5)从 github 上下载实验所需代码到本地,并上传到 CodeCommit 的代码仓库;


git clone https://github.com/micxyj/ml-ops.gitcp -r ml-ops/* ml-ops-codecommitcd ml-ops-codecommitgit add .git commit -m 'update'git push
复制代码


push 成功之后,回到 CodeCommit 控制台,打开存储库,发现代码已经上传完成;



在 cifar10 文件夹中包含了使用 tensorflow 对 cifar-10 数据集进行训练与创建 tersorflow serving 的代码,会通过 Dockerfile 文件与 build_and_push.sh 打包封装成 docker image 并上传到 ECR 当中,上传完成后会执行 invoke_sfn.py 脚本,运行已经定义好的 Amazon Step Functions 状态机,从而完成 Amazon SageMaker 训练与部署的过程。

(6)打开 Amazon CodeBuild 控制台,按照下述信息创建项目;







Buildspec 中定义的代码即为在构建编译过程中所需要执行的命令,可以把该过程理解为:

1)下载执行脚本所需的依赖包 boto3;

2)执行 build_and_push.sh 脚本将算法封装成 docker image 并上传到 ECR;

3)执行 invoke_sfn.py 脚本,触发 Step Functions 状态机进行模型的训练与部署。在 build commands 下复制粘贴以下代码:


- pip install boto3- chmod 777 build_and_push.sh- ./build_and_push.sh sagemaker-tf-cifar10-example- python invoke_sfn.py
复制代码




其他配置保持默认即可,点击创建构建项目。

(7)打开 iam role 的控制台,赋予 codebuild-ml-ops-service-role 角色 Amazon EC2 ContainerRegistryFullAccess 与 Amazon StepFunctionsFullAccess 的权限;



2.3.4 将 Amazon CodeCommit、Amazon CodeBuild 与 Jenkins 集成

(1)打开 jenkins web 页面,下载与 Amazon CodeCommit、Amazon CodeBuild 集成的相关插件;



(2)搜索 Amazon CodeCommit Trigger 与 Amazon CodeBuild 插件并安装,安装完成之后点击 restart;



(3)配置 Amazon CodeCommit Trigger 插件;

Amazon CodeCommit Trigger 插件需要通过 SQS 与 SNS 来实现 webhook 的功能(即 push 代码到 CodeCommit 之后,触发 Jenkins Pipeline),因此需要先对 SQS 与 SNS 进行配置。

创建一个新的 SNS 主题并输入名称。




将以下 json 代码复制到访问策略当中,将 your_account_id 与 your_sns_name 替换为你的账户 id 和 SNS 名称,其他配置保持不变并点击创建主题。


{
  "Version": "2008-10-17",
  "Id": "__default_policy_ID",
  "Statement": [
    {
      "Sid": "__default_statement_ID",
      "Effect": "Allow",
      "Principal": {
        "AWS": "*"
      },
      "Action": [
        "SNS:Publish",
        "SNS:RemovePermission",
        "SNS:SetTopicAttributes",
        "SNS:DeleteTopic",
        "SNS:ListSubscriptionsByTopic",
        "SNS:GetTopicAttributes",
        "SNS:Receive",
        "SNS:AddPermission",
        "SNS:Subscribe"
      ],
      "Resource": "arn:aws:sns:us-east-1:your_account_id:your_sns_name",
      "Condition": {
        "StringEquals": {
          "AWS:SourceOwner": "your_account_id"
        }
      }
    }
  ]
}
复制代码

*左右滑动查看更多



打开 CodeCommit 控制台,配置触发器,按图中信息进行配置,选择刚刚创建好的 SNS 主题后点击创建触发器。




打开 SQS 控制台,创建 SQS 队列并输入名称。




复制以下 json 代码到访问策略当中,将 your_account_id、your_sqs_name、your_sns_name 替换为相应的信息,其他配置保持不变并点击创建。


{
  "Version": "2012-10-17",
  "Id": "arn:aws:sqs:us-east-1:your_account_id:your_sqs_name/SQSDefaultPolicy",
  "Statement": [
    {
      "Effect": "Allow",
      "Principal": {
        "Service": "sns.amazonaws.com"
      },
      "Action": "sqs:SendMessage",
      "Resource": "arn:aws:sqs:us-east-1:your_account_id:your_sqs_name",
      "Condition": {
        "ArnEquals": {
          "aws:SourceArn": "arn:aws:sns:us-east-1:your_account_id:your_sns_name"
        }
      }
    }
  ]
}
复制代码

*左右滑动查看更多



点击订阅 SNS 主题,选择之前创建好的 SNS 主题 ARN 后保存即可。




打开 Jenkins web 页面,点击系统配置。



下拉到 Amazon Code Commit Trigger SQS Plugin 栏目,首先添加亚马逊云科技的 credentials,使用具有 AdministratorAccess 权限的 iam user 即可。




添加完成 credentials 之后,选择刚创建好的 credentials、正确的 region(us-east-1)与之前创建好的 sqs 队列,点击 Test access,返回 successful 则表示配置正确,最后点击 save。



(4)创建 Jenkins Item;

输入名称 ml-ops-pipeline 并选择 Pipeline。



在 Pipeline 中的 Build Triggers 栏目,勾选“Build when a CodeCommit repository is updated and notifies a SQS queue”,点击 “Manually enter CodeCommit URL and branches”,在“Code commit repository URL”处输入 Amazon CodeCommit 代码仓库的 Git URL。



下拉到 Pipeline 栏目,在“Definition”中选择“Pipeline script from SCM”,在“SCM”中选择“Git”。



点击“Credentials”旁的“add”按钮,选择 Jenkins,将弹出如下页面,输入为 Amazon CodeCommit 的 Git credentials(其中 Username 与 Password 都在 2.3.3 章节提到的 Git 凭证中):



添加完成之后,输入 Amazon CodeCommit 代码仓库的 Git URL 与刚创建好的 Credentials。



其他配置保持默认选项,点击 Save。

展示

(1)打开下载到本地的 Amazon CodeCommit 远程仓库代码文件夹,打开 invoke_sfn.py 文件,将 your_account_id 与 your_step_functions_name 分别替换为你的账户 id 与之前执行 notebook 后生成的 Amazon Step Functions 状态机的名称;



(2)打开 Jenkinsfile,将 your_project_name 替换为你的 CodeBuild 项目名称,从代码中可以看出,Jenkins 安装完成 Amazon CodeBuild 插件之后,就可以以常见的 Groovy 语法定义需要执行的 step,触发 Amazon CodeBuild 执行相应的构建编译的过程,因此,Jenkins 在这里只起到调度的作用,编译构建的负载全部交给 Amazon CodeBuild 来完成,用户并不需要预置底层资源;



(3)此时代码已经发生了变更,push 代码到 Amazon Codecommit 当中,触发整个 CI/CD 的流程;



(4)查看 Amazon CodeBuild 的构建日志,任务正在执行,由于 Jenkins 安装了 Amazon CodeBuild 的插件,也可以在 Jenkins 的 console 上看到相同的日志输出,可以利用这一机制,在 Jenkins 上对构建过程的输出进行统一监控管理;




(5)待 Amazon CodeBuild 将 docker image 上传到 ECR 之后,会执行 buildspec 中第二个步骤,触发 Amazon Step Functions,打开 Amazon Step Functions 与 Amazon SageMaker 训练任务的界面,可以看到 Amazon SageMaker 训练过程正在执行;





(6)待状态机中部署的过程执行完成,打开 Amazon SageMaker 的终端节点界面,可以看到终端节点正在创建过程当中,待创建完成之后,就可以用于推理。



总结

本文介绍了如何利用 Amazon Step Functions 定义 Amazon SageMaker 中训练与部署的过程,当模型需要重新训练时,可以直接触发 Amazon Step Functions 中定义好的状态机,从而减少运维人员重复工作;当算法或特征工程代码发生变更时,需要考虑如何实现 MLOps,亚马逊云科技的 Code 系列可以轻松和开源的工具集成,开发者可以利用到两者的优势,比如可以使用 Jenkins 提供的多种插件,并且在编译构建的过程中使用 Amazon CodeBuild,将任务高峰期扩展资源的任务交给亚马逊云科技自动完成。本文通过上述两个场景实现机器学习的 CI/CD 过程,从而进一步提升算法工程师的开发效率,减少运维团队的工作负担。

参考资料

[1] Automating model retraining and deployment using the Amazon Step Functions Data Science SDK for Amazon SageMaker

[2] Automated and continuous deployment of Amazon SageMaker models with Amazon Step Functions

[3] 将 Amazon CodeBuild 与 Jenkins 结合使用

[4] Building your own TensorFlow container

[5] Continuous Delivery for Machine Learning

本篇作者


肖元君

亚马逊云科技解决方案架构师

负责基于亚马逊云科技云计算方案的架构咨询和设计实现,同时致力于数据分析与人工智能的研究与应用



金忠敏

亚马逊云科技解决方案架构师

现在专注于云计算解决方案和架构的工作。具有超过 15 年的 IT 从业经验,曾从事软件开发,售后支持,系统交付,售前等工作。参与过很多大型项目架构设计和实施交付


Pan Xiankun

亚马逊云科技解决方案架构师


用户头像

还未添加个人签名 2019.09.17 加入

还未添加个人简介

评论

发布
暂无评论
通过Amazon SageMaker与Amazon Step Functions实现机器学习的CI/CD 方案