Intelligence Artificielle

vLLM : serveur d’inférence haute performance sur GPU

vLLM sert vos LLM open-source en production : batching continu, PagedAttention, parallélisme multi-GPU et API compatible OpenAI. Quand et comment l'utiliser après Ollama.

Ollama vous a emmené loin : un modèle en local, une API, une petite équipe servie. Puis le mur arrive — une dizaine d’utilisateurs simultanés, et le débit s’effondre parce que les requêtes finissent par se mettre en file. C’est exactement le problème que vLLM résout. Là où Ollama privilégie la simplicité, vLLM privilégie le débit : c’est un moteur d’inférence conçu pour faire tourner des LLM open-source en production, sur GPU, avec un parallélisme et une gestion mémoire pensés pour la charge.

Cet article fait suite au guide pilier Héberger ses LLM soi-même en 2026 et au volet Ollama avancé. Toutes les commandes ci-dessous sont vérifiées sur la documentation officielle de vLLM.

Pourquoi vLLM, et quand

vLLM est un moteur d’inférence haute performance. Son terrain, c’est le GPU : principalement les cartes NVIDIA (CUDA), avec un support des GPU AMD (ROCm) et d’autres accélérateurs. Il n’est pas fait pour tourner sur un laptop sans carte graphique — pour ça, Ollama reste le bon choix. vLLM entre en scène quand vous devez servir beaucoup de requêtes en parallèle, ou un modèle trop gros pour une seule carte, ou les deux.

La promesse tient en un mot : débit. Un serveur naïf traite les requêtes l’une après l’autre, ou par lots figés qui attendent le plus lent. vLLM, lui, exploite deux idées qui changent l’échelle — le batching continu et PagedAttention — pour garder le GPU saturé en permanence. On y revient plus bas, car c’est le cœur du sujet.

Concrètement, cette différence d’architecture se traduit par un nombre de requêtes par seconde bien plus élevé sur le même matériel — et surtout par une dégradation gracieuse quand la charge monte : au lieu de s’écrouler, le débit total continue de progresser à mesure qu’on ajoute des requêtes, jusqu’à la limite du GPU. C’est la propriété qui rend un service utilisable par des dizaines d’utilisateurs en parallèle, et non par un seul à la fois.

vLLM est par ailleurs un projet open-source très actif, adopté pour servir des modèles en production dans de nombreuses organisations. Cela a une conséquence pratique : le support des nouvelles architectures arrive vite. Quand une famille de modèles ouverts sort, sa prise en charge dans vLLM suit généralement de près — un critère qui compte quand on bâtit sur le long terme.

Installer et lancer un serveur

vLLM s’installe comme un paquet Python. Dans un environnement virtuel à jour, avec les pilotes GPU en place :

pip install vllm

Lancer un serveur tient ensuite en une commande. vllm serve télécharge le modèle (ici depuis Hugging Face), le charge sur le GPU, et démarre une API compatible OpenAI :

vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000

Par défaut, le serveur écoute sur le port 8000 et expose ses routes sous /v1. En quelques dizaines de secondes — le temps de charger les poids — vous avez un point d’accès prêt à encaisser des requêtes concurrentes.

Le moteur du débit : PagedAttention et batching continu

Pour comprendre pourquoi vLLM va plus vite, il faut regarder ce qu’un LLM garde en mémoire pendant qu’il génère : le cache KV, c’est-à-dire l’état attentionnel de chaque token déjà produit. Ce cache grossit à chaque mot généré, et il est différent pour chaque requête en cours.

PagedAttention est la technique signature de vLLM : elle gère ce cache KV comme un système d’exploitation gère la mémoire virtuelle — en pages. Au lieu de réserver d’avance un gros bloc contigu par requête (gaspillé si la réponse est courte), vLLM alloue des petites pages à la demande. Résultat : la fragmentation s’effondre, et l’on peut garder bien plus de requêtes simultanées dans la même VRAM.

Le batching continu (continuous batching) complète le tableau. Dans un serveur classique, un lot de requêtes démarre ensemble et tout le monde attend la requête la plus longue avant de libérer la place. vLLM, lui, fait entrer et sortir les requêtes du lot à chaque étape de génération : dès qu’une réponse se termine, sa place est immédiatement reprise par une requête en attente. Le GPU ne reste jamais à moitié vide. C’est ce qui permet, sur la même carte, un débit total très supérieur à une approche naïve.

