Electrosens R&D
Electrosens LLM auto hébergées · 16 October 2026

Faire tourner un LLM local en production : le guide d’ingénierie 2026

Servir un modèle sur son PC, c’est facile. Servir vingt utilisateurs simultanés sans qu’il s’effondre, c’est un métier. En 2026, la vraie frontière du LLM local n’est plus le choix du modèle, mais la pile d’ingénierie qui l’entoure : batching continu, KV cache paginé, quantification raisonnée, routage multi-modèles et observabilité. Voici comment transformer une démo qui « tourne » en un service qui tient.


Le tokens/s marketing est mort : bienvenue dans l’ère du P95

Pendant trois ans, la communauté locale s’est mesurée à un seul chiffre : le tokens par seconde sur une requête unique. Un modèle qui sortait 80 t/s en solo était « rapide ». Un modèle qui plafonnait à 25 t/s était « lent ». Cette métrique a structuré des milliers de fils de discussion, de comparatifs et de tableaux — et elle est aujourd’hui devenue largement trompeuse.

La raison est simple : elle mesure un régime que personne n’utilise en production. En batch=1, un seul utilisateur occupe tout le GPU. Le modèle décode un token à la fois, la bande passante mémoire est monopolisée par une seule séquence, et le chiffre obtenu ne dit rien de ce qui se passe quand dix, trente ou cent requêtes arrivent en même temps. Or c’est exactement le scénario réel : un service interne, un chatbot d’équipe, un agent qui boucle, un pipeline RAG qui interroge le modèle en rafale.

Ce qui compte en production se décompose en trois grandeurs distinctes. Le débit agrégé (throughput) : combien de tokens le serveur produit au total par seconde, toutes requêtes confondues. La latence perçue : le TTFT (time to first token), qui détermine si l’utilisateur a l’impression que « ça répond », et le TPOT (time per output token), qui détermine si le texte s’écoule de façon fluide ou hachée. Et enfin le queueing : le temps qu’une requête passe à attendre dans une file avant même d’être traitée. Ces trois dimensions se contredisent souvent. Optimiser le throughput dégrade la latence ; optimiser la latence gaspille le GPU.

Le paradoxe central de 2026 tient en une phrase : un modèle qui fait 80 t/s en solo peut s’effondrer à 8 t/s effectifs dès vingt utilisateurs simultanés si la pile d’ingénierie est absente. Pas parce que le GPU est mauvais, mais parce que le serveur traite les requêtes une par une, ou par lots statiques mal formés, en laissant 60 à 80 % de la puissance de calcul inutilisée pendant l’attente des séquences les plus longues. Le matériel n’est presque jamais le goulot. La logique de service, si.

Ce dossier décortique cette pile, de bout en bout : le pipeline d’une requête, le batching, le KV cache, la quantification, le dimensionnement, le choix du moteur, l’observabilité et les coûts cachés que les comparatifs ignorent superbement.

De llama.cpp à PagedAttention : la décennie qui a transformé un script en datacenter

L’histoire commence en mars 2023 avec llama.cpp, un projet C++ de Georgi Gerganov qui fait tourner un modèle de langage sur un simple CPU. Quelques semaines plus tard, en juin 2023, vLLM publie sa première version et introduit PagedAttention, formalisé dans un article présenté à SOSP 2023. En juillet 2023, Ollama emballe le tout dans une expérience utilisateur d’une simplicité désarmante : une commande, un modèle, ça marche. En décembre 2023, SGLang arrive avec RadixAttention et le prefix caching. Entre-temps, le continuous batching d’Orca (OSDI 2022) avait déjà posé la base théorique de tout ce qui allait suivre.

Source : faire.com

Cette chronologie raconte une bifurcation. D’un côté, une lignée « outil » : llama.cpp, Ollama, LM Studio — pensée pour un utilisateur, un GPU, une conversation. De l’autre, une lignée « service » : vLLM, SGLang, TensorRT-LLM, TGI, LMDeploy — pensée pour un parc de machines, des dizaines de requêtes concurrentes, des métriques et des SLO. Les deux lignées partagent les mêmes fondations mathématiques (FlashAttention, quantification, KV cache) mais divergent radicalement sur l’ordonnancement.

