

Les traductions sont fournies par des outils de traduction automatique. En cas de conflit entre le contenu d'une traduction et celui de la version originale en anglais, la version anglaise prévaudra.

# Déployez des modèles à partir d'un stockage NVMe local à l'aide de kubectl
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme"></a>

Cette rubrique explique comment déployer des points de terminaison d'inférence sur Amazon SageMaker HyperPod qui chargent les pondérations des modèles à partir du stockage NVMe local d'un nœud au lieu de les transférer sur le réseau depuis Amazon S3 ou Amazon FSx. La lecture locale des pondérations élimine le saut sur le réseau lors du démarrage du pod, ce qui réduit le temps de démarrage à froid du pod par inférence et est utile pour le dimensionnement automatique des événements, la mise à l'échelle des charges de travail à partir de zéro et les basculements sensibles à la latence. Pour les charges de travail pour lesquelles la latence de démarrage à froid n'est pas un problème, utilisez `modelSourceType: s3` ou `fsx` et ignorez cette rubrique.

Le NVMe local est éphémère et local aux nœuds : les données du NVMe sont perdues lorsqu'un nœud est remplacé, par exemple lors d'une interruption ponctuelle, d'une panne matérielle ou d'une actualisation de l'AMI. Les approches décrites dans cette rubrique traitent cela différemment : certaines nécessitent que vous préremplissiez chaque nœud, d'autres recourent automatiquement à Amazon S3 lorsque le modèle n'est pas mis en cache localement. Le stockage d'instance NVMe local se trouve généralement dans les familles d'instances P, G et Trn. Consultez les [spécifications du magasin d'instances Amazon EC2](https://docs.aws.amazon.com/ec2/latest/instancetypes/ac.html#ac_instance-store) pour valider la disponibilité de votre type d'instance.

Vous pouvez choisir l'une des approches suivantes en fonction de vos besoins de stockage :


**Approches de déploiement NVMe**  

| \# | Approche | Description | 
| --- | --- | --- | 
| 1 | Volume Kubernetes (aucune solution de secours) | À utiliser lorsque les poids des modèles existent sur NVMe sur chaque nœud. Configuration la plus simple : Amazon S3, Amazon FSx ou InitContainers PV/PVC ne sont pas nécessaires. | 
| 2 | Volume Kubernetes avec solution de secours | À utiliser lorsque le modèle n'existe pas sur NVMe sur tous les nœuds. Vous fournissez une option personnalisée initContainer qui vérifie d'abord le NVMe et télécharge depuis Amazon S3 à l'aide des informations d'identification IRSA si le modèle est manquant. | 
| 3 | Amazon S3 avec prélecture et repli | À utiliser lorsque vous souhaitez transférer les poids des modèles dans la RAM pour le démarrage du pod. Vous fournissez une configuration personnalisée initContainer qui vérifie d'abord le NVMe et qui revient à copier à partir du support Amazon S3 fourni par l'opérateur si le modèle n'est pas mis en cache localement. | 

## Conditions préalables
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-prereqs"></a>

Avant de commencer, vérifiez les points suivants :
+ Configurez des fonctionnalités d'inférence sur vos SageMaker HyperPod clusters Amazon. Pour de plus amples informations, veuillez consulter [Configuration de vos HyperPod clusters pour le déploiement de modèles](sagemaker-hyperpod-model-deployment-setup.md).
+ Vous avez installé l’utilitaire [kubectl](https://kubernetes.io/docs/reference/kubectl/) et configuré [jq](https://jqlang.org/) dans votre terminal.
+ Pre-populated modélisez les pondérations sur le stockage NVMe local de vos nœuds cibles (voir [Précharger les poids des modèles dans NVMe](#sagemaker-hyperpod-model-deployment-deploy-nvme-preload) les instructions).

## Choisissez votre approche de déploiement
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-choose"></a>

Utilisez le flux de décision suivant pour déterminer l'approche la mieux adaptée à votre cas d'utilisation.

```
                  ┌────────────────────────────┐
                  │ 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.   │  └──────────────────────┘
                  └──────────────────┘
```

## Déploiement à l'aide d'un volume Kubernetes (aucune solution de secours)
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-volume"></a>

Utilisez cette approche lorsque vous avez des pondérations de modèle sur NVMe sur chaque nœud et que vous souhaitez la configuration la plus simple : aucune configuration Amazon S3 ou Amazon FSx, ni PV/PVC aucun InitContainers.

Lorsque vous définissez`modelSourceType: kubernetesVolume`, l'opérateur ignore complètement PV/PVC la création. Aucun pilote CSI, aucun fusible Amazon S3 ou aucun support Amazon FSx n'est utilisé. Le `model-weights` volume fourni par le client est utilisé directement dans les spécifications du module, et le travailleur lit les données du modèle depuis NVMe à l'adresse. `/opt/ml/model`

**Important**  
Lors de l'utilisation`modelSourceType: kubernetesVolume`, l'opérateur déduit le nom du volume attendu `modelVolumeMount.name` dans votre configuration de travail. `kubernetes.volumes`doit contenir un volume portant le même nom. L'opérateur valide cela et rejette le déploiement avec une `KubernetesVolumeValidationFailed` condition si aucun volume correspondant n'est trouvé. Dans les exemples suivants, les deux utilisent`model-weights`.

1. Créez le fichier `InferenceEndpointConfig` YAML. Remplacez les valeurs d'espace réservé par vos identificateurs de ressources réels.

   ```
   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. Déployez le`InferenceEndpointConfig`.

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

1. Vérifiez l'état du déploiement.

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

## Déploiement à l'aide d'un volume Kubernetes avec solution de secours
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback"></a>

Utilisez cette approche lorsque le modèle peut ou non être sur NVMe sur un nœud donné. Un `hostPath` volume ne fonctionne que sur les nœuds où les données existent. Les pods planifiés sur d'autres nœuds installeraient un chemin vide ou inexistant, ce qui provoquerait la défaillance du serveur de modèles.

Dans cette approche, vous définissez `modelSourceType: kubernetesVolume` et fournissez une personnalisation `initContainer` qui vérifie d'abord le NVMe et les télécharge depuis Amazon S3 à l'aide des informations d'identification IRSA si le modèle est manquant.

### Configurer l'IRSA
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback-irsa"></a>

Avant le déploiement, configurez les rôles IAM pour les comptes de service (IRSA) afin de fournir à vos pods les informations d'identification nécessaires au téléchargement depuis Amazon S3.

1. Obtenez l'ID du fournisseur OIDC pour votre cluster.

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

1. Créez une politique de confiance IAM. Enregistrez ce qui suit sous le nom`trust-policy.json`, en remplaçant les valeurs d'espace réservé.

   ```
   {
     "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"
         }
       }
     }]
   }
   ```
**Avertissement**  
Délimitez toujours la politique de confiance à un espace de noms et à un ServiceAccount nom spécifiques. N'utilisez jamais de caractères génériques dans la condition d'objet (par exemple,`system:serviceaccount:*:*`), car cela permettrait ServiceAccount à n'importe quel espace de noms d'assumer le rôle.

1. Créez le rôle IAM et associez une politique de lecture Amazon S3 délimitée à votre modèle de compartiment.

   ```
   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. Créez le compte de service Kubernetes avec l'annotation IRSA.

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

