为 AWS Step Functions SageMaker 创建自定义 Docker 容器镜像并将其用于模型训练 - AWS Prescriptive Guidance

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

为 AWS Step Functions SageMaker 创建自定义 Docker 容器镜像并将其用于模型训练

由 Julia Bluszcz (AWS)、Neha Sharma (AWS)、Aubrey Oosthuizen (AWS)、Mohan Gowda Purushothama (AWS) 和 Mateusz Zaremba (AWS) 创作

环境:生产

技术:机器学习和人工智能; DevOps

AWS 服务:亚马逊 ECR;亚马逊 SageMaker;AWS Step Functions

Summary

此模式展示了如何为亚马逊创建 Docker 容器镜像 SageMaker并将其用于 A WS St ep Functions 中的训练模型。通过将自定义算法打包到容器中,您几乎可以在 SageMaker 环境中运行任何代码,无论编程语言、框架或依赖关系如何。

在提供的示例SageMaker 笔记本中,自定义 Docker 容器镜像存储在亚马逊弹性容器注册表 (Amazon ECR) Cont ainer Registry 中。然后,Step Functions 使用存储在 Amazon ECR 中的容器为其运行 Python 处理脚本。 SageMaker然后,容器将模型导出到亚马逊简单存储服务 (Amazon S3) S imple S3。

先决条件和限制

先决条件

  • 一个有效的 Amazon Web Services account。

  • SageMaker具有 Amazon S3 权限的 A WS 身份和访问管理 (IAM) 角色

  • Ste p Functions 的 IAM 角色

  • 基本熟悉 Python

  • 熟悉亚马逊 SageMaker Python 开发工具包

  • 熟悉 AWS 命令行界面(AWS CLI)

  • 熟悉适用于 Python 的 Amazon SDK (Boto3)

  • 熟悉 Amazon ECR

  • 熟悉 Docker

产品版本

  • AWS Step Functions 数据科学软件开发工具包版本 2.3.0

  • 亚马逊 SageMaker Python SDK 版本 2.78.0

架构

下图显示了在 Step Functions 中为其创建 Docker 容器镜像 SageMaker,然后将其用于训练模型的示例工作流程:

在 Step Functions 中为 SageMaker 训练模型创建 Docker 容器镜像并将其用于训练模型的工作流程

图表显示了以下工作流:

  1. 数据科学家或 DevOps 工程师使用 Amazon SageMaker 笔记本创建自定义 Docker 容器镜像。

  2. 数据科学家或 DevOps 工程师将 Docker 容器映像存储在私有注册表中的 Amazon ECR 私有存储库中。

  3. 数据科学家或 DevOps 工程师使用 Docker 容器在 Step Functions 工作流程中运行 Python SageMaker 处理作业。

自动化和扩展

此模式中的示例 SageMaker 笔记本使用ml.m5.xlarge笔记本实例类型。您可以更改实例类型,以适合您的用例。有关 SageMaker 笔记本实例类型的更多信息,请参阅 Amazon SageMaker 定价

工具

操作说明

任务描述所需技能

设置 Amazon ECR 并新建私有注册表。

如果您尚未设置 Amazon ECR,请按照Amazon ECR 用户指南中的设置 Amazon ECR进行操作。每个 Amazon Web Services account 都提供有原定设置的私有 Amazon ECR 注册表。

DevOps 工程师

创建 Amazon ECR 私有存储库。

请按照Amazon ECR 用户指南中的创建私有存储库进行操作。

注意:您创建的存储库是存储自定义 Docker 容器映像的位置。

DevOps 工程师

创建一个 Dockerfile,其中包含运行 SageMaker 处理作业所需的规范。

通过配置 Dockerfile 来创建包含运行 SageMaker 处理作业所需的规格的 Dockerfile。有关说明,请参阅《Amazon SageMaker 开发者指南》中的调整自己的训练容器

有关 Dockerfiles 的更多信息,请参阅 Doc ker 文档中的 DockerFile 参考

用于创建 DockerFile 的 Jupyter 笔记本代码单元格示例

单元格 1

# Make docker folder !mkdir -p docker

单元格 2

%%writefile docker/Dockerfile FROM python:3.7-slim-buster RUN pip3 install pandas==0.25.3 scikit-learn==0.21.3 ENV PYTHONUNBUFFERED=TRUE ENTRYPOINT ["python3"]
DevOps 工程师

构建您的 Docker 容器映像并将其推送至 Amazon ECR。

  1. 通过在 AWS CLI 中运行docker build命令创建 Dockerfile,然后使用此 Dockerfile 构建容器映像。

  2. 通过运行 docker push命令将容器映像推送至 Amazon ECR。

有关更多信息,请参阅在上构建自己的算法容器中的构建和注册容器 GitHub。

用于构建和注册 Docker 映像的 Jupyter 笔记本代码单元格示例