Vous n’avez rien à configurer pour en profiter : ces deux mécanismes sont actifs par défaut. C’est précisément ce qui distingue vLLM d’un simple script d’inférence.

Plusieurs GPU : le parallélisme de tenseurs

Quand un modèle ne tient pas sur une seule carte — un 70B, même quantifié, dépasse les 24 Go d’une carte grand public — vLLM le répartit sur plusieurs GPU avec le parallélisme de tenseurs. Chaque couche du modèle est découpée entre les cartes, qui calculent ensemble. On l’active avec un seul paramètre, réglé sur le nombre de GPU :

vllm serve meta-llama/Llama-3.1-70B-Instruct   --tensor-parallel-size 4   --gpu-memory-utilization 0.95   --max-model-len 4096   --port 8000

Ici, le modèle est étalé sur 4 GPU. Le parallélisme de tenseurs suppose une bonne interconnexion entre les cartes (idéalement NVLink) : la communication entre GPU à chaque couche peut sinon devenir le goulot d’étranglement. Règle pratique : restez sur une seule carte tant que le modèle y tient — le multi-GPU sert à faire entrer un modèle qui déborde, pas à accélérer un modèle qui tenait déjà.

Mémoire, contexte et quantification

Trois paramètres pèsent directement sur ce que votre carte peut encaisser.

  • --gpu-memory-utilization — fraction de la VRAM que vLLM s’autorise, entre 0 et 1 (défaut 0,9). Plus elle est haute, plus il reste de place pour le cache KV, donc pour les requêtes concurrentes. Montez-la jusqu’à la valeur la plus haute qui reste stable ; laissez une marge pour le système.
  • --max-model-len — longueur maximale de contexte (prompt + réponse) en tokens. La réduire libère énormément de mémoire pour le cache KV : un contexte de 128k « au cas où » coûte cher si vos requêtes réelles font 4k.
  • --quantization — applique une quantification comme awq ou gptq pour charger un modèle plus gros dans moins de VRAM. Sur vLLM, AWQ et GPTQ sont les méthodes au meilleur rendement (à la différence du format GGUF, plutôt côté Ollama).
vllm serve TheBloke/Mistral-7B-Instruct-v0.2-AWQ   --quantization awq   --gpu-memory-utilization 0.9   --port 8000

Le bon réglage se trouve par essais : on pousse --gpu-memory-utilization et --max-model-len jusqu’au point où le serveur démarre de façon fiable sous charge, sans erreur de mémoire.

L’API compatible OpenAI

Le serveur vLLM parle le dialecte de l’API OpenAI. Vos clients existants fonctionnent en changeant simplement l’URL de base — aucun code métier à réécrire :

curl http://localhost:8000/v1/chat/completions   -H "Content-Type: application/json"   -d '{
    "model": "meta-llama/Llama-3.1-8B-Instruct",
    "messages": [{"role": "user", "content": "Explique PagedAttention en une phrase"}]
  }'

Pour protéger un serveur exposé, on ajoute une clé au lancement avec --api-key, que les clients devront présenter. Et comme l’interface est standard, vLLM se branche directement sous LiteLLM (pour l’unifier avec d’autres modèles), OpenWebUI (pour une interface de chat) ou Continue.dev (pour l’assistant de code) — les trois autres briques du cluster.

Inférence hors-ligne en batch

Tout ne passe pas par un serveur. Pour des traitements de masse — évaluer un modèle sur des milliers d’exemples, annoter un jeu de données, générer des résumés en lot — vLLM s’utilise aussi directement en Python, sans lancer de serveur HTTP. C’est souvent le moyen le plus rapide d’abattre un gros volume :

from vllm import LLM, SamplingParams

prompts = [
    "Résume cet article en trois points.",
    "Traduis cette phrase en wolof.",
]
sampling_params = SamplingParams(temperature=0.7, top_p=0.95)

llm = LLM(model="meta-llama/Llama-3.1-8B-Instruct")
outputs = llm.generate(prompts, sampling_params)

for output in outputs:
    print(output.outputs[0].text)

La classe LLM charge le modèle une fois ; SamplingParams règle la génération (température, top-p, top-k…) ; generate() traite toute la liste de prompts en exploitant le batching interne. Idéal pour un pipeline de données ou une campagne d’évaluation, là où la latence d’une requête isolée importe moins que le débit global.

Quand préférer cette voie au serveur ? Dès que le travail est connu d’avance et borné dans le temps : une évaluation, un nettoyage de corpus, une génération de variantes en lot. Le serveur, lui, est fait pour le trafic interactif et imprévisible. Rien n’interdit d’utiliser les deux dans le même projet — l’un pour les utilisateurs, l’autre pour les traitements nocturnes.