Ce qui a poussé les équipes vers le self-hosting n’est pas un enthousiasme technique abstrait. C’est une conjonction d’épisodes très concrets : des factures cloud qui explosent quand un agent se met à boucler la nuit, des exigences de confidentialité qui interdisent d’envoyer des données clients à une API tierce, et des pénuries de GPU qui rendent l’accès à la capacité cloud à la fois cher et incertain. Le self-hosting est devenu, pour beaucoup, un arbitrage économique et réglementaire autant qu’une posture idéologique.

En 2026, la question n’est plus « quel moteur choisir » mais « quelle pile assembler ». Un service local mature combine aujourd’hui plusieurs briques : un moteur d’inférence à batching continu, un cache de prompts, un routeur multi-modèles, une couche d’observabilité et une gestion de files d’attente. Le binaire lancé à la main a laissé place à une architecture.

Anatomie d’une requête : ce qui se passe vraiment entre le HTTP et le token

Prenons une requête concrète : un utilisateur envoie un prompt de 2 000 tokens à un serveur local. Que se passe-t-il ?

D’abord le tokenizer découpe le texte en tokens. C’est une étape CPU, souvent sous-estimée : sur un serveur chargé, le tokenizer peut devenir un point de contention si le nombre de workers est mal calibré. Ensuite vient le scheduling. Le serveur regarde combien de séquences sont en cours, combien de place reste dans le KV cache, et décide quelles requêtes traiter à ce pas de temps. C’est ici que se joue la différence entre batching statique et continuous batching.

Le batching statique regroupe un lot de requêtes, les traite ensemble jusqu’à ce que toutes soient terminées, puis passe au lot suivant. Problème : les séquences n’ont pas la même longueur. Si une requête génère 500 tokens et une autre 20, le GPU reste occupé à attendre la longue pendant que les slots des courtes sont vides. C’est là que se perdent couramment 60 à 80 % de la puissance de calcul. Le continuous batching corrige cela : à chaque pas de décodage, le serveur peut retirer une séquence terminée et en insérer une nouvelle, sans vider le lot. Le GPU reste plein.

Vient ensuite la distinction fondamentale entre prefill et decode. Le prefill traite tout le prompt d’un coup, en parallèle : c’est une opération massivement parallèle, limitée par le calcul (compute-bound). Le decode génère un token à la fois, séquentiellement : c’est une opération limitée par la bande passante mémoire (memory-bound). Ces deux régimes ont des profils de performance radicalement différents, et les mélanger dans un même lot est un art. Le chunked prefill consiste à découper un long prompt en morceaux pour lisser le TTFT sous charge : plutôt que de bloquer le GPU pendant tout le prefill d’un prompt de 8 000 tokens, on l’entrelace avec du decode d’autres requêtes.

Le KV cache est le cœur du problème mémoire. À chaque token généré, le modèle doit se souvenir des clés et valeurs de tous les tokens précédents. Ce cache grandit linéairement avec la longueur du contexte et le nombre de séquences simultanées. Sans gestion fine, il fragmente la VRAM jusqu’à l’OOM. PagedAttention, introduit par vLLM, résout cela en découpant le KV cache en blocs (typiquement de 16 tokens), gérés via une table de pages — exactement comme un système d’exploitation gère la mémoire virtuelle. Le copy-on-write permet de partager des blocs entre séquences qui divergent (utile pour le beam search). Selon l’article vLLM, cette approche réduit la fragmentation mémoire de 60 à 80 %.

Enfin, RadixAttention (SGLang) pousse la logique plus loin : si plusieurs requêtes partagent un préfixe commun — typiquement un long system prompt ou un contexte RAG identique — le serveur réutilise les blocs KV déjà calculés au lieu de refaire le prefill. Sur un workload RAG où 2 000 tokens de contexte sont partagés entre toutes les requêtes, le gain est spectaculaire : on économise tout le calcul de prefill sur ces tokens.

Le sampling (temperature, top-p, top-k) intervient après le forward pass, et le streaming SSE renvoie les tokens au client au fur et à mesure. Ce dernier point n’est pas cosmétique : c’est ce qui transforme un TPOT de 50 ms en une expérience perçue comme instantanée.

Chiffres réels : ce que disent les benchmarks quand on arrête de tricher

Passons aux ordres de grandeur. Ils varient énormément selon le palier matériel, et il faut se méfier des chiffres ronds. Voici ce que l’on peut raisonnablement attendre en 2026, en gardant à l’esprit que les débits dépendent du modèle, de la quantification et surtout du régime (batch=1 vs concurrence).

