Servir un LLM ne consiste pas seulement à charger ses poids sur un GPU. Chaque requête crée un cache KV dont la taille dépend du contexte et de la génération. Lorsque plusieurs utilisateurs arrivent avec des longueurs différentes, ce cache devient une contrainte majeure de capacité et de performance.
Préremplissage et décodage
L’inférence comporte deux phases. Le préremplissage traite tous les tokens du prompt et calcule leur cache KV ; il exploite bien le parallélisme du GPU. Le décodage génère ensuite un token à la fois en relisant ce cache. Cette seconde phase est répétitive et souvent limitée par les accès mémoire.
Le temps jusqu’au premier token dépend beaucoup du préremplissage et de l’attente dans la file. Le débit de sortie dépend ensuite de l’ordonnancement du décodage.
Le problème de la mémoire KV
Réserver à l’avance un bloc contigu pour la longueur maximale de chaque requête gaspille de la mémoire : la plupart des sorties s’arrêtent plus tôt et les tailles varient. La fragmentation empêche aussi d’utiliser certains espaces libres. Le serveur accepte alors moins de requêtes simultanées, même si une partie de la VRAM reste inutilisable.
Ce que fait PagedAttention
PagedAttention découpe le cache KV en blocs, par analogie avec la mémoire paginée des systèmes d’exploitation. Les blocs logiques d’une séquence peuvent être mappés vers des blocs physiques non contigus. Le moteur alloue de la mémoire à mesure que la séquence grandit, réduit le gaspillage et peut partager certains blocs lorsque des séquences ont un préfixe commun.
Cette technique ne rend pas le modèle plus intelligent. Elle permet surtout d’augmenter la concurrence et l’utilisation effective de la mémoire.
Le batching continu
Un batch statique attend que toutes ses requêtes soient terminées avant d’en introduire de nouvelles. Avec des sorties de longueurs variables, les requêtes courtes laissent des places vides. Le batching continu réorganise le travail à chaque étape de décodage : une requête terminée sort et une nouvelle peut entrer. Le GPU reste mieux occupé et le débit global augmente.
Le compromis latence-débit
Ajouter des requêtes au batch améliore souvent le débit, mais peut allonger l’attente avant le premier token. Les longs prompts peuvent aussi bloquer temporairement le décodage. Les moteurs exposent donc des paramètres de concurrence, nombre maximal de tokens batchés, utilisation mémoire et ordonnancement. Il n’existe pas de réglage optimal indépendant de la charge.
Comment benchmarker
Reproduisez la distribution réelle des tailles de prompts, sorties et arrivées. Mesurez temps jusqu’au premier token, temps par token de sortie, latence totale, débit, requêtes simultanées, mémoire GPU et erreurs de saturation. Faites durer le test assez longtemps pour inclure files d’attente, préchauffage et variabilité. Comparez toujours qualité identique, même modèle et même précision numérique.
Checklist de production
- Fixer des limites de contexte et de sortie.
- Protéger le service par quotas et files d’attente.
- Surveiller cache KV, saturation GPU et latence par percentile.
- Séparer les charges interactives des traitements batch si leurs objectifs divergent.
- Tester les longues requêtes et les annulations client.
FAQ
PagedAttention réduit-il la taille des poids du modèle ?
Non. Il optimise surtout l’allocation du cache KV créé pendant l’inférence.
Le batching continu améliore-t-il toujours la latence ?
Il améliore généralement le débit. La latence individuelle dépend de l’ordonnancement et de la charge.
Ces techniques remplacent-elles la quantification ?
Non. Elles sont complémentaires : la quantification réduit notamment la mémoire des poids, tandis que PagedAttention gère le cache dynamique.