

翻訳は機械翻訳により提供されています。提供された翻訳内容と英語版の間で齟齬、不一致または矛盾がある場合、英語版が優先します。

# SageMaker AI で使用するカスタム Docker コンテナ
<a name="docker-containers-adapt-your-own"></a>

既存の Docker イメージを SageMaker AI と連携するように適応させることができます。構築済みの SageMaker AI イメージでは現在サポートされていない機能または安全要件を満たすコンテナがある場合、既存の外部 Docker イメージを SageMaker AI で使用する必要がある場合があります。独自のコンテナを取り込み、それを SageMaker AI で動作するように適応させることができる 2 つのツールキットがあります。
+ [SageMaker トレーニングツールキット](https://github.com/aws/sagemaker-training-toolkit) – このツールキットを使用して、SageMaker AI でモデルをトレーニングします。
+ [SageMaker AI 推論ツールキット](https://github.com/aws/sagemaker-inference-toolkit) – このツールキットを使用して、SageMaker AI でモデルをデプロイします。

次のいくつかのトピックでは、SageMaker トレーニングおよび推論ツールキットを使用して既存のイメージを適応させる方法を示します。

**Topics**
+ [個々のフレームワークライブラリ](#docker-containers-adapt-your-own-frameworks)
+ [SageMaker トレーニングおよび推論ツールキット](amazon-sagemaker-toolkits.md)
+ [独自のトレーニングコンテナの適応](adapt-training-container.md)
+ [Amazon SageMaker AI 用に独自の推論コンテナを適応させる](adapt-inference-container.md)

## 個々のフレームワークライブラリ
<a name="docker-containers-adapt-your-own-frameworks"></a>

SageMaker トレーニングツールキットおよび SageMaker AI 推論ツールキットの他に、SageMaker AI には TensorFlow、MXNet、PyTorch、Chainer に特化したツールキットも備わっています。次の表は、各フレームワークのソースコードとそれぞれに対応するツールキットを含む GitHub リポジトリへのリンクを示しています。リンクされている手順は、Python SDK を使用して SageMaker AI でトレーニングアルゴリズムとホストモデルを実行するためのものです。これらの個々のライブラリの機能は、SageMaker AI トレーニングツールキットおよび SageMaker AI 推論ツールキットに含まれています。


| フレームワーク | Toolkit ソースコード | 
| --- | --- | 
| TensorFlow |  [SageMaker AI TensorFlow トレーニング](https://github.com/aws/sagemaker-tensorflow-training-toolkit) [SageMaker AI TensorFlow Serving](https://github.com/aws/sagemaker-tensorflow-serving-container)  | 
| MXNet |  [SageMaker AI MXNet トレーニング](https://github.com/aws/sagemaker-mxnet-training-toolkit) [SageMaker AI MXNet 推論](https://github.com/aws/sagemaker-mxnet-inference-toolkit)  | 
| PyTorch |  [SageMaker AI PyTorch トレーニング](https://github.com/aws/sagemaker-pytorch-training-toolkit) [SageMaker AI PyTorch 推論](https://github.com/aws/sagemaker-pytorch-inference-toolkit)  | 
| Chainer |  [SageMaker AI Chainer SageMaker AI コンテナ](https://github.com/aws/sagemaker-chainer-container)  | 

# SageMaker トレーニングおよび推論ツールキット
<a name="amazon-sagemaker-toolkits"></a>

[SageMaker トレーニング](https://github.com/aws/sagemaker-training-toolkit)ツールキットおよび [SageMaker AI 推論](https://github.com/aws/sagemaker-inference-toolkit)ツールキットは、SageMaker AI でのスクリプトの実行、アルゴリズムのトレーニング、モデルのデプロイにご使用のコンテナを適合させるために必要な機能を実装します。ライブラリをインストールすると、ユーザーに対して次の内容が定義されます。
+ コードやその他のリソースを保存する場所。
+ コンテナーの起動時に実行するコードを含むエントリポイントです。Dockerfile は、SageMaker AI と互換性のあるコンテナが期待する場所に実行する必要があるコードをコピーする必要があります。
+ このライブラリは、トレーニングと推論のためのデプロイを管理するために、コンテナで必要となるその他の情報。

## SageMaker AI ツールキットコンテナの構造
<a name="sagemaker-toolkits-structure"></a>

SageMaker AI がモデルをトレーニングする場合、コンテナの `/opt/ml` ディレクトリに次のファイルフォルダ構造を作成します。

```
/opt/ml
├── input
│   ├── config
│   │   ├── hyperparameters.json
│   │   └── resourceConfig.json
│   └── data
│       └── <channel_name>
│           └── <input data>
├── model
│
├── code
│
├── output
│
└── failure
```

モデルの*トレーニング*ジョブを実行する場合、SageMaker AI コンテナは、アルゴリズム用のハイパーパラメータと、トレーニングの配信に使用されるネットワークレイアウトを設定する JSON ファイルが含まれる `/opt/ml/input/` ディレクトリを使用します。また、`/opt/ml/input/` ディレクトリには、SageMaker AI が Amazon Simple Storage Service (Amazon S3) に保存されているデータにアクセスするときに経由するチャネルを指定するファイルも含まれています。SageMaker AI コンテナライブラリは、コンテナが実行するスクリプトを `/opt/ml/code/` ディレクトリに配置します。スクリプトは、アルゴリズムによって生成されたモデルを `/opt/ml/model/` ディレクトリに書き込む必要があります。詳細については、「[カスタムトレーニングアルゴリズムを使用するコンテナ](your-algorithms-training-algo.md)」を参照してください。

SageMaker AI でトレーニング済みのモデルをホストして推論を行う場合、モデルを HTTP エンドポイントにデプロイします。**このモデルでは、推論リクエストに応じてリアルタイムの予測を実行します。コンテナには、これらのリクエストを処理するためにサービススタックが含まれている必要があります。

ホスティングコンテナまたはバッチ変換コンテナでは、モデルファイルはトレーニング中に書き込まれたフォルダと同じフォルダに配置されます。

```
/opt/ml/model
│
└── <model files>
```

詳細については、「[カスタム推論コードを持つコンテナ](your-algorithms-inference-main.md)」を参照してください。

## 単一コンテナと複数のコンテナの比較
<a name="sagemaker-toolkits-separate-images"></a>

トレーニングアルゴリズムと推論コードに別々の Docker イメージを提供することも、これらに単一の Docker イメージを使用することもできます。SageMaker AI で使用する Docker イメージを作成する場合は、次の点を考慮してください。
+ 2 つの Docker イメージを提供すると、共通ライブラリが重複することがあるため、ストレージ要件とコストが増加することがあります。
+ 一般的に、小さいコンテナの方がトレーニングとホスティングをより迅速に開始できます。モデルトレーニングが高速になり、ホスティングサービスはより迅速に自動スケーリングすることでトラフィックの増加に対応できます。
+ トレーニングコンテナより大幅に小さい推論コンテナを記述できます。これは、トレーニングに GPU を使用するときに特に一般的ですが、推論コードは CPU 用に最適化されています。
+ SageMaker AI は、Docker コンテナが特権アクセスなしで実行されることを必要とします。
+ 構築した Docker コンテナと SageMaker AI が提供する Docker コンテナの両方が、`Stdout` ファイルと `Stderr` ファイルにメッセージを送信できます。SageMaker AI は、これらのメッセージを AWS アカウントの Amazon CloudWatch logsに送信します。

SageMaker AI のコンテナを作成する方法と、そのコンテナ内でスクリプトを実行する方法については、GitHub の「[SageMaker AI Training Toolkit](https://github.com/aws/sagemaker-training-toolkit)」リポジトリおよび「[SageMaker AI Inference Toolkit](https://github.com/aws/sagemaker-inference-toolkit)」リポジトリを参照してください。これらは、SageMaker AI のコンテナによって提供される重要な環境変数と環境変数のリストも提供します。

# 独自のトレーニングコンテナの適応
<a name="adapt-training-container"></a>

独自のトレーニングモデルを実行するには、Amazon SageMaker ノートブックインスタンスで [Amazon SageMaker トレーニングツールキット](https://github.com/aws/sagemaker-training-toolkit)を使用して Docker コンテナを構築します。

## ステップ 1: SageMaker ノートブックインスタンスを作成する
<a name="byoc-training-step1"></a>

1. Amazon SageMaker AI コンソール ([https://console.aws.amazon.com/sagemaker/](https://console.aws.amazon.com/sagemaker/)) を開きます。

1. 左側のナビゲーションペインで、**[Notebook]** (ノートブック)、**[Notebook instances]** (ノートブックインスタンス)、**[Create notebook instance]** (ノートブックインスタンスの作成) の順に選択します。

1. **[ノートブックインスタンスの作成]** ページで、次の情報を入力します。

   1. [**ノートブックインスタンス名**] に「**RunScriptNotebookInstance**」と入力します。

   1. [**ノートブックインスタンスタイプ**] で、[**ml.t2.medium**] を選択します。

   1. **[Permissions and encryption]** (アクセス許可と暗号化) セクションで、以下の操作を行います。

      1. **[IAM role]** (IAM ロール) は、**[Create a new role]** (新しいロールの作成) を選択します。新しいウィンドウが開きます。

      1. **[Create an IAM role]** (IAM ロールの作成) ページで、**[Specific S3 buckets]** (特定の S3 バケット) を選択し、**sagemaker-run-script** という名前の Amazon S3 バケットを指定して、**[Create role]** (ロールの作成) を選択します。

         SageMaker AI は、`AmazonSageMaker-ExecutionRole-YYYYMMDDTHHmmSS` という名前の IAM ロールを作成します。例えば、`AmazonSageMaker-ExecutionRole-20190429T110788`。実行ロールの命名規則では、ロールが作成された日時を `T` で区切って使用することに注意してください。

   1. **[Root Access]** (ルートアクセス) で、**[Enable]** (有効) を選択します。

   1. **[Create notebook instance]** (ノートブックインスタンスの作成) を選択します。

1. **[Notebook instances]** (ノートブックインスタンス) ページでは **[Status]** (ステータス) は **[Pending]** (保留中) となっています。Amazon SageMaker AI が機械学習コンピューティングインスタンス (この場合ノートブックインスタンス) を起動し、ML ストレージボリュームをアタッチするまでに、数分を要する場合があります。ノートブックインスタンスには、事前設定された Jupyter ノートブックサーバーと一連の Anaconda ライブラリがあります。詳細については、「[  CreateNotebookInstance](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateNotebookInstance.html)」を参照してください。

   

1. 作成したノートブックの **[名前]** をクリックします。新しいページが開きます。

1.  **[Permissions and encryption]** (アクセス許可と暗号化) セクションで、**[the IAM role ARN number]** (IAM ロールの ARN 番号) をコピーし、メモ帳ファイルに貼り付けて、一時的に保存します。この IAM ロールの ARN 番号は、後でノートブックインスタンスでローカルトレーニング推定器を構成するために使用します。[**the IAM role ARN number (IAM ロールの ARN 番号)**] は、次のようになります。`'arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole-20190429T110788'`

1. ノートブックインスタンスのステータスが **[InService]** (InService) に変わったら、**[Open JupyterLab]** (JupyterLab を開く) を選択します。

## ステップ 2: Dockerfile および Python トレーニングスクリプトを作成してアップロードする
<a name="byoc-training-step2"></a>

1. JupyterLab が開いたら、JupyterLab のホームディレクトリに新しいフォルダを作成します。左上隅で、**[New Folder]** (新しいフォルダ) アイコンをクリックし、フォルダ名 `docker_test_folder` を入力します。

1. `docker_test_folder` ディレクトリに `Dockerfile` という名前のテキストファイルを作成します。

   1. 左上隅の **[New Launcher]** (新しいランチャー) アイコン (\$1) を選択します。

   1. 右ペインの**[Other]** (その他) セクションで、**[Text File]** (テキストファイル) を選択します。

   1. 次の `Dockerfile` サンプルコードをテキストファイルに貼り付けます。

      ```
      #Download an open source TensorFlow Docker image
      FROM tensorflow/tensorflow:latest-gpu-jupyter
      
      # Install sagemaker-training toolkit that contains the common functionality necessary to create a container compatible with SageMaker AI and the Python SDK.
      RUN pip3 install sagemaker-training
      
      # Copies the training code inside the container
      COPY train.py /opt/ml/code/train.py
      
      # Defines train.py as script entrypoint
      ENV SAGEMAKER_PROGRAM train.py
      ```

      Dockerfile のスクリプトは以下のタスクを実行します。
      + `FROM tensorflow/tensorflow:latest-gpu-jupyter` - 最新の TensorFlow Docker ベースイメージをダウンロードします。これは、コンテナの構築に持ち込む任意の Docker ベースイメージと、 AWS 構築済みのコンテナベースイメージに置き換えることができます。
      + `RUN pip install sagemaker-training` - SageMaker AI に対応するコンテナを作成するために必要な一般的な機能を備えている [SageMaker AI トレーニングツールキット](https://github.com/aws/sagemaker-training-toolkit)をインストールします。
      + `COPY train.py /opt/ml/code/train.py` - SageMaker AI で所定のコンテナ内の場所にスクリプトをコピーします。スクリプトは、このフォルダにある必要があります。
      + `ENV SAGEMAKER_PROGRAM train.py` - トレーニングスクリプト `train.py` をコンテナの `/opt/ml/code` フォルダにコピーされたエンドポイントスクリプトとして処理します。これは、独自のコンテナを構築する場合に指定する必要がある唯一の環境変数です。

   1.  左側のディレクトリナビゲーションペインでは、テキストファイル名は自動的に `untitled.txt` に設定されます。ファイルの名前を変更するには、ファイルを右クリックし、**[Rename]** (名前の変更) で、ファイル名を `.txt` 拡張子のない `Dockerfile` に変更し、`Ctrl+s` または `Command+s` を押してファイルを保存します。

1. トレーニングスクリプト `train.py` を `docker_test_folder` にアップロードします。次のスクリプトの例を使用して、この演習用に [MNIST データセット](https://en.wikipedia.org/wiki/MNIST_database)でトレーニングされた手書きの数字を読み取るモデルを作成できます。

   ```
   import tensorflow as tf
   import os
   
   mnist = tf.keras.datasets.mnist
   
   (x_train, y_train), (x_test, y_test) = mnist.load_data()
   x_train, x_test = x_train / 255.0, x_test / 255.0
   
   model = tf.keras.models.Sequential([
   tf.keras.layers.Flatten(input_shape=(28, 28)),
   tf.keras.layers.Dense(128, activation='relu'),
   tf.keras.layers.Dropout(0.2),
   tf.keras.layers.Dense(10, activation='softmax')
   ])
   
   model.compile(optimizer='adam',
   loss='sparse_categorical_crossentropy',
   metrics=['accuracy'])
   
   model.fit(x_train, y_train, epochs=1)
   model_save_dir = f"{os.environ.get('SM_MODEL_DIR')}/1"
   
   model.evaluate(x_test, y_test)
   tf.saved_model.save(model, model_save_dir)
   ```

## ステップ 3: コンテナを構築する
<a name="byoc-training-step3"></a>

1. JupyterLab ホームディレクトリで、Jupyter ノートブックを開きます。新しいノートブックを開くには、**[新しい起動]** アイコンを選択し、次に **[ノートブック]** セクションで **conda\$1tensorflow2** の最新バージョンを選択します。

1. 最初のノートブックセルで次のコマンドを実行して、`docker_test_folder` ディレクトリに変更します。

   ```
   cd ~/SageMaker/docker_test_folder
   ```

   これにより、次のように現在のディレクトリが返されます。

   ```
   ! pwd
   ```

   `output: /home/ec2-user/SageMaker/docker_test_folder`

1. Docker コンテナを構築するには、次の Docker ビルドコマンド (最後のスペースとピリオドも含めます) を実行します。

   ```
   ! docker build -t tf-custom-container-test .
   ```

   Docker のビルドコマンドは、作成した Docker ディレクトリ (この場合は `docker_test_folder`) から実行する必要があります。
**注記**  
Docker が Dockerfile を見つけられないという次のエラーメッセージが表示された場合は、Dockerfile の名前が正しいこと、およびそのディレクトリに保存されていることを確認してください。  

   ```
   unable to prepare context: unable to evaluate symlinks in Dockerfile path: 
   lstat /home/ec2-user/SageMaker/docker/Dockerfile: no such file or directory
   ```
`docker` は、現在のディレクトリ内で拡張子を付けずに、`Dockerfile` と名付けられたファイルを検索します。別の名前を指定した場合は、`-f` フラグを付けて手動でファイル名を渡すことができます。例えば、Dockerfile に `Dockerfile-text.txt` という名前を付けた場合、次のコマンドを実行します  

   ```
   ! docker build -t tf-custom-container-test -f Dockerfile-text.txt .
   ```

## ステップ 4: コンテナをテストする
<a name="byoc-training-step4"></a>

1. ノートブックインスタンスでローカルにコンテナをテストするには、Jupyter ノートブックを開きます。**[新しいランチャー]** を選択し、**[ノートブック]** セクションで **conda\$1tensorflow2** の最新バージョンを選択します。

1. 次のサンプルスクリプトをノートブックのコードセルに貼り付けて、SageMaker AI 推定器を設定します。

   ```
   import sagemaker
   from sagemaker.estimator import Estimator
   
   estimator = Estimator(image_uri='tf-custom-container-test',
                         role=sagemaker.get_execution_role(),
                         instance_count=1,
                         instance_type='local')
   
   estimator.fit()
   ```

   前述のコード例では、`sagemaker.get_execution_role()` を `role` 引数に指定して、SageMaker AI セッションに設定されたロールを自動的に取得します。ノートブックインスタンスを設定したときに使用した **[IAM ロール ARN 番号]** の文字列値に置き換えることもできます。ARN は次のようになります。`'arn:aws:iam::111122223333:role/service-role/AmazonSageMaker-ExecutionRole-20190429T110788'`

1. コードセルを実行します。このテストでは、トレーニングの環境設定、環境変数に使用された値、データのソース、およびトレーニング中に得られた損失と正確性が出力されます。

## ステップ 5: Amazon Elastic Container Registry (Amazon ECR) にコンテナをプッシュする
<a name="byoc-training-step5"></a>

1. このローカルモードテストが正常に実行されたら、Docker コンテナを [Amazon ECR](https://docs.aws.amazon.com/AmazonECR/latest/userguide/what-is-ecr.html) にプッシュし、それを使用してトレーニングジョブを実行できます。Amazon ECR の代わりにプライベート Docker レジストリを使用する場合は、「[Push your training container to a private registry](https://docs.aws.amazon.com/sagemaker/latest/dg/docker-containers-adapt-your-own-private-registry.html)」を参照してください。

   ノートブックセルで次のコマンドラインを実行します。

   ```
   %%sh
   
   # Specify an algorithm name
   algorithm_name=tf-custom-container-test
   
   account=$(aws sts get-caller-identity --query Account --output text)
   
   # Get the region defined in the current configuration (default to us-west-2 if none defined)
   region=$(aws configure get region)
   region=${region:-us-west-2}
   
   fullname="${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest"
   
   # If the repository doesn't exist in ECR, create it.
   
   aws ecr describe-repositories --repository-names "${algorithm_name}" > /dev/null 2>&1
   if [ $? -ne 0 ]
   then
   aws ecr create-repository --repository-name "${algorithm_name}" > /dev/null
   fi
   
   # Get the login command from ECR and execute it directly
   
   aws ecr get-login-password --region ${region}|docker login --username AWS --password-stdin ${fullname}
   
   # Build the docker image locally with the image name and then push it to ECR
   # with the full name.
   
   docker build -t ${algorithm_name} .
   docker tag ${algorithm_name} ${fullname}
   
   docker push ${fullname}
   ```
**注記**  
この bash シェルスクリプトは、次のエラーメッセージに似た許可の問題が発生する可能性があります。  

   ```
   "denied: User: [ARN] is not authorized to perform: ecr:InitiateLayerUpload on resource:
   arn:aws:ecr:us-east-1:[id]:repository/tf-custom-container-test"
   ```
このエラーが発生した場合は、**AmazonEC2ContainerRegistryFullAccess** ポリシーを IAM ロールにアタッチする必要があります。[IAM コンソール](https://console.aws.amazon.com/iam/home)に移動し、左側のナビゲーションペインで、**[ロール]** を選択し、ノートブックインスタンスに使用した IAM ロールを検索します。**[Permission]** (許可) タブで、**[Attach policies]** (ポリシーをアタッチ) ボタンをクリックし、**AmazonEC2ContainerRegistryFullAccess** ポリシーを検索します。ポリシーのチェックボックスをオンにして、**[アクセス許可の追加]** を選択して終了します。

1. Studio ノートブックセルで次のコードを実行して、トレーニングコンテナの Amazon ECR イメージを呼び出します。

   ```
   import boto3
   
   account_id = boto3.client('sts').get_caller_identity().get('Account')
   ecr_repository = 'tf-custom-container-test'
   tag = ':latest'
   
   region = boto3.session.Session().region_name
   
   uri_suffix = 'amazonaws.com'
   if region in ['cn-north-1', 'cn-northwest-1']:
       uri_suffix = 'amazonaws.com.cn'
   
   byoc_image_uri = '{}.dkr.ecr.{}.{}/{}'.format(account_id, region, uri_suffix, ecr_repository + tag)
   
   byoc_image_uri
   # This should return something like
   # 111122223333.dkr.ecr.us-east-2.amazonaws.com/sagemaker-byoc-test:latest
   ```

1. 前のステップで取得した `ecr_image` を使用して SageMaker AI 推定器オブジェクトを構成します。次のコードサンプルでは、SageMaker AI 推定器を `byoc_image_uri` で構成し、Amazon EC2 インスタンスでトレーニングジョブを開始します。

------
#### [ SageMaker Python SDK v1 ]

   ```
   import sagemaker
   from sagemaker import get_execution_role
   from sagemaker.estimator import Estimator
   
   estimator = Estimator(image_uri=byoc_image_uri,
                         role=get_execution_role(),
                         base_job_name='tf-custom-container-test-job',
                         instance_count=1,
                         instance_type='ml.g4dn.xlarge')
   
   #train your model
   estimator.fit()
   ```

------
#### [ SageMaker Python SDK v2 ]

   ```
   import sagemaker
   from sagemaker import get_execution_role
   from sagemaker.estimator import Estimator
   
   estimator = Estimator(image_uri=byoc_image_uri,
                         role=get_execution_role(),
                         base_job_name='tf-custom-container-test-job',
                         instance_count=1,
                         instance_type='ml.g4dn.xlarge')
   
   #train your model
   estimator.fit()
   ```

------

1. 独自のコンテナを使用してモデルをデプロイする場合は、「[Adapting Your Own Inference Container](https://docs.aws.amazon.com/sagemaker/latest/dg/adapt-inference-container.html)」を参照してください。TensorFlow モデルをデプロイできる AWSフレームワークコンテナを使用することもできます。モデル例をデプロイして手書きの数字を読み取るには、前のサブステップでモデルのトレーニングに使ったのと同じノートブックに、次のスクリプトの例を入力して、デプロイに必要なイメージ URI (ユニバーサルリソース識別子) を取得し、モデルをデプロイします。

   ```
   import boto3
   import sagemaker
   
   #obtain image uris
   from sagemaker import image_uris
   container = image_uris.retrieve(framework='tensorflow',region='us-west-2',version='2.11.0',
                       image_scope='inference',instance_type='ml.g4dn.xlarge')
   
   #create the model entity, endpoint configuration and endpoint
   predictor = estimator.deploy(1,instance_type='ml.g4dn.xlarge',image_uri=container)
   ```

   次のコード例を使用して、MNIST データセットの手書き数字の例を使用してモデルをテストします。

   ```
   #Retrieve an example test dataset to test
   import numpy as np
   import matplotlib.pyplot as plt
   from keras.datasets import mnist
   
   # Load the MNIST dataset and split it into training and testing sets
   (x_train, y_train), (x_test, y_test) = mnist.load_data()
   # Select a random example from the training set
   example_index = np.random.randint(0, x_train.shape[0])
   example_image = x_train[example_index]
   example_label = y_train[example_index]
   
   # Print the label and show the image
   print(f"Label: {example_label}")
   plt.imshow(example_image, cmap='gray')
   plt.show()
   ```

   テスト用の手書き数字を TensorFlow が取り込んでテスト予測を行える形式に変換します。

   ```
   from sagemaker.serializers import JSONSerializer
   data = {"instances": example_image.tolist()}
   predictor.serializer=JSONSerializer() #update the predictor to use the JSONSerializer
   predictor.predict(data) #make the prediction
   ```

カスタムコンテナをローカルでテストし、Amazon ECR イメージにプッシュする方法を示す完全な例については、「[独自の TensorFlow コンテナを構築する](https://sagemaker-examples.readthedocs.io/en/latest/advanced_functionality/tensorflow_bring_your_own/tensorflow_bring_your_own.html)」のサンプルノートブックを参照してください。

**ヒント**  
システム使用率の問題 (CPU ボトルネックや GPU の低使用率など) を監視し、トレーニングの問題 (オーバーフィット、オーバートレーニング、テンソルの爆発、勾配消失など) を特定するためのトレーニングジョブをプロファイリングおよびデバッグするには、Amazon SageMaker Debugger を使用します。詳細については、「[カスタムトレーニングで Debugger を使用する](debugger-bring-your-own-container.md)」を参照してください。

## ステップ 6: リソースをクリーンアップする
<a name="byoc-training-step6"></a>

**入門サンプルを終了したときにリソースをクリーンアップするには**

1. [SageMaker AI コンソール](https://console.aws.amazon.com/sagemaker/)を開き、ノートブックインスタンス ** [RunScriptNotebookInstance]**、**[アクション]**、**[停止]** の順に選択します。インスタンスが停止するまで、数分かかる場合があります。

1. インスタンスの **[Status]** (ステータス) が**[Stopped]** (停止) に変化したら、**[Actions]** (アクション)、**[Delete]** (削除) の順に選択し、ダイアログボックスで **[Delete]** (削除) を選択します。インスタンスが削除されるまで、数分かかる場合があります。ノートブックインスタンスが削除されると、テーブルには表示されなくなります。

1. [Amazon S3 コンソール](https://console.aws.amazon.com/s3/)を開き、モデルのアーティファクトとトレーニングデータセットを保存するために作成したバケットを削除します。

1. [IAM コンソール](https://console.aws.amazon.com/iam/)を開き、IAM ロールを削除します。アクセス許可ポリシーを作成した場合は、それも削除することができます。
**注記**  
 Docker コンテナは、実行後に自動的にシャットダウンします。削除する必要はありません。

## ブログと導入事例
<a name="byoc-blogs-and-examples"></a>

以下のブログでは、Amazon SageMaker AI でカスタムトレーニングコンテナを使用するケーススタディについて説明しています。
+ 「[Why bring your own container to Amazon SageMaker AI and how to do it right](https://medium.com/@pandey.vikesh/why-bring-your-own-container-to-amazon-sagemaker-and-how-to-do-it-right-bc158fe41ed1)」、*Medium* (2023 年 1 月 20 日)

# プライベート Docker レジストリ内のイメージにアクセスするようにトレーニングジョブを適応
<a name="docker-containers-adapt-your-own-private-registry"></a>

Amazon Elastic Container Registry (Amazon ECR) の代わりにプライベート [Docker レジストリ](https://docs.docker.com/registry/)を使用して、SageMaker AI トレーニング用のイメージをホストできます。以下の手順では、Docker レジストリの作成、仮想プライベートクラウド (VPC) とトレーニングジョブの設定、イメージの保存、プライベート Docker レジストリ内のトレーニングイメージへのアクセス許可を SageMaker AI に付与する方法を示します。また、SageMaker トレーニングジョブで認証を必要とする Docker レジストリの使用方法についても説明します。

## プライベート Docker レジストリでのイメージの作成と保存
<a name="docker-containers-adapt-your-own-private-registry-prerequisites"></a>

プライベート Docker レジストリを作成してイメージを保存します。レジストリは次の条件を満たす必要があります。
+ [Docker レジストリ HTTP API](https://docs.docker.com/registry/spec/api/) プロトコルを使用します
+ `CreateTrainingJob` API の [VPCConfig](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html#API_CreateTrainingJob_RequestSyntax) パラメータで指定されているのと同じ VPC からアクセス可能です。トレーニングジョブの作成時に `VpcConfig` を入力します。
+ 既知の公開認証機関 (CA) からの [TLS 証明書](https://aws.amazon.com/what-is/ssl-certificate/)で保護されています。

Docker レジストリの作成の詳細については、「[Deploy a registry server](https://docs.docker.com/registry/deploying/)」を参照してください。

## VPC と SageMaker トレーニングジョブの設定
<a name="docker-containers-adapt-your-own-private-registry-configure"></a>

SageMaker AI は VPC 内のネットワーク接続を使用して Docker レジストリ内のイメージにアクセスします。Docker レジストリ内のイメージをトレーニングに使用するには、アカウントの Amazon VPC からレジストリにアクセス可能である必要があります。詳細については、「[トレーニングに認証が必要な Docker レジストリの使用](docker-containers-adapt-your-own-private-registry-authentication.md)」を参照してください。

また、Docker レジストリがアクセスできるのと同じ VPC に接続するようにトレーニングジョブを設定する必要があります。詳細については、「[Configure a Training Job for Amazon VPC Access](https://docs.aws.amazon.com/sagemaker/latest/dg/train-vpc.html#train-vpc-configure)」を参照してください。

## プライベート Docker レジストリのイメージを使用したトレーニングジョブの作成
<a name="docker-containers-adapt-your-own-private-registry-create"></a>

プライベート Docker レジストリのイメージをトレーニングに使用するには、以下のガイドを使用してイメージの設定、トレーニングジョブの設定と作成を行います。次のコード例では、 AWS SDK for Python (Boto3) クライアントを使用します。

1. トレーニングイメージ設定オブジェクトを作成し、以下のように `TrainingRepositoryAccessMode` フィールドに `Vpc` を入力します。

   ```
   training_image_config = {
       'TrainingRepositoryAccessMode': 'Vpc'
   }
   ```
**注記**  
プライベート Docker レジストリに認証が必要な場合は、`TrainingRepositoryAuthConfig` オブジェクトを、トレーニングイメージ設定オブジェクトに追加する必要があります。オブジェクトの `TrainingRepositoryCredentialsProviderArn`フィールドを使用して SageMaker AI にアクセス認証情報を提供する AWS Lambda 関数の Amazon リソースネーム (ARN) も指定する必要があります`TrainingRepositoryAuthConfig`。詳細については、以下のコード構造例を参照してください。  

   ```
   training_image_config = {
      'TrainingRepositoryAccessMode': 'Vpc',
      'TrainingRepositoryAuthConfig': {
           'TrainingRepositoryCredentialsProviderArn': 'arn:aws:lambda:Region:Acct:function:FunctionName'
      }
   }
   ```

   認証を提供するために Lambda 関数を作成する方法については、「[トレーニングに認証が必要な Docker レジストリの使用](docker-containers-adapt-your-own-private-registry-authentication.md)」を参照してください。

1. Boto3 クライアントを使用してトレーニングジョブを作成し、正しい設定を [create\$1training\$1job](https://docs.aws.amazon.com/sagemaker/latest/APIReference/API_CreateTrainingJob.html) API に渡します。以下の手順は、コンポーネントの設定方法とトレーニングジョブの作成方法を示しています。

   1. `create_training_job` に渡す `AlgorithmSpecification` オブジェクトを作成します。次のコード例に示すように、前のステップで作成したトレーニングイメージ設定オブジェクトを使用します。

      ```
      algorithm_specification = {
         'TrainingImage': 'myteam.myorg.com/docker-local/my-training-image:<IMAGE-TAG>',
         'TrainingImageConfig': training_image_config,
         'TrainingInputMode': 'File'
      }
      ```
**注記**  
更新バージョンではなく固定バージョンのイメージを使用するには、名前やタグではなく、イメージの[ダイジェスト](https://docs.docker.com/engine/reference/commandline/pull/#pull-an-image-by-digest-immutable-identifier)を参照します。

   1. 次のコード例に示すように、`create_training_job` に渡すトレーニングジョブの名前とロールを指定します。

      ```
      training_job_name = 'private-registry-job'
      execution_role_arn = 'arn:aws:iam::123456789012:role/SageMakerExecutionRole'
      ```

   1. トレーニングジョブの VPC 設定のセキュリティグループとサブネットを指定します。プライベート Docker レジストリは、以下のコード例に示すように、指定したセキュリティグループからのインバウンドトラフィックを許可する必要があります。

      ```
      vpc_config = {
          'SecurityGroupIds': ['sg-0123456789abcdef0'],
          'Subnets': ['subnet-0123456789abcdef0','subnet-0123456789abcdef1']
      }
      ```
**注記**  
サブネットがプライベート Docker レジストリと同じ VPC にない場合は、2 つの VPC 間にネットワーク接続を設定する必要があります。詳細については、「[VPC ピアリング](https://docs.aws.amazon.com/vpc/latest/userguide/vpc-peering.html)を使用して VPC を接続する」を参照してください。

   1. 次のコード例に示すように、トレーニングに使用する機械学習コンピューティングインスタンスやストレージボリュームなどのリソース設定を指定します。

      ```
      resource_config = {
          'InstanceType': 'ml.m4.xlarge',
          'InstanceCount': 1,
          'VolumeSizeInGB': 10,
      }
      ```

   1. 次のコード例に示すように、入力および出力データ設定、トレーニングデータセットの保存場所、モデルアーティファクトの保存場所を指定します。

      ```
      input_data_config = [
          {
              "ChannelName": "training",
              "DataSource":
              {
                  "S3DataSource":
                  {
                      "S3DataDistributionType": "FullyReplicated",
                      "S3DataType": "S3Prefix",
                      "S3Uri": "s3://your-training-data-bucket/training-data-folder"
                  }
              }
          }
      ]
      
      output_data_config = {
          'S3OutputPath': 's3://your-output-data-bucket/model-folder'
      }
      ```

   1. 次のコード例に示すように、モデルトレーニングジョブを実行できる最大秒数を指定します。

      ```
      stopping_condition = {
          'MaxRuntimeInSeconds': 1800
      }
      ```

   1. 最後に、次のコード例に示すように、前のステップで指定したパラメータを使用してトレーニングジョブを作成します。

      ```
      import boto3
      sm = boto3.client('sagemaker')
      try:
          resp = sm.create_training_job(
              TrainingJobName=training_job_name,
              AlgorithmSpecification=algorithm_specification,
              RoleArn=execution_role_arn,
              InputDataConfig=input_data_config,
              OutputDataConfig=output_data_config,
              ResourceConfig=resource_config,
              VpcConfig=vpc_config,
              StoppingCondition=stopping_condition
          )
      except Exception as e:
          print(f'error calling CreateTrainingJob operation: {e}')
      else:
          print(resp)
      ```

# SageMaker AI 推定器を使用したトレーニングジョブの実行
<a name="docker-containers-adapt-your-own-private-registry-estimator"></a>

SageMaker Python SDK の[推定器](https://sagemaker.readthedocs.io/en/stable/api/training/estimators.html)を使用して、SageMaker トレーニングジョブの設定と実行を処理することもできます。以下のコード例は、プライベート Docker レジストリからのイメージを使用して推定器を設定および実行する方法を示しています。

1. 次のコード例に示すように、必要なライブラリと依存関係をインポートします。

   ```
   import boto3
   import sagemaker
   from sagemaker.estimator import Estimator
   
   session = sagemaker.Session()
   
   role = sagemaker.get_execution_role()
   ```

1. 次のコード例に示すように、トレーニングイメージ、セキュリティグループ、トレーニングジョブの VPC 設定用サブネットに Uniform Resource Identifier (URI) を指定します。

   ```
   image_uri = "myteam.myorg.com/docker-local/my-training-image:<IMAGE-TAG>"
   
   security_groups = ["sg-0123456789abcdef0"]
   subnets = ["subnet-0123456789abcdef0", "subnet-0123456789abcdef0"]
   ```

   `security_group_ids` および `subnets` の詳細については、SageMaker Python SDK の「[推定器](https://sagemaker.readthedocs.io/en/stable/api/training/estimators.html)」セクションにある該当するパラメータの説明を参照してください。
**注記**  
SageMaker AI は VPC 内のネットワーク接続を使用して Docker レジストリ内のイメージにアクセスします。Docker レジストリ内のイメージをトレーニングに使用するには、レジストリがアカウントの Amazon VPC からアクセス可能である必要があります。

1. 必要に応じて、Docker レジストリで認証が必要な場合は、SageMaker AI にアクセス認証情報を提供する AWS Lambda 関数の Amazon リソースネーム (ARN) も指定する必要があります。次のコード例は、ARN を指定する方法を示しています。

   ```
   training_repository_credentials_provider_arn = "arn:aws:lambda:us-west-2:1234567890:function:test"
   ```

   認証が必要な Docker レジストリでイメージを使用する方法の詳細については、以下の「**Use a Docker registry that requires authentication for training**」を参照してください。

1. 次のコード例に示すように、前のステップのコード例を使用して推定器を設定します。

   ```
   # The training repository access mode must be 'Vpc' for private docker registry jobs 
   training_repository_access_mode = "Vpc"
   
   # Specify the instance type, instance count you want to use
   instance_type="ml.m5.xlarge"
   instance_count=1
   
   # Specify the maximum number of seconds that a model training job can run
   max_run_time = 1800
   
   # Specify the output path for the model artifacts
   output_path = "s3://your-output-bucket/your-output-path"
   
   estimator = Estimator(
       image_uri=image_uri,
       role=role,
       subnets=subnets,
       security_group_ids=security_groups,
       training_repository_access_mode=training_repository_access_mode,
       training_repository_credentials_provider_arn=training_repository_credentials_provider_arn,  # remove this line if auth is not needed
       instance_type=instance_type,
       instance_count=instance_count,
       output_path=output_path,
       max_run=max_run_time
   )
   ```

1. 次のコード例に示すように、ジョブ名と入力パスをパラメータとして使用して `estimator.fit` を呼び出し、トレーニングジョブを開始します。

   ```
   input_path = "s3://your-input-bucket/your-input-path"
   job_name = "your-job-name"
   
   estimator.fit(
       inputs=input_path,
       job_name=job_name
   )
   ```

# トレーニングに認証が必要な Docker レジストリの使用
<a name="docker-containers-adapt-your-own-private-registry-authentication"></a>

Docker レジストリで認証が必要な場合は、SageMaker AI にアクセス認証情報を指定する AWS Lambda 関数を作成する必要があります。次に、トレーニングジョブを作成し、[create\$1training\$1job](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html#SageMaker.Client.create_training_job) API 内でこの Lambda 関数の ARN を指定します。最後に、VPC がインターネット経由でトラフィックを送信せずに Lambda 関数と通信できるように、オプションでインターフェイス VPC エンドポイントを作成できます。次のガイドでは、Lambda 関数を作成し、正しいロールを割り当て、インターフェイス VPC エンドポイントを作成する方法を示しています。

## Lambda 関数を作成する
<a name="docker-containers-adapt-your-own-private-registry-authentication-create-lambda"></a>

アクセス認証情報を SageMaker AI に渡し、レスポンスを返す AWS Lambda 関数を作成します。次のコード例では、次のように Lambda 関数ハンドラーを作成します。

```
def handler(event, context):
   response = {
      "Credentials": {"Username": "username", "Password": "password"}
   }
   return response
```

プライベート Docker レジストリの設定に使用される認証の種類によって、Lambda 関数から返されるレスポンスの内容が次のように決まります。
+ プライベート Docker レジストリが基本認証を使用する場合は、Lambda 関数はレジストリの認証に必要なユーザー名とパスワードを返します。
+ プライベート Docker レジストリが[ベアラートークン認証](https://docs.docker.com/registry/spec/auth/token/)を使用する場合は、ユーザー名とパスワードが認可サーバーに送信され、認可サーバーは、ベアラートークンが返します。その後、このトークンはプライベート Docker レジストリの認証に使用されます。

**注記**  
同じアカウントのレジストリに複数の Lambda 関数があり、トレーニングジョブの実行ロールが同じ場合、レジストリ 1 のトレーニングジョブは他のレジストリの Lambda 関数にアクセスできます。

## Lambda 関数への適切なロールのアクセス許可の付与
<a name="docker-containers-adapt-your-own-private-registry-authentication-lambda-role"></a>

`create_training_job` API で使用する [IAMrole](https://docs.aws.amazon.com/sagemaker/latest/dg/sagemaker-roles.html)には、 AWS Lambda 関数を呼び出すアクセス許可が必要です。次のコード例は、IAM ロールのアクセス許可ポリシーを拡張して、`myLambdaFunction` を呼び出す方法を示しています。

```
{
    "Effect": "Allow",
    "Action": [
        "lambda:InvokeFunction"
    ],
    "Resource": [
        "arn:aws:lambda:*:*:function:*myLambdaFunction*"
    ]
}
```

ロールのアクセス許可ポリシーの編集の詳細については、「*AWS Identity and Access Management ユーザーガイド*」の「[ロールのアクセス許可ポリシーの変更 (コンソール)](https://docs.aws.amazon.com/IAM/latest/UserGuide/roles-managingrole-editing-console.html#roles-modify_permissions-policy)」を参照してください。

**注記**  
**AmazonSageMakerFullAccess** 管理ポリシーがアタッチされている IAM ロールには、名前に「SageMaker AI」を含む任意の Lambda 関数を呼び出すアクセス許可があります。

## Lambda のインターフェイス VPC エンドポイントを作成する
<a name="docker-containers-adapt-your-own-private-registry-authentication-lambda-endpoint"></a>

インターフェイスエンドポイントを作成すると、Amazon VPC がインターネット経由でトラフィックを送信せずに Lambda 関数と通信できます。詳細については、*AWS Lambda デベロッパーガイド*の「[Lambda のインターフェイス VPC エンドポイントの設定](https://docs.aws.amazon.com/lambda/latest/dg/configuration-vpc-endpoints.html)」を参照してください。

インターフェースエンドポイントが作成されると、SageMaker トレーニングは VPC 経由で `lambda.region.amazonaws.com` にリクエストを送信して Lambda 関数を呼び出します。インターフェイスエンドポイントの作成時に **DNS 名の有効化**を選択した場合、Amazon Route 53 は呼び出しを Lambda インターフェイスエンドポイントにルーティングします。別の DNS プロバイダーを使用する場合は、`lambda.region.amazonaws.co`m を Lambda インターフェイスエンドポイントにマッピングする必要があります。

# Amazon SageMaker AI 用に独自の推論コンテナを適応させる
<a name="adapt-inference-container"></a>

ユースケースに [構築済みの SageMaker AI Docker イメージ](docker-containers-prebuilt.md) Amazon SageMaker AI にリストされているイメージを使用できない場合は、独自の Docker コンテナを構築し、SageMaker AI 内でトレーニングと推論に使用できます。SageMaker AI と互換性を持つには、コンテナに次の特性が必要です。
+ コンテナには、ポート `8080` にウェブサーバーのリストが必要です。
+ コンテナは、`/invocations` および `/ping` リアルタイムエンドポイントへの `POST` リクエストを受け入れる必要があります。これらのエンドポイントに送信するリクエストは、通常の応答の場合は 60 秒、ストリーミング応答の場合は 8 分以内に返される必要があり、最大サイズは 25 MB です。

SageMaker AI でのトレーニングと推論用に独自の Docker コンテナを構築する方法の詳細と例については、「[Building your own algorithm container](https://github.com/aws/amazon-sagemaker-examples/blob/main/advanced_functionality/scikit_bring_your_own/scikit_bring_your_own.ipynb)」を参照してください。

次のガイドでは、Amazon SageMaker Studio Classic で `JupyterLab` スペースを使用して、SageMaker AI ホスティングと連携するように推論コンテナを適応させる方法を示します。この例では、NGINX ウェブサーバーである Gunicorn を Python ウェブサーバーゲートウェイインターフェイスとして使用し、Flask をウェブアプリケーションフレームワークとして使用します。前述の要件を満たしている限り、さまざまなアプリケーションを使用してコンテナを適応させることができます。独自の推論コードの使用の詳細については、「[ホスティングサービスでのカスタム推論コードの使用](your-algorithms-inference-code.md)」を参照してください。

**推論コンテナを適応させる**

SageMaker AI ホスティングと連携するように独自の推論コンテナを適応させるには、次のステップを使用します。次の手順に示す例では、`Python` および以下に [spaCy](https://spacy.io/) 自然言語処理 (NLP) ライブラリを使用する、事前トレーニング済みの[名前付きエンティティ認識 (NER) モデル](https://spacy.io/universe/project/video-spacys-ner-model-alt)を使用します。
+ NER モデルを含むコンテナを構築するための Dockerfile。
+ NER モデルを提供する推論スクリプト。

この例をユースケースに適応させる場合は、モデルのデプロイと提供に必要な Dockerfile と推論スクリプトを使用する必要があります。

1. Amazon SageMaker Studio Classic を使用して JupyterLab スペースを作成します (オプション)。

   任意のノートブックを使用してスクリプトを実行し、SageMaker AI ホスティングに推論コンテナを適応させることができます。この例では、Amazon SageMaker Studio Classic 内で JupyterLab スペースを使用して SageMaker AI ディストリビューションイメージに付属する JupyterLab アプリケーションを起動する方法を示します。詳細については、「[SageMaker JupyterLab](studio-updated-jl.md)」を参照してください。

1. Docker ファイルと推論スクリプトをアップロードします。

   1. ホームディレクトリに新しいフォルダを作成します。JupyterLab を使用している場合は、左上隅で **[新しいフォルダ]** アイコンを選択し、Dockerfile を格納するフォルダ名を入力します。この例では、フォルダは `docker_test_folder` という名前です。

   1. Dockerfile テキストファイルを新しいフォルダにアップロードします。以下は、[spaCy](https://spacy.io/) が提供する事前にトレーニング済みの[名前付きエンティティ認識 (NER) モデル](https://spacy.io/universe/project/video-spacys-ner-model)を持つ Docker コンテナを作成する Dockerfile の例、この例を実行するために必要なアプリケーションと環境変数の例です。

      ```
      FROM python:3.8
      
      RUN apt-get -y update && apt-get install -y --no-install-recommends \
               wget \
               python3 \
               nginx \
               ca-certificates \
          && rm -rf /var/lib/apt/lists/*
      
      RUN wget https://bootstrap.pypa.io/get-pip.py && python3 get-pip.py && \
          pip install flask gevent gunicorn && \
              rm -rf /root/.cache
      
      #pre-trained model package installation
      RUN pip install spacy
      RUN python -m spacy download en
      
      
      # Set environment variables
      ENV PYTHONUNBUFFERED=TRUE
      ENV PYTHONDONTWRITEBYTECODE=TRUE
      ENV PATH="/opt/program:${PATH}"
      
      COPY NER /opt/program
      WORKDIR /opt/program
      ```

      前のコード例において、環境変数 `PYTHONUNBUFFERED` は、Python における、ユーザーへのログの高速配信を可能にする標準出力ストリームのバッファリングを防止します。環境変数 `PYTHONDONTWRITEBYTECODE` は、Python における、このユースケースには不要なコンパイルされたバイトコード `.pyc` ファイルの書き込みを防止します。環境変数 `PATH` は、コンテナが呼び出されたときに、`train` および `serve` プログラムの場所を識別するために使用されます。

   1. 新しいフォルダ内に新しいディレクトリを作成し、モデルを提供するスクリプトを含めます。この例では、`NER` というディレクトリを使用します。このディレクトリには、この例を実行するために必要な次のスクリプトが含まれています。
      + `predictor.py` – モデルで推論をロードして実行するロジックを含む Python スクリプト。
      + `nginx.conf` – ウェブサーバーを設定するスクリプト。
      + `serve` – 推論サーバーを起動するスクリプト。
      + `wsgi.py` – モデルを提供するヘルパースクリプト。
**重要**  
推論スクリプトを `.ipynb` で終わるノートブックにコピーして名前を変更すると、スクリプトに、エンドポイントのデプロイを妨げるフォーマット文字が含まれる可能性があります。代わりに、テキストファイルを作成し、名前を変更してください。

   1. スクリプトをアップロードして、モデルを推論で使用できるようにします。以下は、Flask を使用して `/ping` エンドポイントと `/invocations` エンドポイントを提供する、`predictor.py` というスクリプトの例です。

      ```
      from flask import Flask
      import flask
      import spacy
      import os
      import json
      import logging
      
      #Load in model
      nlp = spacy.load('en_core_web_sm') 
      #If you plan to use a your own model artifacts, 
      #your model artifacts should be stored in /opt/ml/model/ 
      
      
      # The flask app for serving predictions
      app = Flask(__name__)
      @app.route('/ping', methods=['GET'])
      def ping():
          # Check if the classifier was loaded correctly
          health = nlp is not None
          status = 200 if health else 404
          return flask.Response(response= '\n', status=status, mimetype='application/json')
      
      
      @app.route('/invocations', methods=['POST'])
      def transformation():
          
          #Process input
          input_json = flask.request.get_json()
          resp = input_json['input']
          
          #NER
          doc = nlp(resp)
          entities = [(X.text, X.label_) for X in doc.ents]
      
          # Transform predictions to JSON
          result = {
              'output': entities
              }
      
          resultjson = json.dumps(result)
          return flask.Response(response=resultjson, status=200, mimetype='application/json')
      ```

      前のスクリプト例の `/ping` エンドポイントは、モデルが正しくロードされた場合は `200`、モデルが正しくロードされていない場合は `404` のステータスコードを返します。`/invocations` エンドポイントは、JSON でフォーマットされたリクエストを処理し、入力フィールドを抽出し、NER モデルを使用して可変エンティティ内のエンティティを識別して保存します。Flask アプリケーションは、これらのエンティティを含むレスポンスを返します。これらの必要なヘルスリクエストの詳細については、「[コンテナがヘルスチェック (Ping) リクエストに応答する方法](your-algorithms-inference-code.md#your-algorithms-inference-algo-ping-requests)」を参照してください。

   1. スクリプトをアップロードして推論サーバーを起動します。次のスクリプト例では、Gunicorn をアプリケーションサーバーとして、Nginx をウェブサーバーとして、`serve` を呼び出します。

      ```
      #!/usr/bin/env python
      
      # This file implements the scoring service shell. You don't necessarily need to modify it for various
      # algorithms. It starts nginx and gunicorn with the correct configurations and then simply waits until
      # gunicorn exits.
      #
      # The flask server is specified to be the app object in wsgi.py
      #
      # We set the following parameters:
      #
      # Parameter                Environment Variable              Default Value
      # ---------                --------------------              -------------
      # number of workers        MODEL_SERVER_WORKERS              the number of CPU cores
      # timeout                  MODEL_SERVER_TIMEOUT              60 seconds
      
      import multiprocessing
      import os
      import signal
      import subprocess
      import sys
      
      cpu_count = multiprocessing.cpu_count()
      
      model_server_timeout = os.environ.get('MODEL_SERVER_TIMEOUT', 60)
      model_server_workers = int(os.environ.get('MODEL_SERVER_WORKERS', cpu_count))
      
      def sigterm_handler(nginx_pid, gunicorn_pid):
          try:
              os.kill(nginx_pid, signal.SIGQUIT)
          except OSError:
              pass
          try:
              os.kill(gunicorn_pid, signal.SIGTERM)
          except OSError:
              pass
      
          sys.exit(0)
      
      def start_server():
          print('Starting the inference server with {} workers.'.format(model_server_workers))
      
      
          # link the log streams to stdout/err so they will be logged to the container logs
          subprocess.check_call(['ln', '-sf', '/dev/stdout', '/var/log/nginx/access.log'])
          subprocess.check_call(['ln', '-sf', '/dev/stderr', '/var/log/nginx/error.log'])
      
          nginx = subprocess.Popen(['nginx', '-c', '/opt/program/nginx.conf'])
          gunicorn = subprocess.Popen(['gunicorn',
                                       '--timeout', str(model_server_timeout),
                                       '-k', 'sync',
                                       '-b', 'unix:/tmp/gunicorn.sock',
                                       '-w', str(model_server_workers),
                                       'wsgi:app'])
      
          signal.signal(signal.SIGTERM, lambda a, b: sigterm_handler(nginx.pid, gunicorn.pid))
      
          # Exit the inference server upon exit of either subprocess
          pids = set([nginx.pid, gunicorn.pid])
          while True:
              pid, _ = os.wait()
              if pid in pids:
                  break
      
          sigterm_handler(nginx.pid, gunicorn.pid)
          print('Inference server exiting')
      
      # The main routine to invoke the start function.
      
      if __name__ == '__main__':
          start_server()
      ```

      前のスクリプト例では、シグナルハンドラー関数 `sigterm_handler` を定義し、`SIGTERM` シグナルを受信したときに Nginx と Gunicorn サブプロセスをシャットダウンします。`start_server` 関数は、シグナルハンドラーを起動し、Nginx および Gunicorn サブプロセスを起動してモニタリングし、ログストリームをキャプチャします。

   1. スクリプトをアップロードしてウェブサーバーを設定します。`nginx.conf` という次のスクリプト例では、Gunicorn をアプリケーションサーバーとして使用して Nginx ウェブサーバーを設定し、推論用のモデルを提供します。

      ```
      worker_processes 1;
      daemon off; # Prevent forking
      
      
      pid /tmp/nginx.pid;
      error_log /var/log/nginx/error.log;
      
      events {
        # defaults
      }
      
      http {
        include /etc/nginx/mime.types;
        default_type application/octet-stream;
        access_log /var/log/nginx/access.log combined;
        
        upstream gunicorn {
          server unix:/tmp/gunicorn.sock;
        }
      
        server {
          listen 8080 deferred;
          client_max_body_size 5m;
      
          keepalive_timeout 5;
          proxy_read_timeout 1200s;
      
          location ~ ^/(ping|invocations) {
            proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
            proxy_set_header Host $http_host;
            proxy_redirect off;
            proxy_pass http://gunicorn;
          }
      
          location / {
            return 404 "{}";
          }
        }
      }
      ```

      前のスクリプト例では、Nginx をフォアグラウンドで実行するように設定し、`error_log` をキャプチャする場所を設定し、`upstream` を Gunicorn サーバーのソケットソックスとして定義します。サーバーは、ポート `8080` をリッスンするようにサーバーブロックを設定し、クライアントリクエスト本文サイズとタイムアウト値に制限を設定します。サーバーブロックは、`/ping` または `/invocations` パスを含むリクエストを Gunicorn `server http://gunicorn` に転送し、他のパスの場合は `404` エラーを返します。

   1. モデルの提供に必要な他のスクリプトをアップロードします。この例では、Gunicorn がアプリケーションを見つけるために、`wsgi.py` という次のスクリプトの例が必要です。

      ```
      import predictor as myapp
      
      # This is just a simple wrapper for gunicorn to find your app.
      # If you want to change the algorithm file, simply change "predictor" above to the
      # new file.
      
      app = myapp.app
      ```

   フォルダ `docker_test_folder` から、ディレクトリ構造に Dockerfile とフォルダ NER が含まれている必要があります。NER フォルダには、次のように `nginx.conf`、`predictor.py`、`serve`、`wsgi.py`ファイルが含まれている必要があります。

    ![\[The Dockerfile structure has inference scripts under the NER directory next to the Dockerfile.\]](http://docs.aws.amazon.com/ja_jp/sagemaker/latest/dg/images/docker-file-struct-adapt-ex.png) 

1. 独自のコンテナを構築します。

   フォルダ `docker_test_folder` から、Docker コンテナを構築します。次のコマンド例では、Dockerfile で設定された Docker コンテナを構築します。

   ```
   ! docker build -t byo-container-test .
   ```

   前のコマンドは、現在の作業ディレクトリに `byo-container-test` というコンテナを構築します。Docker ビルドパラメータの詳細については、「[Build arguments](https://docs.docker.com/build/guide/build-args/)」を参照してください。
**注記**  
Docker が Dockerfile を見つけられないという次のエラーメッセージが表示された場合は、Dockerfile の名前が正しいこと、およびそのディレクトリに保存されていることを確認してください。  

   ```
   unable to prepare context: unable to evaluate symlinks in Dockerfile path:
   lstat /home/ec2-user/SageMaker/docker_test_folder/Dockerfile: no such file or directory
   ```
Docker は、現在のディレクトリ内で拡張子を付けずに、Dockerfile と名付けられたファイルを検索します。別の名前を指定した場合は、-f フラグを付けて手動でファイル名を渡すことができます。例えば、Dockerfile を Dockerfile-text.txt として指定した場合は、次のように `-f` フラグを使用して Docker コンテナを構築し、その後に次のようにファイルを作成します。  

   ```
   ! docker build -t byo-container-test -f Dockerfile-text.txt .
   ```

1. Amazon Elastic Container Registry (Amazon ECR) に Docker イメージをプッシュします

   ノートブックセルで、Docker イメージを ECR にプッシュします。次のコード例は、コンテナをローカルで構築し、ログインして ECR にプッシュする方法を示しています。

   ```
   %%sh
   # Name of algo -> ECR
   algorithm_name=sm-pretrained-spacy
   
   #make serve executable
   chmod +x NER/serve
   account=$(aws sts get-caller-identity --query Account --output text)
   # Region, defaults to us-west-2
   region=$(aws configure get region)
   region=${region:-us-east-1}
   fullname="${account}.dkr.ecr.${region}.amazonaws.com/${algorithm_name}:latest"
   # If the repository doesn't exist in ECR, create it.
   aws ecr describe-repositories --repository-names "${algorithm_name}" > /dev/null 2>&1
   if [ $? -ne 0 ]
   then
       aws ecr create-repository --repository-name "${algorithm_name}" > /dev/nullfi
   # Get the login command from ECR and execute it directly
   aws ecr get-login-password --region ${region}|docker login --username AWS --password-stdin ${fullname}
   # Build the docker image locally with the image name and then push it to ECR
   # with the full name.
   
   docker build  -t ${algorithm_name} .
   docker tag ${algorithm_name} ${fullname}
   
   docker push ${fullname}
   ```

   前の例では、サンプル Docker コンテナを ECR にプッシュするために必要な次のステップを実行する方法を示しています。

   1. アルゴリズム名を `sm-pretrained-spacy` として定義します。

   1. NER フォルダ内の `serve` ファイルを実行可能にします。

   1. を設定します AWS リージョン。

   1. ECR がまだ存在しない場合は、作成します。

   1. ECR にログインします。

   1. Docker コンテナをローカルで構築します。

   1. Docker イメージを ECR にプッシュします。

1. SageMaker AI クライアントのセットアップ

   推論に SageMaker AI ホスティングサービスを使用する場合は、[モデルを作成](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/create_model.html)し、[エンドポイント設定](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/create_endpoint_config.html#)を作成し、[エンドポイントを作成](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker/client/create_endpoint.html#)する必要があります。エンドポイントから推論を取得するには、SageMaker AI boto3 Runtime クライアントを使用してエンドポイントを呼び出します。次のコードは、[SageMaker AI boto3 クライアント](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker.html)を使用して、SageMaker AI クライアントと SageMaker Runtime クライアントの両方を設定する方法を示しています。

   ```
   import boto3
   from sagemaker import get_execution_role
   
   sm_client = boto3.client(service_name='sagemaker')
   runtime_sm_client = boto3.client(service_name='sagemaker-runtime')
   
   account_id = boto3.client('sts').get_caller_identity()['Account']
   region = boto3.Session().region_name
   
   #used to store model artifacts which SageMaker AI will extract to /opt/ml/model in the container, 
   #in this example case we will not be making use of S3 to store the model artifacts
   #s3_bucket = '<S3Bucket>'
   
   role = get_execution_role()
   ```

   前のコード例では、Amazon S3 バケットは使用されませんが、モデルアーティファクトの保存方法を示すコメントとして挿入されています。

   前のコード例を実行した後にアクセス許可エラーが表示された場合は、IAM ロールにアクセス許可を追加する必要がある場合があります。IAM ロールの詳細については、「[Amazon SageMaker Role Manager](role-manager.md)」を参照してください。現在のロールにアクセス許可を追加する方法の詳細については、「[AWS Amazon SageMaker AI の マネージドポリシー](security-iam-awsmanpol.md)」を参照してください。

1. モデルを作成します。

   推論に SageMaker AI ホスティングサービスを使用する場合は、SageMaker AI でモデルを作成する必要があります。次のコード例は、SageMaker AI 内で spaCy NER モデルを作成する方法を示しています。

   ```
   from time import gmtime, strftime
   
   model_name = 'spacy-nermodel-' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
   # MODEL S3 URL containing model atrifacts as either model.tar.gz or extracted artifacts. 
   # Here we are not  
   #model_url = 's3://{}/spacy/'.format(s3_bucket) 
   
   container = '{}.dkr.ecr.{}.amazonaws.com/sm-pretrained-spacy:latest'.format(account_id, region)
   instance_type = 'ml.c5d.18xlarge'
   
   print('Model name: ' + model_name)
   #print('Model data Url: ' + model_url)
   print('Container image: ' + container)
   
   container = {
   'Image': container
   }
   
   create_model_response = sm_client.create_model(
       ModelName = model_name,
       ExecutionRoleArn = role,
       Containers = [container])
   
   print("Model Arn: " + create_model_response['ModelArn'])
   ```

   前のコード例は、ステップ 5 のコメントから Amazon S3 バケットを使用する場合に、`s3_bucket` を使用して `model_url` を定義する方法を示し、コンテナイメージの ECR URI を定義します。前のコード例では、`ml.c5d.18xlarge` をインスタンスタイプとして定義しています。また、別のインスタンスタイプを選択することもできます。使用可能なインスタンスタイプの詳しい情報については、「[Amazon EC2 インスタンスタイプ](https://aws.amazon.com/ec2/instance-types/)」をご参照ください。

   前のコード例では、`Image` キーはコンテナイメージ URI を指します。`create_model_response` 定義は `create_model method` を使用してモデルを作成し、モデル名、ロール、コンテナ情報を含むリストを返します。

   前のスクリプトからの出力例を次に示します。

   ```
   Model name: spacy-nermodel-YYYY-MM-DD-HH-MM-SS
   Model data Url: s3://spacy-sagemaker-us-east-1-bucket/spacy/
   Container image: 123456789012.dkr.ecr.us-east-2.amazonaws.com/sm-pretrained-spacy:latest
   Model Arn: arn:aws:sagemaker:us-east-2:123456789012:model/spacy-nermodel-YYYY-MM-DD-HH-MM-SS
   ```

1. 

   1. 

**エンドポイントの設定と作成**

      推論に SageMaker AI ホスティングを使用するには、エンドポイントも設定して作成する必要があります。SageMaker AI はこのエンドポイントを推論に使用します。次の設定例は、以前に定義したインスタンスタイプとモデル名を使用してエンドポイントを生成および設定する方法を示しています。

      ```
      endpoint_config_name = 'spacy-ner-config' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
      print('Endpoint config name: ' + endpoint_config_name)
      
      create_endpoint_config_response = sm_client.create_endpoint_config(
          EndpointConfigName = endpoint_config_name,
          ProductionVariants=[{
              'InstanceType': instance_type,
              'InitialInstanceCount': 1,
              'InitialVariantWeight': 1,
              'ModelName': model_name,
              'VariantName': 'AllTraffic'}])
              
      print("Endpoint config Arn: " + create_endpoint_config_response['EndpointConfigArn'])
      ```

      前の設定例では、`create_endpoint_config_response` は `model_name` を、タイムスタンプで作成された `endpoint_config_name` という一意のエンドポイント設定名に関連付けます。

      前のスクリプトからの出力例を次に示します。

      ```
      Endpoint config name: spacy-ner-configYYYY-MM-DD-HH-MM-SS
      Endpoint config Arn: arn:aws:sagemaker:us-east-2:123456789012:endpoint-config/spacy-ner-config-MM-DD-HH-MM-SS
      ```

      エンドポイントエラーの詳細については、「[Why does my Amazon SageMaker AI endpoint go into the failed state when I create or update an endpoint?](https://repost.aws/knowledge-center/sagemaker-endpoint-creation-fail)」を参照してください。

   1. 

**エンドポイントを作成し、エンドポイントが稼働するのを待ちます。**

       次のコード例では、前の設定例の設定を使用してエンドポイントを作成し、モデルをデプロイします。

      ```
      %%time
      
      import time
      
      endpoint_name = 'spacy-ner-endpoint' + strftime("%Y-%m-%d-%H-%M-%S", gmtime())
      print('Endpoint name: ' + endpoint_name)
      
      create_endpoint_response = sm_client.create_endpoint(
          EndpointName=endpoint_name,
          EndpointConfigName=endpoint_config_name)
      print('Endpoint Arn: ' + create_endpoint_response['EndpointArn'])
      
      resp = sm_client.describe_endpoint(EndpointName=endpoint_name)
      status = resp['EndpointStatus']
      print("Endpoint Status: " + status)
      
      print('Waiting for {} endpoint to be in service...'.format(endpoint_name))
      waiter = sm_client.get_waiter('endpoint_in_service')
      waiter.wait(EndpointName=endpoint_name)
      ```

      前のコード例では、`create_endpoint` メソッドは前のコード例で作成した生成されたエンドポイント名を使用してエンドポイントを作成し、エンドポイントの Amazon リソースネームを出力します。`describe_endpoint` メソッドは、エンドポイントとそのステータスに関する情報を返します。SageMaker AI ウェーターは、エンドポイントが稼働するのを待ちます。

1. エンドポイントをテストします。

   エンドポイントが稼働したら、エンドポイントに[呼び出しリクエスト](https://boto3.amazonaws.com/v1/documentation/api/1.9.42/reference/services/sagemaker-runtime.html#SageMakerRuntime.Client.invoke_endpoint)を送信します。次のコード例は、エンドポイントにテストリクエストを送信する方法を示しています。

   ```
   import json
   content_type = "application/json"
   request_body = {"input": "This is a test with NER in America with \
       Amazon and Microsoft in Seattle, writing random stuff."}
   
   #Serialize data for endpoint
   #data = json.loads(json.dumps(request_body))
   payload = json.dumps(request_body)
   
   #Endpoint invocation
   response = runtime_sm_client.invoke_endpoint(
   EndpointName=endpoint_name,
   ContentType=content_type,
   Body=payload)
   
   #Parse results
   result = json.loads(response['Body'].read().decode())['output']
   result
   ```

   前のコード例では、メソッド `json.dumps` は `request_body` を JSON でフォーマットされた文字列にシリアル化し、可変ペイロードに保存します。次に、SageMaker AI Runtime クライアントは、[呼び出しエンドポイント](https://boto3.amazonaws.com/v1/documentation/api/latest/reference/services/sagemaker-runtime/client/invoke_endpoint.html)メソッドを使用して、エンドポイントにペイロードを送信します。結果には、出力フィールドを抽出した後のエンドポイントからのレスポンスが含まれます。

   前のコード例では、次の出力が返されます。

   ```
   [['NER', 'ORG'],
    ['America', 'GPE'],
    ['Amazon', 'ORG'],
    ['Microsoft', 'ORG'],
    ['Seattle', 'GPE']]
   ```

1. エンドポイントの削除

   呼び出しが完了したら、エンドポイントを削除してリソースを節約します。次のコード例は、エンドポイントを削除する方法を示しています。

   ```
   sm_client.delete_endpoint(EndpointName=endpoint_name)
   sm_client.delete_endpoint_config(EndpointConfigName=endpoint_config_name)
   sm_client.delete_model(ModelName=model_name)
   ```

   この例のコードを含む完全なノートブックについては、[BYOC-Single-Model](https://github.com/aws-samples/sagemaker-hosting/tree/main/Bring-Your-Own-Container/BYOC-Single-Model) を参照してください。