Surveiller l'inférence des LLM en production (2026) : Prometheus & Grafana pour vLLM, TGI, llama.cpp

Surveillez un LLM avec Prometheus et Grafana

L’inference LLM semble être « juste une autre API » — jusqu’à ce que les latences augmentent, les files d’attente se remplissent à nouveau, et que vos GPU atteignent 95 % de mémoire sans explication évidente.

Le monitoring devient critique dès que vous dépassez un seul nœud ou commencez à optimiser le débit. À ce stade, les métriques d’API traditionnelles ne suffisent pas. Vous avez besoin d’une visibilité sur les tokens, le comportement de regroupement, le temps d’attente dans la file d’attente, et la pression sur le cache KV — les véritables goulets d’étranglement des systèmes LLM modernes.

Cet article fait partie de mon guide plus large sur l’observabilité et le monitoring, où je traite des fondamentaux du monitoring vs de l’observabilité, de l’architecture Prometheus, et des bonnes pratiques en production. Ici, nous nous concentrerons spécifiquement sur le monitoring des charges de travail d’inference LLM.

(Si vous réfléchissez à l’infrastructure, consultez mon guide sur l’hébergement LLM en 2026. Si vous souhaitez un plongeon approfondi dans les mécanismes de regroupement, les limites de VRAM, et les compromis entre débit et latence, consultez le guide d’ingénierie de performance LLM.)

Contrairement aux services REST typiques, le service LLM est façonné par les tokens, le regroupement continu, l’utilisation du cache KV, la saturation GPU/CPU, et les dynamiques de file d’attente. Deux requêtes avec des tailles de charge identiques peuvent avoir des latences radicalement différentes selon max_new_tokens, la concurrence, et la réutilisation du cache.

Ce guide est une promenade pratique, axée sur la production, pour construire le monitoring d’inference LLM avec Prometheus et Grafana :

  • Ce qu’il faut mesurer (p95/p99 latence, tokens/sec, durée de la file d’attente, utilisation du cache, taux d’erreur)
  • Comment scraper /metrics depuis des serveurs courants (vLLM, Hugging Face TGI, llama.cpp)
  • Exemples de PromQL pour les percentiles, la saturation, et le débit
  • Schémas de déploiement avec Docker Compose et Kubernetes
  • Dépannage des problèmes qui ne se manifestent qu’en charge réelle

Les exemples sont intentionnellement neutres en termes de fournisseurs. Quel que soit le suivi OpenTelemetry, l’autoscaling ou le mesh de service que vous ajouterez ultérieurement, le même modèle de métrique s’applique.


surveillance llm avec prometheus et grafana

Pourquoi vous devez surveiller l’inference LLM différemment

Le monitoring d’API traditionnel (RPS, latence p95, taux d’erreur) est nécessaire mais insuffisant. Le service LLM ajoute des axes supplémentaires :

1) La latence a deux significations

  • Latence E2E : temps entre la réception de la requête et la livraison du dernier token.
  • Latence inter-token : temps par token pendant le décodage (critique pour l’UX en flux continu).

Certains serveurs exposent les deux. Par exemple, TGI expose la durée de la requête et le temps moyen par token comme des histogrammes.

2) Le débit est exprimé en tokens, pas en requêtes

Un service « rapide » qui renvoie 5 tokens n’est pas comparable à un autre qui renvoie 500 tokens. Votre « RPS » devrait souvent être « tokens/sec ».

3) La file d’attente est le produit

Si vous exécutez un regroupement continu, la profondeur de la file d’attente est ce que vous vendez. Surveiller la durée de la file d’attente et la taille de la file vous indique si vous respectez les attentes des utilisateurs.

4) La pression du cache est un prélude à une panne

L’épuisement (ou la fragmentation) du cache KV apparaît souvent sous forme de pics soudains de latence et de timeouts. vLLM expose l’utilisation du cache KV comme un gauge.


Checklist des métriques pour le monitoring de l’inference LLM

Utilisez-la comme votre boussole. Vous n’avez pas besoin de tout le jour 1 — mais vous voudrez la plupart d’entre elles finalement.

Signaux d’or (LLM adaptés)

  • Trafic : requêtes/sec, tokens/sec
  • Erreurs : taux d’erreur, timeouts, OOMs, 429s (limitation de débit)
  • Latence : p50/p95/p99 durée de la requête ; latence de préremplissage vs décodage ; latence inter-token
  • Saturation : utilisation du GPU, utilisation de la mémoire, utilisation du cache KV, taille de la file

Si vous avez besoin d’une visibilité détaillée sur l’utilisation de la mémoire du GPU, la température et l’utilisation en dehors de Prometheus (pour le débogage ou les configurations à un seul nœud), consultez mon guide sur les applications de surveillance du GPU sous Linux / Ubuntu.