### Déploiement du modèle
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-fallback-deploy"></a>

1. Créez le fichier `InferenceEndpointConfig` YAML. Remplacez les valeurs d'espace réservé par vos identificateurs de ressources réels.

   ```
   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. Déployez le`InferenceEndpointConfig`.

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

1. Vérifiez l'état du déploiement.

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

## Déployez à l'aide d'Amazon S3 avec prefetch et solution de secours NVMe
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-s3-prefetch"></a>

Utilisez cette approche lorsque vous souhaitez obtenir des performances d'inférence en transférant le poids du modèle à la RAM, avec un retour automatique vers Amazon S3 si le modèle n'est pas mis en cache localement sur NVMe.

Lorsque vous définissez `modelSourceType: s3` avec`prefetchEnabled: true`, l'opérateur crée automatiquement deux volumes :
+ Un volume nommé d'après votre `modelVolumeMount.name` (généralement`model-weights`) : un fusible Amazon S3 CSI contenant votre modèle
+ `model-weights-copy`— un RAM-backed `emptyDir` endroit où le travailleur lit un extrait

Vous ajoutez un `nvme-cache` volume personnalisé pointant vers le stockage NVMe local du nœud, et un volume personnalisé `initContainer` qui :
+ Si le modèle existe sur NVMe, copie du NVMe vers la RAM (`model-weights-copy`), en omettant complètement le réseau.
+ Si le modèle est manquant, recommencez à copier du support Amazon S3 (`model-weights`) vers la RAM (`model-weights-copy`). Copie éventuellement vers NVMe afin que les prochains démarrages du pod sur le même nœud utilisent le chemin local rapide.

**Important**  
Ne remplacez `model-weights` pas cette approche `kubernetes.volumes` lorsque vous utilisez cette approche. L'opérateur crée un `model-weights` pointage vers le volume Amazon S3 CSI. Le remplacer supprime le volume provisionné par l'opérateur dont votre InitContainer a besoin pour le repli. Utilisez un nom de volume distinct (par exemple,`nvme-cache`) pour votre chemin d'hôte NVMe.

**Important**  
Ne pas inclure `model-weights-copy` dans`kubernetes.volumes`. Il s'agit d'un nom réservé créé automatiquement par l'opérateur. Votre InitContainer peut le référencer `volumeMounts` mais ne doit pas le déclarer en tant que volume.

1. Créez le fichier `InferenceEndpointConfig` YAML. Remplacez les valeurs d'espace réservé par vos identificateurs de ressources réels.

   ```
   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. Déployez le`InferenceEndpointConfig`.

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