Source : dictionnaire.lerobert.com
Matériel VRAM / mémoire Profil typique Débit batch=1 (ordre de grandeur)
RTX 3090 / 4090 24 Go Modèles 7-14B quantifiés Élevé en solo, s’effondre sans batching
RTX 5090 32 Go Modèles 14-32B quantifiés Très élevé en solo
RTX 6000 Ada 48 Go Modèles 32-70B quantifiés Élevé, bonne marge KV cache
Mac Studio M3 Ultra jusqu’à 512 Go unifiés Gros modèles, contexte long Modéré mais constant
AMD Strix Halo (iGPU) 256 Go/s de bande passante MoE, modèles moyens ~40-60 tok/s (Llama 3 8B Q4, Vulkan)

Un point capital : la bande passante mémoire est le facteur limitant du decode. Le Strix Halo affiche 256 Go/s de bande passante sur un bus 256 bits — c’est ce qui explique qu’un iGPU puisse tenir ~40-60 tok/s sur un Llama 3 8B Q4 en Vulkan, alors qu’un GPU discret avec une bande passante supérieure fera mieux mais sera bridé par sa VRAM limitée sur les gros modèles. Sur un Radeon 780M, on tombe à ~10-12 tok/s sur Qwen 2.5 7B, avec un gain de +50 % apporté par les optimisations Vulkan de llama.cpp et +12,9 % via le réglage MMVQ.

Le vrai enseignement des benchmarks sérieux (MLPerf Inference, Artificial Analysis, retours Databricks et Anyscale) est ailleurs : le throughput agrégé en continuous batching croît de façon quasi-linéaire jusqu’à un point de saturation, alors que le tokens/s par utilisateur, lui, décroît. À 32 requêtes concurrentes, un bon serveur peut multiplier son débit total par un facteur important par rapport au batch=1, tout en maintenant un TPOT acceptable. À 128 requêtes, on sature la bande passante et le TTFT explose. Le point d’équilibre dépend du matériel et du SLO.

Sur la quantification, les benchmarks convergent : passer de FP16 à Q4_K_M ou AWQ dégrade la perplexité WikiText-2 de façon mesurable mais souvent acceptable pour du chat ou du RAG simple, tandis que les tâches de raisonnement long, de code et les langues rares souffrent davantage. Les scores MMLU et HumanEval chutent plus nettement en dessous de 4 bits. Le prefix caching, lui, apporte un gain direct sur les workloads RAG à contexte partagé — d’autant plus fort que le préfixe est long.

Quantification : le levier le plus surestimé et le plus mal compris

La quantification est probablement le sujet le plus mal compris du LLM local. On la présente souvent comme un simple curseur « qualité vs mémoire ». La réalité est plus nuancée.

Il faut d’abord distinguer deux choses radicalement différentes. La quantification des poids (Q4_K_M, AWQ, GPTQ, FP8, INT8) réduit la taille du modèle lui-même. La quantification du KV cache (q8_0, q4_0) réduit la mémoire consommée par le cache d’attention — un levier distinct, souvent négligé, et pourtant décisif sur les contextes longs. Un modèle en FP16 avec un KV cache quantifié en q8_0 consommera bien moins de VRAM qu’un modèle en Q4 avec un KV cache FP16, pour un contexte équivalent.

Le piège classique est de « tout quantifier » par réflexe. Or la dégradation n’est pas linéaire. Un modèle 70B en Q4_K_M peut surpasser un modèle 13B en FP16 sur bien des tâches, mais s’effondrer sur du tool calling précis ou du raisonnement multi-étapes. La quantification frappe d’abord les capacités les plus fragiles : le respect strict de formats structurés, l’appel d’outils, la génération de code complexe, les langues à faible ressource.

La règle pragmatique : pour du chat et du RAG simple, Q4_K_M ou AWQ est un excellent compromis. Pour du code, du raisonnement long ou des agents qui doivent appeler des outils de façon fiable, il vaut souvent mieux un modèle plus petit en FP16 ou en Q8 qu’un gros modèle en Q4. La qualité perçue d’un service dépend bien plus de la fiabilité du format de sortie que de la taille brute du modèle.

Enfin, la quantification du KV cache mérite une attention particulière dès qu’on manipule des contextes longs. Sur un contexte de 32 000 tokens avec plusieurs séquences, le KV cache peut dépasser la taille des poids du modèle. Le quantifier en q8_0 est souvent le levier le plus rentable — un gain mémoire substantiel pour une perte de qualité minime.

