Sélection de conteneur de serving
Le conteneur de serving est l'élément le plus susceptible de casser un déploiement SageMaker qui « semblait correct sur le papier ». Un mauvais conteneur, une étiquette obsolète, ou le mauvais AMI — produisent tous la même erreur opaque Failed to pass health check.
Règle zéro : les images HuggingFace gagnent toujours
Quand une famille curée par HuggingFace (huggingface-vllm, huggingface-vllm-omni, huggingface-sglang, tei, huggingface-pytorch-inference) et une famille générique (vllm, vllm-omni, sglang, djl-inference) peuvent servir le modèle, celle de HuggingFace est obligatoire, pas seulement préférée. Les seules raisons valides d'utiliser une image générique :
- Incompatibilité vérifiée — le modèle nécessite une architecture/modalité/fonctionnalité qu'aucune étiquette HuggingFace disponible ne supporte, confirmée par rapport au catalogue (pas supposée).
- Aucune étiquette HuggingFace n'existe dans la région cible et le mirroring n'est pas une option.
- L'image HuggingFace est dans « Images connues comme cassées » ci-dessous.
Un numéro de version plus récent sur le repo générique n'est pas une raison. Le repo AWS vllm publie souvent une version vLLM supérieure à huggingface-vllm ; une étiquette huggingface-vllm plus ancienne mais compatible gagne quand même. « Dernier vLLM » n'est pas une exigence que quelqu'un a énoncée — c'est la compatibilité avec le modèle qui compte. Si vous revenez en arrière, enregistrez dans le journal de déploiement laquelle des trois raisons s'appliquait.
D'où proviennent les URIs d'image
Source principale : le catalogue officiel AWS Deep Learning Containers.
URL : https://aws.github.io/deep-learning-containers/reference/available_images/
Cette page est maintenue par AWS et liste chaque famille d'images avec des URIs d'exemple, des étiquettes, des versions CUDA, des versions Python, et la plateforme (SageMaker vs EC2/ECS/EKS). Quand vous choisissez un URI pour un déploiement, lisez-le directement sur cette page — copiez l'URL d'exemple, remplacez <region> par la région de l'utilisateur, et passez-le à deploy.py --image-uri.
Les URLs d'exemple utilisent 763104351884 comme ID de compte pour la plupart des régions. Quelques régions utilisent des comptes différents (par ex. eu-south-1 utilise 692866216735). Consultez la page Region Availability en cas de doute.
Exception : aucune actuellement. Chaque famille d'images utilisée par ce workflow se trouve maintenant sur la page du catalogue AWS (TEI a été ajouté fin 2026). Si vous rencontrez une nouvelle famille qui n'y figure pas, mirrorisez-la via mirror_image.py et passez l'URI résultant directement.
Décision rapide
| Modèle | Famille de conteneur | Comment obtenir l'URI |
|---|---|---|
| LLM de génération de texte HuggingFace (Llama, Qwen, Mistral, etc.) | HuggingFace vLLM | Catalogue AWS → « HuggingFace vLLM Inference » (repo ECR huggingface-vllm) |
| Idem, multimodal | HuggingFace vLLM-Omni | Catalogue AWS → « HuggingFace vLLM-Omni Inference » (repo ECR huggingface-vllm-omni) |
| Embeddings HuggingFace | TEI | Catalogue AWS → « HuggingFace Text Embeddings Inference » |
Encodeur / rerankers cross-encoder (famille BERT *ForSequenceClassification) |
TEI | Idem que les embeddings |
| Rerankers génératifs (causal-LM, ex. Qwen3-Reranker) | HuggingFace vLLM | Idem que les LLMs de génération de texte — pas TEI, voir « Rerankers : TEI ou vLLM ? » |
| Texte-vers-image / diffusion (Stable Diffusion, FLUX) | DJL Inference | Catalogue AWS → « DJL Inference » — pas HuggingFace Inference Toolkit, voir « Images connues comme cassées » |
| Classifieurs HuggingFace, NER, QA, summarization | HuggingFace Inference Toolkit (CPU) | Catalogue AWS → « HuggingFace PyTorch Inference » ; les étiquettes GPU sont actuellement cassées — voir « Images connues comme cassées » |
| L'utilisateur veut spécifiquement SGLang | HuggingFace SGLang | Catalogue AWS → « HuggingFace SGLang Inference » |
Pas d'étiquette huggingface-vllm compatible (incompatibilité vérifiée ou écart régional — voir « Règle zéro ») |
vLLM (AWS) | Catalogue AWS → section « vLLM » — fallback uniquement, jamais pour la fraîcheur de version |
| L'utilisateur veut spécifiquement DJL-LMI | DJL Inference | Catalogue AWS → « DJL Inference » |
| Amazon Nova | SageMaker JumpStart | Utilisez JumpStart, pas la création d'endpoint brute |
| Code d'inférence personnalisé | BYOC | L'utilisateur fournit l'URI |
Les DLCs curés par HuggingFace sont obligatoires quand l'un est compatible (voir « Règle zéro »). huggingface-vllm est déployé directement sur le DLC AWS vLLM — *contrat `SMVLLMidentique et la même règle d'AMI cu130** — et ajoutetransformersactuel,huggingface_hub+hf_xetactuel (évite les échecs de téléchargement 403 XET-CDN que les anciennes images connaissent), et les défauts de performance HF. C'est aussi vers quoi le SageMaker SDK v3 s'achemine automatiquement. L'image AWSvllmest un échappatoire de compatibilité uniquement ; elle affiche généralement une version vLLM supérieure àhuggingface-vllm`, et ce n'est pas une raison de la choisir.
N'utilisez pas TGI. Text Generation Inference est archivé. Les modèles publiés après l'archivage (Qwen3 en particulier) échouent les vérifications de santé ping sur TGI. Utilisez vLLM à la place. (Le SageMaker SDK v3 est d'accord : depuis PR #5960, juin 2026, son ModelBuilder s'achemine automatiquement la text-generation vers le DLC HuggingFace vLLM et les tâches multimodales vers HuggingFace vLLM-Omni.)
Raisonnement complet pour chaque famille dans references/model-to-image.md.
Rerankers : TEI ou vLLM ?
« Reranker » couvre deux architectures très différentes, et choisir mal gaspille un cycle complet de création d'endpoint (~20 min) avant que TEI rejette le modèle :
- Encodeur cross-encoders (BAAI/bge-reranker-*, mixedbread, plupart des rerankers
sentence-transformers) — modèles de famille BERT avec une tête de classification.config.jsonaarchitectures: [..ForSequenceClassification]sur un type d'encodeur supporté par TEI. → TEI. - Rerankers génératifs (Qwen/Qwen3-Reranker-, et juges causal-LM similaires) — LLMs décoder qui évaluent la pertinence via la logprob d'un token oui/non.
config.jsonaarchitectures: [..ForCausalLM]. → HuggingFace vLLM, déployé exactement comme un LLM de génération de texte. TEI chargera l'architecture puis rejettera le type de modèleclassifier(le support Qwen3 dans TEI est embeddings uniquement*). Le motif d'invocation (API completions brute,max_tokens=1, évaluation logprobs) se trouve danshf-cloud-sagemaker-production-defaults.
Pré-contrôle avant de créer des ressources — une GET HTTP règle la question :
curl -s https://huggingface.co/<model-id>/raw/main/config.json
# "architectures": ["Qwen3ForCausalLM"] → vLLM
# "architectures": ["XLMRobertaForSequenceClassification"] → TEI
Pour TEI, confirmez aussi la paire (architecture, tâche) : une architecture apparaissant dans la liste supportée par TEI signifie support des embeddings, pas nécessairement support de la classification/reranking.
Attention : SageMaker SDK v3 (PR #5960) achemine la tâche text-ranking vers TEI inconditionnellement — correct pour les cross-encoders, faux pour les rerankers génératifs. Ne traitez pas l'acheminement du SDK comme preuve que TEI peut servir un reranker donné.
Workflow
Pour chaque famille : lisez l'URI sur la page du catalogue AWS.
- Ouvrez https://aws.github.io/deep-learning-containers/reference/available_images/
- Trouvez la section pour la bonne famille (ex. « HuggingFace vLLM Inference » pour les LLMs HuggingFace, « HuggingFace Text Embeddings Inference » pour les embeddings)
- Choisissez la ligne la plus récente marquée
SageMakerdans la colonne plateforme — la plus récente au sein de cette famille. Ne basculez pas vers la section d'une autre famille parce qu'elle liste une version moteur supérieure (voir « Règle zéro ») - Remplacez
<region>par la région de l'utilisateur (depuishf-cloud-aws-context-discovery) - Pour vLLM : vérifiez aussi l'exigence d'AMI (voir « Exigence d'AMI vLLM » ci-dessous)
- Passez l'URI à
deploy.py --image-uri(temps réel) oudeploy_async.py --image-uri(async)
TEI : choisir la bonne variante
La ligne du catalogue TEI liste deux URIs — GPU (repo tei) et CPU (repo tei-cpu). Choisissez selon le type d'instance :
ml.g*,ml.p*,ml.inf*→ variante GPUml.c*,ml.m*,ml.t*→ variante CPU
Les mélanger échoue : image CPU sur une instance GPU gaspille le matériel, image GPU sur une instance CPU échoue au démarrage.
Note sur l'ID de compte TEI : la page du catalogue affiche 683313688378 comme compte d'exemple, mais TEI est publié depuis un espace de noms de compte différent des DLCs AWS principaux et les ID de compte par région varient. Si 683313688378.dkr.ecr.<region>.amazonaws.com/tei:... retourne une erreur ECR pull pour une région autre que us-east-1, consultez la page Region Availability pour l'ID de compte correct pour cette région.
Exigence d'AMI vLLM
Les images DLC vLLM avec CUDA 13 ou supérieur (défaut actuel : cu130) nécessitent de définir InferenceAmiVersion=al2-ami-sagemaker-inference-gpu-3-1 sur ProductionVariant. Cela s'applique également à huggingface-vllm et huggingface-vllm-omni (déployés sur la même base cu130) et au repo AWS vllm. Sans cela, le conteneur meurt au démarrage sans aucun journal CloudWatch jamais créé. L'échec ressemble à beaucoup d'autres choses (problèmes au niveau du compte, quota, réseautage) et envoie régulièrement les gens sur les mauvais chemins de diagnostic.
Tableau de consultation :
| L'étiquette contient | InferenceAmiVersion à passer |
|---|---|
cu130 (ou supérieur) |
al2-ami-sagemaker-inference-gpu-3-1 |
cu129 ou inférieur |
(omettez le drapeau ; l'AMI par défaut fonctionne) |
Règle empirique : si l'étiquette vLLM que vous avez choisie contient cu130 ou plus récent, passez --inference-ami-version al2-ami-sagemaker-inference-gpu-3-1 à deploy.py. Si une version CUDA future (cu140+) nécessite un AMI différent, ajoutez une ligne au tableau quand AWS publie la nouvelle image.
C'est une préoccupation spécifique à vLLM. Les images TEI et HuggingFace Inference Toolkit n'ont pas besoin d'override d'AMI.
Configuration des DLCs vLLM (HuggingFace vLLM et AWS vLLM)
Les deux images partagent le même contrat : configuration en tant que variables d'environnement sur la définition de modèle SageMaker, SM_VLLM_* mappée aux drapeaux CLI vLLM. Le point d'entrée huggingface-vllm détecte également automatiquement le modèle quand SM_VLLM_MODEL n'est pas défini — depuis /opt/ml/model si les artefacts sont montés, sinon depuis HF_MODEL_ID — mais définir SM_VLLM_MODEL explicitement fonctionne sur les deux et est ce que nos exemples utilisent.
Requis pour chaque déploiement LLM HuggingFace
| Variable env | Objectif | Notes |
|---|---|---|
SM_VLLM_MODEL |
ID modèle HF (ex. Qwen/Qwen3-0.6B) ou /opt/ml/model si chargement depuis S3 |
— |
SM_VLLM_HOST |
Doit être 0.0.0.0 |
Sinon vLLM se lie à localhost uniquement, ping échoue, conteneur meurt avant les logs. Cause principale des mystérieux échecs avec cette image. |
SM_VLLM_TRUST_REMOTE_CODE |
true pour Qwen et plusieurs architectures récentes |
Définissez inconditionnellement — l'inconvénient est négligeable, l'avantage c'est que le modèle se charge. |
HUGGING_FACE_HUB_TOKEN |
Jeton HF | Requis pour les modèles gatés. |
Réglage (optionnel)
| Variable env | Objectif |
|---|---|
SM_VLLM_MAX_MODEL_LEN |
Longueur max de séquence — définissez ceci ; les défauts peuvent être incorrects pour les fine-tunes |
SM_VLLM_GPU_MEMORY_UTILIZATION |
Float 0.0–1.0, ~0.9 raisonnable |
SM_VLLM_TENSOR_PARALLEL_SIZE |
Nombre de GPUs pour instances multi-GPU |
SM_VLLM_DTYPE |
auto, bfloat16, float16 |
N'importe quel drapeau CLI vLLM fonctionne — majuscules, remplacez tirets par underscores, préfixez par SM_VLLM_.
Configuration de TEI
Contrat env plus simple que vLLM :
| Variable env | Objectif | Requis |
|---|---|---|
HF_MODEL_ID |
ID modèle HF (ex. BAAI/bge-large-en-v1.5) ou /opt/ml/model |
Oui |
HF_TOKEN |
Jeton d'authentification HF | Seulement pour les modèles gatés |
MAX_BATCH_TOKENS |
Max tokens par batch (défaut 16384) | Non |
MAX_CLIENT_BATCH_SIZE |
Max requêtes par batch client (défaut 32) | Non |
Pas de liaison d'hôte à configurer, pas de drapeau trust-remote-code. Les architectures que TEI supporte (BERT, CamemBERT, RoBERTa, XLM-RoBERTa, NomicBert, JinaBert, JinaCodeBert, Mistral, Qwen2/3, Gemma2/3, ModernBert) sont intégrées à l'image.
Compatibilité CUDA / instance
Critique et facile à se tromper :
| CUDA dans l'étiquette d'image | AMI par défaut | Avec al2-ami-sagemaker-inference-gpu-3-1 |
|---|---|---|
| cu124 / cu128 | g5, g6, p5 fonctionnent tous | (non nécessaire) |
| cu129 | g6, p5 ; g5 échoue (driver mismatch → CannotStartContainerError) | devrait corriger g5 (non vérifiés) |
| cu130+ | échoue partout — drapeau AMI est obligatoire | g5, g6, p5 fonctionnent tous (cu130-sur-g5 vérifié juin 2026) |
Le driver vient de l'AMI hôte, pas de la famille d'instances — donc passer l'AMI gpu-3-1 (que les images vLLM cu130 requièrent de toute façon) rend aussi ml.g5.* viable pour les images cu129+.
Problème de passerelle VPC / NAT
Les endpoints SageMaker à l'intérieur d'un VPC sans passerelle NAT ne peuvent pas tirer de public.ecr.aws. Le déploiement échoue avec une erreur de tirage d'image qui ne mentionne pas « VPC » ou « egress ».
Pour les images sur l'ECR régional AWS (tout dans le catalogue) : SageMaker les atteint via un acheminement intégré, pas de NAT nécessaire. Utilisez le motif d'URI régional (<account>.dkr.ecr.<region>.amazonaws.com/...), pas le motif public.ecr.aws/....
Pour les images nécessitant l'accès à public.ecr.aws (moins courant) : mirrorisez vers un repo ECR privé dans votre compte avec scripts/mirror_image.py (multiplateforme ; nécessite Docker + la CLI aws). Exécutez-le depuis le shell où la CLI AWS fonctionne.
# macOS / Linux
PRIVATE_URI=$(python3 scripts/mirror_image.py \
public.ecr.aws/deep-learning-containers/vllm:<tag> \
vllm-mirror)
# Windows (PowerShell) — capturez stdout dans une variable
$PRIVATE_URI = python scripts\mirror_image.py `
public.ecr.aws/deep-learning-containers/vllm:<tag> vllm-mirror
Quand la page du catalogue ne rend pas, est obsolète, ou est incorrecte
La page ne rend pas / le fetch retourne des ordures : la page du catalogue est lourde en JavaScript et certains outils de fetch obtiennent une coquille vide. Fallbacks, dans l'ordre :
- Les données source du catalogue sur GitHub — la page est générée à partir d'un fichier YAML par version, listant les étiquettes exactes, CUDA, et versions Python. Listez les fichiers d'une famille, puis récupérez le plus récent :
curl -s https://api.github.com/repos/aws/deep-learning-containers/contents/docs/src/data/huggingface-vllm curl -s https://raw.githubusercontent.com/aws/deep-learning-containers/main/docs/src/data/huggingface-vllm/0.21.0-gpu-sagemaker.ymlLes noms de répertoires correspondent aux repos ECR (
huggingface-vllm,huggingface-vllm-omni,huggingface-tei,vllm,djl-inference, ...). - Interrogez ECR directement pour les étiquettes actuelles dans la région cible (fonctionne avec les credentials qui peuvent lire le registre DLC ; s'il retourne AccessDenied, utilisez les fichiers YAML) :
aws ecr describe-images --registry-id 763104351884 --repository-name huggingface-vllm \ --region <region> --query 'sort_by(imageDetails,&imagePushedAt)[-5:].imageTags' --output json - Notes de version sur le repo GitHub DLC.
Une étiquette vient d'être publiée et n'est pas sur la page encore : rare ; AWS met à jour la page à chaque version. Vérifiez les notes de version ci-dessus.
Une architecture dont vous avez besoin n'est pas encore supportée par l'image listée : pour TEI spécifiquement, vous pouvez mirroriser l'image amont depuis GHCR (ghcr.io/huggingface/text-embeddings-inference:<version>) dans l'ECR privée et passer l'URI résultant directement à deploy.py --image-uri. Même script mirror_image.py.
Images connues comme cassées (dernière vérification juillet 2026)
| Image | Défaut | Utilisez à la place |
|---|---|---|
Étiquettes GPU huggingface-pytorch-inference — toutes les récentes testées (PT 2.3–2.6, cu121/cu124, transformers 4.48–5.5.3) |
ImportError: libtorch_cuda.so: undefined symbol: ncclCommResume à import torch. Le NCCL bundlé dans l'image est plus ancien que celui sur lequel torch se lie — un défaut de packaging à l'intérieur du conteneur, sur g5 et g6, indépendamment de l'AMI, du modèle, ou du code d'inférence. Le front-end Java MMS continue de répondre à /ping, donc l'endpoint peut atteindre InService tandis que le worker Python crash-loops et ne sert rien. |
DJL Inference (bundle sa propre pile CUDA/NCCL complète) ou BYOC. Les étiquettes CPU ne sont pas affectées. |
Re-vérifiez quand AWS publie de nouvelles étiquettes huggingface-pytorch-inference GPU — supprimez la ligne une fois qu'une image corrigée est confirmée.
Règle de fallback générale : quand un DLC HF échoue avec des erreurs de lien CUDA/NCCL, basculez vers DJL Inference plutôt que d'itérer sur des étiquettes sœurs — la classe de défaut est par repo, pas par étiquette (trois étiquettes différentes ont été essayées pour le cas ci-dessus ; toutes cassées).
Gotcha connexe HF Hub : les anciens DLCs peuvent échouer le téléchargement de modèle avec 403 Forbidden depuis le CDN XET de HF (leur huggingface_hub bundlé est antérieur à l'auth XET). Définissez HF_HUB_ENABLE_HF_TRANSFER=0 pour forcer le chemin de téléchargement standard, ou pré-étapez les poids en S3.
Temps de téléchargement Hub au premier démarrage
Le chargement du modèle depuis HF Hub se produit à l'intérieur du conteneur après le démarrage de l'endpoint — attendez-vous à 5–15+ minutes avant InService même pour les petits modèles, plus long pour ceux de plusieurs GB. Un premier démarrage lent n'est pas une défaillance ; ne démontez pas ou ne re-diagnostiquez pas avant l'expiration de l'attente de 30 minutes du script de déploiement.
Pour la production ou les déploiements répétés, pré-étapez les poids en S3 et passez --model-s3-uri à deploy.py (le modèle se charge alors depuis /opt/ml/model) — plus rapide, immunisé contre les limites de taux/pannes Hub, et pas de HUGGING_FACE_HUB_TOKEN nécessaire à l'exécution.