1. Vérifiez l'état du déploiement.

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

## Comprendre les poids des modèles et les poids des modèles et copier avec Prefetch
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-prefetch-volumes"></a>

Lors de l'utilisation de prefetch, l'opérateur crée deux volumes liés au modèle :
+ Un volume nommé d'après votre `modelVolumeMount.name` (généralement`model-weights`) : un fusible Amazon S3 CSI contenant votre modèle
+ `model-weights-copy`— un RAM-backed EmptyDir dans lequel le travailleur lit réellement

Dans votre`InferenceEndpointConfig`, vous définissez :

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

Pendant que vous faites référence`model-weights`, quand`prefetchEnabled: true`, c'est en fait `model-weights-copy` ce qui est monté `/opt/ml/model` dans le conteneur de travail. Lorsque vous utilisez un InitContainer personnalisé, assurez-vous de copier les données dans le volume appelé`model-weights-copy`, c'est là que le travailleur s'attend à les trouver.

Lorsqu'`prefetchEnabled: false`il n'y a qu'un seul volume (nommé d'après votre`modelVolumeMount.name`) et qu'il est monté directement sur`/opt/ml/model`.

## Configuration d'un compte de service personnalisé
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa"></a>

Vous pouvez attribuer un Kubernetes personnalisé ServiceAccount à vos pods de point de terminaison d'inférence à l'aide du champ du`spec.kubernetes.serviceAccountName`. `InferenceEndpointConfig` Cela est utile pour fournir des AWS informations d'identification via IRSA (IAM Roles for Service Accounts) à vos conteneurs de travail ou à vos conteneurs d'initialisation, par exemple pour télécharger les pondérations des modèles depuis Amazon S3 dans le cadre d'un scénario de repli.

