Amazon SageMaker 如何运行训练映像
您可以使用自定义入口点脚本来自动配置基础设施,以便在生产环境中进行训练。如果您将入口点脚本传递到 Docker 容器中,则也可以将其作为独立脚本运行,而无需重新构建映像。SageMaker 使用 Docker 容器入口点脚本处理您的训练映像。
本节将介绍如何无需训练工具包来使用自定义入口点。如果您想使用自定义入口点,但不熟悉如何手动配置 Docker 容器,我们建议您改为使用 SageMaker 训练工具包库
默认情况下,SageMaker 会在您的容器中查找名为 train
的脚本。您也可以使用 AlgorithmSpecification API 的 ContainerArguments
和 ContainerEntrypoint
参数,手动提供自己的自定义入口点。
您可以采用以下两个选项来手动配置 Docker 容器以运行您的映像。
-
使用 CreateTrainingJob API 和其中包含入口点指令的 Docker 容器。
-
使用
CreateTrainingJob
API,然后从 Docker 容器外部传递您的训练脚本。
如果您从 Docker 容器外部传递您的训练脚本,则在更新脚本时无需重新构建 Docker 容器。您也可以使用多个不同的脚本在同一个容器中运行。
您的入口点脚本应包含映像的训练代码。如果您在估算器source_dir
参数,则它应引用相对 Amazon S3 路径,指向包含入口点脚本的文件夹。您可以使用 source_dir
参数引用多个文件。如果您不使用 source_dir
,可以使用 entry_point
参数指定入口点。有关包含估算器的自定义入口点脚本的示例,请参阅在 SageMaker 脚本模式中自带模型
使用 Docker 容器内部捆绑的入口点脚本运行训练作业
SageMaker 可以运行您的 Docker 容器内部捆绑的入口点脚本。
-
默认情况下,Amazon SageMaker 运行以下容器。
docker run
image
train -
SageMaker 通过在映像名称后指定
train
参数来覆盖容器中的任何默认 CMD语句。在您的 Docker 容器中,使用 ENTRYPOINT
指令的exec
形式:ENTRYPOINT ["
executable
", "param1
", "param2
", ...]以下示例显示如何指定名为
k-means-algorithm.py
的 Python 入口点指令。ENTRYPOINT ["python", "k-means-algorithm.py"]
exec
形式的ENTRYPOINT
指令直接启动可执行文件,而不是/bin/sh
的子级。这使其能够接收来自 SageMaker API 的信号,如SIGTERM
和SIGKILL
。使用 SageMaker API 时,以下条件适用。-
CreateTrainingJob
API 有一个停止条件,它指示 SageMaker 在特定的时间后停止模型训练。 -
下面显示了
StopTrainingJob
API。此 API 发出与docker stop
(具有 2 分钟超时)等效的命令,以便正常停止指定容器:docker stop -t 120
该命令尝试通过发送
SIGTERM
信号来停止正在运行的容器。在 2 分钟的超时时间后,API 会发送SIGKILL
,然后强行停止容器。如果容器正常处理了SIGTERM
并在收到信号后的 120 秒内退出,则不会发送SIGKILL
。
如果您希望在 SageMaker 停止训练之后访问中间模型构件,则添加代码以处理在
SIGTERM
处理程序中保存构件的操作。 -
-
如果您计划使用 GPU 设备进行模型训练,请确保您的容器与
nvidia-docker
兼容。容器上仅包含 CUDA 工具包;不要将 NVIDIA 驱动程序与映像捆绑。有关nvidia-docker
的更多信息,请参阅 NVIDIA/nvidia-docker。 -
您不能使用
tini
初始化程序作为 SageMaker 容器中的入口点脚本,因为它会被train
参数和serve
参数混淆。 -
/opt/ml
及其所有子目录是 SageMaker 训练保留的目录。在您构建算法的 Docker 映像时,请确保不要在此目录中放置算法所需的任何数据。因为如果这样做,则在训练期间数据可能不再可见。
要在 Docker 映像内部捆绑 Shell 或 Python 脚本,或者要在 Amazon S3 存储桶中提供脚本或使用 Amazon Command Line Interface (CLI),请继续阅读以下部分。
在 Docker 容器内部捆绑您的 Shell 脚本
如果您要在 Docker 映像内部捆绑自定义 Shell 脚本,请使用以下步骤。
-
将 Shell 脚本从工作目录复制到 Docker 容器内部。以下代码片段将自定义入口点脚本
custom_entrypoint.sh
从当前工作目录,复制到位于mydir
中的 Docker 容器。以下示例假定基本 Docker 映像已安装 Python。FROM
<base-docker-image>
:<tag>
# Copy custom entrypoint from current dir to /mydir on container COPY./custom_entrypoint.sh /mydir/
-
按照《Amazon ECR 用户指南》中推送 Docker 映像的说明,构建 Docker 容器并将其推送到 Amazon Elastic Container Registry (Amazon ECR)。
-
通过运行以下 Amazon CLI 命令启动训练作业。
aws --region
<your-region>
sagemaker create-training-job \ --training-job-name<your-training-job-name>
\ --role-arn<your-execution-role-arn>
\ --algorithm-specification '{ \ "TrainingInputMode": "File", \ "TrainingImage": "<your-ecr-image>
", \ "ContainerEntrypoint": ["/bin/sh
"], \ "ContainerArguments": ["/mydir/custom_entrypoint.sh
"]}' \ --output-data-config '{"S3OutputPath": "s3://custom-entrypoint-output-bucket/
"}' \ --resource-config '{"VolumeSizeInGB":10
,"InstanceCount":1
,"InstanceType":"ml.m5.2xlarge
"}' \ --stopping-condition '{"MaxRuntimeInSeconds":180
}'
在 Docker 容器内部捆绑您的 Python 脚本
要在 Docker 映像内部捆绑自定义 Python 脚本,请使用以下步骤。
-
将 Python 脚本从工作目录复制到 Docker 容器内部。以下代码片段将自定义入口点脚本
custom_entrypoint.py
从当前工作目录,复制到位于mydir
中的 Docker 容器。FROM
<base-docker-image>
:<tag>
# Copy custom entrypoint from current dir to /mydir on container COPY./custom_entrypoint.py /mydir/
-
通过运行以下 Amazon CLI 命令启动训练作业。
--algorithm-specification '{ \ "TrainingInputMode": "File", \ "TrainingImage": "
<your-ecr-image>
", \ "ContainerEntrypoint": ["python
"], \ "ContainerArguments": ["/mydir/custom_entrypoint.py
"]}' \
使用在 Docker 容器外部的入口点脚本运行训练作业
您可以使用自己的 Docker 容器进行训练,并将入口点脚本从 Docker 容器的外部传入。在容器之外构建入口点脚本有一些好处。如果您更新入口点脚本,则无需重新构建 Docker 容器。您也可以使用多个不同的脚本在同一个容器中运行。
使用 AlgorithmSpecification API 的 ContainerEntrypoint
和 ContainerArguments
参数,指定训练脚本的位置。这些入口点和参数的行为方式与 Docker 入口点和参数相同。这些参数中的值会覆盖提供作为 Docker 容器一部分的对应 ENTRYPOINT
或 CMD
。
当您将自定义入口点脚本传递给 Docker 训练容器时,您提供的输入决定了容器的行为。
-
例如,如果您仅提供
ContainerEntrypoint
,则使用 CreateTrainingJob API 的请求语法如下所示。{ "AlgorithmSpecification": { "ContainerEntrypoint": ["
string
"], ... } }然后,SageMaker 训练后端如下所示运行您的自定义入口点。
docker run --entrypoint
<ContainerEntrypoint>
image注意
如果提供了
ContainerEntrypoint
,则 SageMaker 训练后端使用给定的入口点运行映像,并覆盖映像中的默认ENTRYPOINT
。 -
如果您仅提供
ContainerArguments
,则 SageMaker 会假定 Docker 容器包含入口点脚本。使用CreateTrainingJob
API 的请求语法如下所示。{ "AlgorithmSpecification": { "ContainerArguments": ["
arg1
", "arg2
"], ... } }SageMaker 训练后端如下所示运行您的自定义入口点。
docker run image
<ContainerArguments>
-
如果您同时提供
ContainerEntrypoint
和ContainerArguments
,则使用CreateTrainingJob
API 的请求语法如下所示。{ "AlgorithmSpecification": { "ContainerEntrypoint": ["
string
"], "ContainerArguments": ["arg1
", "arg2
"], ... } }SageMaker 训练后端如下所示运行您的自定义入口点。
docker run --entrypoint
<ContainerEntrypoint>
image<ContainerArguments>
您可以在 CreateTrainingJob
API 中使用任何支持的 InputDataConfig
源,提供入口点脚本来运行您的训练映像。
在 Amazon S3 存储桶中提供您的入口点脚本
要使用 S3 存储桶提供自定义入口点脚本,请使用 DataSource API 的 S3DataSource
参数来指定脚本的位置。如果使用 S3DataSource
参数,则需要以下信息。
-
InputMode 必须为类型
File
。 -
S3DataDistributionType 必须为
FullyReplicated
。
以下示例在 S3 存储桶的路径中放置了一个名为 custom_entrypoint.sh 的脚本:s3://<bucket-name>/<bucket
prefix>/custom_entrypoint.sh
。
#!/bin/bash echo "Running custom_entrypoint.sh" echo "Hello you have provided the following arguments: " "$@"
接下来,您必须设置输入数据通道的配置以运行训练作业。要执行此操作,请直接使用 Amazon CLI,也可以使用 JSON 文件。
使用 Amazon CLI 和 JSON 文件配置输入数据通道
要使用 JSON 文件配置输入数据通道,请按以下代码结构所示使用 Amazon CLI。确保以下所有字段都使用在 CreateTrainingJob API 中定义的请求语法。
// run-my-training-job.json { "AlgorithmSpecification": { "ContainerEntrypoint": ["
/bin/sh
"], "ContainerArguments": ["/opt/ml/input/data/<your_channel_name>
/custom_entrypoint.sh
"], ... }, "InputDataConfig": [ { "ChannelName": "<your_channel_name>
", "DataSource": { "S3DataSource": { "S3DataDistributionType": "FullyReplicated", "S3DataType": "S3Prefix", "S3Uri": "s3://<bucket-name>
/<bucket_prefix>
" } }, "InputMode": "File", }, ...] }
接下来,运行 Amazon CLI 命令从 JSON 文件启动训练作业,如下所示。
aws sagemaker create-training-job --cli-input-json file:
//run-my-training-job.json
直接使用 Amazon CLI 配置输入数据通道
要配置输入数据通道而不使用 JSON 文件,请使用以下 Amazon CLI 代码结构。
aws --region
<your-region>
sagemaker create-training-job \ --training-job-name<your-training-job-name>
\ --role-arn<your-execution-role-arn>
\ --algorithm-specification '{ \ "TrainingInputMode": "File", \ "TrainingImage": "<your-ecr-image>
", \ "ContainerEntrypoint": ["/bin/sh
"], \ "ContainerArguments": ["/opt/ml/input/data/<your_channel_name>/custom_entrypoint.sh"]}
' \ --input-data-config '[{ \ "ChannelName":"<your_channel_name>
", \ "DataSource":{ \ "S3DataSource":{ \ "S3DataType":"S3Prefix", \ "S3Uri":"s3://<bucket-name>
/<bucket_prefix>
", \ "S3DataDistributionType":"FullyReplicated"}}}]' \ --output-data-config '{"S3OutputPath": "s3://custom-entrypoint-output-bucket/
"}' \ --resource-config '{"VolumeSizeInGB":10
,"InstanceCount":1
,"InstanceType":"ml.m5.2xlarge
"}' \ --stopping-condition '{"MaxRuntimeInSeconds":180
}'