Dimensionner sans se ruiner : RAM, VRAM et nombre d’utilisateurs par palier

La formule de dimensionnement tient en une addition : poids du modèle + (KV cache par token × contexte × batch) + overhead des activations + fragmentation. Chaque terme compte, et le second est celui qu’on oublie.

Source : larousse.fr

Le KV cache par token dépend de l’architecture du modèle (nombre de couches, de têtes d’attention, dimension des têtes). Sur un modèle de taille moyenne, il se compte en dizaines de kilo-octets par token en FP16 — ce qui, multiplié par 32 000 tokens et 16 séquences simultanées, devient considérable. C’est pourquoi le choix du contexte maximal et du batch est un arbitrage direct : on ne peut pas avoir les deux à fond sans VRAM abondante.

Quelques configurations réalistes en 2026 :

Configuration Modèle Matériel Remarque
2× RTX 4090 (tensor parallel) Llama 3.3 70B Q4_K_M (~40 Go) 48 Go VRAM Contexte et batch limités, mais viable
RTX 5090 (32 Go) Qwen 2.5 32B AWQ 32 Go Bon équilibre, KV cache serré
Mac Studio M3 Ultra Mistral Small 24B mémoire unifiée Contexte long confortable, débit modéré
RTX 4070 Ti Super Phi-4 14B VRAM moyenne Idéal pour un service mono-utilisateur

Le nombre d’utilisateurs simultanés à 20 tok/s par utilisateur dépend entièrement du régime. Un serveur bien configuré sur 2× RTX 4090 peut servir une poignée d’utilisateurs en parallèle avec un TPOT correct, mais s’effondrera au-delà sans gestion de file. Sur un mini-PC à mémoire unifiée comme le Ryzen AI Halo (128 Go, jusqu’à 120B+ de modèles, 3 999 $), on privilégie le contexte long et les gros modèles plutôt que la concurrence massive.

Deux stratégies s’opposent pour les gros modèles. L’offload partiel (llama.cpp --n-gpu-layers) place une partie des couches sur GPU et le reste sur CPU/RAM : simple, mais chaque token doit traverser le bus PCIe, ce qui plombe le débit. Le tensor parallel répartit un même modèle sur plusieurs GPU : plus rapide, mais exige des GPU identiques et une interconnexion correcte. Pour un seul gros modèle, le tensor parallel gagne ; pour un modèle moyen sur une machine modeste, l’offload partiel reste le seul recours.

Le speculative decoding (EAGLE-2, Medusa, ngram) mérite le détour : un petit modèle « draft » propose plusieurs tokens, le grand modèle les valide en un seul forward pass. Le gain annoncé est de 1,5 à 2,5×, avec des pointes de 2 à 3× sur du code et du texte structuré — au prix d’une VRAM supplémentaire pour le modèle draft. En production, c’est un levier réel mais qui complique l’observabilité et le dimensionnement.

vLLM, SGLang, llama.cpp, TensorRT-LLM : le match par matériel et par workload

Il n’existe pas de « meilleur moteur ». Il existe un meilleur moteur par matériel et par workload.

vLLM domine le datacenter : batching continu mature, PagedAttention, support multi-GPU et tensor parallel, écosystème large. Mais sur un GPU consumer à faible VRAM, sa gourmandise en mémoire et sa complexité de configuration le rendent parfois moins pratique qu’un simple llama-server.

SGLang apporte RadixAttention et un excellent prefix caching — un avantage net sur les workloads RAG et agents à contexte partagé. TensorRT-LLM offre les meilleures performances brutes sur NVIDIA, au prix d’une compilation et d’une rigidité qui découragent hors production sérieuse. TGI et LMDeploy occupent des niches solides. ExLlamaV2 reste une référence pour la quantification EXL2 sur GPU consumer.

llama.cpp (dont la version 0.5.0 a apporté des changements notables côté backend, modèles et serveur) reste imbattable sur Mac et CPU : portabilité Metal, Vulkan, ROCm, CPU, quantification GGUF mature, serveur OpenAI-compatible avec flags -fa (Flash Attention), --cache-type-k/v (quantification KV cache, ex. q8_0), --ngl et --ctx-size. Le flag --fit on, apparu fin 2025, détermine automatiquement le nombre de couches à offloader. Mais il plafonne en concurrence élevée : son ordonnancement est moins agressif que celui de vLLM.

