View a markdown version of this page

Déployez des modèles à partir d'un stockage NVMe local à l'aide de kubectl - Amazon SageMaker AI

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

Cette rubrique explique comment déployer des points de terminaison d'inférence sur Amazon SageMaker HyperPod qui chargent les poids des modèles à partir du stockage NVMe local d'un nœud au lieu de les transférer via le réseau depuis Amazon S3 ou Amazon FSx. La lecture locale des poids élimine le saut réseau lors du démarrage du pod, ce qui réduit le temps de démarrage à froid du pod d'inférence et est utile pour les événements de dimensionnement automatique, les 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 local et éphémère : 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 ce problème différemment : certaines nécessitent de pré-remplir chaque nœud, d'autres font automatiquement appel à 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 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 (pas de solution de secours) À utiliser lorsque des poids de modèle existent sur NVMe sur chaque nœud. Configuration la plus simple : aucun Amazon S3, Amazon FSx ou PV/PVC InitContainers n'est requis.
2 Volume Kubernetes avec solution de secours À utiliser lorsque le modèle n'existe peut-être pas sur NVMe sur tous les nœuds. Vous fournissez une option personnalisée initContainer qui vérifie d'abord NVMe et effectue les téléchargements depuis Amazon S3 à l'aide des informations d'identification IRSA si le modèle est absent.
3 Amazon S3 avec fonction de prélecture et de repli À utiliser lorsque vous souhaitez adapter le poids du modèle à la RAM pour le démarrage du pod. Vous fournissez une personnalisation initContainer qui vérifie d'abord NVMe et revient à la copie depuis le montage Amazon S3 provisionné par l'opérateur si le modèle n'est pas mis en cache localement.

Conditions préalables

Avant de commencer, vérifiez les points suivants :

Choisissez votre approche de déploiement

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 (pas de solution de secours)

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 : pas de configuration Amazon S3 ou Amazon FSx PV/PVC, non et pas d'InitContainers.

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

Important

Lors de l'utilisationmodelSourceType: kubernetesVolume, l'opérateur dérive le nom de volume attendu à partir de la configuration modelVolumeMount.name de votre serveur de travail. kubernetes.volumesdoit 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 utilisentmodel-weights.

  1. Créez le fichier InferenceEndpointConfig YAML. Remplacez les valeurs des espaces réservés par vos identifiants 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
    Note

    Pour configurer la mise en cache KV et le routage intelligent afin d'améliorer les performances, consultezConfiguration de la mise en cache KV et du routage intelligent.

  2. Déployez leInferenceEndpointConfig.

    kubectl apply -f deploy_nvme_k8s_volume.yaml
  3. 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

Utilisez cette approche lorsque le modèle peut être sur NVMe ou non 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 créeraient un chemin vide ou inexistant, provoquant la défaillance du serveur modèle.

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

Configurer IRSA

