

本文為英文版的機器翻譯版本，如內容有任何歧義或不一致之處，概以英文版為準。

# Amazon SageMaker AI 如何執行您的訓練映像
<a name="your-algorithms-training-algo-dockerfile"></a>

您可以使用自訂的進入點指令碼，將基礎結構自動化，以便在生產環境中進行訓練。如果您將進入點指令碼傳送到 Docker 容器中，還可以將它作為獨立的指令碼來運作，而無需重建映像。SageMaker AI 會使用 Docker 容器進入點指令碼處理您的訓練映像。

本節會說明如何在不使用訓練工具組的情況下，使用自訂的進入點。如果您想要使用自訂進入點，但不熟悉如何手動設定 Docker 容器，建議您改用 [SageMaker 訓練工具組程式庫](https://github.com/aws/sagemaker-training-toolkit)。如需如何使用訓練工具組的詳細資訊，請參閱[調整自有訓練容器](adapt-training-container.md)。

根據預設，SageMaker AI 會在容器內尋找名為 `train` 的指令碼。您也可以使用 [AlgorithmSpecification](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_AlgorithmSpecification.html) API 的 `ContainerArguments` 和 `ContainerEntrypoint` 參數，手動提供您的自訂進入點。

您可以使用以下兩個選項來手動配置 Docker 容器，以執行映像。
+ 使用 [CreateTrainingJob](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html) API 和包含一個進入點指示的 Docker 容器。
+ 使用 `CreateTrainingJob` API，並從 Docker 容器外傳送您的訓練指令碼。

如果您從 Docker 容器外傳送訓練指令碼，則在更新指令碼時不需要重建 Docker 容器。您也可以使用幾個不同的指令碼，在同一個容器中執行。

您的進入點指令碼應包含映像的訓練程式碼。如果您在[估算器](https://sagemaker.readthedocs.io/en/stable/api/training/estimators.html)內選用 `source_dir` 參數，它應將相對的 Amazon S3 路徑引至包含進入點指令碼的資料夾。您可以使用 `source_dir` 參數，參考多個檔案。如果不使用 `source_dir`，則可以使用 `entry_point` 參數指定進入點。如需包含估算器的自訂進入點指令碼範例，請參閱 [以 SageMaker AI 指令碼模式帶入自有模型](https://sagemaker-examples.readthedocs.io/en/latest/sagemaker-script-mode/sagemaker-script-mode.html)。

SageMaker AI 模型訓練支援高效能 S3 Express One Zone 目錄儲存貯體，作為檔案模式、快速檔案模式和管道模式的資料輸入位置。您也可以使用 S3 Express One Zone 目錄儲存貯體來儲存訓練輸出。若要使用 S3 Express One Zone，請提供 S3 Express One Zone 目錄儲存貯體的 URI，而非 Amazon S3 一般用途儲存貯體。您只能使用 Amazon S3 受管金鑰 (SSE-S3) 在伺服器端加密的目錄儲存貯體中加密 SageMaker AI 輸出資料。目前不支援使用 AWS KMS 金鑰的伺服器端加密 (SSE-KMS) 將 SageMaker AI 輸出資料儲存在目錄儲存貯體中。如需詳細資訊，請參閱 [S3 Express One Zone](https://docs.aws.amazon.com/AmazonS3/latest/userguide/s3-express-one-zone.html)。

## 使用 Docker 容器內綁定的進入點指令碼，執行訓練工作
<a name="your-algorithms-training-algo-dockerfile-api-ep-in"></a>

SageMaker AI 可以在您的 Docker 容器中，執行綁定的進入點指令碼。
+ 根據預設，Amazon SageMaker AI 會執行下列容器。

  ```
  docker run image train
  ```
+ SageMaker AI 會在映像名稱後指定 `train` 引數，藉此覆寫容器內預設的 [CMD](https://docs.docker.com/engine/reference/builder/#cmd) 陳述式。在您的 Docker 容器中，使用 `ENTRYPOINT` 指示內的 `exec` 格式。

  ```
  ENTRYPOINT ["executable", "param1", "param2", ...]
  ```

  以下範例顯示如何指定稱為 `k-means-algorithm.py` 的 Python 進入點指示。

  ```
  ENTRYPOINT ["python", "k-means-algorithm.py"]
  ```

  `ENTRYPOINT` 指示的 `exec` 格式直啟動可執行檔，而非 `/bin/sh` 的子項。如此一來即可接收訊號，例如來自 SageMaker API 的 `SIGTERM` 與 `SIGKILL`。使用 SageMaker API 時，適用下列條件。
  + [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html) API 的停用條件會指示 SageMaker AI 在特定時間後，停止模型訓練作業。
  + 以下顯示 [https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_StopTrainingJob.html](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_StopTrainingJob.html) 的 API。API 會發送相當於 `docker stop` 的命令 (逾時時間為 2 分鐘)，藉此命令系統從容地停止執行指定的容器。

    ```
    docker stop -t 120
    ```

    該命令會嘗試傳送 `SIGTERM` 訊號，以便停止執行中的容器。在 2 分鐘逾時後，API 會傳送 `SIGKILL` 並強制停止容器。如果容器在接收到 `SIGTERM` 後於 120 秒內從容處理完畢並結束，就不會傳送任何 `SIGKILL`。

  若想要在 SageMaker AI 停止訓練後存取中介模型成品，請新增程式碼，使用您的 `SIGTERM` 處理常式處理成品儲存作業。
+ 如果您計劃將 GPU 裝置用於模型訓練，請確保容器與 `nvidia-docker` 相容。容器僅能納入 CUDA 工具組，請勿將 NVIDIA 驅動程式與映像一併封裝。如需 `nvidia-docker` 的詳細資訊，請參閱 [NVIDIA/nvidia-docker](https://github.com/NVIDIA/nvidia-docker)。
+ 不可將 `tini` 初始設定式作為 SageMaker AI 容器的進入點指令碼，因為 `train` 和 `serve` 引數會混淆該設定式。
+ SageMaker 訓練會保留 `/opt/ml` 與所有子目錄。建立演算法的 Docker 映像檔時，請確定您沒有在此目錄中放置演算法所需的任何資料。因為如果您這樣做，在訓練期間可能會看不見這些資料。

若要在 Docker 映像中綁定 shell 或 Python 指令碼，或在 Amazon S3 儲存貯體中提供指令碼，或使用 AWS Command Line Interface (CLI)，請繼續下一節。

### 將您的 Shell 程式碼與 Docker 容器綁定
<a name="your-algorithms-training-algo-dockerfile-script-sh"></a>

 如果要在 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/
   ```

1. 請依照 *Amazon ECR 使用者指南*中[推送 Docker 映像](https://docs.aws.amazon.com/AmazonECR/latest/userguide/docker-push-ecr-image.html)的說明，建置 Docker 容器並將其推送到 Amazon Elastic Container Registry ([Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html))。

1. 執行下列 AWS 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}'
   ```

### 將您的 Python 腳本與 Docker 容器綁定
<a name="your-algorithms-training-algo-dockerfile-script-py"></a>

請使用以下步驟將自訂的 Python 程式碼與 Docker 映像檔綁定。

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/
   ```

1. 執行下列 AWS CLI 命令來啟動訓練任務。

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

## 使用 Docker 容器外的進入點指令碼執行訓練工作
<a name="your-algorithms-training-algo-dockerfile-api-pass-ep"></a>

您可以使用自有的 Docker 容器進行訓練，並從 Docker 容器外傳入進入點指令碼。在容器外建構進入點指令碼有一些優點。如果您更新進入點指令碼，不需要重建 Docker 容器。您也可以使用幾個不同的指令碼，在同一個容器中執行。

使用 [AlgorithmSpecification](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_AlgorithmSpecification.html) 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 AI 會假設 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 儲存貯體中提供進入點指令碼
<a name="your-algorithms-training-algo-dockerfile-script-s3"></a>

 若要使用 S3 儲存貯體提供自訂進入點指令碼，請使用 [DataSource](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DataSource.html#sagemaker-Type-DataSource-S3DataSource) API 的 `S3DataSource` 參數來指定指令碼的位置。若使用這個 `S3DataSource` 參數，需要以下條件。
+ [InputMode](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_Channel.html#sagemaker-Type-Channel-InputMode) 必須為 `File` 類型。
+ [S3DataDistributionType](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DataSource.html#sagemaker-Type-DataSource-S3DataSource) 必須是 `FullyReplicated`。

下列範例會將名為 custom\$1entrypoint.sh 的指令碼放置在 S3 儲存貯體 `s3://<bucket-name>/<bucket prefix>/custom_entrypoint.sh` 的路徑上。

```
#!/bin/bash
echo "Running custom_entrypoint.sh"
echo "Hello you have provided the following arguments: " "$@"
```

接下來，您必須設定輸入資料通道的組態，才能執行訓練工作。 AWS CLI 直接使用 或搭配 JSON 檔案來執行此操作。

#### 使用 AWS CLI 搭配 JSON 檔案設定輸入資料通道
<a name="your-algorithms-training-algo-dockerfile-script-s3-json"></a>

若要使用 JSON 檔案設定輸入資料通道，請使用 AWS CLI ，如下列程式碼結構所示。請確定下列所有欄位均使用 [CreateTrainingJob](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#API_CreateTrainingJob_RequestSyntax) API 中定義的請求語法。

```
// run-my-training-job.json
{
 "[AlgorithmSpecification](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-AlgorithmSpecification)": { 
        "ContainerEntrypoint": ["/bin/sh"],
        "ContainerArguments": ["/opt/ml/input/data/<your_channel_name>/custom_entrypoint.sh"],
         ...
   },
  "[InputDataConfig](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#sagemaker-CreateTrainingJob-request-InputDataConfig)": [ 
    { 
        "[ChannelName](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_Channel.html#sagemaker-Type-Channel-ChannelName)": "<your_channel_name>",
        "[DataSource](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_Channel.html#sagemaker-Type-Channel-DataSource)": { 
            "[S3DataSource](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_DataSource.html#sagemaker-Type-DataSource-S3DataSource)": { 
                "[S3DataDistributionType](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html#sagemaker-Type-S3DataSource-S3DataDistributionType)": "FullyReplicated",
                "[S3DataType](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html#sagemaker-Type-S3DataSource-S3DataType)": "S3Prefix",
                "[S3Uri](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_S3DataSource.html#sagemaker-Type-S3DataSource-S3Uri)": "s3://<bucket-name>/<bucket_prefix>"
            }
        },
        "[InputMode](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_Channel.html#sagemaker-Type-Channel-InputMode)": "File",
    },
    ...]
}
```

接著，執行 AWS CLI 命令，從 JSON 檔案啟動訓練任務，如下所示。

```
aws sagemaker create-training-job --cli-input-json file://run-my-training-job.json
```

#### AWS CLI 直接使用 設定輸入資料通道
<a name="your-algorithms-training-algo-dockerfile-script-s3-directly"></a>

若要設定沒有 JSON 檔案的輸入資料通道，請使用下列 AWS 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}'
```