**Important**  
La prise en charge des comptes de service personnalisés est désactivée par défaut et doit être explicitement activée par un administrateur de cluster avant utilisation. Pour obtenir des instructions, consultez [Activer les comptes de service personnalisés](#sagemaker-hyperpod-model-deployment-deploy-nvme-sa-enable).

Si vous ne spécifiez pas a ServiceAccount, la valeur par défaut de l'espace de noms ServiceAccount est utilisée.

### Activer les comptes de service personnalisés
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-enable"></a>

La prise en charge des comptes de service personnalisés est désactivée par défaut. Un administrateur de cluster doit l'activer dans la configuration Helm de l'opérateur avant que les utilisateurs puissent faire référence à la personnalisation ServiceAccounts dans leur`InferenceEndpointConfig`.
+ Mettez à jour les valeurs Helm de l'opérateur pour activer la fonctionnalité. Si vous avez déployé l'opérateur via Helm, procédez à la mise à niveau avec le drapeau suivant :

  ```
  helm upgrade hyperpod-inference-operator <CHART_PATH> \
    --set enableCustomServiceAccounts=true \
    --reuse-values
  ```
+ Si vous avez déployé l'opérateur en tant que module complémentaire Amazon EKS, mettez à jour la configuration du module complémentaire pour l'inclure `enableCustomServiceAccounts: true` dans les paramètres de configuration avancés.
+ Vérifiez que la variable d'environnement est définie sur le pod opérateur :

  ```
  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")'
  ```

  Vous devriez voir :

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

**Important**  
Si cette fonctionnalité n'est pas activée, toute `InferenceEndpointConfig` fonctionnalité spécifiée `kubernetes.serviceAccountName` est rejetée avec un `DeploymentFailed` statut et le message :`kubernetes.serviceAccountName is not enabled. Requires addon configuration (enableCustomServiceAccounts: true)`.

### Étiqueter le compte de service
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-label"></a>

Avant de pouvoir référencer une personnalisation ServiceAccount, un administrateur de cluster doit l'étiqueter comme étant assignable par l'utilisateur :

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

Ce n'est qu' ServiceAccounts avec cette étiquette que les points de terminaison d'inférence peuvent être référencés. Il s'agit d'un contrôle de sécurité destiné à empêcher l'augmentation non autorisée des privilèges.

### Spécifiez le compte de service dans votre configuration
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-spec"></a>

Ajoutez le `serviceAccountName` champ ci-dessous `spec.kubernetes` dans votre `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
```

### Règles de validation
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-validation"></a>

L'opérateur valide le `serviceAccountName` champ lors des opérations de création et de mise à jour. Votre déploiement sera rejeté avec un `DeploymentFailed` statut si l'une des conditions suivantes est remplie :
+ Le ServiceAccount n'existe pas dans l'espace de noms — `serviceAccountName "X" not found in namespace "Y"`
+  ServiceAccount Il manque l'étiquette requise — `serviceAccountName "X" is not labeled as user-assignable (requires label sagemaker.amazonaws.com/user-assignable=true)`
+  ServiceAccount C'est le système de l'opérateur ServiceAccount — `serviceAccountName must not reference the operator's service account`

**Note**  
Tous les conteneurs du module d'inférence (conteneurs de travail, conteneurs d'initialisation et sidecars) héritent des autorisations spécifiées. ServiceAccount Si le ServiceAccount est annoté avec`eks.amazonaws.com/role-arn`, le pod reçoit des AWS informations d'identification temporaires pour ce rôle IAM. Les administrateurs de clusters ne doivent étiqueter ServiceAccounts le cluster comme étant assignable par l'utilisateur qu'après avoir examiné les rôles RBAC et les autorisations IAM associés.

**Note**  
Si a ServiceAccount est supprimé alors qu'un `InferenceEndpointConfig` est déjà en cours d'exécution, les pods existants continuent de fonctionner avec leurs informations d'identification actuelles jusqu'à ce qu'ils soient redémarrés. Cependant, la création d'un nouveau module (par exemple, lors du redimensionnement ou de la replanification) échouera car il ServiceAccount n'existe plus. L'opérateur valide le ServiceAccount moment où le déploiement est créé pour la première fois et la date de mise à jour des spécifications IEC. Il ne surveille pas en permanence le. ServiceAccount La mise à jour de la spécification IEC après la suppression de la SA entraînera un `DeploymentFailed` statut.

### Bonnes pratiques de sécurité pour les comptes de service personnalisés
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-sa-security"></a>

Lorsque vous utilisez une option personnalisée ServiceAccount avec des points de terminaison d'inférence, l'opérateur d' HyperPod inférence crée des déploiements en votre nom. Tous les conteneurs du module d'inférence, y compris le worker, les conteneurs d'initialisation et les sidecars, héritent des autorisations spécifiées. ServiceAccount Suivez ces bonnes pratiques pour sécuriser votre cluster.

