Amazon SageMaker 如何运行训练映像 - Amazon SageMaker
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

Amazon SageMaker 如何运行训练映像

您可以使用自定义入口点脚本来自动配置基础设施,以便在生产环境中进行训练。如果您将入口点脚本传递到 Docker 容器中,则也可以将其作为独立脚本运行,而无需重新构建映像。SageMaker 使用 Docker 容器入口点脚本处理您的训练映像。

本节将介绍如何无需训练工具包来使用自定义入口点。如果您想使用自定义入口点,但不熟悉如何手动配置 Docker 容器,我们建议您改为使用 SageMaker 训练工具包库。有关如何使用训练工具包的更多信息,请参阅 调整自己的训练容器

默认情况下,SageMaker 会在您的容器中查找名为 train 的脚本。您也可以使用 AlgorithmSpecification API 的 ContainerArgumentsContainerEntrypoint 参数,手动提供自己的自定义入口点。

您可以采用以下两个选项来手动配置 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 的信号,如 SIGTERMSIGKILL。使用 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 脚本,请使用以下步骤。

  1. 将 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/
  2. 按照《Amazon ECR 用户指南》推送 Docker 映像的说明,构建 Docker 容器并将其推送到 Amazon Elastic Container Registry (Amazon ECR)。

  3. 通过运行以下 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 脚本,请使用以下步骤。

  1. 将 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/
  2. 通过运行以下 Amazon CLI 命令启动训练作业。

    --algorithm-specification '{ \ "TrainingInputMode": "File", \ "TrainingImage": "<your-ecr-image>", \ "ContainerEntrypoint": ["python"], \ "ContainerArguments": ["/mydir/custom_entrypoint.py"]}' \

使用在 Docker 容器外部的入口点脚本运行训练作业

您可以使用自己的 Docker 容器进行训练,并将入口点脚本从 Docker 容器的外部传入。在容器之外构建入口点脚本有一些好处。如果您更新入口点脚本,则无需重新构建 Docker 容器。您也可以使用多个不同的脚本在同一个容器中运行。

使用 AlgorithmSpecification API 的 ContainerEntrypointContainerArguments 参数,指定训练脚本的位置。这些入口点和参数的行为方式与 Docker 入口点和参数相同。这些参数中的值会覆盖提供作为 Docker 容器一部分的对应 ENTRYPOINTCMD

当您将自定义入口点脚本传递给 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>
  • 如果您同时提供 ContainerEntrypointContainerArguments,则使用 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 参数,则需要以下信息。

以下示例在 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}'