Technique
Labs, checklist de mise en production et aide-mémoire MetricsQL
Pour : ingénieurs et SREPrérequis : Avoir lu les leçons 1 à 5 du parcours et disposer de Docker avec Compose v2.
Module 17 : travaux pratiques
Section intitulée « Module 17 : travaux pratiques »Lab 1 : déployer la pile et ingérer les premières métriques
Section intitulée « Lab 1 : déployer la pile et ingérer les premières métriques »Objectif : déployer la pile Docker Compose complète (VictoriaMetrics, OTel Collector, vmagent, vmalert, Alertmanager, Grafana, simulateur), vérifier les métriques dans vmui et dans Grafana. Durée estimée : 30 minutes. Niveau : débutant. Prérequis : Docker avec Compose v2, environ 8 Go de RAM libres (la pile compte neuf conteneurs).
-
Clonez le dépôt et démarrez la pile :
Fenêtre de terminal git clone https://forge.erythix.tech/labstraining/labs/VMLLM.gitcd VMLLMdocker compose up -d --builddocker compose ps # vérifier que tous les services tournent -
Le simulateur démarre avec la pile (service
llm-simulator, 10 requêtes par seconde, 3 modèles) et expose ses métriques sur le port 9100. Vérifiez qu’il produit des séries :Fenêtre de terminal curl -s http://localhost:9100/metrics | grep llm_requests_total | head -
Vérifiez l’ingestion dans vmui (
http://localhost:8428/vmui) avec la requête :sum by (model) (rate(llm_requests_total[1m])) * 60 -
Ouvrez Grafana (
http://localhost:3000). Les tableaux de bord sont provisionnés au démarrage : ouvrez le tableau de bord de production (identifiantllm-prod), défini dansgrafana/dashboards/dashboard-llm-prod.json.
Lab 2 : écrire cinq requêtes MetricsQL
Section intitulée « Lab 2 : écrire cinq requêtes MetricsQL »Objectif : à partir des métriques du simulateur, écrire les cinq requêtes de production essentielles, les valider dans vmui, puis les ajouter à un tableau de bord Grafana.
Durée estimée : 40 minutes. Niveau : intermédiaire. Corrigé : solutions/lab2-queries.md dans le dépôt.
- Coût total par modèle sur les dernières 24 heures.
- TTFT P95 par fournisseur (
histogram_quantile). - Anomalie du score de recherche RAG (z-score par rapport à une référence de 7 jours, voir le module 7 ; la référence exige sept jours d’historique, sur une pile neuve le z-score reste partiel).
- Les 5 tenants les plus coûteux (
topk+increase). - Efficacité GPU : tokens de sortie par joule (division entre métriques).
Lab 3 : configurer une alerte de production
Section intitulée « Lab 3 : configurer une alerte de production »Objectif : configurer l’alerte RAGIndexDrift dans vmalert, la tester en injectant une dégradation du score, vérifier la notification dans un canal Slack de test.
Durée estimée : 25 minutes, plus les 15 minutes du for: de l’alerte. Niveau : intermédiaire.
- Adaptez
alerts/llm-quality.ymletalertmanager.ymldu dépôt, avec l’URL de votre webhook Slack de test. - Rechargez les règles par une requête GET :
curl http://localhost:8880/-/reload(oudocker compose restart vmalert). Rechargez Alertmanager avecdocker compose restart alertmanager. - Injectez une dégradation du score :
make lab3-drift(oubash scripts/triggers/01_rag_index_drift.sh). Le script arrête le simulateur nominal et en relance un avec--score-drift 0.5, qui divise les scores par deux. - Dans l’interface de vmalert (
http://localhost:8880), vérifiez que l’alerte passe en attente puis se déclenche au bout de 15 minutes. - Confirmez la réception dans Slack, puis restaurez le simulateur nominal :
make lab3-restore(oubash scripts/triggers/_restore.sh).
Lab 4 : règles d’enregistrement et performance
Section intitulée « Lab 4 : règles d’enregistrement et performance »Objectif : ajouter les règles d’enregistrement essentielles et comparer les temps de réponse des requêtes avec et sans elles, via l’API VictoriaMetrics.
Durée estimée : 20 minutes. Niveau : avancé. Corrigé : solutions/lab4-recording-rules.md dans le dépôt (sans retenir ses gains chiffrés, voir l’encadré sur le lab VMLLM).
-
Copiez les règles du module 10 dans
alerts/recording-rules.yml(le dépôt en contient une version proche), puis rechargez vmalert :curl http://localhost:8880/-/reload. -
Attendez deux ou trois intervalles d’évaluation, puis vérifiez dans vmui que la série
llm:request_duration_ms:p99_5mexiste. -
Mesurez la requête complète :
Fenêtre de terminal time curl -sG 'http://localhost:8428/api/v1/query' \--data-urlencode 'query=histogram_quantile(0.99, sum by (le, model, pipeline_id) (rate(llm_request_duration_ms_bucket[5m])))' \> /dev/null -
Mesurez la série précalculée :
Fenêtre de terminal time curl -sG 'http://localhost:8428/api/v1/query' \--data-urlencode 'query=llm:request_duration_ms:p99_5m' \> /dev/null -
Répétez chaque mesure une dizaine de fois et comparez les médianes. Faites de même avec
increase(llm_cost_usd_total[24h])etllm:cost_usd:increase24h. -
Interprétez : la cardinalité du simulateur est faible (quelques centaines de séries), l’écart absolu sera donc modeste. Il croît avec le nombre de séries lues par la requête complète ; c’est ce rapport que vous devez mesurer sur votre propre instance avant de généraliser les règles.
Annexe A : checklist de mise en production
Section intitulée « Annexe A : checklist de mise en production »Avant la mise en production
Section intitulée « Avant la mise en production »- VictoriaMetrics est déployé avec
-storageDataPathsur un SSD persistant. - La rétention est définie :
-retentionPeriodsur chaque instance et-retentionFilteruniquement si vous utilisez la version Enterprise (sinon, des instances distinctes par rétention). - vmbackup est configuré vers un stockage compatible S3 (test de restauration réussi).
- vmagent ou l’OTel Collector ingère les quatre catégories de métriques (qualité, latence, coût, GPU).
- Les six règles vmalert de production sont chargées et testées (alerte de test reçue dans Slack ou Teams).
- Au moins deux règles d’enregistrement sont actives pour les coûts.
- Le tableau de bord Grafana de production est importé et ses variables fonctionnent.
- vmauth est configuré avec une authentification (basique ou par jeton ; l’acceptation de connexions mTLS est une fonction de vmauth Enterprise), jamais d’accès non authentifié.
- La cardinalité totale est mesurée et documentée (
/api/v1/status/tsdb). - Les labels à risque (
trace_id,session_id) sont supprimés par réétiquetage. - Une alerte d’autosurveillance
VictoriaMetricsDownest active. - Un runbook d’incident existe (qui appeler, comment restaurer, comment monter en charge).
- Des utilisateurs Grafana en lecture seule existent pour les rôles non techniques (direction, finance).
Après la mise en production (J+7, J+30)
Section intitulée « Après la mise en production (J+7, J+30) »- La cardinalité s’est stabilisée (pas de croissance linéaire).
- La consommation disque est mesurée et projetée à 90 jours.
- Au moins une alerte réelle a été reçue et le routage confirmé.
- La latence P99 des requêtes Grafana est mesurée et comparée à la cible que vous avez fixée (par exemple moins d’une seconde).
- Un test de restauration vmbackup a été mené sur une instance de test.
- Les seuils d’alerte ont été revus avec les équipes (faux positifs ?).
- Les requêtes MetricsQL personnalisées des équipes sont documentées.
Annexe B : aide-mémoire MetricsQL pour les LLM
Section intitulée « Annexe B : aide-mémoire MetricsQL pour les LLM »Coûts et tokens
Section intitulée « Coûts et tokens »# Coût horaire par modèlesum by (model) (increase(llm_cost_usd_total[1h]))
# Coût quotidien projetésum(rate(llm_cost_usd_total[30m])) * 86400
# Les 10 tenants les plus coûteux sur 24 htopk(10, sum by (tenant_id) (increase(llm_cost_usd_total[24h])))
# Coût moyen par requête (règle d'enregistrement recommandée)sum(rate(llm_cost_usd_total[5m])) / sum(rate(llm_requests_total[5m]))Latence et performance
Section intitulée « Latence et performance »# Latence de bout en bout P99 par modèlehistogram_quantile(0.99, sum by (le, model) (rate(llm_request_duration_ms_bucket[5m])))
# TTFT P95 (streaming)histogram_quantile(0.95, sum by (le, model) (rate(llm_ttft_ms_bucket[5m])))
# Taux d'erreur globalsum(rate(llm_errors_total[5m])) / sum(rate(llm_requests_total[5m]))
# Débit de tokens de sortie par modèle (tokens/s)sum by (model) (rate(llm_tokens_total{type='output'}[1m]))Qualité RAG
Section intitulée « Qualité RAG »# Z-score du score de recherche par rapport à une référence de 7 jours# (remplace anomaly_score(), qui n'est pas une fonction MetricsQL)( avg by (index_id) (rag_retrieval_score_avg) - avg_over_time(avg by (index_id) (rag_retrieval_score_avg)[7d:1h]))/ stddev_over_time(avg by (index_id) (rag_retrieval_score_avg)[7d:1h])
# Si vous utilisez vmanomaly (Enterprise) : interroger la métrique qu'il écritanomaly_score > 1
# Pression de contexte P95 par pipelinehistogram_quantile(0.95, sum by (le, pipeline_id) (rate(rag_context_pressure_ratio_bucket[5m])))
# Part de chunks abandonnés (exige un compteur rag_chunks_retrieved_total)sum by (pipeline_id) (rate(rag_chunks_dropped_total[5m])) / sum by (pipeline_id) (rate(rag_chunks_retrieved_total[5m]))GPU et infrastructure
Section intitulée « GPU et infrastructure »# Utilisation GPU moyenne par nœud et par GPUavg by (node, gpu) (DCGM_FI_DEV_GPU_UTIL)
# Saturation de la VRAM (alerter avant l'OOM)DCGM_FI_DEV_FB_USED / (DCGM_FI_DEV_FB_USED + DCGM_FI_DEV_FB_FREE)
# Tokens de sortie par joule (global ; les séries DCGM n'ont pas de label de modèle LLM)sum(rate(llm_tokens_total{type='output'}[5m])) / sum(DCGM_FI_DEV_POWER_USAGE)
# File d'attente vLLMvllm:num_requests_waitingMotifs avancés
Section intitulée « Motifs avancés »# Médiane robuste (ignore les pics)median_over_time(rag_retrieval_score_avg[30m])
# Ouverture, plus haut, plus bas, clôture des scores RAG (chandeliers)rollup_candlestick(rag_retrieval_score_avg[1h])
# Trafic quasi nul : la pente d'un compteur est un débit par secondeabs(deriv(llm_requests_total[10m])) < 0.01
# Comparaison d'une semaine sur l'autresum(rate(llm_cost_usd_total[1h])) / sum(rate(llm_cost_usd_total[1h] offset 7d))Références
Section intitulée « Références »Documentation officielle VictoriaMetrics
Section intitulée « Documentation officielle VictoriaMetrics »| Ressource | URL |
|---|---|
| Documentation VictoriaMetrics | docs.victoriametrics.com |
| Référence MetricsQL | docs.victoriametrics.com/metricsql |
| vmagent | docs.victoriametrics.com/vmagent |
| vmalert | docs.victoriametrics.com/vmalert |
| vmauth | docs.victoriametrics.com/vmauth |
| vmanomaly | docs.victoriametrics.com/anomaly-detection |
| Code source VictoriaMetrics | github.com/VictoriaMetrics/VictoriaMetrics |
Intégrations et outils
Section intitulée « Intégrations et outils »| Outil | URL |
|---|---|
| OTel Collector Contrib | github.com/open-telemetry/opentelemetry-collector-contrib |
| DCGM exporter (GPU) | github.com/NVIDIA/dcgm-exporter |
| Métriques vLLM | docs.vllm.ai (section « Metrics ») |
| Métriques du proxy LiteLLM | docs.litellm.ai/docs/proxy/prometheus |
| Plugin Grafana VictoriaMetrics | grafana.com/grafana/plugins/victoriametrics-metrics-datasource |
| prometheus_client pour Python | github.com/prometheus/client_python |