

 **Aidez à améliorer cette page** 

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.

Pour contribuer à ce guide de l'utilisateur, cliquez sur le GitHub lien **Modifier cette page sur** qui se trouve dans le volet droit de chaque page.

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.

# Charger &amp; des modèles de serveur sur Amazon EKS
<a name="ml-inference-load-serve-model"></a>

**Astuce**  
 [Inscrivez-vous](https://events.eksworkshop.com/workshops/genai/) aux prochains AI/ML ateliers Amazon EKS.

Les étapes décrites dans cette section permettent de déployer un modèle de langage étendu (LLM) sur Amazon EKS, de le diffuser avec vLLM et d'interagir avec le point de terminaison d'inférence.

La procédure pas à pas utilise les outils suivants :
+  [vLLM](https://docs.vllm.ai/en/latest/) : moteur d'inférence à haut débit optimisé pour le service LLM et la gestion de la mémoire GPU.
+  [Run:ai Model Streamer](https://github.com/run-ai/runai-model-streamer) : diffuse les poids des modèles directement depuis Amazon S3 vers la mémoire GPU, réduisant ainsi le temps de chargement de quelques minutes à quelques secondes.
+  [Open WebUI](https://openwebui.com/) : interface de discussion auto-hébergée qui se connecte à l'API de vLLM. OpenAI-compatible 

Cette section utilise le [Ministral-3-8B-Instruct-2512 modèle](https://huggingface.co/mistralai/Ministral-3-8B-Instruct-2512), mais vous pouvez déployer n'importe quel modèle d'IA pris en charge par vLLM. Pour obtenir la liste des modèles pris en charge, consultez la section [Modèles pris en charge](https://docs.vllm.ai/en/latest/models/supported_models/#text-generation) dans la documentation vLLM.

**Important**  
Utilisez le cluster que vous avez créé dans la [Configuration du cluster Amazon EKS pour les charges AI/ML de travail](ml-cluster-setup.md) section. Les instructions de cette procédure pas à pas fonctionnent à la fois pour le mode automatique EKS et pour Karpenter autogéré.

![Schéma d'architecture illustrant le flux de travail d'inférence LLM avec vLLM sur Amazon EKS](http://docs.aws.amazon.com/fr_fr/eks/latest/userguide/images/ml-inference-load-serve-model-arch.png)


Le schéma d'architecture montre le flux de bout en bout :

1. Les poids des modèles sont téléchargés depuis Hugging Face vers Amazon S3.

1. vLLM diffuse le modèle directement depuis S3 vers la mémoire du GPU à l'aide de Run:ai Model Streamer.

1. Les utilisateurs envoient des demandes d'inférence au point de terminaison vLLM.

Lorsque vous avez effectué ces étapes, vous disposez d'un point de terminaison d'inférence vLLM que vous pouvez utiliser pour interagir avec un modèle ministériel via une application d'interface de chat.

## Conditions préalables
<a name="_prerequisites"></a>

Suivez les étapes décrites dans la [section Configuration du cluster](ml-cluster-setup.md).

Si vous avez ouvert un nouveau terminal, définissez le nom du cluster et la région que vous avez utilisés dans la section [Configuration du cluster via CLI](ml-cluster-setup-cli.md) :

```
export CLUSTER_NAME=ai-eks-docs
export AWS_REGION=us-east-2
```

Recherchez le compartiment de poids du modèle que vous avez créé à l'étape du [compartiment S3 du poids du modèle](ml-cluster-setup-cli.md#cluster-setup-cli-model-bucket) :

```
MODEL_BUCKET=$(aws s3api list-buckets \
  --query "Buckets[?starts_with(Name, '${CLUSTER_NAME}-models-')].Name | [0]" \
  --output text)
echo "Model bucket: ${MODEL_BUCKET}"
```

## Étape 1 : Téléchargez le modèle depuis Hugging Face
<a name="_step_1_download_the_model_from_hugging_face"></a>

Au cours de cette étape, vous déployez un Kubernetes Job qui télécharge le modèle depuis Hugging Face et le télécharge dans le compartiment S3 que vous avez créé dans la section des prérequis.

Pour télécharger le modèle, appliquez le manifeste de Job suivant :

### Télécharger le modèle Job manifest
<a name="ml-inference-step1-model-download-yaml"></a>

```
cat << EOF | kubectl apply -f -
apiVersion: batch/v1
kind: Job
metadata:
  name: model-download
  namespace: default
  labels:
    guide: ai-eks-docs
spec:
  backoffLimit: 10
  activeDeadlineSeconds: 3600
  ttlSecondsAfterFinished: 86400
  template:
    spec:
      restartPolicy: Never
      serviceAccountName: model-storage-sa
      containers:
      - name: downloader
        image: python:3.11-slim
        command: ["/bin/bash", "-c"]
        args:
        - |
          set -e
          pip install -q huggingface_hub boto3
          echo "Downloading Ministral-3-8B-Instruct-2512 from Hugging Face..."
          python3 -c "from huggingface_hub import snapshot_download; snapshot_download('mistralai/Ministral-3-8B-Instruct-2512', local_dir='/tmp/mistral', allow_patterns=['*.json', '*.txt', '*.md', 'consolidated.safetensors'], ignore_patterns=['model-*.safetensors', 'model.safetensors.index.json'])"
          echo "Uploading to S3 bucket: \${MODEL_BUCKET}"
          python3 << 'PYTHON'
          import boto3
          import os
          from pathlib import Path

          s3 = boto3.client('s3')
          bucket = os.environ.get('MODEL_BUCKET')
          local_dir = Path("/tmp/mistral")

          for file_path in local_dir.rglob("*"):
              if file_path.is_file():
                  if '.cache' in file_path.parts:
                      continue
                  s3_key = f"Ministral-3-8B-Instruct-2512/{file_path.relative_to(local_dir)}"
                  print(f"Uploading {file_path.name}...")
                  s3.upload_file(str(file_path), bucket, s3_key)
          print("Upload complete!")
          PYTHON
        env:
        - name: MODEL_BUCKET
          value: "${MODEL_BUCKET}"
        - name: HF_HUB_DISABLE_XET
          value: "1"
        resources:
          requests:
            memory: "2Gi"
            cpu: "1"
          limits:
            memory: "4Gi"
            cpu: "2"
EOF
```

Attendez que le Job soit terminé. Les poids du modèle (consolidated.safetensors) sont d'environ 10,4 Go, et cette étape prend généralement 3 à 5 minutes.

```
kubectl wait --for=condition=complete job/model-download --timeout=600s
```

Sortie attendue :

```
job.batch/model-download condition met
```

Vérifiez que les poids du modèle ont été téléchargés sur S3 :

```
aws s3 ls s3://$(kubectl get job model-download -o jsonpath='{.spec.template.spec.containers[0].env[?(@.name=="MODEL_BUCKET")].value}')/Ministral-3-8B-Instruct-2512/ --recursive
```

Sortie attendue :

```
2026-05-18 10:29:53      20311 Ministral-3-8B-Instruct-2512/README.md
2026-05-18 10:29:53       2361 Ministral-3-8B-Instruct-2512/SYSTEM_PROMPT.txt
2026-05-18 10:29:53       1903 Ministral-3-8B-Instruct-2512/config.json
2026-05-18 10:29:54 10420633176 Ministral-3-8B-Instruct-2512/consolidated.safetensors
2026-05-18 10:29:53        131 Ministral-3-8B-Instruct-2512/generation_config.json
2026-05-18 10:29:53       1185 Ministral-3-8B-Instruct-2512/params.json
2026-05-18 10:29:53        976 Ministral-3-8B-Instruct-2512/processor_config.json
2026-05-18 10:29:53   16753777 Ministral-3-8B-Instruct-2512/tekken.json
2026-05-18 10:29:53   17077402 Ministral-3-8B-Instruct-2512/tokenizer.json
2026-05-18 10:29:53      21168 Ministral-3-8B-Instruct-2512/tokenizer_config.json
```

Le fichier .safetensors consolidé contient les poids du modèle (environ 10,4 Go). Les autres fichiers sont des fichiers de configuration et de tokenisation dont vLLM a besoin pour servir le modèle.

## Étape 2 : Déployer le conteneur d'inférence
<a name="_step_2_deploy_the_inference_container"></a>

Dans cette section, vous déployez vLLM en tant que déploiement Kubernetes pour servir le modèle que vous avez chargé sur Amazon S3.

Cette section utilise les [AWS Deep Learning Containers](https://github.com/aws/deep-learning-containers/tree/master) (DLC), qui sont des images Docker préinstallées avec des frameworks d'apprentissage profond et optimisées pour les performances de l'infrastructure. AWS Les DLC incluent des correctifs de sécurité, des versions de framework validées et des configurations de pilotes GPU optimisées.

Ce déploiement utilise le AWS DLC suivant pour [vLLM 0.21.0](https://gallery.ecr.aws/deep-learning-containers/vllm) avec support SOCI :

```
public.ecr.aws/deep-learning-containers/vllm:0.21.0-gpu-py312-cu130-ubuntu22.04-ec2-v1.0-soci
```

La balise image indique vLLM 0.21.0 avec support GPU, Python 3.12, CUDA 13.0, Ubuntu 22.04, optimisé pour les charges de travail et pour EC2-based un démarrage plus rapide des conteneurs. SOCI-enabled 

Ce manifeste crée un déploiement qui exécute vLLM sur un nœud GPU et diffuse le modèle directement depuis S3 vers la mémoire GPU à l'aide de Run:ai Model Streamer. Le manifeste crée également un service ClusterIP qui expose le point de terminaison vLLM sur le port 8000 pour un accès intégré au cluster.

Appliquez le manifeste :

### Déploiement de vLLM et service YAML
<a name="ml-inference-step2-vllm-deployment-yaml"></a>

```
cat << EOF | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: vllm-inference-app
  labels:
    guide: ai-eks-docs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: vllm-inference-app
  template:
    metadata:
      labels:
        app: vllm-inference-app
        guide: ai-eks-docs
    spec:
      serviceAccountName: model-storage-sa
      tolerations:
      - key: nvidia.com/gpu
        operator: Exists
        effect: NoSchedule
      nodeSelector:
        karpenter.sh/nodepool: gpu-inf
      containers:
      - name: vllm-inference
        image: public.ecr.aws/deep-learning-containers/vllm:0.21.0-gpu-py312-cu130-ubuntu22.04-ec2-v1.0-soci
        ports:
        - containerPort: 8000
        args:
        - "--model=s3://${MODEL_BUCKET}/Ministral-3-8B-Instruct-2512/"
        - "--host=0.0.0.0"
        - "--port=8000"
        - "--tensor-parallel-size=1"
        - "--gpu-memory-utilization=0.9"
        - "--max-model-len=8192"
        - "--max-num-seqs=1"
        - "--load-format=runai_streamer"
        - "--enforce-eager"
        - "--tokenizer_mode=mistral"
        - "--config_format=mistral"
        - "--enable-auto-tool-choice"
        - "--tool-call-parser=mistral"
        resources:
          limits:
            nvidia.com/gpu: 1
          requests:
            memory: "40Gi"
            cpu: "8"
---
apiVersion: v1
kind: Service
metadata:
  name: vllm-inference-svc
  namespace: default
  labels:
    app: vllm-inference-app
spec:
  selector:
    app: vllm-inference-app
  ports:
  - name: http
    port: 8000
    targetPort: 8000
    protocol: TCP
EOF
```

Vérifiez que le pod vLLM est à l'état Prêt :

```
kubectl get pod -l app=vllm-inference-app -w
```

Sortie attendue :

```
NAME                                  READY   STATUS    RESTARTS   AGE
vllm-inference-app-65df5fddc8-5kmjm   1/1     Running   0          86s
```

L'extraction de l'image du conteneur peut prendre environ 2 minutes et le transfert des poids du modèle par vLLM depuis S3 vers la mémoire du GPU peut prendre environ 2 minutes. Attendez que le module `1/1` apparaisse dans la colonne PRÊT avant de continuer.

La combinaison d'EKS, de SOCI et de Run:ai Model Streamer permet un démarrage rapide du pod. Pour vérifier l'heure de démarrage de chaque étape, consultez les événements du pod :

```
kubectl describe pod -l app=vllm-inference-app | grep -A 20 "Events:"
```

Sortie attendue :

```
Events:
  Type     Reason            Age   From                   Message
  ----     ------            ----  ----                   -------
  Warning  FailedScheduling  86s   default-scheduler      0/2 nodes are available: 2 node(s) had untolerated taint(s).
  Normal   Nominated         85s   eks-auto-mode/compute  Pod should schedule on: nodeclaim/gpu-inf-kqkq6
  Normal   Scheduled         55s   default-scheduler      Successfully assigned default/vllm-inference-app-d9d54586d-csmd7 to i-04f8792414384d2d3
  Normal   Pulling           52s   kubelet                Pulling image "public.ecr.aws/deep-learning-containers/vllm:0.21.0-gpu-py312-cu130-ubuntu22.04-ec2-v1.0-soci"
  Normal   Pulled            4s    kubelet                Successfully pulled image "public.ecr.aws/deep-learning-containers/vllm:0.21.0-gpu-py312-cu130-ubuntu22.04-ec2-v1.0-soci" in 48.376s (48.376s including waiting). Image size: 8802823997 bytes.
  Normal   Created           4s    kubelet                Created container vllm-inference
  Normal   Started           4s    kubelet                Started container vllm-inference
```

Dans cet exemple, le nœud GPU a été provisionné en 30 secondes et l'image du conteneur de 8,8 Go a été extraite en 48 secondes environ à l'aide du protocole SOCI. Les extractions d'images rapides réduisent les temps de démarrage à froid pour les grands conteneurs d'inférence, ce qui vous permet de dimensionner les modules GPU de manière dynamique au lieu de surprovisionner la capacité du GPU inactif.

Ensuite, consultez les journaux vLLM pour vérifier le temps de chargement du modèle :

```
kubectl logs $(kubectl get pod -l app=vllm-inference-app -o jsonpath='{.items[0].metadata.name}') | grep -i 'Model loading took'
```

Sortie attendue :

```
INFO 05-18 18:41:49 [gpu_model_runner.py:4959] Model loading took 9.81 GiB memory and 5.023344 seconds
```

Le journal confirme que Run:ai Model Streamer a chargé les 10,4 Go de poids du modèle directement depuis S3 dans la mémoire du processeur graphique en 5 secondes environ, consommant ainsi 9,8 Go de mémoire du processeur graphique.

Dans cet exemple, le temps de téléchargement de l'image était effectué à l'aide d'une instance g6e.4xlarge, dotée d'une bande passante réseau soutenue de 20 Gbit/s. Les temps d'extraction d'images et de chargement des modèles varient selon le type d'instance en fonction de la bande passante réseau disponible.

## Étape 3 : Exécuter l'inférence
<a name="_step_3_run_inference"></a>

Lorsque le déploiement vLLM est en cours d'exécution, validez le point de terminaison d'inférence et déployez une interface de chat pour interagir avec le modèle.

### Exécuter un test de validation du modèle
<a name="_run_a_model_validation_test"></a>

Exposez le point de terminaison d'inférence via le port forward :

```
kubectl port-forward svc/vllm-inference-svc 8000:8000
```

Ouvrez une nouvelle fenêtre de terminal, puis vérifiez que le conteneur d'inférence répond :

```
curl -sI -X GET http://localhost:8000/health
```

Sortie attendue :

```
HTTP/1.1 200 OK
date: Fri, 18 May 2026 00:39:23 GMT
server: uvicorn
content-length: 0
```

## Étape 4 : Surveiller vLLM
<a name="ml-inference-load-serve-model-monitoring"></a>

vLLM expose les indicateurs Prometheus prêts à l'emploi, notamment le taux de demandes, le débit de jetons, la latence de bout en bout et l'utilisation du cache KV du GPU. Dans cette section, vous utilisez ces métriques avec la pile de surveillance que vous avez configurée dans les étapes de [configuration du cluster](ml-cluster-setup.md) et vous les visualisez sur un tableau de bord Grafana préconfiguré.

**Important**  
Vous devez compléter la sous-section [Surveillance](ml-cluster-setup-cli.md#cluster-setup-cli-monitoring) de la section [Configuration du cluster via CLI](ml-cluster-setup-cli.md) avant de continuer. Cette étape dépend du kube-prometheus-stack en cours d'installation et du tableau de bord vLLM Grafana déjà configuré dans le fichier de valeurs.

### Appliquer le vLLM ServiceMonitor
<a name="ml-inference-load-serve-model-monitoring-servicemonitor"></a>

A ServiceMonitor indique à Prometheus où extraire les métriques VLLM.

```
cat << EOF | kubectl apply -f -
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: vllm-inference-app
  namespace: default
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      app: vllm-inference-app
  endpoints:
  - port: http
    path: /metrics
    interval: 15s
EOF
```

Vérifiez que le ServiceMonitor a été créé :

```
kubectl get servicemonitor vllm-inference-app
```

Sortie attendue :

```
NAME                  AGE
vllm-inference-app    5s
```

#### Générer du trafic d'inférence
<a name="ml-inference-load-serve-model-monitoring-traffic"></a>

Pour remplir le tableau de bord avec des métriques, générez du trafic d'inférence par rapport au point de terminaison vLLM que vous avez déjà exposé via le port forward lors de l'étape de validation.

Découvrez le nom du modèle desservi :

```
MODEL_NAME=$(curl -s http://localhost:8000/v1/models | jq -r '.data[0].id')
echo "Using model: $MODEL_NAME"
```

Envoyez 50 demandes de fin de chat en parallèle :

```
for i in $(seq 1 50); do
  curl -s -X POST http://localhost:8000/v1/chat/completions \
    -H "Content-Type: application/json" \
    -d "{\"model\": \"$MODEL_NAME\", \"messages\": [{\"role\": \"user\", \"content\": \"Write a short poem about Kubernetes.\"}], \"max_tokens\": 128}" \
    > /dev/null &
done
wait
```

Pendant que le trafic circule (ou immédiatement après), vérifiez les métriques de débit de jetons directement depuis le point de terminaison vLLM : `/metrics`

```
curl -s http://localhost:8000/metrics | grep -E '^vllm:(prompt_tokens_total|generation_tokens_total|avg_generation_throughput_toks_per_s|avg_prompt_throughput_toks_per_s)' | head
```

Les `vllm:generation_tokens_total` métriques `vllm:prompt_tokens_total` et augmentent de façon monotone les compteurs de jetons d'entrée et de sortie servis. Les `vllm:avg_generation_throughput_toks_per_s` indicateurs `vllm:avg_prompt_throughput_toks_per_s` et sont des indicateurs de débit à moyenne mobile. Ces mêmes indicateurs alimentent le tableau de bord Grafana que vous ouvrez dans la sous-section suivante.

### Afficher le tableau de bord de vLLM Grafana
<a name="ml-inference-load-serve-model-monitoring-dashboard"></a>

**Le fichier de valeurs kube-prometheus-stack de la section [Monitoring](ml-cluster-setup-cli.md#cluster-setup-cli-monitoring) approvisionne déjà le tableau de [bord vLLM communautaire (GnetID 25263) dans le dossier GPU Monitoring](https://grafana.com/grafana/dashboards/25263-vllm-metrics/), aucune importation supplémentaire n'est donc nécessaire.**

Pour accéder à Grafana, lancez une redirection de port vers le service Grafana :

```
kubectl port-forward svc/kube-prometheus-stack-grafana 3000:80 -n monitoring
```

Ouvrez [http://localhost:3000](http://localhost:3000) dans votre navigateur et accédez à **Tableaux de bord > Surveillance du GPU > Mesures vLLM**.

 **Tableau de bord vLLM Grafana** 

![Tableau de bord vLLM Grafana indiquant le taux de demandes, le débit de jetons, la latence de bout en bout et l'utilisation du cache KV du GPU](http://docs.aws.amazon.com/fr_fr/eks/latest/userguide/images/ml-inference-load-serve-model-vllm-monitoring.png)


Le tableau de bord affiche le taux de demandes, le débit des jetons d'invite et de génération, les percentiles de latence et l'utilisation du cache KV du GPU pour le point de terminaison d'inférence vLLM.

## Étape 5 : Déployer l'application de chat
<a name="_step_5_deploy_chat_application"></a>

Au cours de cette étape, vous déployez Open WebUI comme interface de discussion pour interagir avec le modèle. Open WebUI est une interface d'IA open source auto-hébergée qui OpenAI-compatible prend en charge les API et fournit une interface de chat avec historique des conversations et rendu des marquages. Comme vLLM expose une OpenAI-compatible API, Open WebUI s'y connecte directement en tant que backend.

Pour déployer l'application Open WebUI, appliquez le manifeste suivant :

### Déploiement et service Open WebUI (YAML)
<a name="ml-inference-step5-open-webui-yaml"></a>

```
cat << 'EOF' | kubectl apply -f -
apiVersion: apps/v1
kind: Deployment
metadata:
  name: open-webui
  namespace: default
  labels:
    app: open-webui
    guide: ai-eks-docs
spec:
  replicas: 1
  selector:
    matchLabels:
      app: open-webui
  template:
    metadata:
      labels:
        app: open-webui
        guide: ai-eks-docs
    spec:
      containers:
      - name: open-webui
        image: ghcr.io/open-webui/open-webui:v0.9.2
        ports:
        - containerPort: 8080
        resources:
          requests:
            cpu: "500m"
            memory: "500Mi"
          limits:
            cpu: "1000m"
            memory: "1Gi"
        env:
        - name: OPENAI_API_BASE_URLS
          value: "http://vllm-inference-svc:8000/v1"
        - name: OPENAI_API_KEY
          value: "dummy"
        - name: WEBUI_AUTH
          value: "False"
        - name: ENABLE_OLLAMA_API
          value: "False"
        - name: ENABLE_EVALUATION_ARENA_MODELS
          value: "False"
        volumeMounts:
        - name: webui-volume
          mountPath: /app/backend/data
      volumes:
      - name: webui-volume
        emptyDir: {}
---
apiVersion: v1
kind: Service
metadata:
  name: open-webui
  namespace: default
  labels:
    app: open-webui
spec:
  type: ClusterIP
  selector:
    app: open-webui
  ports:
  - protocol: TCP
    port: 80
    targetPort: 8080
EOF
```

Attendez que le module Open WebUI soit prêt :

```
kubectl wait --for=condition=ready pod -l app=open-webui --timeout=300s
```

Sortie attendue :

```
pod/open-webui-6cbfc9867f-jf9w9 condition met
```

Pour accéder à l'application, configurez la redirection de port et ouvrez l'application dans votre navigateur :

```
kubectl port-forward svc/open-webui 8080:80 &
sleep 5
echo "Open WebUI: http://localhost:8080"
```

Ouvrez [http://localhost:8080](http://localhost:8080) dans votre navigateur.

L'interface de chat apparaît où vous pouvez interagir avec le modèle Ministral.

Lorsque vous avez terminé les tests, arrêtez les processus de transfert de port en arrière-plan en les exécutant `kill %1 %2` (ou en les exécutant pour les `jobs` répertorier et `kill %<jobspec>` pour chacun d'eux).

![Capture d'écran de l'interface de chat Open WebUI montrant une conversation avec le modèle Ministral](http://docs.aws.amazon.com/fr_fr/eks/latest/userguide/images/ml-inference-load-serve-model-chatui.png)


## Nettoyage
<a name="_clean_up"></a>

Pour supprimer les ressources de charge de travail que vous avez créées dans cette section, supprimez l'application Open WebUI, le serveur d'inférence vLLM et le Job de téléchargement de modèles :

```
kubectl delete deployment open-webui
kubectl delete service open-webui
kubectl delete deployment vllm-inference-app
kubectl delete service vllm-inference-svc
kubectl delete servicemonitor vllm-inference-app
kubectl delete job model-download
```

Pour obtenir des instructions sur la suppression des ressources d'infrastructure telles que le cluster et le compartiment S3 NodePool, consultez la section [Nettoyage de la configuration du cluster](ml-cluster-setup-cli.md#cluster-setup-cli-cleanup).