Avant le déploiement, configurez les rôles IAM pour les comptes de service (IRSA) pour fournir les informations d'identification de vos pods à télécharger 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
  2. Créez une politique de confiance IAM. Enregistrez ce qui suit soustrust-policy.json, en remplaçant les valeurs des espaces réservés.

    { "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

    Étendez 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 à n'importe quel utilisateur de n'importe ServiceAccount quel espace de noms d'assumer le rôle.

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

    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>/*" ] }] }'
  4. 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

  1. Créez le fichier InferenceEndpointConfig YAML. Remplacez les valeurs des espaces réservés par vos identifiants 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
    Note

    Pour configurer la mise en cache KV et le routage intelligent afin d'améliorer les performances, consultezConfiguration de la mise en cache KV et du routage intelligent.

  2. Déployez leInferenceEndpointConfig.

    kubectl apply -f deploy_nvme_k8s_volume_fallback.yaml
  3. 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 NVMe Fallback

Utilisez cette approche lorsque vous souhaitez inférer les performances en répartissant les poids du modèle dans 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 avecprefetchEnabled: true, l'opérateur crée automatiquement deux volumes :

  • Un volume nommé d'après votre modelVolumeMount.name (généralementmodel-weights) : un support de fusible Amazon S3 CSI contenant votre modèle

  • model-weights-copy— un RAM-backed emptyDir endroit où le travailleur lit un extrait de

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 de NVMe vers la RAM (model-weights-copy), en ignorant complètement le réseau.

  • Si le modèle est absent, recommence à copier depuis le support Amazon S3 (model-weights) vers la RAM (model-weights-copy). Copie éventuellement vers NVMe afin que les démarrages ultérieurs du pod sur le même nœud utilisent le chemin local rapide.

Important

Ne l'utilisez pas model-weights en kubernetes.volumes cas d'utilisation de cette approche. L'opérateur crée un model-weights pointage vers le volume Amazon S3 CSI. Le fait de le remplacer supprime le volume provisionné par l'opérateur dont votre InitContainer a besoin pour se replier. Utilisez un nom de volume distinct (par exemplenvme-cache) pour votre NVMe HostPath.

Important

Ne pas inclure model-weights-copy danskubernetes.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 comme un volume.

  1. Créez le fichier InferenceEndpointConfig YAML. Remplacez les valeurs des espaces réservés par vos identifiants 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
    Note

    Pour configurer la mise en cache KV et le routage intelligent afin d'améliorer les performances, consultezConfiguration de la mise en cache KV et du routage intelligent.

  2. Déployez leInferenceEndpointConfig.

    kubectl apply -f deploy_nvme_s3_prefetch_fallback.yaml
  3. Vérifiez l'état du déploiement.

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

Comprendre les pondérations des modèles et les pondérations des modèles avec Prefetch

Lors de l'utilisation de la fonction prefetch, l'opérateur crée deux volumes liés au modèle :

  • Un volume nommé d'après votre modelVolumeMount.name (généralementmodel-weights) : un support de fusible Amazon S3 CSI contenant votre modèle

  • model-weights-copy— un RAM-backed EmptyDir où le travailleur lit réellement à partir de

Dans votreInferenceEndpointConfig, vous définissez :

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

Pendant que vous faites référencemodel-weights, quandprefetchEnabled: 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.

Quand prefetchEnabled: false il n'y a qu'un seul volume (nommé d'après le vôtremodelVolumeMount.name) et qu'il est monté directement sur/opt/ml/model.

Configurer un compte de service personnalisé

Vous pouvez attribuer un Kubernetes personnalisé ServiceAccount à vos pods de points de terminaison d'inférence à l'aide du champ duspec.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 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.

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

Activer les comptes de service personnalisés

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 pour que les utilisateurs puissent faire référence à la personnalisation ServiceAccounts dans leurInferenceEndpointConfig.

  • Mettez à jour les valeurs Helm de l'opérateur pour activer la fonctionnalité. Si vous avez déployé l'opérateur via Helm, effectuez 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 dans le module opérateur :

    kubectl get deployment hyperpod-inference-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, tout InferenceEndpointConfig ce qui kubernetes.serviceAccountName est spécifié est rejeté avec un DeploymentFailed statut et le message :kubernetes.serviceAccountName is not enabled. Requires addon configuration (enableCustomServiceAccounts: true).

Étiquetez le compte de service

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 toute escalade de privilèges non autorisée.

Spécifiez le compte de service dans votre configuration

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

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 pod d'inférence (worker, conteneurs d'initialisation et sidecars) héritent des autorisations du conteneur spécifié. ServiceAccount Si le ServiceAccount est annoté aveceks.amazonaws.com/role-arn, le pod reçoit des AWS informations d'identification temporaires pour ce rôle IAM. Les administrateurs de cluster ne doivent étiqueter ServiceAccounts comme pouvant être attribués 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 que an 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 pod (par exemple, lors de la mise à l'échelle 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 à laquelle la spécification IEC est mise à jour ; 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.

Meilleures pratiques de sécurité pour les comptes de service personnalisés

Lorsque vous utilisez une configuration 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 des éléments spécifiés. 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 les réutilisez pas ServiceAccounts sur des charges de travail indépendantes.

  • Liez uniquement 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 à l'échelle du cluster (ClusterRoleBindings) aux pods d' ServiceAccounts inférence utilisés.

Champ d'application des rôles IAM de l'IRSA

  • Lorsque vous annotez un ServiceAccount witheks.amazonaws.com/role-arn, assurez-vous que le rôle IAM respecte les principes du moindre privilège.

  • Étendez les autorisations Amazon S3 au compartiment et au préfixe spécifiques contenant les poids de vos modèles.

    { "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 de gestion générales, comme AmazonS3FullAccess dans le cas de la production. Utilisez AmazonS3ReadOnlyAccess ou une politique personnalisée adaptée à votre compartiment de modèles.

Protégez l'étiquette assignable par l'utilisateur

  • Seuls les administrateurs de cluster peuvent 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 élément ServiceAccount avant de le qualifier d'attribuable par l'utilisateur.

  • Auditez périodiquement ServiceAccounts ceux qui portent l'user-assignableétiquette.

    kubectl get serviceaccounts -n <NAMESPACE> -l sagemaker.amazonaws.com/user-assignable=true
  • Assurez-vous que les rôles non-administrateurs n'incluent pas de patchupdate, ou de 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. Restreindre les personnes autorisées à modifier ServiceAccounts via RBAC est le principal contrôle pour protéger cette étiquette. Non-admin les utilisateurs ne devraient avoir get et list accéder qu'à :

    # 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 en tant qu'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 espaces, l'opérateur attribue les éléments spécifiés aux espaces qu'il crée. ServiceAccount Cela signifie que toutes les autorisations accordées à un objet assignable par l'utilisateur ServiceAccount sont effectivement disponibles pour quiconque peut 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échargez les poids du modèle dans NVMe

Si vous devez préremplir 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 via nodeName et ne fonctionne pas avec la mise à l'échelle automatique. Pour les scénarios de dimensionnement automatique, utilisez le volume Kubernetes avec repli ou Amazon S3 avec des approches de prélecture, qui gèrent automatiquement les modèles manquants via la logique de repli InitContainer.

  1. Créez le fichier YAML du pod de préchargement. Remplacez les valeurs des espaces réservés par vos identifiants 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
  2. 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
  3. Nettoyez le module une fois la synchronisation terminée.

    kubectl delete pod nvme-s3-copy

Noms de volumes réservés

L'opérateur gère plusieurs volumes internes qui ne peuvent pas être remplacés via. kubernetes.volumes L'utilisation de l'un de ces noms entraîne la création d'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 fermés

Choses à retenir

  • N'utilisez pas de noms de volumes réservés. L'opérateur gère plusieurs volumes internes (voirNoms de volumes réservés). L'utilisation de l'un de ces noms kubernetes.volumes entraîne la création d'une KubernetesVolumeValidationFailed condition.

  • Les noms des volumes doivent correspondre. L'opérateur obtient le nom du volume à partir demodelVolumeMount.name. Lors de l'utilisationmodelSourceType: kubernetesVolume, kubernetes.volumes doit contenir un volume portant le même nom.

  • Montez les volumes au bon endroit dans votre InitContainer. Assurez-vous que tout volume que vous créez est monté sur le chemin correct dans votre InitContainer.

  • Aucun compte de service personnalisé n'est nécessaire pour S3/FSx. Si vous ne parvenez pas à créer des comptes de service personnalisés ou si vous préférez ne pas le faire, vous pouvez utiliser modelSourceType: s3 oufsx. L'opérateur approvisionne S3/FSx les volumes automatiquement. 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-tokenvolume,,AWS_WEB_IDENTITY_TOKEN_FILE) dans tous les conteneursAWS_ROLE_ARN, y compris vos InitContainers personnalisés.

  • Ne pas régler modelLocation lors de l'utilisationkubernetesVolume. Le trajet du volume est contrôlé parkubernetes.volumes. modelSourceTypeLe fait de définir modelLocation quand kubernetesVolume entraîne une erreur de validation.

  • Comprenez comment model-weights-copy fonctionne model-weights vs 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 remplacement)

    • model-weights-copy— un RAM-backed EmptyDir où le travailleur lit réellement à partir de

  • Pendant que vous model-weights faites référence dans votre configurationprefetchEnabled: 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. Quand prefetchEnabled: false il n'y a qu'un seul volume (nommé d'après le vôtremodelVolumeMount.name) et qu'il est monté directement sur/opt/ml/model.

Résolution des problèmes

Utilisez ces commandes de débogage si votre déploiement ne fonctionne pas comme prévu.

  • Vérifiez l'InferenceEndpointConfigétat 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 l'état 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 « introuvable dans l'espace de noms », vérifiez ServiceAccount qu'il existe :

    kubectl get serviceaccount <name> -n <namespace>
  • Si le déploiement échoue avec le message « non étiqueté comme assignable par l'utilisateur », demandez à votre administrateur de cluster d'ajouter l'étiquette requise :

    kubectl label serviceaccount <name> sagemaker.amazonaws.com/user-assignable=true -n <namespace>
  • Si le déploiement échoue avec le message « 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.