Pour une vue plus large de l’observabilité des LLM au-delà des métriques — y compris le traçage, les journaux structurés, les tests synthétiques, le profilage du GPU et la conception des SLO — consultez mon guide approfondi sur l’observabilité pour les systèmes LLM.

Dimensions utiles (étiquettes)

Gardez la cardinalité des étiquettes basse. Bonnes étiquettes :

  • model, endpoint, method (préremplissage/décodage), status (succès/erreur), instance

Évitez les étiquettes comme :

  • prompt brut, user_id brut, les identifiants de requête — ces dernières augmentent le nombre de séries.

Exposition des métriques : endpoints /metrics intégrés (vLLM, TGI, llama.cpp)

Le chemin le plus simple est : utiliser les métriques que le serveur expose déjà.

vLLM : endpoint /metrics compatible Prometheus

vLLM expose un endpoint /metrics compatible Prometheus (via son journalisateur de métriques Prometheus) et publie des métriques du serveur/requête avec le préfixe vllm:, y compris des gauges comme le nombre de requêtes en cours et l’utilisation du cache KV.

Exemples de métriques que vous verrez souvent :

  • vllm:num_requests_running
  • vllm:num_requests_waiting
  • vllm:kv_cache_usage_perc

Hugging Face TGI : /metrics avec file d’attente + histogrammes de requêtes

TGI expose de nombreuses métriques de production sur /metrics, notamment la taille de la file d’attente, la durée de la requête, la durée de la file d’attente, et le temps moyen par token.

Les plus notables :

  • tgi_queue_size (gauge)
  • tgi_request_duration (histogramme, latence E2E)
  • tgi_request_queue_duration (histogramme)
  • tgi_request_mean_time_per_token_duration (histogramme)

Serveur llama.cpp : activer l’endpoint des métriques

Le serveur llama.cpp prend en charge un endpoint des métriques compatible Prometheus qui doit être activé avec un drapeau (par exemple, --metrics).

Si vous exécutez llama.cpp derrière un proxy, scannez le serveur directement autant que possible (pour éviter la latence du proxy qui masque le comportement réel de l’inference).


Configuration Prometheus : scanner vos serveurs d’inference

Cet exemple suppose :

  • vLLM à http://vllm:8000/metrics
  • TGI à http://tgi:8080/metrics
  • llama.cpp à http://llama:8080/metrics
  • intervalle de scan ajusté pour un retour rapide

prometheus.yml

global:
  scrape_interval: 5s
  evaluation_interval: 15s

scrape_configs:
  - job_name: "vllm"
    metrics_path: /metrics
    static_configs:
      - targets: ["vllm:8000"]

  - job_name: "tgi"
    metrics_path: /metrics
    static_configs:
      - targets: ["tgi:8080"]

  - job_name: "llama_cpp"
    metrics_path: /metrics
    static_configs:
      - targets: ["llama:8080"]

Si vous êtes nouveau avec Prometheus ou que vous souhaitez une explication plus détaillée des configurations de scan, des exportateurs, du relabeling et des règles d’alerte, consultez mon guide complet sur la configuration du monitoring avec Prometheus.

Astuce professionnelle : ajouter une étiquette “service”

Si vous exécutez plusieurs modèles/replicas, ajoutez un relabeling pour inclure une étiquette service stable pour les tableaux de bord.

relabel_configs:
  - target_label: service
    replacement: "llm-inference"

Exemples de PromQL que vous pouvez copier-coller

Taux de requêtes (RPS)

sum(rate(tgi_request_count[5m]))

Pour vLLM, utilisez ses compteurs de requêtes (les noms varient selon la version), mais le modèle est le même : sum(rate(<counter>[5m])).

Taux d’erreur (%)

Si vous avez des compteurs *_success, calculez le taux de défaillance :

1 - (
  sum(rate(tgi_request_success[5m]))
  /
  sum(rate(tgi_request_count[5m]))
)

p95 latence pour les métriques histogramme (Prometheus)

Les histogrammes de Prometheus sont des compteurs par bucket ; utilisez histogram_quantile() sur rate() des buckets. Prometheus documente ce modèle et les compromis entre histogramme et résumé.

histogram_quantile(
  0.95,
  sum by (le) (rate(tgi_request_duration_bucket[5m]))
)

p99 temps d’attente dans la file

histogram_quantile(
  0.99,
  sum by (le) (rate(tgi_request_queue_duration_bucket[5m]))
)

Temps moyen par token (latence inter-token)

histogram_quantile(
  0.95,
  sum by (le) (rate(tgi_request_mean_time_per_token_duration_bucket[5m]))
)

La latence inter-token est souvent limitée par les goulets d’étranglement de décodage et la bande passante mémoire — des sujets abordés en détail dans le guide d’optimisation de performance LLM.