重要提示:运行以下单元格之前,请确保已创建一个 Dockerfile 并将其存储在名为docker的目录中。此外,请确保您已创建一个 Amazon ECR 存储库,并将第一个单元格中的ecr_repository 值替换为存储库名称。

单元格 1

import boto3 tag = ':latest' account_id = boto3.client('sts').get_caller_identity().get('Account') region = boto3.Session().region_name ecr_repository = 'byoc' image_uri = '{}.dkr.ecr.{}.amazonaws.com/{}'.format(account_id, region, ecr_repository + tag)

单元格 2

# Build docker image !docker build -t $image_uri docker

单元格 3

# Authenticate to ECR !aws ecr get-login-password --region {region} | docker login --username AWS --password-stdin {account_id}.dkr.ecr.{region}.amazonaws.com

单元格 4

# Push docker image !docker push $image_uri

注意:您必须对私有注册表的 Docker 客户端进行身份验证,这样才能使用 docker pushdocker pull命令。这些命令将图像推送和拉出注册表中存储库。

DevOps 工程师
任务描述所需技能

创建包含自定义处理和模型训练逻辑的 Python 脚本。

编写将在数据处理脚本中运行的自定义处理逻辑。然后,将其另存为名为training.py的 Python 脚本。

有关更多信息,请参阅在开启 SageMaker 脚本模式的情况下自带模型 GitHub。

含自定义处理和模型训练逻辑的 Python 脚本示例

%%writefile training.py from numpy import empty import pandas as pd import os from sklearn import datasets, svm from joblib import dump, load if __name__ == '__main__': digits = datasets.load_digits() #create classifier object clf = svm.SVC(gamma=0.001, C=100.) #fit the model clf.fit(digits.data[:-1], digits.target[:-1]) #model output in binary format output_path = os.path.join('/opt/ml/processing/model', "model.joblib") dump(clf, output_path)
数据科学家

创建一个 Step Functions 工作流程,其中包含您的 SageMaker 处理作业。

安装并导入AWS Step Functions Data Science SDK,然后将training.py 文件上传至 Amazon S3。然后,使用 Amaz SageMaker on Python 开发工具包在 Step Functions 中定义处理步骤。

重要提示:请确保您已在 Amazon Web Services account 中为 Step Functions 创建 IAM 执行角色

要上传至 Amazon S3 的环境设置和自定义训练脚本示例

!pip install stepfunctions import boto3 import stepfunctions import sagemaker import datetime from stepfunctions import steps from stepfunctions.inputs import ExecutionInput from stepfunctions.steps import ( Chain ) from stepfunctions.workflow import Workflow from sagemaker.processing import ScriptProcessor, ProcessingInput, ProcessingOutput sagemaker_session = sagemaker.Session() bucket = sagemaker_session.default_bucket() role = sagemaker.get_execution_role() prefix = 'byoc-training-model' # See prerequisites section to create this role workflow_execution_role = f"arn:aws:iam::{account_id}:role/AmazonSageMaker-StepFunctionsWorkflowExecutionRole" execution_input = ExecutionInput( schema={ "PreprocessingJobName": str}) input_code = sagemaker_session.upload_data( "training.py", bucket=bucket, key_prefix="preprocessing.py", )

使用自定义 Amazon ECR 图像和 Python 脚本的 SageMaker 处理步骤定义示例

注意:请务必使用 execution_input参数指定作业名称。每次运行作业时,参数值必须是唯一的。此外,training.py 文件的代码作为input 参数传递至ProcessingStep,这意味着它将被复制到容器中。ProcessingInput 代码的目标与container_entrypoint内部的第二个参数相同。

script_processor = ScriptProcessor(command=['python3'], image_uri=image_uri, role=role, instance_count=1, instance_type='ml.m5.xlarge') processing_step = steps.ProcessingStep( "training-step", processor=script_processor, job_name=execution_input["PreprocessingJobName"], inputs=[ ProcessingInput( source=input_code, destination="/opt/ml/processing/input/code", input_name="code", ), ], outputs=[ ProcessingOutput( source='/opt/ml/processing/model', destination="s3://{}/{}".format(bucket, prefix), output_name='byoc-example') ], container_entrypoint=["python3", "/opt/ml/processing/input/code/training.py"], )

运行处理作业的 Step Functions 工作 SageMaker 流程示例

注意:此示例工作流仅包括 SageMaker 处理作业步骤,不包括完整的 Step Functions 工作流程。有关完整的工作流程示例,请参阅 AWS Step Functions 数据科学软件开发工具包文档 SageMaker中的示例笔记本

workflow_graph = Chain([processing_step]) workflow = Workflow( name="ProcessingWorkflow", definition=workflow_graph, role=workflow_execution_role ) workflow.create() # Execute workflow execution = workflow.execute( inputs={ "PreprocessingJobName": str(datetime.datetime.now().strftime("%Y%m%d%H%M-%SS")), # Each pre processing job (SageMaker processing job) requires a unique name, } ) execution_output = execution.get_output(wait=True)
数据科学家

相关资源