**Verrouiller les autorisations RBAC**
+ Créez une charge de travail dédiée ServiceAccount à chaque charge de travail d'inférence. Ne réutilisez pas le produit ServiceAccounts sur des charges de travail indépendantes.
+ Ne liez que les autorisations RBAC minimales requises. Par exemple, si votre conteneur d'initialisation doit uniquement lire depuis Amazon S3, il ne ServiceAccount doit pas être autorisé à répertorier ou à modifier les ressources 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>
  ```
+ Évitez d'accorder des autorisations (ClusterRoleBindings) à l'échelle du cluster aux modules d'inférence ServiceAccounts utilisés par les pods d'inférence.

**Étendue des rôles IRSA IAM**
+ Lorsque vous annotez un ServiceAccount avec`eks.amazonaws.com/role-arn`, assurez-vous que le rôle IAM respecte les principes du moindre privilège.
+ Élargissez les autorisations Amazon S3 au compartiment et au préfixe spécifiques contenant les pondérations de votre modèle.

  ```
  {
    "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>/*"
      ]
    }]
  }
  ```
+ N'utilisez pas de politiques gérées de manière générale, comme `AmazonS3FullAccess` dans le cadre de la production. Utilisez `AmazonS3ReadOnlyAccess` une politique personnalisée adaptée à votre compartiment de modèles.

**Protégez l'étiquette assignable par l'utilisateur**
+ Seuls les administrateurs du cluster doivent ajouter ou supprimer l'`sagemaker.amazonaws.com/user-assignable=true`étiquette. Utilisez Kubernetes RBAC pour limiter les personnes autorisées à modifier les ServiceAccount étiquettes dans votre espace de noms.
+ Passez en revue les rôles RBAC et les autorisations IAM associés à un ServiceAccount avant de l'étiqueter comme étant assignable par l'utilisateur.
+ Auditez périodiquement ServiceAccounts ceux qui portent le `user-assignable` label.

  ```
  kubectl get serviceaccounts -n <NAMESPACE> -l sagemaker.amazonaws.com/user-assignable=true
  ```
+ Assurez-vous que les rôles non administrateurs n'incluent pas `patch` de `update` `create` verbes sur ServiceAccount les ressources. L'opérateur valide l'`user-assignable`étiquette au moment du déploiement, mais n'empêche pas les utilisateurs non autorisés d'ajouter l'étiquette à un ServiceAccount. Le contrôle principal pour protéger cette étiquette est de restreindre les personnes autorisées à modifier ServiceAccounts via le RBAC. Non-admin les utilisateurs ne doivent avoir `get` et `list` accéder qu'aux éléments suivants :

  ```
  # 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"]
  ```

**Important**  
L'opérateur HyperPod d'inférence agit comme un intermédiaire qui crée des déploiements pour le compte des utilisateurs. Contrairement aux charges de travail Kubernetes standard dans lesquelles l'appelant crée directement des pods, l'opérateur assigne les pods spécifiés aux pods qu'il crée. ServiceAccount Cela signifie que toutes les autorisations accordées à un objet assignable par l'utilisateur ServiceAccount sont effectivement accessibles à tous ceux qui peuvent en créer un `InferenceEndpointConfig` dans cet espace de noms. Assurez-vous que le RBAC au niveau de l'espace de noms contrôle qui peut créer et mettre à jour des ressources. `InferenceEndpointConfig`

## Précharger les poids des modèles dans NVMe
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-preload"></a>

Si vous devez préremplir le NVMe sur des nœuds spécifiques avant le déploiement, vous pouvez utiliser un module unique pour effectuer la synchronisation depuis Amazon S3.

**Note**  
Cette approche cible un nœud spécifique `nodeName` et ne fonctionne pas avec l'autoscaling. Pour les scénarios de dimensionnement automatique, utilisez le volume Kubernetes avec solution de secours ou Amazon S3 avec des approches de prélecture, qui gèrent automatiquement les modèles manquants via la logique de repli d'InitContainer.

1. Créez le fichier YAML du pod de préchargement. Remplacez les valeurs d'espace réservé par vos identificateurs de ressources réels.

   ```
   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. Appliquez le module et surveillez la progression de la synchronisation.

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

1. Nettoyez le pod une fois la synchronisation terminée.

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

## Noms de volumes réservés
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-reserved-volumes"></a>

L'opérateur gère plusieurs volumes internes qui ne peuvent pas être remplacés par. `kubernetes.volumes` L'utilisation de l'un de ces noms entraîne une `KubernetesVolumeValidationFailed` condition.


**Noms de volumes réservés**  

| \# | Nom | Objectif | 
| --- | --- | --- | 
| 1 | shm | Mémoire partagée (/dev/shm) pour la communication entre processus | 
| 2 | model-weights-copy | RAM-backed EmptyDir utilisé lorsque prefetchEnabled: true | 
| 3 | parallel-copy-configmap | ConfigMap pour un script de copie parallèle (prefetch) | 
| 4 | lmcache-config | Volume de configuration LMCache | 
| 5 | gated-model-downloader-configmap | ConfigMap pour le script de téléchargement de modèles sécurisés | 