Profondeur de la file (instantané)

max(tgi_queue_size)

Utilisation du cache KV vLLM (instantané)

max(vllm:kv_cache_usage_perc)

Tableaux de bord Grafana : panneaux qui aident réellement les équipes d’incident

Grafana peut visualiser les histogrammes de plusieurs manières (percentiles, chaleurs, distributions de buckets). Grafana Labs a un guide détaillé sur la visualisation des histogrammes Prometheus.

Un tableau de bord minimal, à haute signalisation :

Ligne 1 — Expérience utilisateur

  1. Latence p95 des requêtes (séries temporelles)
  2. Latence p95 inter-token (séries temporelles)
  3. Taux d’erreur (séries temporelles + stat)

Ligne 2 — Capacité et saturation

  1. Taille de la file (séries temporelles)
  2. Requêtes en cours vs en attente (empilées)
  3. Utilisation du cache KV % (gauge)

Ligne 3 — Débit

  1. Requêtes/sec
  2. Tokens générés par requête (p50/p95)

Si vous avez du streaming, ajoutez un panneau pour « la latence du premier token » (TTFT) lorsqu’il est disponible.

Exemples de requêtes Grafana

  • panneau p95 de latence : la requête histogram_quantile(0.95, …) ci-dessus
  • panneau chaleur : graphique des taux de bucket (*_bucket) en tant que chaleur (Grafana prend en charge cette approche)

Option de déploiement 1 : Docker Compose (local rapide + un seul nœud)

Si vous hésitez entre une architecture locale, auto-hébergée ou basée sur le cloud, consultez l’analyse complète dans mon guide de comparaison de l’hébergement LLM.

Créez un dossier comme :

monitoring/
  docker-compose.yml
  prometheus/
    prometheus.yml
  grafana/
    provisioning/
      datasources/datasource.yml
      dashboards/dashboards.yml
    dashboards/
      llm-inference.json

docker-compose.yml

services:
  prometheus:
    image: prom/prometheus:latest
    volumes:
      - ./prometheus/prometheus.yml:/etc/prometheus/prometheus.yml:ro
    ports:
      - "9090:9090"

  grafana:
    image: grafana/grafana:latest
    environment:
      - GF_SECURITY_ADMIN_USER=admin
      - GF_SECURITY_ADMIN_PASSWORD=admin
    volumes:
      - ./grafana/provisioning:/etc/grafana/provisioning
      - ./grafana/dashboards:/var/lib/grafana/dashboards
    ports:
      - "3000:3000"
    depends_on:
      - prometheus

Si vous préférez une installation manuelle de Grafana au lieu de Docker, consultez mon guide étape par étape sur l’installation et l’utilisation de Grafana sous Ubuntu.

Provisioning de la source de données Grafana (grafana/provisioning/datasources/datasource.yml)

apiVersion: 1
datasources:
  - name: Prometheus
    type: prometheus
    access: proxy
    url: http://prometheus:9090
    isDefault: true

Provisioning du tableau de bord Grafana (grafana/provisioning/dashboards/dashboards.yml)

apiVersion: 1
providers:
  - name: "LLM"
    folder: "LLM"
    type: file
    disableDeletion: true
    options:
      path: /var/lib/grafana/dashboards

Option de déploiement 2 : Kubernetes (Prometheus Operator + ServiceMonitor)

Si vous utilisez kube-prometheus-stack (Prometheus Operator), scrapez les cibles via ServiceMonitor.

Pour les compromis d’infrastructure entre Kubernetes, un seul nœud Docker, et les fournisseurs d’inference gérés, consultez mon guide d’hébergement LLM en 2026.

1) Exposez votre déploiement d’inference avec un Service

apiVersion: v1
kind: Service
metadata:
  name: tgi
  labels:
    app: tgi
spec:
  selector:
    app: tgi
  ports:
    - name: http
      port: 8080
      targetPort: 8080

2) Créez un ServiceMonitor

apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: tgi
  labels:
    release: kube-prometheus-stack
spec:
  selector:
    matchLabels:
      app: tgi
  endpoints:
    - port: http
      path: /metrics
      interval: 5s

Répétez cela pour les services vLLM et llama.cpp. Cela s’adapte proprement à mesure que vous ajoutez des réplicas.

3) Alertes : règles de type SLO (exemple)

Voici de bonnes alertes de départ :

  • Latence p95 élevée (taux de brûlure)
  • Temps d’attente p99 trop élevé (utilisateurs en attente)
  • Taux d’erreur > 1%
  • Utilisation du cache KV > 90% (chute de capacité)

Exemple de règle (latence p95 de la durée de la requête) :

- alert: LLMHighP95Latency
  expr: histogram_quantile(0.95, sum by (le) (rate(tgi_request_duration_bucket[5m]))) > 3
  for: 10m
  labels:
    severity: page
  annotations:
    summary: "Latence p95 TGI > 3s (10m)"

