

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

# Amazon SageMaker AI でのモデルデプロイ用のモデルサーバー
<a name="deploy-model-frameworks"></a>

TorchServe、DJL Serving、Triton Inference Server などの一般的なモデルサーバーを使用して、SageMaker AI でモデルをデプロイできます。次のトピックでは、その方法を説明します。

**Topics**
+ [TorchServe を使用したモデルのデプロイ](deploy-models-frameworks-torchserve.md)
+ [DJL サービングを使用したモデルのデプロイ](deploy-models-frameworks-djl-serving.md)
+ [Triton Inference Server によるモデルのデプロイ](deploy-models-frameworks-triton.md)

# TorchServe を使用したモデルのデプロイ
<a name="deploy-models-frameworks-torchserve"></a>

TorchServe は、 AWS PyTorch 深層学習コンテナ (DLC) にプリインストールされた PyTorch 用の推奨モデルサーバーです。この強力なツールは、モデルのサイズやディストリビューションに関係なく、CPU、GPU、Neuron、Graviton などのさまざまな AWS インスタンスに複数の PyTorch モデルをデプロイする際に高いパフォーマンスを提供し、一貫性のあるユーザーフレンドリーなエクスペリエンスをお客様に提供します。

TorchServe は、動的バッチ処理、マイクロバッチ処理、モデル A/B テスト、ストリーミング、トーチ XLA、TensorRT、ONNX、IPEX など、さまざまな高度な機能をサポートしています。さらに、PyTorch の大規模モデルソリューションである PiPPy をシームレスに統合できるため、大規模モデルを効率的に処理できます。また、TorchServe は、DeepSpeed、Accelerate、Fast Transformers などの一般的なオープンソースライブラリにもサポートを拡張し、その機能をさらに拡張しています。TorchServe を使用すると、 AWS ユーザーは PyTorch モデルを確実にデプロイして提供できるため、さまざまなハードウェア設定やモデルタイプで汎用性と最適化されたパフォーマンスを活用できます。詳細な情報については、「[PyTorch のドキュメント](https://pytorch.org/serve/)」と「[GitHub の TorchServe](https://github.com/pytorch/serve)」を参照してください。

次の表に、 AWS TorchServe でサポートされている PyTorch TorchServe DLCs を示します。


| インスタンスタイプ | SageMaker AI PyTorch DLC リンク | 
| --- | --- | 
| CPU および GPU | [SageMaker AI PyTorch コンテナ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only) | 
| Neuron | [PyTorch Neuron コンテナ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#neuron-containers) | 
| Graviton | [SageMaker AI PyTorch Graviton コンテナ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-graviton-containers-sm-support-only) | 

以下のセクションでは、Amazon SageMaker AI で PyTorch DLC をビルドしてテストするためのセットアップについて説明します。

## 開始方法
<a name="deploy-models-frameworks-torchserve-prereqs"></a>

開始するには、次の前提条件が整っていることを確認してください。

1.  AWS アカウントにアクセスできることを確認します。が IAM ユーザーまたは IAM AWS ロールを介してアカウント AWS CLI にアクセスできるように環境を設定します。IAM ロールの使用をお勧めします。個人アカウントでテストする目的で、以下の管理アクセス許可ポリシーを IAM ロールにアタッチできます。
   + [AmazonEC2ContainerRegistryFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess)
   + [AmazonEC2FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2FullAccess)
   + [AWS ServiceRoleForAmazonEKSNodegroup](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AWSServiceRoleForAmazonEKSNodegroup)
   + [AmazonSageMakerFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonSageMakerFullAccess)
   + [AmazonS3FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonS3FullAccess)

1. 次の例のように、依存関係をローカルに設定します。

   ```
   from datetime import datetime
       import os
       import json
       import logging
       import time
       
       # External Dependencies:
       import boto3
       from botocore.exceptions import ClientError
       import sagemaker
       
       sess = boto3.Session()
       sm = sess.client("sagemaker")
       region = sess.region_name
       account = boto3.client("sts").get_caller_identity().get("Account")
       
       smsess = sagemaker.Session(boto_session=sess)
       role = sagemaker.get_execution_role()
       
       # Configuration:
       bucket_name = smsess.default_bucket()
       prefix = "torchserve"
       output_path = f"s3://{bucket_name}/{prefix}/models"
       print(f"account={account}, region={region}, role={role}")
   ```

1. 次の例に示すように、PyTorch の DLC イメージを取得します。

   SageMaker AI PyTorch DLC イメージは、すべての AWS リージョンで利用できます。詳細については、「[DLC コンテナイメージのリスト](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#sagemaker-framework-containers-sm-support-only)」を参照してください。

   ```
   baseimage = sagemaker.image_uris.retrieve(
           framework="pytorch",
           region="<region>",
           py_version="py310",
           image_scope="inference",
           version="2.0.1",
           instance_type="ml.g4dn.16xlarge",
       )
   ```

1. ローカルワークスペースの作成

   ```
   mkdir -p workspace/
   ```

## パッケージの追加
<a name="deploy-models-frameworks-torchserve-package"></a>

以下のセクションでは、PyTorch DLC イメージにパッケージを追加および事前インストールする方法について説明します。

**BYOC のユースケース**

以下の手順は、PyTorch DLC イメージにパッケージを追加する方法を示しています。コンテナのカスタマイズの詳細については、[AWS 「深層学習コンテナのカスタムイメージの構築](https://github.com/aws/deep-learning-containers/blob/master/custom_images.md)」を参照してください。

1. PyTorch DLC Docker イメージにパッケージを追加するとします。次の例に示すように、`docker` ディレクトリの下に Dockerfile を作成します。

   ```
   mkdir -p workspace/docker
       cat workspace/docker/Dockerfile
       
       ARG BASE_IMAGE
       
       FROM $BASE_IMAGE
       
       #Install any additional libraries
       RUN pip install transformers==4.28.1
   ```

1. 次の [build\$1and\$1push.sh](https://github.com/aws/amazon-sagemaker-examples/blob/main/inference/torchserve/mme-gpu/workspace/docker/build_and_push.sh) スクリプトを使用して、カスタマイズした Docker イメージをビルドして公開します。

   ```
   # Download script build_and_push.sh to workspace/docker
       ls workspace/docker
       build_and_push.sh  Dockerfile
       
       # Build and publish your docker image
       reponame = "torchserve"
       versiontag = "demo-0.1"
       
       ./build_and_push.sh {reponame} {versiontag} {baseimage} {region} {account}
   ```

**SageMaker AI プリインストールのユースケース**

次の例は、PyTorch DLC コンテナにパッケージをプリインストールする方法を示しています。`requirements.txt` ファイルはディレクトリ `workspace/code` の下にローカルに作成する必要があります。

```
mkdir -p workspace/code
    cat workspace/code/requirements.txt
    
    transformers==4.28.1
```

## TorchServe モデルアーティファクトの作成
<a name="deploy-models-frameworks-torchserve-artifacts"></a>

次の例では、事前トレーニング済みの [MNIST モデル](https://github.com/pytorch/serve/tree/master/examples/image_classifier/mnist)を使用します。ディレクトリ `workspace/mnist` を作成し、[TorchServe カスタムサービスの手順](https://github.com/pytorch/serve/blob/master/docs/custom_service.md#custom-service)に従って [mnist\$1handler.py](https://github.com/pytorch/serve/blob/master/examples/image_classifier/mnist/mnist_handler.py) を実装し、[model-config.yaml](https://github.com/aws/amazon-sagemaker-examples/blob/main/inference/torchserve/mme-gpu/workspace/lama/model-config.yaml) で[モデルパラメータを設定](https://github.com/pytorch/serve/tree/master/model-archiver#config-file) (バッチサイズやワーカーなど) します。次に、TorchServe ツール `torch-model-archiver` を使用してモデルアーティファクトを構築し、Amazon S3 にアップロードします。

1. `model-config.yaml` でモデルパラメータを設定します。

   ```
   ls -al workspace/mnist-dev
       
       mnist.py
       mnist_handler.py
       mnist_cnn.pt
       model-config.yaml
       
       # config the model
       cat workspace/mnist-dev/model-config.yaml
       minWorkers: 1
       maxWorkers: 1
       batchSize: 4
       maxBatchDelay: 200
       responseTimeout: 300
   ```

1. [torch-model-archiver](https://github.com/pytorch/serve/tree/master/model-archiver#torch-model-archiver-for-torchserve) を使用してモデルアーティファクトを構築します。

   ```
   torch-model-archiver --model-name mnist --version 1.0 --model-file workspace/mnist-dev/mnist.py --serialized-file workspace/mnist-dev/mnist_cnn.pt --handler workspace/mnist-dev/mnist_handler.py --config-file workspace/mnist-dev/model-config.yaml --archive-format tgz
   ```

   パッケージをプリインストールする場合は、`code` ディレクトリを `tar.gz` ファイルに含める必要があります。

   ```
   cd workspace
       torch-model-archiver --model-name mnist --version 1.0 --model-file mnist-dev/mnist.py --serialized-file mnist-dev/mnist_cnn.pt --handler mnist-dev/mnist_handler.py --config-file mnist-dev/model-config.yaml --archive-format no-archive
       
       cd mnist
       mv ../code .
       tar cvzf mnist.tar.gz .
   ```

1. `mnist.tar.gz` を Amazon S3 にアップロードします。

   ```
   # upload mnist.tar.gz to S3
       output_path = f"s3://{bucket_name}/{prefix}/models"
       aws s3 cp mnist.tar.gz {output_path}/mnist.tar.gz
   ```

## 単一モデルのエンドポイントを使用した TorchServe でのデプロイ
<a name="deploy-models-frameworks-torchserve-single-model"></a>

次の例は、[Amazon SageMaker Python SDK](https://sagemaker.readthedocs.io/en/stable/) を使用して、[単一モデルのリアルタイム推論エンドポイント](https://docs.aws.amazon.com/sagemaker/latest/dg/realtime-endpoints-deployment.html)を作成し、そのモデルをエンドポイントにデプロイし、エンドポイントをテストする方法を示しています。

```
from sagemaker.model import Model
    from sagemaker.predictor import Predictor
    
    # create the single model endpoint and deploy it on SageMaker AI
    model = Model(model_data = f'{output_path}/mnist.tar.gz', 
                  image_uri = baseimage,
                  role = role,
                  predictor_cls = Predictor,
                  name = "mnist",
                  sagemaker_session = smsess)
                  
    endpoint_name = 'torchserve-endpoint-' + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())
    predictor = model.deploy(instance_type='ml.g4dn.xlarge',
                             initial_instance_count=1,
                             endpoint_name = endpoint_name,
                             serializer=JSONSerializer(),
                             deserializer=JSONDeserializer())  
                             
    # test the endpoint
    import random
    import numpy as np
    dummy_data = {"inputs": np.random.rand(16, 1, 28, 28).tolist()}
    
    res = predictor.predict(dummy_data)
```

## マルチモデルエンドポイントを使用した TorchServe でのデプロイ
<a name="deploy-models-frameworks-torchserve-multi-model"></a>

[マルチモデルエンドポイント](https://docs.aws.amazon.com/sagemaker/latest/dg/multi-model-endpoints.html)は、1 つのエンドポイントの背後で多数のモデルをホスティングするためのスケーラブルで費用対効果の高いソリューションです。同じリソースのフリートとサービングコンテナを共有し、すべてのモデルをホストすることで、エンドポイントの使用率を向上させます。また、SageMaker AI はモデルのロードとアンロードを動的に管理し、トラフィックパターンに基づいてリソースをスケーリングするため、デプロイのオーバーヘッドも削減されます。マルチモデルエンドポイントは、処理能力の高速化を必要とする深層学習や生成系 AI モデルに特に役立ちます。

SageMaker AI マルチモデルエンドポイント上で TorchServe を使用すると、SageMaker AI マルチモデルエンドポイントが提供するリソース共有や簡素化されたモデル管理を活用しながら、使い慣れたサービングスタックを使用して開発をスピードアップできます。

次の例は、[Amazon SageMaker Python SDK](https://sagemaker.readthedocs.io/en/stable/) を使用してマルチモデルエンドポイントを作成し、そのモデルをエンドポイントにデプロイし、エンドポイントをテストする方法を示しています。その他の詳細については、この「[ノートブックサンプル](https://github.com/aws/amazon-sagemaker-examples/blob/main/inference/torchserve/mme-gpu/torchserve_multi_model_endpoint.ipynb)」を参照してください。

```
from sagemaker.multidatamodel import MultiDataModel
    from sagemaker.model import Model
    from sagemaker.predictor import Predictor
    
    # create the single model endpoint and deploy it on SageMaker AI
    model = Model(model_data = f'{output_path}/mnist.tar.gz', 
                  image_uri = baseimage,
                  role = role,
                  sagemaker_session = smsess)
                  
    endpoint_name = 'torchserve-endpoint-' + time.strftime("%Y-%m-%d-%H-%M-%S", time.gmtime())
    mme = MultiDataModel(
        name = endpoint_name,
        model_data_prefix = output_path,
        model = model,
        sagemaker_session = smsess)
    
    mme.deploy(
        initial_instance_count = 1,
        instance_type = "ml.g4dn.xlarge",
        serializer=sagemaker.serializers.JSONSerializer(),
        deserializer=sagemaker.deserializers.JSONDeserializer())
    
    # list models
    list(mme.list_models())
    
    # create mnist v2 model artifacts
    cp mnist.tar.gz mnistv2.tar.gz
    
    # add mnistv2
    mme.add_model(mnistv2.tar.gz)
    
    # list models
    list(mme.list_models())
    
    predictor = Predictor(endpoint_name=mme.endpoint_name, sagemaker_session=smsess)
                             
    # test the endpoint
    import random
    import numpy as np
    dummy_data = {"inputs": np.random.rand(16, 1, 28, 28).tolist()}
    
    res = predictor.predict(date=dummy_data, target_model="mnist.tar.gz")
```

## メトリクス
<a name="deploy-models-frameworks-torchserve-metrics"></a>

TorchServe は、システムレベルとモデルレベルの両方のメトリクスをサポートします。環境変数 `TS_METRICS_MODE` を介して、ログ形式モードまたは Prometheus モードのいずれかでメトリクスを有効にできます。TorchServe セントラルメトリクス設定ファイル `metrics.yaml` を使用して、リクエスト数、レイテンシー、メモリ使用量、GPU 使用率など、追跡するメトリクスのタイプを指定できます。このファイルを参照することで、デプロイされたモデルのパフォーマンスと状態に関するインサイトが得られ、TorchServer サーバーの動作をリアルタイムで効果的にモニタリングできます。詳細については、「[TorchServe メトリクスのドキュメント](https://github.com/pytorch/serve/blob/master/docs/metrics.md#torchserve-metrics)」を参照してください。

Amazon CloudWatch ログフィルターを介して StatsD 形式に似た TorchServe メトリクスログにアクセスできます。TorchServe メトリクスログの例を次に示します。

```
CPUUtilization.Percent:0.0|#Level:Host|#hostname:my_machine_name,timestamp:1682098185
    DiskAvailable.Gigabytes:318.0416717529297|#Level:Host|#hostname:my_machine_name,timestamp:1682098185
```

# DJL サービングを使用したモデルのデプロイ
<a name="deploy-models-frameworks-djl-serving"></a>

DJL Serving は、高性能のユニバーサルスタンドアロンモデル提供ソリューションです。深層学習モデル、複数のモデル、またはワークフローをとり、HTTP エンドポイントを介して利用できるようにします。

DJL Serving [深層学習コンテナ (DLC)](https://docs.aws.amazon.com/deep-learning-containers/latest/devguide/what-is-dlc.html) のいずれかを使用して、 AWS上でモデルを提供できます。サポートされているモデルタイプとフレームワークについては、「[DJL Serving GitHub リポジトリ](https://github.com/deepjavalibrary/djl-serving)」を参照してください。

DJL Serving は、モデルを高パフォーマンスでデプロイするのに役立つ多くの特徴量を提供します。
+ 使いやすさ — DJL Serving はほとんどのモデルを変更せずに使用できます。モデルのアーティファクトを持ち込むと、DJL Serving がそれらをホストできます。
+ 複数のデバイスとアクセラレーターのサポート – DJL Serving は CPUs、GPUs、および AWS Inferentia へのモデルのデプロイをサポートしています。
+ パフォーマンス — DJL Serving は 1 台の Java 仮想マシン (JVM) でマルチスレッド推論を実行し、スループットを向上させます。
+ 動的バッチ処理 — DJL Serving は動的バッチ処理をサポートし、スループットを向上させます。
+ 自動スケーリング — DJL Serving は、トラフィックの負荷に応じてワーカーを自動的にスケールアップまたはスケールダウンします。
+ マルチエンジンサポート — DJL Serving は、異なるフレームワーク (PyTorch や TensorFlow など) を使用してモデルを同時にホストできます。
+ アンサンブルモデルとワークフローモデル — DJL Serving は、複数のモデルで構成される複雑なワークフローのデプロイをサポートし、ワークフローの一部を CPU で、他の部分を GPU で実行できます。ワークフロー内のモデルは、さまざまなフレームワークを活用できます。

以下のセクションでは、SageMaker AI で DJL Serving を使用してエンドポイントを設定する方法について説明します。

## 開始方法
<a name="deploy-models-frameworks-djl-prereqs"></a>

開始するには、次の前提条件が整っていることを確認してください。

1.  AWS アカウントにアクセスできることを確認します。が IAM ユーザーまたは IAM AWS ロールを介してアカウント AWS CLI にアクセスできるように環境を設定します。IAM ロールの使用をお勧めします。個人アカウントでテストする目的で、以下の管理アクセス許可ポリシーを IAM ロールにアタッチできます。
   + [AmazonEC2ContainerRegistryFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2ContainerRegistryFullAccess)
   + [AmazonEC2FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonEC2FullAccess)
   + [AmazonSageMakerFullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonSageMakerFullAccess)
   + [AmazonS3FullAccess](https://console.aws.amazon.com/iam/home#policies/arn:aws:iam::aws:policy/AmazonS3FullAccess)

1. システムに [Docker](https://docs.docker.com/get-docker/) クライアントがセットアップされていることを確認します。

1. Amazon Elastic Container Registry にログインし、以下の環境変数を設定します。

   ```
   export ACCOUNT_ID=<your_account_id>
   export REGION=<your_region>
   aws ecr get-login-password --region $REGION | docker login --username AWS --password-stdin $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com
   ```

1. Docker イメージをプルします。

   ```
   docker pull 763104351884.dkr.ecr.us-west-2.amazonaws.com/djl-inference:0.22.1-deepspeed0.9.2-cu118
   ```

   使用可能なすべての DJL Serving コンテナイメージについては、「[大規模モデル推論コンテナ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#large-model-inference-containers)」と「[DJL Serving CPU 推論コンテナ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#djl-cpu-full-inference-containers)」を参照してください。上記のリンクのテーブルからイメージを選択するときは、URL 列の例の AWS リージョンを、現在使用しているリージョンに置き換えます。DLC は、「[使用可能な深層学習コンテナイメージ](https://github.com/aws/deep-learning-containers/blob/master/available_images.md)」ページの上部にある表に記載されているリージョンで使用できます。

## コンテナのカスタマイズ
<a name="deploy-models-frameworks-djl-byoc"></a>

ベース DLC イメージにパッケージを追加して、コンテナをカスタマイズできます。`763104351884.dkr.ecr.us-west-2.amazonaws.com/djl-inference:0.22.1-deepspeed0.9.2-cu118` Docker イメージにパッケージを追加したいとします。目的のイメージをベースイメージとして Dockerfile を作成し、必要なパッケージを追加して、そのイメージを Amazon ECR にプッシュする必要があります。

パッケージを作成するには、次のステップを実行します。

1. ベースイメージの Dockerfile に、目的のライブラリまたはパッケージを実行する手順を指定します。

   ```
   FROM 763104351884.dkr.ecr.us-west-2.amazonaws.com/djl-inference:0.22.1-deepspeed0.9.2-cu118
                           
   ## add custom packages/libraries
   RUN git clone https://github.com/awslabs/amazon-sagemaker-examples
   ```

1. Dockerfile から Docker イメージをビルドします。Amazon ECR リポジトリ、ベースイメージの名前、およびイメージのタグを指定します。Amazon ECR リポジトリがない場合は、「*Amazon ECR ユーザーガイド*」の「[AWS CLIで Amazon ECR を使用する](https://docs.aws.amazon.com/AmazonECR/latest/userguide/getting-started-cli.html)」を参照して、リポジトリを作成する方法を確認してください。

   ```
   docker build -f Dockerfile -t <registry>/<image_name>:<image_tag>
   ```

1. Amazon ECR リポジトリに Docker イメージをプッシュします

   ```
   docker push $ACCOUNT_ID.dkr.ecr.$REGION.amazonaws.com/<image_name>:<image_tag>
   ```

これで、モデル提供に使用できるカスタマイズされたコンテナイメージがあるはずです。コンテナをカスタマイズするその他の例については、「[Building AWS Deep Learning Containers Custom Images](https://github.com/aws/deep-learning-containers/blob/master/custom_images.md)」を参照してください。

## モデルのアーティファクトの準備
<a name="deploy-models-frameworks-djl-artifacts"></a>

SageMaker AI にモデルをデプロイする前に、モデルアーティファクトを `.tar.gz` ファイルにパッケージ化する必要があります。DJL Serving はアーカイブ内の以下のアーティファクトを受け入れます。
+ モデルチェックポイント: モデルの重みを格納するファイル。
+ `serving.properties`: モデルごとに追加できる設定ファイル。モデルファイルと同じディレクトリに `serving.properties` を置きます。
+ `model.py`: 推論ハンドラーコード。これは Python モードを使用する場合にのみ適用されます。`model.py` を指定しない場合、djl-serving はデフォルトハンドラーの 1 つを使用します。

以下は、`model.tar.gz` 構造の例です。

```
 - model_root_dir # root directory
    - serving.properties            
    - model.py # your custom handler file for Python, if you choose not to use the default handlers provided by DJL Serving
    - model binary files # used for Java mode, or if you don't want to use option.model_id and option.s3_url for Python mode
```

DJL Serving は、DJL または Python エンジンを搭載した Java エンジンをサポートします。前述のアーティファクトのすべてが必須というわけではありません。必要なアーティファクトは、選択するモードによって異なります。例えば、Python モードでは、`serving.properties` ファイル内で `option.model_id` を指定するだけでよく、LMI コンテナ内のモデルチェックポイントを指定する必要はありません。Java モードでは、モデルチェックポイントをパッケージ化する必要があります。`serving.properties` の設定とさまざまなエンジンの操作方法の詳細については、「[DJL Serving 操作モード](https://github.com/deepjavalibrary/djl-serving/blob/master/serving/docs/modes.md)」を参照してください。

## 単一モデルのエンドポイントを使用した DJL Serving でのデプロイ
<a name="deploy-models-frameworks-djl-single-model"></a>

モデルアーティファクトを準備したら、モデルを SageMaker AI エンドポイントにデプロイできます。このセクションでは、DJL Serving を使用して、単一モデルを、エンドポイントにデプロイする方法について説明します。複数のモデルをデプロイする場合は、このセクションをスキップして 「[マルチモデルのエンドポイントを使用して DJL Serving でデプロイする](#deploy-models-frameworks-djl-mme)」に進んでください。

次の例は、Amazon SageMaker Python SDK を使用してモデルオブジェクトを作成する方法を示します。以下のフィールドを指定する必要があります。
+ `image_uri`: この例で示すように、ベースの DJL Serving イメージの 1 つを取得することも、「[コンテナのカスタマイズ](#deploy-models-frameworks-djl-byoc)」の手順に従って Amazon ECR リポジトリからカスタム Docker イメージを指定することもできます。
+ `model_s3_url`: これは `.tar.gz` ファイルを指す Amazon S3 URI である必要があります。
+ `model_name`: モデルオブジェクトの名前を指定します。

```
import boto3
 import sagemaker
from sagemaker.model import Model
from sagemaker import image_uris, get_execution_role

aws_region = "aws-region"
sagemaker_session = sagemaker.Session(boto_session=boto3.Session(region_name=aws_region))
role = get_execution_role()

def create_model(model_name, model_s3_url):
    # Get the DJL DeepSpeed image uri
    image_uri = image_uris.retrieve(
        framework="djl-deepspeed",
        region=sagemaker_session.boto_session.region_name,
        version="0.20.0"
    )
    model = Model(
        image_uri=image_uri,
        model_data=model_s3_url,
        role=role,
        name=model_name,
        sagemaker_session=sagemaker_session,
    )
    return model
```

## マルチモデルのエンドポイントを使用して DJL Serving でデプロイする
<a name="deploy-models-frameworks-djl-mme"></a>

複数のモデルをエンドポイントにデプロイする場合、SageMaker AI はマルチモデルエンドポイントを提供しており、これは、多数のモデルをデプロイするためのスケーラブルで費用対効果の高いソリューションです。DJL Serving は、複数のモデルを同時にロードし、各モデルで同時に推論を実行することもサポートしています。DJL Serving コンテナは SageMaker AI マルチモデルエンドポイント契約に準拠しており、マルチモデルエンドポイントのデプロイに使用できます。

個々のモデルアーティファクトは、前のセクション「[モデルのアーティファクトの準備](#deploy-models-frameworks-djl-artifacts)」で説明したのと同じ方法でパッケージ化する必要があります。モデル固有の設定を `serving.properties` ファイルに、モデル固有の推論ハンドラーコードを `model.py` に設定できます。マルチモデルエンドポイントの場合、モデルは次のように配置する必要があります。

```
 root_dir
        |-- model_1.tar.gz
        |-- model_2.tar.gz
        |-- model_3.tar.gz
            .
            .
            .
```

Amazon SageMaker Python SDK は、[MultiDataModel](https://sagemaker.readthedocs.io/en/stable/api/inference/multi_data_model.html) オブジェクトを使用してマルチモデルエンドポイントをインスタンス化します。ルートディレクトリの Amazon S3 URI は、`model_data_prefix` 引数として `MultiDataModel` コンストラクターに渡す必要があります。

DJL Serving には、モデルのメモリ要件を管理するための複数の設定パラメータ (`required_memory_mb` や `reserved_memory_mb` など) も用意されており、[serving.properties](https://github.com/deepjavalibrary/djl-serving/blob/master/serving/docs/modes.md#servingproperties) ファイルでモデルごとに設定できます。これらのパラメータは、メモリ不足エラーをより適切に処理するのに役立ちます。設定可能なすべてのパラメータについては、「[djl-serving での OutofMemory 処理](https://github.com/deepjavalibrary/djl-serving/blob/master/serving/docs/out_of_memory_management.md)」を参照してください。

DJL Serving の自動スケーリング機能により、受信トラフィックに合わせてモデルが適切にスケールされることを簡単に確認できます。デフォルトでは、DJL Serving は、使用可能なハードウェア (CPU コアや GPU デバイスなど) に基づいて、サポート可能なモデルの最大ワーカー数を決定します。モデルごとに下限と上限を設定して、常にトラフィックの最小レベルを処理できるようにし、1 つのモデルが使用可能なリソースをすべて消費しないようにできます。[serving.properties](https://github.com/deepjavalibrary/djl-serving/blob/master/serving/docs/modes.md#servingproperties) ファイルでは、以下のプロパティを設定できます。
+ `gpu.minWorkers`: GPU の最小ワーカー数。
+ `gpu.maxWorkers`: GPU の最大ワーカー数。
+ `cpu.minWorkers`: CPU の最小ワーカー数。
+ `cpu.maxWorkers`: CPU の最大ワーカー数。

DJL サービングコンテナを使用して SageMaker AI にマルチモデルエンドポイントをデプロイする方法のエンドツーエンドの例については、サンプルノートブック「[Multi-model-Inference-Demo.ipynb](https://github.com/deepjavalibrary/djl-demo/blob/master/aws/sagemaker/Multi-Model-Inference-Demo.ipynb)」を参照してください。

# Triton Inference Server によるモデルのデプロイ
<a name="deploy-models-frameworks-triton"></a>

[Triton 推論サーバーは](https://github.com/triton-inference-server/server) AI 推論を効率化するオープンソースの推論サービングソフトウェアです。Triton を使用すると、TensorRT、TensorFlow、PyTorch、ONNX、OpenVINO、Python、RAPIDS FIL など、複数の深層学習および機械学習フレームワークで構築されたあらゆるモデルをデプロイできます。

SageMaker AI Triton コンテナは、SageMaker AI ホスティングプラットフォーム上に Triton 推論サーバーをデプロイし、トレーニング済みモデルを本番環境で提供するのに役立ちます。SageMaker AI が動作するさまざまなモードをサポートしています。SageMaker AI で使用可能な Triton 推論サーバーコンテナのリストについては、「[NVIDIA Triton Inference Containers (SM support only)](https://github.com/aws/deep-learning-containers/blob/master/available_images.md#nvidia-triton-inference-containers-sm-support-only)」を参照してください。

エンドツーエンドのノートブックサンプルについては、「[amazon-sagemaker-examples リポジトリ](https://github.com/aws/amazon-sagemaker-examples/tree/main/sagemaker-triton)」を参照することをお勧めします。

## ホスティングモード
<a name="deploy-models-frameworks-triton-modes"></a>

Triton コンテナでは、以下の SageMaker AI ホスティングモードがサポートされています。
+ シングルモデルエンドポイント
  + これは SageMaker AI のデフォルトの動作モードです。このモードでは、Triton コンテナは 1 つのモデルまたは 1 つのアンサンブルモデルをロードできます。
  + モデルの名前は、`CreateModel` SageMaker AI API コールの一部であるコンテナ環境のプロパティとして渡す必要があります。モデル名を渡すために使用される環境変数は `SAGEMAKER_TRITON_DEFAULT_MODEL_NAME` です。
+ アンサンブルによる単一モデルエンドポイント
  + Triton 推論サーバーは、パイプラインまたはモデルの DAG (有向非巡回グラフ) であるアンサンブルをサポートします。**アンサンブルは技術的には複数のモデルで構成されますが、デフォルトの単一モデルエンドポイントモードでは、SageMaker AI は*アンサンブル自体* (パイプラインを表すメタモデル) をロードするメインモデルとして扱い、その後に関連するモデルをロードすることができます。
  + モデルをロードするには、アンサンブル自体のモデル名を使用する必要があります。`CreateModel` SageMaker API 呼び出しの一部であるコンテナ環境のプロパティとして渡す必要があります。モデル名を渡すために使用される環境変数は `SAGEMAKER_TRITON_DEFAULT_MODEL_NAME` です。
+ マルチモデルエンドポイント
  + このモードでは、SageMaker AI は 1 つのエンドポイントで複数のモデルを提供できます。このモードを使用するには、`CreateModel` SageMaker API 呼び出しの一部であるコンテナ環境のプロパティとして環境変数 `‘MultiModel’: true` を指定します。
  + デフォルトでは、インスタンスの起動時にモデルはロードされません。特定のモデルに対して推論リクエストを実行するには、`InvokeEndpoint` SageMaker API 呼び出しの `TargetModel` プロパティの引数として、対応するモデルの `*.tar.gz` ファイルを指定します。
+ アンサンブルによるマルチモデルエンドポイント
  + このモードでは、SageMaker AI は、マルチモデルエンドポイントの説明通りに機能します。ただし、SageMaker AI Triton コンテナは複数のアンサンブルモデルをロードできます。つまり、複数のモデルパイプラインを同じインスタンスで実行できます。SageMaker AI はすべてのアンサンブルを 1 つのモデルとして扱い、対応する `*.tar.gz` アーカイブを `TargetModel` として指定することで、各モデルのアンサンブル自体を呼び出すことができます。
  + 動的メモリの `LOAD` および `UNLOAD` 時のメモリ管理を向上するために、アンサンブルサイズを小さくしておくことをお勧めします。

## 推論ペイロードのタイプ
<a name="deploy-models-frameworks-triton-payloads"></a>

Triton は、推論ペイロードをネットワーク経由で送信する方法として、`json` と `binary+json` (またはバイナリエンコーディングされた json) の 2 つの方法をサポートしています。どちらの場合も JSON ペイロードには、データ型、シェイプ、および実際の推論リクエストテンソルが含まれます。リクエストテンソルはバイナリテンソルである必要があります。

`binary+json` 形式では、Triton がバイナリペイロードを正しく解析できるように、ヘッダーにリクエストメタデータの長さを指定する必要があります。SageMaker AI Triton コンテナでは、`application/vnd.sagemaker-triton.binary+json;json-header-size={}` というカスタム `Content-Type` ヘッダーを使用して行われます。これは、SageMaker AI ではカスタムヘッダーが許可されていないため、スタンドアロンの Triton 推論サーバーで `Inference-Header-Content-Length` ヘッダーを使用するのとは異なります。

## config.pbtxt を使用してモデル設定を設定する
<a name="deploy-models-frameworks-triton-config"></a>

SageMaker AI 上の Triton 推論サーバーでは、各モデルに少なくともモデルの次の設定を指定する `config.pbtxt` ファイルを含める必要があります。
+ `name`: SageMaker AI の外部で実行されるモデルの場合は任意ですが、SageMaker AI 上の Triton で実行されるモデルの名前を常に指定することをお勧めします。
+ [`platform` および/または `backend`](https://github.com/triton-inference-server/backend/blob/main/README.md#backends): モデルのタイプを指定するには、バックエンドの設定が不可欠です。バックエンドによっては、`tensorflow_savedmodel` や ` tensorflow_graphdef` のようにさらに分類されているものもあります。このようなオプションは、`backend` キーに加えて `platform` キーの一部として指定できます。最も一般的なバックエンドは、`tensorrt`、`onnxruntime`、`tensorflow`、`pytorch`、`python`、`dali`、`fil`、`openvino` です。
+ `input`: 入力には `name`、`data_type` および `dims` (シェイプ) の 3 つの属性を指定します。
+ `output`: 出力には `name`、`data_type` および `dims` (シェイプ) の 3 つの属性を指定します。
+ `max_batch_size`: バッチサイズを、Triton がモデルで使用する最大バッチサイズを示す 1 以上の値に設定します。

`config.pbtxt` の設定の詳細については、「Triton の GitHub [リポジトリ](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/model_configuration.md)」を参照してください。Triton には、モデルの動作を微調整するための設定がいくつか用意されています。最も一般的で重要な設定オプションは以下のとおりです。
+ [https://github.com/triton-inference-server/server/blob/main/docs/user_guide/model_configuration.md#instance-groups](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/model_configuration.md#instance-groups): インスタンスグループは、指定されたモデルの数と場所を指定するのに役立ちます。これらには `count`、`kind`、および `gpus` (`kind` が `KIND_GPU` の場合に使用) という属性があります。`count` 属性は、ワーカーの数と同等です。通常のモデル提供では、各ワーカーがモデルのコピーを所有します。同様に、Triton では、`count` はデバイスあたりのモデルコピー数を指定します。例えば、`instance_group` タイプが `KIND_CPU` の場合、CPU には `count` 数のモデルのコピーがあります。
**注記**  
GPU インスタンスでは、`instance_group` 設定は GPU デバイスごとに適用されます。例えば、モデルをロードする GPU デバイスを明示的に指定しない限り、各 GPU デバイスには `count` 数のモデルのコピーが配置されます。
+ [https://github.com/triton-inference-server/server/blob/main/docs/user_guide/model_configuration.md#dynamic-batcher](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/model_configuration.md#dynamic-batcher) と [https://github.com/triton-inference-server/server/blob/main/docs/user_guide/architecture.md#stateful-models](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/architecture.md#stateful-models): ステートレスモデルには動的バッチ処理が使用され、ステートフルモデル (毎回同じモデルインスタンスにリクエストをルーティングする場合) にはシーケンスバッチ処理が使用されます。バッチ処理スケジューラーではモデルごとのキューが有効になり、バッチ処理の設定によってはスループットの向上に役立ちます。
+ [https://github.com/triton-inference-server/server/blob/main/docs/user_guide/architecture.md#ensemble-models](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/architecture.md#ensemble-models): アンサンブルモデルは、1 つ以上のモデルの*パイプライン*と、それらのモデル間の入力および出力テンソルの接続を表します。`platform` を `ensemble` と指定することで設定できます。アンサンブル設定はモデルパイプラインの単なる表現です。SageMaker AI では、アンサンブルに含まれるすべてのモデルはアンサンブルモデルの依存モデルとして扱われ、`LoadedModelCount` などの SageMaker AI メトリクスでは単一のモデルとしてカウントされます。

## デフォルトの Triton メトリクスを Amazon CloudWatch に発行する
<a name="deploy-models-frameworks-triton-metrics"></a>

NVIDIA Triton 推論コンテナは、Triton 推論サーバーで使用されるさまざまなモデルと GPU のメトリクスをポート 8002 (設定可能) で発行します。利用可能なデフォルトのメトリクスの詳細については、「[Triton 推論サーバーメトリクスの GitHub](https://github.com/triton-inference-server/server/blob/main/docs/user_guide/metrics.md)」ページを参照してください。これらのメトリクスは Prometheus 形式で、Prometheus スクレイパー設定を使用してスクレイプすることができます。

バージョン v23.07 以降、SageMaker AI Triton コンテナはいくつかの環境変数を指定することで、Amazon CloudWatch へのこれらのメトリクスの発行をサポ－トしています。Prometheus メトリクスをスクレイプするために、SageMaker AI Triton コンテナは Amazon CloudWatch エージェントを活用します。

メトリクスを収集するために指定する必要がある必須環境変数は次のとおりです。


| 環境変数 | 説明 | 値の例 | 
| --- | --- | --- | 
|  `SAGEMAKER_TRITON_ALLOW_METRICS`  |  このオプションを指定すると、Triton が Prometheus エンドポイントにメトリクスを発行できるようになります。  | "true" | 
|  `SAGEMAKER_TRITON_PUBLISH_METRICS_TO_CLOUDWATCH`  |  このオプションを指定すると、Amazon CloudWatch にメトリクスを発行するために必要な事前チェックが開始されます。  | "true" | 
|  `SAGEMAKER_TRITON_CLOUDWATCH_LOG_GROUP`  |  このオプションを指定して、メトリクスが書き込まれるロググループを指すようにします。  | 「/aws/SageMaker AI/Endpoints/TritonMetrics/SageMakerTwoEnsemblesTest」 | 
|  `SAGEMAKER_TRITON_CLOUDWATCH_METRIC_NAMESPACE`  |  このオプションを指定して、メトリクスを表示およびプロットするメトリクス名前空間を指すようにします。  | 「/aws/SageMaker AI/Endpoints/TritonMetrics/SageMakerTwoEnsemblesPublicTest」 | 
|  `SAGEMAKER_TRITON_METRICS_PORT`  |  これを 8002 またはその他のポートとして指定します。SageMaker AI が指定されたポートをブロックしていない場合は、そのポートが使用されます。そうでない場合は、ブロックされていない別のポートが自動的に選択されます。  | 「8002」 | 

SageMaker AI で Triton を使用してメトリクスを発行する場合、以下の制限に注意してください。
+ C-API と Python バックエンド (v23.05 以降) を使用してカスタムメトリクスを生成することはできますが、Amazon CloudWatch への発行は現在サポートされていません。
+ SageMaker AI マルチモデルエンドポイント (MME) モードでは、各モデル (アンサンブルモデルを除く) は独自のモデルリポジトリにあるかのように扱われるため、Triton はモデル名前空間を有効にする必要がある環境で実行されます。現在、これによりメトリクスに制限が生じています。モデルの名前空間を有効にすると、Triton は異なるアンサンブルに属する同じ名前の 2 つのモデル間のメトリクスを区別しません。回避策として、デプロイされるすべてのモデルに一意の名前を付けます。これにより、CloudWatch でメトリクスを検索するのも簡単になります。

## 環境変数
<a name="deploy-models-frameworks-triton-variables"></a>

次の表は、SageMaker AI 上の Triton でサポートされている環境変数の一覧です。


| 環境変数 | 説明 | タイプ | 使用できる値 | 
| --- | --- | --- | --- | 
| `SAGEMAKER_MULTI_MODEL` | Triton が SageMaker AI のマルチモデルエンドポイントモードで動作できるようにします。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_DEFAULT_MODEL_NAME` | SageMaker AI 単一モデル (デフォルト) モードでロードするモデルを指定します。アンサンブルモードの場合は、アンサンブル自体の名前を指定します。 | String | *<model\$1name>* config.pbtxt で指定 | 
| `SAGEMAKER_TRITON_PING_MODE` | `'ready'` は SageMaker AI の単一モデルモードではデフォルトモードで、`'live'` は SageMaker AI のマルチモデルエンドポイントモードではデフォルトモードです。 | String | `ready`, `live` | 
| `SAGEMAKER_TRITON_DISABLE_MODEL_NAMESPACING` | SageMaker AI Triton コンテナでは、デフォルトで `true` に設定されています。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_BIND_TO_PORT` | SageMaker AI では、デフォルトポートは 8080 です。マルチコンテナのシナリオでは、別のポートにカスタマイズできます。 | String | *<port\$1number>* | 
| `SAGEMAKER_SAFE_PORT_RANGE` | これは、マルチコンテナモードを使用するときに SageMaker AI プラットフォームによって設定されます。 | String | *<port\$11>*–*<port\$12>* | 
| `SAGEMAKER_TRITON_ALLOW_GRPC` | SageMaker AI は現在 GRPC をサポートしていませんが、カスタムリバースプロキシの前に Triton を使用している場合は GRPC を有効にすることができます。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_GRPC_PORT` | GRPC のデフォルトポートは 8001 ですが、変更できます。 | String | *<port\$1number>* | 
| `SAGEMAKER_TRITON_THREAD_COUNT` | デフォルトの HTTP リクエストハンドラーのスレッド数を設定できます。 | String | *<number>* | 
| `SAGEMAKER_TRITON_LOG_VERBOSE` | SageMaker AI ではデフォルトで `true` ですが、このオプションを選択的にオフにすることもできます。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_LOG_INFO` | SageMaker AI のデフォルトでは `false` です。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_LOG_WARNING` | SageMaker AI のデフォルトでは `false` です。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_LOG_ERROR` | SageMaker AI のデフォルトでは `false` です。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_SHM_DEFAULT_BYTE_SIZE` | Python バックエンドの shm サイズをバイト単位で指定します。デフォルト値は 16 MB ですが、これより大きくすることもできます。 | String | *<number>* | 
| `SAGEMAKER_TRITON_SHM_GROWTH_BYTE_SIZE` | Python バックエンドの shm 成長サイズをバイト単位で指定します。デフォルト値は 1 MB ですが、増分を増やすこともできます。 | String | *<number>* | 
| `SAGEMAKER_TRITON_TENSORFLOW_VERSION` | デフォルト値は `2` です。Triton v23.04 以降、Triton は Tensorflow 2 をサポートしなくなりました。この変数は以前のバージョンで設定できます。 | String | *<number>* | 
| `SAGEMAKER_TRITON_MODEL_LOAD_GPU_LIMIT` | モデルのロードに使用される最大 GPU メモリの割合を制限し、残りを推論リクエストに使用できるようにします。 | String | *<number>* | 
| `SAGEMAKER_TRITON_ALLOW_METRICS` | SageMaker AI のデフォルトでは `false` です。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_METRICS_PORT` | デフォルトのポート番号は 8002 です。 | String | *<number>* | 
| `SAGEMAKER_TRITON_PUBLISH_METRICS_TO_CLOUDWATCH` | SageMaker AI のデフォルトでは `false` です。この変数を `true` に設定すると、Triton のデフォルトメトリクスを Amazon CloudWatch にプッシュできるようになります。このオプションを有効にすると、メトリクスがアカウントに発行される際の CloudWatch コストはお客様の負担となります。 | ブール値 | `true`, `false` | 
| `SAGEMAKER_TRITON_CLOUDWATCH_LOG_GROUP` | CloudWatch へのメトリクスの発行を有効にしている場合は必須です。 | String | *<cloudwatch\$1log\$1group\$1name>* | 
| `SAGEMAKER_TRITON_CLOUDWATCH_METRIC_NAMESPACE` | CloudWatch へのメトリクスの発行を有効にしている場合は必須です。 | String | *<cloudwatch\$1metric\$1namespace>* | 
| `SAGEMAKER_TRITON_ADDITIONAL_ARGS` | Triton サーバーの起動時に追加の引数を追加します。 | String | *<additional\$1args>* | 