Ollama reste le meilleur point d’entrée pour un développeur solo, mais n’est pas conçu pour servir un parc d’utilisateurs. MLC-LLM et Aphrodite sont des alternatives crédibles mais de niche. Le choix se résume souvent à : llama.cpp pour Mac/CPU/petite échelle, vLLM ou SGLang pour la concurrence sérieuse sur NVIDIA.

Ce que les comparatifs ignorent : files d’attente, timeouts, cache de prompts et coût énergétique

Voici la face cachée. Un service qui reçoit 200 requêtes pour 4 slots de traitement doit décider quoi faire. Sans backpressure, il accepte tout, sature sa file, et finit par des timeouts en cascade. La bonne pratique : une file bornée, un rejet explicite (HTTP 429) au-delà, et une dégradation gracieuse — par exemple router vers un modèle plus petit quand la charge explose.

Les timeouts et retries côté client sont tout aussi critiques. Un agent qui réessaie indéfiniment une requête lente amplifie la charge. Il faut des timeouts courts, un budget de retries, et idéalement un circuit breaker.

Le cache de prompts (RadixAttention, prefix caching) est le levier le plus rentable sur les workloads RAG et agents : quand toutes les requêtes partagent un long contexte, on économise le prefill. Sur des scénarios à préfixe long, le gain en TTFT est immédiat et visible.

L’observabilité distingue un service amateur d’un service fiable. Les métriques à surveiller : TTFT, TPOT, profondeur de file, taux d’utilisation du KV cache, fragmentation de la mémoire GPU, taux de rejet. Sans ces mesures, on pilote à l’aveugle. Un tracing OpenTelemetry permet de suivre une requête de bout en bout et d’identifier si la lenteur vient du prefill, du decode ou de la file.

Reste le coût énergétique, rarement mentionné. Un serveur 2× RTX 4090 consomme plusieurs centaines de watts en charge continue. Sur un mois d’utilisation intensive, la facture électrique s’ajoute au coût matériel. Face à une API cloud facturée à l’usage, le self-hosting n’est rentable que si le volume est suffisant et l’utilisation régulière. Le vrai TCO intègre le matériel amorti, l’électricité, le refroidissement, le temps d’ingénierie — et ce dernier poste est souvent le plus lourd.

Demain : ce qui va changer la donne (et ce qui ne changera pas)

Les tendances 2026-2027 dessinent plusieurs évolutions. Les modèles MoE (Mixture of Experts) changent l’économie VRAM : un modèle massif n’active qu’une fraction de ses paramètres par token, ce qui permet de faire tourner des modèles de plusieurs centaines de milliards de paramètres sur du matériel consumer. Des moteurs comme FreeToken, développé par UC Berkeley et UT Austin, exploitent cette propriété avec du cache d’experts LRU et du double buffering pour faire tourner des modèles MoE massifs sur un simple PC de gaming, avec des gains annoncés de 2 à 4× face à Ollama.

La compression du KV cache (Q8, Q4, offload sur CPU/NVMe via des projets comme LMCache) va repousser les limites de contexte. Le speculative decoding natif deviendra la norme. Le hardware unifié (Strix Halo, Apple Silicon, mini-PC à 128 Go et plus) brouille la frontière entre RAM et VRAM et rend les gros modèles accessibles sans GPU discret.

Mais certaines choses ne changeront pas. La bande passante mémoire restera le goulot fondamental du decode. Le batching restera indispensable pour amortir le coût du GPU. L’observabilité restera la différence entre un service qui tient et un service qui s’écroule en silence. Et le self-hosting restera ce qu’il a toujours été : un arbitrage, pas une religion. Pour un développeur solo qui teste des idées, une API cloud est souvent plus rationnelle. Pour une équipe avec des contraintes de confidentialité et un volume stable, une pile locale bien conçue devient imbattable. Pour une PME, la réponse dépend du volume, du budget et de l’appétit pour l’ingénierie.

La bonne question n’est plus « quel modèle fait le plus de tokens par seconde », mais « quelle pile me permet de servir mes utilisateurs de façon fiable, à un coût que je maîtrise ». C’est un changement de perspective, et c’est probablement la leçon la plus importante de 2026.

Sources

Article recherché et rédigé automatiquement · Magazine Electrosens
📬 Restez à la pointe
Recevez chaque semaine les nouveautés de ce magazine par email.
💬 Une remarque, une correction ?
Aidez-nous à améliorer cet article. Nous prenons en compte vos retours.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *