

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

# kubectl を使用してローカル NVMe ストレージからモデルをデプロイする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme"></a>

このトピックでは、Amazon S3 または Amazon FSx からネットワーク経由でモデル重みをプルするのではなく、ノードのローカル NVMe ストレージからモデル重みをロードする推論エンドポイントを Amazon SageMaker HyperPod にデプロイする方法について説明します。 NVMe Amazon S3 FSx 重みをローカルで読み取ると、ポッドの起動時のネットワークホップがなくなり、推論ポッドのコールドスタート時間が短縮され、イベントの自動スケーリング、scale-from-zeroワークロード、レイテンシーの影響を受けやすいフェイルオーバーに役立ちます。コールドスタートレイテンシーが懸念されないワークロードの場合は、 `modelSourceType: s3`または を使用し、このトピック`fsx`をスキップします。

ローカル NVMe はノードローカルおよびエフェメラルです。スポット中断、ハードウェア障害、AMI 更新などでノードが置き換えられると、NVMe 上のデータは失われます。このトピックのアプローチでは、これを異なる方法で処理します。モデルがローカルにキャッシュされていない場合、ノードごとに事前入力する必要があるものもあれば、自動的に Amazon S3 にフォールバックするものがあります。ローカル NVMe インスタンスストレージは通常、P、G、および Trn インスタンスファミリーにあります。インスタンスタイプの可用性を検証するには、[Amazon EC2 インスタンスストアの仕様](https://docs.aws.amazon.com/ec2/latest/instancetypes/ac.html#ac_instance-store)」を参照してください。

ストレージ要件に基づいて、次のアプローチから選択できます。


**NVMe デプロイアプローチ**  

| \# | アプローチ | 説明 | 
| --- | --- | --- | 
| 1 | Kubernetes ボリューム (フォールバックなし) | モデル重みがすべてのノードの NVMe に存在する場合に使用します。Amazon S3、Amazon FSx、PV/PVC、または initContainers を必要としない最も簡単なセットアップ。 | 
| 2 | フォールバックを含む Kubernetes ボリューム | モデルがすべてのノードの NVMe に存在しない場合に使用します。モデルが見つからない場合は、最初に NVMe をチェックし、IRSA 認証情報を使用して Amazon S3 からダウンロードinitContainerするカスタム を指定します。 | 
| 3 | プリフェッチとフォールバックを備えた Amazon S3  | ポッド起動のためにモデルの重みを RAM にステージングする場合に使用します。モデルinitContainerがローカルにキャッシュされていない場合は、最初に NVMe をチェックし、オペレータがプロビジョニングした Amazon S3 マウントからのコピーにフォールバックするカスタムを指定します。 | 

## 前提条件
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-prereqs"></a>

開始する前に、以下が整っていることを検証します。
+ Amazon SageMaker HyperPod クラスターでの推論機能の設定。詳細については、「[モデルデプロイ用の HyperPod クラスターの設定](sagemaker-hyperpod-model-deployment-setup.md)」を参照してください。
+ [kubectl](https://kubernetes.io/docs/reference/kubectl/) ユーティリティのインストールとターミナルでの [jq](https://jqlang.org/) の設定
+ ターゲットノードのローカル NVMe ストレージに事前入力されたモデルの重み (手順[モデルの重みを NVMe に事前ロードする](#sagemaker-hyperpod-model-deployment-deploy-nvme-preload)については「」を参照）。

## デプロイアプローチを選択する
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-choose"></a>

次の決定フローを使用して、ユースケースに適したアプローチを決定します。

```
                  ┌────────────────────────────┐
                  │ Want to use a volume of    │
                  │ your choice, e.g. NVMe?    │
                  └─────┬──────────────┬───────┘
                   YES  │              │ NO
                        ▼              ▼
        ┌──────────────────────┐   Use S3/FSx/HF
        │ Are you sure EVERY   │   as-is (no volume
        │ node has the model   │   override needed)
        │ on NVMe?             │
        └─────┬──────────┬─────┘
         YES  │          │ NO
              ▼          ▼
  ┌─────────────────┐  ┌───────────────────────────────┐
  │ Approach 1      │  │ Do you need the operator to   │
  │                 │  │ create S3/FSx PVCs as a       │
  │ Use k8sVolume   │  │ fallback when the model is    │
  │ field in CRD to │  │ missing on a node?            │
  │ read from NVMe  │  └──────┬────────────────┬───────┘
  │ directly.       │    YES  │                │ NO
  └─────────────────┘         ▼                ▼
                  ┌──────────────────┐  ┌──────────────────────┐
                  │ Approach 3       │  │ Approach 2           │
                  │                  │  │                      │
                  │ Use S3 with      │  │ Use k8sVolume with a │
                  │ prefetch enabled.│  │ custom initContainer │
                  │ Custom           │  │ you create that      │
                  │ initContainer    │  │ checks NVMe first    │
                  │ checks NVMe      │  │ and downloads from   │
                  │ first, falls     │  │ S3 via IRSA if the   │
                  │ back to S3, and  │  │ model is missing.    │
                  │ copies to RAM.   │  └──────────────────────┘
                  └──────────────────┘
```

## Kubernetes ボリュームを使用してデプロイする (フォールバックなし)
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-volume"></a>

このアプローチは、すべてのノードで NVMe にモデルの重みがあり、Amazon S3 または Amazon FSx 設定、PV/PVC、initContainers のいずれも必要としない場合に使用します。

を設定すると`modelSourceType: kubernetesVolume`、オペレータは PV/PVC の作成を完全にスキップします。CSI ドライバー、Amazon S3 ヒューズマウント、または Amazon FSx マウントは使用されません。お客様が用意した`model-weights`ボリュームはポッド仕様で直接使用され、ワーカーは で NVMe からモデルデータを読み取ります`/opt/ml/model`。

**重要**  
を使用する場合`modelSourceType: kubernetesVolume`、オペレーターはワーカー設定`modelVolumeMount.name`の から想定されるボリューム名を取得します。 には、同じ名前のボリュームが含まれている`kubernetes.volumes`必要があります。演算子はこれを検証し、一致するボリュームが見つからない場合、 `KubernetesVolumeValidationFailed`条件でデプロイを拒否します。次の例では、どちらも を使用します`model-weights`。

1. `InferenceEndpointConfig` YAML ファイルを作成します。プレースホルダー値を実際のリソース識別子に置き換えます。

   ```
   cat <<EOF> deploy_nvme_k8s_volume.yaml
   apiVersion: inference.sagemaker.aws.amazon.com/v1
   kind: InferenceEndpointConfig
   metadata:
     name: nvme-k8s-volume
     namespace: default
   spec:
     endpointName: nvme-k8s-volume
     modelName: Qwen2.5-VL-7B-Instruct
     invocationEndpoint: v1/chat/completions
     replicas: 1
     modelSourceConfig:
       modelSourceType: kubernetesVolume
     kubernetes:
       volumes:
         - name: model-weights
           hostPath:
             path: /opt/dlami/nvme/<YOUR_MODEL>
             type: Directory
     loadBalancer:
       healthCheckPath: /health
     worker:
       image: lmcache/vllm-openai:latest
       args:
         - /opt/ml/model
         - --max-model-len
         - "15000"
         - --tensor-parallel-size
         - "1"
       modelInvocationPort:
         containerPort: 8000
         name: http
       modelVolumeMount:
         name: model-weights
         mountPath: /opt/ml/model
       resources:
         limits:
           nvidia.com/gpu: "1"
         requests:
           cpu: "6"
           memory: 30Gi
           nvidia.com/gpu: "1"
       environmentVariables:
         - name: PYTHONHASHSEED
           value: "123"
         - name: VLLM_REQUEST_TIMEOUT
           value: "600"
   EOF
   ```

1. をデプロイします`InferenceEndpointConfig`。

   ```
   kubectl apply -f deploy_nvme_k8s_volume.yaml
   ```

1. デプロイのステータスを確認します。

   ```
   kubectl describe InferenceEndpointConfig nvme-k8s-volume -n default
   ```

## フォールバックで Kubernetes ボリュームを使用してデプロイする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback"></a>

このアプローチは、モデルが特定のノードで NVMe 上にある場合とそうでない場合があります。`hostPath` ボリュームは、データが存在するノードでのみ機能します。他のノードでスケジュールされたポッドは、空のパスまたは存在しないパスをマウントし、モデルサーバーが失敗します。

このアプローチでは、NVMe を最初にチェックし、モデルがない場合は IRSA 認証情報を使用して Amazon S3 からダウンロード`initContainer`するカスタム を設定`modelSourceType: kubernetesVolume`して提供します。

### IRSA のセットアップ
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback-irsa"></a>

デプロイする前に、Amazon S3 からダウンロードするための認証情報をポッドに付与するように、サービスアカウントの IAM ロール (IRSA) を設定します。

1. クラスターの OIDC プロバイダー ID を取得します。

   ```
   aws eks describe-cluster --name <CLUSTER_NAME> --region <REGION> \
     --query "cluster.identity.oidc.issuer" --output text
   ```

1. IAM 信頼ポリシーを作成します。プレースホルダー値を置き換えて`trust-policy.json`、以下を として保存します。

   ```
   {
     "Version": "2012-10-17",		 	 	 
     "Statement": [{
       "Effect": "Allow",
       "Principal": {
         "Federated": "arn:aws:iam::<ACCOUNT_ID>:oidc-provider/oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>"
       },
       "Action": "sts:AssumeRoleWithWebIdentity",
       "Condition": {
         "StringEquals": {
           "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:sub": "system:serviceaccount:<NAMESPACE>:<SA_NAME>",
           "oidc.eks.<REGION>.amazonaws.com/id/<OIDC_ID>:aud": "sts.amazonaws.com"
         }
       }
     }]
   }
   ```
**警告**  
常に信頼ポリシーの範囲を特定の名前空間と ServiceAccount 名に設定します。サブジェクト条件 ( など`system:serviceaccount:*:*`) でワイルドカードを使用しないでください。これにより、任意の名前空間の ServiceAccount がロールを引き受けることができます。

1. IAM ロールを作成し、モデルバケットのスコープ付き Amazon S3 読み取りポリシーをアタッチします。

   ```
   aws iam create-role --role-name <ROLE_NAME> \
     --assume-role-policy-document file://trust-policy.json
   
   aws iam put-role-policy --role-name <ROLE_NAME> \
     --policy-name S3ModelReadAccess \
     --policy-document '{
       "Version": "2012-10-17",		 	 	 
       "Statement": [{
         "Effect": "Allow",
         "Action": ["s3:GetObject", "s3:ListBucket"],
         "Resource": [
           "arn:aws:s3:::<YOUR_BUCKET>",
           "arn:aws:s3:::<YOUR_BUCKET>/<YOUR_MODEL_PREFIX>/*"
         ]
       }]
     }'
   ```

1. IRSA 注釈を使用して Kubernetes サービスアカウントを作成します。

   ```
   kubectl create sa <SA_NAME> -n <NAMESPACE>
   kubectl annotate sa <SA_NAME> -n <NAMESPACE> \
     eks.amazonaws.com/role-arn=arn:aws:iam::<ACCOUNT_ID>:role/<ROLE_NAME>
   ```

### モデルをデプロイする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback-deploy"></a>

1. `InferenceEndpointConfig` YAML ファイルを作成します。プレースホルダー値を実際のリソース識別子に置き換えます。

   ```
   cat <<EOF> deploy_nvme_k8s_volume_fallback.yaml
   apiVersion: inference.sagemaker.aws.amazon.com/v1
   kind: InferenceEndpointConfig
   metadata:
     name: nvme-k8s-volume-fallback
     namespace: default
   spec:
     endpointName: nvme-k8s-volume-fallback
     modelName: Qwen2.5-VL-7B-Instruct
     invocationEndpoint: v1/chat/completions
     replicas: 1
     modelSourceConfig:
       modelSourceType: kubernetesVolume
     kubernetes:
       serviceAccountName: <YOUR_SERVICE_ACCOUNT>
       initContainers:
         - name: smart-loader
           image: public.ecr.aws/aws-cli/aws-cli:latest
           command: ["/bin/bash", "-c"]
           args:
             - |
               if [ "$(ls -A /model)" ]; then
                 echo "NVMe hit — model already present ($(du -sh /model | cut -f1))"
               else
                 echo "NVMe miss — downloading from S3"
                 aws s3 sync s3://<YOUR_BUCKET>/<YOUR_MODEL>/ /model/
               fi
           volumeMounts:
             - name: model-weights
               mountPath: /model
       volumes:
         - name: model-weights
           hostPath:
             path: /opt/dlami/nvme/<YOUR_MODEL>
             type: DirectoryOrCreate
     loadBalancer:
       healthCheckPath: /health
     worker:
       image: lmcache/vllm-openai:latest
       args:
         - /opt/ml/model
         - --max-model-len
         - "15000"
         - --tensor-parallel-size
         - "1"
       modelInvocationPort:
         containerPort: 8000
         name: http
       modelVolumeMount:
         name: model-weights
         mountPath: /opt/ml/model
       resources:
         limits:
           nvidia.com/gpu: "1"
         requests:
           cpu: "6"
           memory: 30Gi
           nvidia.com/gpu: "1"
       environmentVariables:
         - name: PYTHONHASHSEED
           value: "123"
   EOF
   ```

1. をデプロイします`InferenceEndpointConfig`。

   ```
   kubectl apply -f deploy_nvme_k8s_volume_fallback.yaml
   ```

1. デプロイのステータスを確認します。

   ```
   kubectl describe InferenceEndpointConfig nvme-k8s-volume-fallback -n default
   ```

## プリフェッチと NVMe フォールバックで Amazon S3 を使用してデプロイする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-s3-prefetch"></a>

このアプローチは、モデルの重みを RAM にステージングして推論パフォーマンスを行う場合に使用します。モデルが NVMe にローカルにキャッシュされていない場合は、Amazon S3 に自動的にフォールバックします。

`modelSourceType: s3` で を設定すると`prefetchEnabled: true`、オペレーターは 2 つのボリュームを自動的に作成します。
+ にちなんで名付けられたボリューム `modelVolumeMount.name` (通常は `model-weights`) — モデルを含む Amazon S3 CSI ヒューズマウント
+ `model-weights-copy` — ワーカー`emptyDir`が から読み取る RAM-backed

ノードのローカル NVMe ストレージを指すカスタム`nvme-cache`ボリュームと、次のカスタムボリュームを追加します`initContainer`。
+ モデルが NVMe に存在する場合 — は NVMe から RAM (`model-weights-copy`) にコピーし、ネットワーク全体をスキップします。
+ モデルが見つからない場合 — Amazon S3 マウント (`model-weights`) から RAM () へのコピーに戻ります`model-weights-copy`。必要に応じて NVMe にコピーし、同じノード上の後続のポッドスタートアップが高速ローカルパスを使用するようにします。

**重要**  
このアプローチ`kubernetes.volumes`を使用する場合は、 `model-weights`を上書きしないでください。オペレーターは、Amazon S3 CSI ボリューム`model-weights`を指す を作成します。上書きすると、initContainer がフォールバックに必要とするオペレータがプロビジョニングしたボリュームが削除されます。NVMe hostPath には別のボリューム名 ( など`nvme-cache`) を使用します。

**重要**  
`model-weights-copy` に を含めないでください`kubernetes.volumes`。これは、オペレータによって自動的に作成された予約名です。initContainer は で参照できます`volumeMounts`が、ボリュームとして宣言することはできません。

1. `InferenceEndpointConfig` YAML ファイルを作成します。プレースホルダー値を実際のリソース識別子に置き換えます。

   ```
   cat <<EOF> deploy_nvme_s3_prefetch_fallback.yaml
   apiVersion: inference.sagemaker.aws.amazon.com/v1
   kind: InferenceEndpointConfig
   metadata:
     name: nvme-s3-prefetch-fallback
     namespace: default
   spec:
     endpointName: nvme-s3-prefetch-fallback
     modelName: Qwen2.5-VL-7B-Instruct
     invocationEndpoint: v1/chat/completions
     replicas: 1
     modelSourceConfig:
       modelSourceType: s3
       s3Storage:
         bucketName: <YOUR_BUCKET>
         region: <YOUR_REGION>
       prefetchEnabled: true
     kubernetes:
       serviceAccountName: <YOUR_SERVICE_ACCOUNT>
       initContainers:
         - name: smart-loader
           image: public.ecr.aws/aws-cli/aws-cli:latest
           command: ["/bin/bash", "-c"]
           args:
             - |
               # Check NVMe first, fall back to S3 mount, then copy to RAM
               if [ "$(ls -A /nvme)" ]; then
                 echo "NVMe hit ($(du -sh /nvme | cut -f1))"
                 echo "Copying model from NVMe to RAM..."
                 cp -r /nvme/* /model/
               else
                 echo "NVMe miss — copying from S3 mount to NVMe, then NVMe to RAM"
                 cp -r /s3-model/* /nvme/
                 cp -r /nvme/* /model/
               fi
               echo "Done. $(du -sh /model | cut -f1) in RAM."
           volumeMounts:
             - name: model-weights
               mountPath: /s3-model
             - name: nvme-cache
               mountPath: /nvme
             - name: model-weights-copy
               mountPath: /model
       volumes:
         - name: nvme-cache
           hostPath:
             path: /opt/dlami/nvme/<YOUR_MODEL>
             type: DirectoryOrCreate
     loadBalancer:
       healthCheckPath: /health
     worker:
       image: lmcache/vllm-openai:latest
       args:
         - /opt/ml/model
         - --max-model-len
         - "15000"
         - --tensor-parallel-size
         - "1"
       modelInvocationPort:
         containerPort: 8000
         name: http
       modelVolumeMount:
         name: model-weights
         mountPath: /opt/ml/model
       resources:
         limits:
           nvidia.com/gpu: "1"
         requests:
           cpu: "6"
           memory: 30Gi
           nvidia.com/gpu: "1"
       environmentVariables:
         - name: PYTHONHASHSEED
           value: "123"
         - name: VLLM_REQUEST_TIMEOUT
           value: "600"
   EOF
   ```

1. をデプロイします`InferenceEndpointConfig`。

   ```
   kubectl apply -f deploy_nvme_s3_prefetch_fallback.yaml
   ```

1. デプロイのステータスを確認します。

   ```
   kubectl describe InferenceEndpointConfig nvme-s3-prefetch-fallback -n default
   ```

## プリフェッチを使用した model-weights と model-weights-copy について
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-prefetch-volumes"></a>

プリフェッチを使用する場合、演算子は 2 つのモデル関連ボリュームを作成します。
+ にちなんで名付けられたボリューム `modelVolumeMount.name` (通常は `model-weights`) — モデルを含む Amazon S3 CSI ヒューズマウント
+ `model-weights-copy` — ワーカーが実際に から読み取る RAM-backed emptyDir 

では`InferenceEndpointConfig`、以下を定義します。

```
modelVolumeMount:
    name: model-weights
    mountPath: /opt/ml/model
```

を参照している間`model-weights`、 の場合`prefetchEnabled: true`、 は実際にワーカーコンテナの `/opt/ml/model`に`model-weights-copy`マウントされます。カスタム initContainer を使用する場合は、 という名前のボリュームにデータをコピーしてください。`model-weights-copy`つまり、ワーカーがデータを見つける場所です。

の場合`prefetchEnabled: false`、ボリュームは 1 つだけ ( の後に名前が付けられます`modelVolumeMount.name`)、 に直接マウントされます`/opt/ml/model`。

## カスタムサービスアカウントを設定する
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa"></a>

の `spec.kubernetes.serviceAccountName`フィールドを使用して、推論エンドポイントポッドにカスタム Kubernetes ServiceAccount を割り当てることができます`InferenceEndpointConfig`。これは、ワーカーコンテナまたは init コンテナに IRSA (サービスアカウントの IAM ロール) 経由で認証情報を提供する AWS 場合に役立ちます。例えば、フォールバックシナリオで Amazon S3 からモデル重みをダウンロードする場合などです。

**重要**  
カスタムサービスアカウントサポートはデフォルトで無効になっており、使用前にクラスター管理者が明示的に有効にする必要があります。手順については「[カスタムサービスアカウントを有効にする](#sagemaker-hyperpod-model-deployment-deploy-nvme-sa-enable)」を参照してください。

ServiceAccount を指定しない場合、名前空間のデフォルトの ServiceAccount が使用されます。

### カスタムサービスアカウントを有効にする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-enable"></a>

カスタムサービスアカウントのサポートはデフォルトで無効になっています。クラスター管理者は、ユーザーが でカスタム ServiceAccounts を参照する前に、オペレーターの Helm 設定で有効にする必要があります`InferenceEndpointConfig`。
+ 演算子 Helm 値を更新して機能を有効にします。Helm 経由でオペレータをデプロイした場合は、 フラグを使用してアップグレードします。

  ```
  helm upgrade hyperpod-inference-operator <CHART_PATH> \
    --set enableCustomServiceAccounts=true \
    --reuse-values
  ```
+ 演算子を Amazon EKS アドオンとしてデプロイした場合は、アドオン設定を更新して、詳細設定`enableCustomServiceAccounts: true`に を含めます。
+ オペレータポッドに環境変数が設定されていることを確認します。

  ```
  kubectl get deployment hyperpod-inference-operator-controller-manager \
    -n hyperpod-inference-system \
    -o jsonpath='{.spec.template.spec.containers[0].env}' | jq '.[] | select(.name=="ENABLE_CUSTOM_SERVICE_ACCOUNTS")'
  ```

  以下が表示されます。

  ```
  {
    "name": "ENABLE_CUSTOM_SERVICE_ACCOUNTS",
    "value": "true"
  }
  ```

**重要**  
この機能が有効になっていない場合、 `InferenceEndpointConfig`を指定する `kubernetes.serviceAccountName`は`DeploymentFailed`ステータスとメッセージ で拒否されます`kubernetes.serviceAccountName is not enabled. Requires addon configuration (enableCustomServiceAccounts: true)`。

### サービスアカウントにラベルを付ける
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-label"></a>

カスタム ServiceAccount を参照する前に、クラスター管理者はそれをユーザー割り当て可能としてラベル付けする必要があります。

```
kubectl label serviceaccount <your-service-account> \
  sagemaker.amazonaws.com/user-assignable=true \
  -n <namespace>
```

このラベルを持つ ServiceAccounts のみが推論エンドポイントで参照できます。これは、権限の不正なエスカレーションを防ぐためのセキュリティコントロールです。

### 設定でサービスアカウントを指定する
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-spec"></a>

の `spec.kubernetes`に `serviceAccountName`フィールドを追加します`InferenceEndpointConfig`。

```
apiVersion: inference.sagemaker.aws.amazon.com/v1
kind: InferenceEndpointConfig
metadata:
  name: my-inference-endpoint
  namespace: my-namespace
spec:
  kubernetes:
    serviceAccountName: my-inference-sa
  # ... rest of your config
```

### 検証ルール
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-validation"></a>

演算子は、作成オペレーションと更新オペレーションの両方で `serviceAccountName`フィールドを検証します。次のいずれかの条件が満たされた場合、デプロイは `DeploymentFailed`ステータスで拒否されます。
+ ServiceAccount が名前空間に存在しません — `serviceAccountName "X" not found in namespace "Y"`
+ ServiceAccount に必要なラベルがありません — `serviceAccountName "X" is not labeled as user-assignable (requires label sagemaker.amazonaws.com/user-assignable=true)`
+ ServiceAccount はオペレーターのシステム ServiceAccount です。 `serviceAccountName must not reference the operator's service account`

**注記**  
推論ポッド内のすべてのコンテナ (ワーカー、初期化コンテナ、サイドカー) は、指定された ServiceAccount のアクセス許可を継承します。ServiceAccount に という注釈が付いている場合`eks.amazonaws.com/role-arn`、ポッドはその IAM ロールの一時的な AWS 認証情報を受け取ります。クラスター管理者は、関連する RBAC ロールと IAM アクセス許可を確認した後にのみServiceAccounts をユーザー割り当て可能としてラベル付けする必要があります。

**注記**  
`InferenceEndpointConfig` の実行中に ServiceAccount が削除された場合、既存のポッドは再起動されるまで現在の認証情報で実行され続けます。ただし、ServiceAccount が存在しないため、新しいポッドの作成 (スケーリングや再スケジュール中など) は失敗します。オペレーターは、デプロイが最初に作成されたときと IEC 仕様が更新されたときに ServiceAccount を検証しますServiceAccount は継続的にモニタリングされません。SA が削除された後に IEC 仕様を更新すると、 `DeploymentFailed`ステータスになります。

### カスタムサービスアカウントのセキュリティのベストプラクティス
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-security"></a>

推論エンドポイントでカスタム ServiceAccount を使用する場合、HyperPod 推論演算子はユーザーに代わってデプロイを作成します。ワーカー、init コンテナ、サイドカーなど、推論ポッド内のすべてのコンテナは、指定された ServiceAccount のアクセス許可を継承します。クラスターを保護するには、以下のベストプラクティスに従ってください。

**RBAC アクセス許可をロックダウンする**
+ 推論ワークロードごとに専用の ServiceAccount を作成します。無関係なワークロード間で ServiceAccounts を再利用しないでください。
+ 必要な最小 RBAC アクセス許可のみをバインドします。例えば、init コンテナが Amazon S3 からのみ読み取る必要がある場合、ServiceAccount には Kubernetes リソースを一覧表示または変更するアクセス許可があってはなりません。

  ```
  # Example: minimal Role for an inference workload that only needs S3 access via IRSA
  # No Kubernetes API permissions needed — IRSA provides AWS credentials directly
  apiVersion: v1
  kind: ServiceAccount
  metadata:
    name: my-inference-sa
    namespace: my-namespace
    labels:
      sagemaker.amazonaws.com/user-assignable: "true"
    annotations:
      eks.amazonaws.com/role-arn: arn:aws:iam::<ACCOUNT_ID>:role/<SCOPED_ROLE_NAME>
  ```
+ 推論ポッドで使用される ServiceAccounts にクラスター全体のアクセス許可 (ClusterRoleBindings) を付与することは避けてください。

**IRSA IAM ロールの範囲**
+ で ServiceAccount に注釈を付けるときは`eks.amazonaws.com/role-arn`、IAM ロールが最小特権の原則に従っていることを確認します。
+ Amazon S3 のアクセス許可を、モデルの重みを含む特定のバケットとプレフィックスにスコープします。

  ```
  {
    "Version": "2012-10-17",		 	 	 
    "Statement": [{
      "Effect": "Allow",
      "Action": ["s3:GetObject", "s3:ListBucket"],
      "Resource": [
        "arn:aws:s3:::<YOUR_BUCKET>",
        "arn:aws:s3:::<YOUR_BUCKET>/<YOUR_MODEL_PREFIX>/*"
      ]
    }]
  }
  ```
+ 本番環境`AmazonS3FullAccess`では、 などの広範な管理ポリシーを使用しないでください。`AmazonS3ReadOnlyAccess` またはモデルバケットを対象とするカスタムポリシーを使用します。

**ユーザー割り当て可能なラベルを保護する**
+ クラスター管理者のみが`sagemaker.amazonaws.com/user-assignable=true`ラベルを追加または削除する必要があります。Kubernetes RBAC を使用して、名前空間内の ServiceAccount ラベルを変更できるユーザーを制限します。
+ ユーザー割り当て可能としてラベル付けする前に、ServiceAccount に関連付けられた RBAC ロールと IAM アクセス許可を確認してください。
+ ラベルが付けられている ServiceAccounts を定期的に監査します`user-assignable`。

  ```
  kubectl get serviceaccounts -n <NAMESPACE> -l sagemaker.amazonaws.com/user-assignable=true
  ```
+ 管理者以外のロールに ServiceAccount リソースの `patch`、`update`、または`create`動詞が含まれていないことを確認します。オペレーターはデプロイ時に`user-assignable`ラベルを検証しますが、権限のないユーザーが ServiceAccount にラベルを追加できないようにします。このラベルを保護するための主なコントロールは、RBAC を介して ServiceAccounts を変更できるユーザーを制限することです。管理者以外のユーザーには、 `get`と `list` アクセスのみが必要です。

  ```
  # Example: RBAC Role for non-admin users — read-only access to ServiceAccounts
  apiVersion: rbac.authorization.k8s.io/v1
  kind: Role
  metadata:
    name: sa-read-only
    namespace: <NAMESPACE>
  rules:
    - apiGroups: [""]
      resources: ["serviceaccounts"]
      verbs: ["get", "list"]
  ```

**重要**  
HyperPod 推論演算子は、ユーザーに代わってデプロイを作成する仲介として機能します。発信者がポッドを直接作成する標準の Kubernetes ワークロードとは異なり、オペレータは作成したポッドに指定された ServiceAccount を割り当てます。つまり、ユーザー割り当て可能な ServiceAccount に付与されたアクセス許可は、その名前空間`InferenceEndpointConfig`で を作成できるすべてのユーザーが効果的に使用できます。名前空間レベルの RBAC が、`InferenceEndpointConfig`リソースを作成および更新できるユーザーを制御していることを確認します。

## モデルの重みを NVMe に事前ロードする
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-preload"></a>

デプロイ前に特定のノードに NVMe を事前に入力する必要がある場合は、1 回限りのポッドを使用して Amazon S3 から同期できます。

**注記**  
このアプローチは を介して特定のノードをターゲット`nodeName`とし、自動スケーリングでは機能しません。自動スケーリングシナリオでは、フォールバックで Kubernetes ボリュームを使用するか、プリフェッチアプローチで Amazon S3 を使用します。プリフェッチアプローチは、initContainer フォールバックロジックを介して欠落しているモデルを自動的に処理します。

1. プリロードポッド YAML ファイルを作成します。プレースホルダー値を実際のリソース識別子に置き換えます。

   ```
   cat <<EOF> nvme-s3-copy.yaml
   apiVersion: v1
   kind: Pod
   metadata:
     name: nvme-s3-copy
     namespace: default
   spec:
     nodeName: <TARGET_NODE>
     restartPolicy: Never
     containers:
       - name: s3-copy
         image: public.ecr.aws/aws-cli/aws-cli:latest
         command: ["/bin/bash", "-c"]
         args:
           - |
             echo "=== Starting S3 sync to NVMe ==="
             aws s3 sync s3://<YOUR_BUCKET>/<YOUR_MODEL>/ /nvme/<YOUR_MODEL>/ --region <YOUR_REGION>
             echo "=== Sync complete ==="
             ls -la /nvme/<YOUR_MODEL>/
             du -sh /nvme/<YOUR_MODEL>/
             echo "=== Done ==="
         volumeMounts:
           - name: nvme-storage
             mountPath: /nvme
     serviceAccountName: default
     volumes:
       - name: nvme-storage
         hostPath:
           path: /opt/dlami/nvme
           type: Directory
   EOF
   ```

1. ポッドを適用し、同期の進行状況をモニタリングします。

   ```
   kubectl apply -f nvme-s3-copy.yaml
   kubectl get pod nvme-s3-copy -w
   kubectl logs nvme-s3-copy -f
   ```

1. 同期が完了したら、ポッドをクリーンアップします。

   ```
   kubectl delete pod nvme-s3-copy
   ```

## 予約済みボリューム名
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-reserved-volumes"></a>

演算子は、 を介して上書きできない複数の内部ボリュームを管理します`kubernetes.volumes`。これらの名前のいずれかを使用すると、 `KubernetesVolumeValidationFailed` 条件になります。


**予約済みボリューム名**  

| \# | 名前 | 目的 | 
| --- | --- | --- | 
| 1 | shm | プロセス間通信用の共有メモリ (/dev/shm) | 
| 2 | model-weights-copy | RAM-backed emptyDir は prefetchEnabled: true | 
| 3 | parallel-copy-configmap | 並列コピースクリプトの ConfigMap (プリフェッチ) | 
| 4 | lmcache-config | LMCache 設定ボリューム | 
| 5 | gated-model-downloader-configmap | ゲートモデルダウンロードスクリプトの ConfigMap  | 

## 覚えておくべきこと
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-things-to-remember"></a>
+ **リザーブドボリューム名を使用しないでください。**演算子は、複数の内部ボリュームを管理します (「」を参照[予約済みボリューム名](#sagemaker-hyperpod-model-deployment-deploy-nvme-reserved-volumes))。これらの名前のいずれかを で使用すると、 `KubernetesVolumeValidationFailed` 条件`kubernetes.volumes`になります。
+ **ボリューム名は一致する必要があります。**演算子は、 からボリューム名を取得します`modelVolumeMount.name`。を使用する場合`modelSourceType: kubernetesVolume`、 には同じ名前のボリュームが含まれている`kubernetes.volumes`必要があります。
+ **initContainer の正しい場所にボリュームをマウントします。**作成したボリュームが initContainer の正しいパスにマウントされていることを確認します。
+ **S3/FSx にはカスタムサービスアカウントは必要ありません。**カスタムサービスアカウントを作成できない場合、または作成しない場合は、 `modelSourceType: s3`または を使用できます`fsx`。演算子は S3/FSx ボリュームを自動的にプロビジョニングします。オペレーターマネージドストレージの上にカスタムボリューム`initContainers`とオーバーライドボリュームを追加することもできます。
+ **IRSA 認証情報はすべてのコンテナに挿入されます。**IRSA 注釈を使用してサービスアカウントに `kubernetes.serviceAccountName`を設定すると、Amazon EKS はカスタム initContainers を含むすべてのコンテナに AWS 認証情報 (`aws-iam-token` ボリューム`AWS_ROLE_ARN`、、`AWS_WEB_IDENTITY_TOKEN_FILE`) を挿入します。
+ **`modelLocation`を使用する場合は、 を設定しないでください`kubernetesVolume`。**ボリュームパスは によって制御されます`kubernetes.volumes`。`modelSourceType` を `modelLocation`に設定すると、検証エラー`kubernetesVolume`が発生します。
+ **`model-weights`と がプリフェッチと`model-weights-copy`どのように連携するかを理解します。**の場合`prefetchEnabled: true`、演算子は 2 つのモデル関連ボリュームを作成します。
  + `model-weights` — ソースボリューム (Amazon S3/Amazon FSx PVC またはオーバーライドから)
  + `model-weights-copy` — ワーカーが実際に から読み取る RAM-backed emptyDir 
+ 設定`model-weights`で を参照している間、 の場合`prefetchEnabled: true`、 は実際にワーカーコンテナの `/opt/ml/model`にマウント`model-weights-copy`されます。カスタム initContainer を使用する場合は、 という名前のボリュームにデータをコピーしてください。`model-weights-copy`つまり、ワーカーがデータを見つける場所です。の場合`prefetchEnabled: false`、ボリュームは 1 つだけ ( の後に名前が付けられます`modelVolumeMount.name`)、 に直接マウントされます`/opt/ml/model`。

## トラブルシューティング
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-troubleshooting"></a>

デプロイが想定どおりに機能しない場合は、これらのデバッグコマンドを使用します。
+ `InferenceEndpointConfig` ステータスをチェックして、高レベルのデプロイ状態と設定の問題を確認します。

  ```
  kubectl describe InferenceEndpointConfig <ENDPOINT_NAME> -n <NAMESPACE>
  ```
+ Kubernetes デプロイのステータスを確認します。

  ```
  kubectl describe deployment <ENDPOINT_NAME> -n <NAMESPACE>
  ```
+ 名前空間内のすべての Kubernetes オブジェクトのステータスを確認します。

  ```
  kubectl get pods,svc,deployment,InferenceEndpointConfig,sagemakerendpointregistration -n <NAMESPACE>
  ```
+ モデルのロードステップが失敗した場合は、initContainer ログを確認します。

  ```
  kubectl logs <POD_NAME> -c smart-loader -n <NAMESPACE>
  ```
+ デプロイが「名前空間に見つかりません」で失敗した場合、ServiceAccount が存在することを確認します。

  ```
  kubectl get serviceaccount <name> -n <namespace>
  ```
+ デプロイが「ユーザー割り当て可能としてラベル付けされていない」で失敗した場合、クラスター管理者に必要なラベルを追加するように依頼します。

  ```
  kubectl label serviceaccount <name> sagemaker.amazonaws.com/user-assignable=true -n <namespace>
  ```
+ 「オペレーターのサービスアカウントを参照してはいけません」でデプロイが失敗する場合は、ワークロード用に別の ServiceAccount を作成します。HyperPod 推論演算子独自の ServiceAccount を使用することはできません。