Déployer proprement : Docker et observabilité

En production, on ne lance pas vllm serve à la main dans un terminal. L’image Docker officielle vllm/vllm-openai embarque tout l’environnement CUDA et expose la même API ; on la pilote avec les mêmes arguments que la CLI, ce qui rend le déploiement reproductible et facile à redémarrer après une mise à jour.

Côté supervision, vLLM publie des métriques (débit, latence, taux d’occupation du cache KV, requêtes en file) au format Prometheus. Les brancher sur un tableau de bord répond à la seule question qui compte sous charge : le GPU est-il saturé de travail utile, ou passe-t-il son temps à attendre ? C’est ce qui guide la décision d’ajouter une carte ou de réduire le contexte.

Dimensionner : combien de GPU pour combien d’utilisateurs ?

Il n’existe pas de formule magique, car tout dépend de trois variables : la taille du modèle, la longueur des prompts et des réponses, et le débit visé. Mais une démarche fiable existe. Partez d’une seule carte avec le modèle à servir, poussez --gpu-memory-utilization au maximum stable, puis chargez le serveur avec un outil de test de montée en charge en augmentant le nombre de requêtes concurrentes. Vous observerez deux régimes : tant que le GPU n’est pas saturé, la latence reste plate et le débit grimpe ; passé le point de saturation, la latence par requête s’allonge. Ce point vous donne la capacité réelle d’une carte pour votre cas. Au-delà, on ajoute des répliques du serveur derrière un répartiteur — et c’est précisément là que LiteLLM, en plus d’unifier les API, sait équilibrer le trafic entre plusieurs instances.

Pièges courants

  • Erreur de mémoire au démarrage (OOM). Le modèle plus le cache KV dépassent la VRAM. Baissez --max-model-len, réduisez --gpu-memory-utilization d’un cran, ou passez à un modèle quantifié. C’est de loin le souci le plus fréquent.
  • Quantification mal comprise. --quantization awq attend un modèle déjà quantifié en AWQ (un checkpoint dédié), pas un modèle brut que vLLM convertirait à la volée. Tirez directement la bonne variante du modèle.
  • Parallélisme de tenseurs mal dimensionné. La valeur de --tensor-parallel-size doit diviser le nombre de têtes d’attention du modèle. Une valeur arbitraire (3 sur un modèle à 32 têtes) refusera de démarrer.
  • Gabarit de conversation absent. Si les réponses sont incohérentes, le modèle attend peut-être un chat template précis : vérifiez que vous servez bien la variante « instruct » du modèle, et non le modèle de base.

Ollama ou vLLM : comment trancher

Ce n’est pas un duel, c’est une progression. Les deux outils répondent à des moments différents du même projet.

  • Ollama — pour démarrer, prototyper, développer en local, servir une petite équipe. Installation triviale, tourne même sans GPU, idéal sur un poste de travail.
  • vLLM — pour la production sous charge : beaucoup d’utilisateurs concurrents, exigence de débit, modèles volumineux répartis sur plusieurs GPU. Demande un GPU et un peu plus de réglage, mais encaisse une tout autre échelle.

Le schéma gagnant pour beaucoup d’équipes : prototyper sur Ollama, valider le modèle et les prompts, puis basculer la charge de production sur vLLM — sans changer une ligne de code applicatif, puisque les deux exposent la même API compatible OpenAI. C’est tout l’intérêt d’un cluster cohérent plutôt que d’un outil isolé.

En résumé

  • vLLM est un moteur d’inférence GPU à haut débit ; il prend le relais d’Ollama quand la concurrence ou la taille du modèle l’exigent.
  • PagedAttention (cache KV paginé) et batching continu, actifs par défaut, gardent le GPU saturé et démultiplient le débit.
  • --tensor-parallel-size répartit un gros modèle sur plusieurs GPU ; --gpu-memory-utilization, --max-model-len et --quantization règlent la mémoire.
  • API compatible OpenAI sur le port 8000, plus une voie d’inférence offline en Python pour les traitements de masse.

Voir aussi

Malick Diallo

Rédaction SenTur

Contributeur SenTur — passionné de tech et de transmission.

Aucun commentaire pour l'instant — lancez la discussion !

Laisser un commentaire

Votre adresse email ne sera pas publiée. La discussion est modérée — restez courtois et constructif.