## Choses à retenir
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-things-to-remember"></a>
+ **N'utilisez pas de noms de volumes réservés.** L'opérateur gère plusieurs volumes internes (voir[Noms de volumes réservés](#sagemaker-hyperpod-model-deployment-deploy-nvme-reserved-volumes)). L'utilisation de l'un de ces noms `kubernetes.volumes` entraîne une `KubernetesVolumeValidationFailed` condition.
+ **Les noms des volumes doivent correspondre.** L'opérateur tire le nom du volume de`modelVolumeMount.name`. Lors de l'utilisation`modelSourceType: kubernetesVolume`, `kubernetes.volumes` il doit contenir un volume portant le même nom.
+ **Montez les volumes au bon emplacement dans votre InitContainer.** Assurez-vous que tout volume que vous créez est monté sur le bon chemin dans votre InitContainer.
+ **Aucun compte de service personnalisé n'est nécessaire pour S3/FSx.** Si vous ne parvenez pas à créer de comptes de service personnalisés ou si vous préférez ne pas le faire, vous pouvez utiliser `modelSourceType: s3` ou`fsx`. L'opérateur approvisionne automatiquement S3/FSx les volumes. Vous pouvez toujours ajouter des volumes personnalisés `initContainers` et des volumes de remplacement en plus du stockage géré par l'opérateur.
+ **Les informations d'identification IRSA sont injectées dans tous les conteneurs.** Lorsque vous définissez un compte `kubernetes.serviceAccountName` de service avec une annotation IRSA, Amazon EKS injecte des AWS informations d'identification (`aws-iam-token`volume,,`AWS_WEB_IDENTITY_TOKEN_FILE`) dans tous les conteneurs`AWS_ROLE_ARN`, y compris vos InitContainers personnalisés.
+ **Ne le réglez pas `modelLocation` lors de l'utilisation`kubernetesVolume`.** Le chemin du volume est contrôlé par`kubernetes.volumes`. `modelSourceType`Le réglage du `modelLocation` moment `kubernetesVolume` entraîne une erreur de validation.
+ **Comprenez comment `model-weights` VS `model-weights-copy` fonctionne avec Prefetch.** Lorsque `prefetchEnabled: true` l'opérateur crée deux volumes liés au modèle :
  + `model-weights`— le volume source (depuis Amazon S3/Amazon FSx PVC ou votre override)
  + `model-weights-copy`— un RAM-backed EmptyDir dans lequel le travailleur lit réellement
+ Lorsque vous faites référence `model-weights` dans votre configuration, à quel moment`prefetchEnabled: true`, c'est réellement `model-weights-copy` ce qui est monté `/opt/ml/model` dans le conteneur de travail. Lorsque vous utilisez un InitContainer personnalisé, assurez-vous de copier les données dans le volume appelé`model-weights-copy`, c'est là que le travailleur s'attend à les trouver. Lorsqu'`prefetchEnabled: false`il n'y a qu'un seul volume (nommé d'après votre`modelVolumeMount.name`) et qu'il est monté directement sur`/opt/ml/model`.

## Résolution des problèmes
<a name="sagemaker-hyperpod-model-deployment-deploy-nvme-troubleshooting"></a>

Utilisez ces commandes de débogage si votre déploiement ne fonctionne pas comme prévu.
+ Vérifiez le `InferenceEndpointConfig` statut pour connaître l'état de déploiement de haut niveau et les éventuels problèmes de configuration.

  ```
  kubectl describe InferenceEndpointConfig <ENDPOINT_NAME> -n <NAMESPACE>
  ```
+ Vérifiez le statut du déploiement de Kubernetes.

  ```
  kubectl describe deployment <ENDPOINT_NAME> -n <NAMESPACE>
  ```
+ Vérifiez le statut de tous les objets Kubernetes de votre espace de noms.

  ```
  kubectl get pods,svc,deployment,InferenceEndpointConfig,sagemakerendpointregistration -n <NAMESPACE>
  ```
+ Consultez les journaux InitContainer si l'étape de chargement du modèle échoue.

  ```
  kubectl logs <POD_NAME> -c smart-loader -n <NAMESPACE>
  ```
+ Si le déploiement échoue avec le message « introuvable dans l'espace de noms », vérifiez que cela ServiceAccount existe :

  ```
  kubectl get serviceaccount <name> -n <namespace>
  ```
+ Si le déploiement échoue avec la mention « non étiqueté comme assignable par l'utilisateur », demandez à votre administrateur de cluster d'ajouter le libellé requis :

  ```
  kubectl label serviceaccount <name> sagemaker.amazonaws.com/user-assignable=true -n <namespace>
  ```
+ Si le déploiement échoue avec la mention « ne doit pas faire référence au compte de service de l'opérateur », créez un compte distinct ServiceAccount pour votre charge de travail. Vous ne pouvez pas utiliser le propre ServiceAccount opérateur d' HyperPod inférence.