vLLM — Inférence LLM haute performance¶
vLLM est un serveur d'inférence LLM haute performance conçu pour les environnements de production avec GPU. Il remplace Ollama lorsque du matériel GPU est disponible, en servant une API compatible OpenAI avec du batching continu et une utilisation optimisée de la mémoire GPU. LiteLLM route automatiquement vers vLLM lorsqu'il est activé.
Architecture¶
Notebooks / Cockpit / Applications
|
+-----v------+
| LiteLLM | API compatible OpenAI (port 4000)
| (Passerelle) |
+-----+------+
|
+-----v------+
| vLLM | Inférence GPU (port 8000)
| Qwen/Qwen2.5-7B-Instruct
+------------+
En développement (sans GPU), LiteLLM route vers Ollama. En production (GPU disponible), LiteLLM route vers vLLM. Le basculement est transparent — le code applicatif ne change jamais.
Dev : LiteLLM → Ollama (CPU, plusieurs petits modèles)
Prod : LiteLLM → vLLM (GPU, un seul modèle haute performance)
URLs¶
| Mode | URL |
|---|---|
| Kubernetes (production) | Interne uniquement — accessible via la passerelle LiteLLM |
vLLM n'a pas d'ingress propre. Toutes les requêtes passent par LiteLLM (https://llm.akko.local), qui route vers vLLM en interne.
Utilisation¶
Depuis les notebooks (via LiteLLM)¶
Aucune modification de code nécessaire. La même API LiteLLM fonctionne que le backend soit Ollama ou vLLM :
from openai import OpenAI
client = OpenAI(
base_url="http://akko-akko-litellm:4000/v1",
api_key="akko-dev-litellm-key",
)
response = client.chat.completions.create(
model="akko-coder", # Routé vers vLLM en production
messages=[{"role": "user", "content": "Écris une requête SQL pour la segmentation clients"}],
)
print(response.choices[0].message.content)
API vLLM directe (interne)¶
Pour les services qui doivent contourner LiteLLM :
from openai import OpenAI
client = OpenAI(
base_url="http://akko-akko-vllm:8000/v1",
api_key="EMPTY", # vLLM ne requiert pas d'authentification en interne
)
response = client.chat.completions.create(
model="Qwen/Qwen2.5-7B-Instruct",
messages=[{"role": "user", "content": "Explique Apache Iceberg"}],
)
Configuration¶
Environnement de développement (values-dev.yaml)¶
vLLM est désactivé en dev — Ollama gère l'inférence sur CPU :
Environnement de production (values-production.yaml)¶
vLLM est activé avec des ressources GPU :
akko-vllm:
enabled: true
replicaCount: 1
model:
name: "Qwen/Qwen2.5-7B-Instruct"
maxModelLen: 4096
gpuMemoryUtilization: 0.9
akko-litellm:
vllmBackend:
enabled: true
host: "akko-akko-vllm"
port: 8000
model: "Qwen/Qwen2.5-7B-Instruct"
Configuration du modèle¶
| Paramètre | Défaut | Description |
|---|---|---|
model.name |
Qwen/Qwen2.5-7B-Instruct |
Identifiant du modèle HuggingFace |
model.maxModelLen |
4096 |
Longueur maximale de séquence |
model.gpuMemoryUtilization |
0.9 |
Fraction de mémoire GPU à utiliser (0.0-1.0) |
Fonctionnalités principales¶
| Fonctionnalité | Description |
|---|---|
| Batching continu | Regroupe dynamiquement les requêtes entrantes pour un débit maximal |
| PagedAttention | Gestion efficace de la mémoire GPU, sert plus de requêtes simultanées |
| API compatible OpenAI | Remplacement direct — même API qu'OpenAI, GPT4All, Ollama |
| Modèles HuggingFace | Charge n'importe quel modèle depuis HuggingFace Hub par identifiant |
| Optimisation mémoire GPU | Ratio d'utilisation configurable pour équilibrer débit et taille de modèle |
| Parallélisme tensoriel | Mise à l'échelle sur plusieurs GPU pour les modèles plus grands |
Dev vs Production¶
| Aspect | Dev (Ollama) | Production (vLLM) |
|---|---|---|
| Matériel | CPU (Apple Silicon / x86) | GPU NVIDIA (CUDA) |
| Modèles | Plusieurs petits modèles (3B-7B) | Un seul modèle optimisé (7B+) |
| Débit | Faible (1-5 tokens/s) | Élevé (50-200+ tokens/s) |
| Batching | Séquentiel | Batching continu |
| Mémoire | RAM système | VRAM GPU (16 Gi+ recommandé) |
| Valeur Helm | akko-vllm.enabled: false |
akko-vllm.enabled: true |
Ressources requises¶
| Ressource | Minimum | Recommandé |
|---|---|---|
| GPU | 1x NVIDIA (16 Go VRAM) | 1x NVIDIA A100 (40/80 Go) |
| RAM | 8 Gi | 16 Gi |
| Utilisation mémoire GPU | 0.8 | 0.9 |
GPU requis
vLLM nécessite un GPU NVIDIA avec support CUDA. Il ne démarrera pas sur des nœuds sans GPU. Pour le développement sans GPU, utilisez Ollama à la place (akko-vllm.enabled: false).
Téléchargement du modèle
Au premier démarrage, vLLM télécharge le modèle depuis HuggingFace Hub. Pour Qwen/Qwen2.5-7B-Instruct, cela représente environ 15 Go. Assurez-vous de disposer de suffisamment d'espace disque et de bande passante réseau.
Healthcheck¶
vLLM expose un endpoint /health utilisé par les sondes Kubernetes :
livenessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 120 # Le chargement du modèle prend du temps
periodSeconds: 30
readinessProbe:
httpGet:
path: /health
port: 8000
initialDelaySeconds: 60
periodSeconds: 10
Démarrage lent
vLLM met 60 à 120 secondes pour charger un modèle 7B en mémoire GPU. Le initialDelaySeconds est configuré en conséquence pour éviter les redémarrages prématurés.
Dépannage¶
GPU non détecté¶
Symptômes : Le pod vLLM ne démarre pas. Les logs affichent RuntimeError: No CUDA GPUs are available ou torch.cuda.is_available() returns False. Le pod entre en CrashLoopBackOff.
Cause : Le nœud Kubernetes n'a pas de GPU NVIDIA, le plugin de périphériques NVIDIA n'est pas installé, ou la spécification du pod ne contient pas la demande de ressource nvidia.com/gpu.
Solution :
# Vérifier si le plugin de périphériques NVIDIA tourne
kubectl get pods -n kube-system | grep nvidia
# Vérifier que les ressources GPU sont annoncées par les nœuds
kubectl describe nodes | grep -A5 "nvidia.com/gpu"
# Consulter les événements du pod vLLM pour les échecs de planification
kubectl describe pod -n akko -l app.kubernetes.io/name=akko-vllm | grep -A10 "Events"
# Vérifier que le pod demande des ressources GPU
kubectl get pod -n akko -l app.kubernetes.io/name=akko-vllm -o jsonpath='{.items[0].spec.containers[0].resources}'
# Si aucun GPU n'est disponible, désactiver vLLM et utiliser Ollama à la place
# helm upgrade akko helm/akko/ -n akko --set akko-vllm.enabled=false
Incompatibilité de version CUDA¶
Symptômes : Le pod vLLM démarre mais plante immédiatement. Les logs affichent CUDA driver version is insufficient for CUDA runtime version ou CUDA error: no kernel image is available for execution on the device.
Cause : La version du runtime CUDA dans l'image du conteneur vLLM ne correspond pas à la version du driver CUDA installé sur le nœud hôte. Cela arrive typiquement avec des drivers GPU anciens ou des images de conteneur plus récentes.
Solution :
# Vérifier la version du driver CUDA sur l'hôte
kubectl exec -n akko -l app.kubernetes.io/name=akko-vllm -- nvidia-smi 2>/dev/null || echo "nvidia-smi non disponible"
# Vérifier la version CUDA dans le conteneur vLLM
kubectl logs -n akko deploy/akko-akko-vllm --tail=20 | grep -i "cuda\|driver"
# Vérifier que la capacité de calcul du GPU correspond aux exigences du modèle
kubectl exec -n akko deploy/akko-akko-vllm -- python3 -c "import torch; print(torch.cuda.get_device_capability())" 2>/dev/null
# Solutions :
# 1. Mettre à jour le driver NVIDIA sur le nœud hôte
# 2. Utiliser une image vLLM compilée pour votre version CUDA
# 3. Fixer le tag de l'image vLLM à une version compatible avec votre driver
Timeout de téléchargement du modèle¶
Symptômes : Le pod vLLM reste en état Running mais ne devient jamais Ready. Les logs affichent Downloading model... avec une progression lente ou bloquée. La sonde de disponibilité finit par échouer et le pod redémarre.
Cause : Le téléchargement du modèle HuggingFace est lent à cause de limitations de bande passante réseau, d'un proxy bloquant les gros téléchargements, ou d'un HF_TOKEN manquant pour les modèles à accès restreint.
Solution :
# Vérifier la progression du téléchargement dans les logs
kubectl logs -n akko deploy/akko-akko-vllm --tail=30 | grep -i "download\|model\|huggingface"
# Vérifier la connectivité réseau depuis le pod
kubectl exec -n akko deploy/akko-akko-vllm -- curl -sI https://huggingface.co
# Augmenter le timeout de la sonde de disponibilité pour les téléchargements lents
# Dans values : initialDelaySeconds: 300, failureThreshold: 30
# Pour les modèles à accès restreint, s'assurer que HF_TOKEN est défini
kubectl get secret -n akko -l app.kubernetes.io/name=akko-vllm -o yaml | grep HF_TOKEN
# Envisager le pré-téléchargement du modèle sur un PVC pour éviter les téléchargements répétés
Mémoire VRAM insuffisante¶
Symptômes : vLLM plante avec torch.cuda.OutOfMemoryError: CUDA out of memory ou ValueError: The model's max seq len is too large. Le pod redémarre en boucle.
Cause : Le modèle nécessite plus de VRAM GPU que disponible. Le ratio gpuMemoryUtilization est trop élevé (ne laissant pas de place pour le cache KV), ou maxModelLen est trop grand pour la mémoire disponible.
Solution :
# Vérifier l'utilisation de la mémoire GPU
kubectl exec -n akko deploy/akko-akko-vllm -- nvidia-smi 2>/dev/null
# Vérifier la configuration actuelle
kubectl get cm -n akko -l app.kubernetes.io/name=akko-vllm -o yaml | grep -i "memory\|model_len\|gpu"
# Réduire l'utilisation de la mémoire GPU et la longueur maximale de séquence
# Dans votre fichier values :
# akko-vllm.model.gpuMemoryUtilization: 0.8 (au lieu de 0.9)
# akko-vllm.model.maxModelLen: 2048 (au lieu de 4096)
helm upgrade akko helm/akko/ -n akko -f helm/examples/values-dev.yaml \
--set akko-vllm.model.gpuMemoryUtilization=0.8 \
--set akko-vllm.model.maxModelLen=2048
# Ou passer à un modèle plus petit (ex. 3B au lieu de 7B)
Démarrage lent (chargement du modèle)¶
Symptômes : Le pod vLLM est Running mais pas Ready pendant plusieurs minutes. L'endpoint de santé retourne des erreurs. Les routes LiteLLM échouent car le backend vLLM n'est pas encore disponible.
Cause : Le chargement d'un modèle 7B+ en mémoire GPU prend 60 à 120+ secondes. Le initialDelaySeconds par défaut peut être insuffisant pour des modèles plus grands ou du matériel plus lent.
Solution :
# Vérifier l'âge du pod et le statut de disponibilité
kubectl get pods -n akko -l app.kubernetes.io/name=akko-vllm -o wide
# Suivre les logs de démarrage en temps réel
kubectl logs -n akko deploy/akko-akko-vllm -f --tail=20
# Vérifier si l'endpoint de santé répond
kubectl exec -n akko deploy/akko-akko-vllm -- curl -s http://localhost:8000/health || echo "Pas encore prêt"
# Si le pod redémarre à cause d'échecs de sonde, augmenter le délai
# Dans values : livenessProbe.initialDelaySeconds: 300
# Dans values : readinessProbe.initialDelaySeconds: 120, failureThreshold: 30
# Vérifier que LiteLLM gère le démarrage de vLLM correctement
kubectl logs -n akko deploy/akko-akko-litellm --tail=20 | grep -i "vllm\|backend\|error"