Dépannage : échecs courants de Prometheus + Grafana dans les stacks LLM

1) La cible Prometheus est « DOWN »

Symptômes

  • Interface utilisateur Prometheus → Cibles montre DOWN
  • « context deadline exceeded » ou connexion refusée

Checklist

  • Le serveur expose-t-il vraiment /metrics ?
  • Port incorrect ? Schéma incorrect (http vs https) ?
  • Kubernetes : le Service sélectionne-t-il les pods ? L’étiquette ServiceMonitor release est-elle correcte ?

Test rapide

curl -sS http://tgi:8080/metrics | head

2) Vous pouvez scraper les métriques, mais les panneaux sont vides

Causes les plus courantes

  • Nom de métrique incorrect (version du serveur changée)
  • Le tableau de bord attend _bucket mais vous n’avez qu’un gauge/counter
  • Intervalle de scan Prometheus trop long pour les fenêtres courtes (par exemple, [1m] avec un scan de 30s peut être bruyant)

Solution

  • Utilisez Grafana Explore pour chercher les préfixes de métrique (par exemple, tgi_ / vllm:)
  • Augmentez la fenêtre de plage de [1m][5m]

3) Les percentiles d’histogramme semblent « plats » ou incorrects

Les histogrammes Prometheus nécessitent une agrégation correcte :

  • utilisez rate(metric_bucket[5m])
  • puis sum by (le) (et optionnellement d’autres étiquettes stables)
  • puis histogram_quantile()

Prometheus documente le modèle de bucket et le calcul des quantiles côté serveur.
Le guide de visualisation des histogrammes de Grafana inclut des modèles de panneaux pratiques.

4) Explosion de cardinalité (pics de mémoire Prometheus)

Symptômes

  • Utilisation de la mémoire Prometheus augmente
  • « trop de séries » erreurs

Cause racine typique

  • Vous avez ajouté prompt, user_id, ou des identifiants de requête comme des étiquettes dans un exporteur personnalisé.

Solution

  • Supprimez les étiquettes à haute cardinalité
  • Agrégez préalablement en étiquettes à faible cardinalité (modèle, endpoint, statut)
  • Pensez à utiliser les journaux/traces pour le débogage par requête au lieu des étiquettes

5) « Nous avons des métriques, mais aucune idée de pourquoi c’est lent »

Les métriques sont nécessaires, mais parfois vous avez besoin de corrélation :

  • Ajoutez des journaux structurés avec les métadonnées de la requête (modèle, comptage de tokens, TTFT)
  • Ajoutez du traçage (OpenTelemetry) autour de votre passerelle + serveur d’inference
  • Utilisez des exemples (quand ils sont pris en charge) pour sauter d’un pic de latence à une trace

Un bon workflow : pic de tableau de bord Grafana → cliquez sur Explore → restreignez par instance/modèle → vérifiez les journaux/traces pour cette période.

Cela suit le modèle classique des métriques → journaux → traces décrit dans le guide d’architecture de l’observabilité et du monitoring.

6) Quirks des métriques multi-processus de vLLM

Si votre pile de service s’exécute sur plusieurs processus, vous pouvez avoir besoin de la configuration multi-processus de Prometheus (dépend de la manière dont le processus expose les métriques). Les documents vLLM mettent l’accent sur l’exposition des métriques via /metrics pour le polling de Prometheus ; vérifiez le mode des métriques du serveur lors du déploiement.


Un tableau de bord et un ensemble d’alertes « day-1 » pratiques

Si vous souhaitez une configuration légère qui fonctionne tout de même en production, commencez avec :

Panneaux du tableau de bord

  1. Latence p95 des requêtes
  2. Temps moyen par token p95
  3. Taille de la file
  4. Durée de la file p95
  5. Taux d’erreur
  6. Utilisation du cache KV %

Alertes

  • Latence p95 des requêtes > X pendant 10m
  • Durée de la file p99 > Y pendant 10m
  • Taux d’erreur > 1% pendant 5m
  • Utilisation du cache KV > 90% pendant 15m
  • Cible Prometheus hors ligne (toujours)

Guides d’observabilité liés

Guides d’infrastructure LLM liés


Notes de fin

Prometheus + Grafana vous donnent une vue « toujours active » de la santé de l’inference. Une fois les bases acquises, les prochaines grandes victoires viennent généralement de :

  • SLO par modèle / client
  • forme de requête (max tokens, limites de concurrence)
  • autoscaling lié au temps d’attente dans la file et à la marge de cache KV

Pour une explication plus large du monitoring vs de l’observabilité, des fondamentaux Prometheus et des schémas de production, consultez mon guide complet sur l’observabilité.