Optimiser l'inférence des LLM en production avec quantization et batching
18/09/2026
Optimiser l'inférence des LLM en production avec quantization et batching
Pour un CTO ou un lead dev qui met en production des assistants ou des services basés sur de grands modèles de langage, réduire la latence et le coût d'inférence sans détériorer l'expérience utilisateur est un enjeu central. Ce guide technique explique, pas à pas, comment combiner quantization, batching et une architecture d'inférence (Triton/ONNX ou serveur d'inférence équivalent) pour obtenir des performances opérationnelles robustes.
À qui s'adresse cet article et résultat attendu
- Persona : CTO / lead dev / ingénieur ML en charge de la mise en production.
- Résultat : vous saurez convertir un modèle pour l'inférence, appliquer une quantization sûre, configurer le batching côté serveur, déployer avec Triton/ONNX et mesurer l'impact sur latence et coût.
Pré-requis
- Connaissance de base PyTorch/TensorFlow et Docker.
- Accès à une image de serveur d'inférence (ex. NVIDIA Triton) ou à ONNX Runtime en production. Voir la documentation officielle pour les images et bonnes pratiques : NVIDIA Triton, ONNX Runtime quantization.
- GPU recommandé pour les LLM ; CPU possible pour modèles légers quantifiés.
Étapes techniques pas à pas
1. Exporter le modèle en ONNX (si nécessaire)
Beaucoup d'architectures d'inférence professionnelles travaillent avec ONNX pour la portabilité. Exemple minimal d'export PyTorch vers ONNX :
# export_model.py (extrait)
import torch
from transformers import AutoModelForCausalLM, AutoTokenizer
model_name = "votre-model"
model = AutoModelForCausalLM.from_pretrained(model_name).eval().to("cpu")
tokenizer = AutoTokenizer.from_pretrained(model_name)
dummy_input = tokenizer("Bonjour", return_tensors="pt")
with torch.no_grad():
torch.onnx.export(
model,
(dummy_input["input_ids"],),
"model.onnx",
opset_version=13,
input_names=["input_ids"],
output_names=["logits"],
dynamic_axes={"input_ids": {0: "batch", 1: "seq"}, "logits": {0: "batch", 1: "seq"}}
)
Remarques :
- Vérifiez les opset compatibility et la documentation du modèle. Pour certains LLMs il est préférable d'utiliser des outils d'export spécialisés (voir docs Hugging Face).
- Si vous utilisez TensorFlow, adaptez l'export selon la chaîne TF → ONNX.
2. Appliquer une quantization contrôlée
La quantization réduit la taille et accélère l'inférence en utilisant des formats numériques plus compacts (int8, int4, etc.). Approche simple avec ONNX Runtime (quantization dynamique) :
# ex. commande Python (ONNX Runtime quantization)
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic("model.onnx", "model_quant.onnx", weight_type=QuantType.QInt8)
Bonnes pratiques :
- Commencez par quantization dynamique (moins risquée) avant d'expérimenter int8 static ou int4.
- Validez la qualité (tests d'output, perplexité approximative) avant et après quantization.
- Conserver un chemin de fallback non quantifié pour les cas dégradés.
3. Préparer la repository modèle pour le serveur (ex. Triton)
Structure recommandée :
model_repository/
my_llm/
1/
model.onnx
config.pbtxt
Exemple minimal de config.pbtxt pour Triton (ONNX) :
name: "my_llm"
platform: "onnxruntime_onnx"
max_batch_size: 8
input [
{
name: "input_ids"
data_type: TYPE_INT32
dims: [-1]
}
]
output [
{
name: "logits"
data_type: TYPE_FP32
dims: [-1]
}
]
Points d'attention :
- max_batch_size définit la plus grande taille de batch côté serveur (impact direct sur latence/throughput).
- Les noms et dimensions doivent correspondre exactement à l'export ONNX.
4. Configurer le serveur pour le batching
Le batching côté serveur agrège plusieurs requêtes pour maximiser le débit GPU. Dans Triton, on peut activer le dynamic batching via config. Exemple d’ajout :
dynamic_batching {
preferred_batch_size: [ 4, 8 ]
max_queue_delay_microseconds: 1000
}
Conseils :
- Choisissez preferred_batch_size en fonction de la latence cible — plus le batch est grand, meilleur le débit mais plus élevée la latence p99.
- max_queue_delay_microseconds limite le temps d'attente pour compléter un batch — ajustez selon SLA.
- Testez différentes tailles et mesures p50/p95/p99 pour trouver le compromis optimal.
5. Déployer en Docker / Kubernetes
Exemple de déploiement Kubernetes (déploiement simplifié) :
apiVersion: apps/v1
kind: Deployment
metadata:
name: triton-llm
spec:
replicas: 1
selector:
matchLabels:
app: triton-llm
template:
metadata:
labels:
app: triton-llm
spec:
containers:
- name: triton
image: nvcr.io/nvidia/tritonserver:latest
args: ["tritonserver", "--model-repository=/models"]
volumeMounts:
- name: model-repo
mountPath: /models
volumes:
- name: model-repo
hostPath:
path: /srv/model_repository
Autoscaling (HPA) basé sur GPU est possible via des métriques custom. Pour du CPU-only, HPA sur utilisation CPU resta standard.
6. Client d'inférence : batching côté client et timeouts
Exemple Python avec le client Triton (ou tritonclient) :
from tritonclient.grpc import InferenceServerClient, InferInput
client = InferenceServerClient(url="triton:8001")
input_ids = [[101, 102, ...], [101, 55, ...]] # batch 2
infer_input = InferInput("input_ids", [len(input_ids), seq_len], "INT32")
infer_input.set_data_from_numpy(np.array(input_ids, dtype=np.int32))
result = client.infer("my_llm", inputs=[infer_input])
logits = result.as_numpy("logits")
Astuce : gérez côté client un timeout soft et un mécanisme de retry; évitez de surcharger le serveur avec des requêtes unitaires si le batching est la voie de performance choisie.
Erreurs fréquentes et dépannage
- Model fails to load: vérifier noms d'inputs/outputs et opset incompatibility. Log du serveur indique souvent le nom attendu.
- OOM GPU: réduire max_batch_size, activer quantization, ou augmenter la mémoire GPU.
- Résultats dégradés après quantization: tester avec un jeu d'évaluation; si dégradation, essayer une quantization plus conservatrice (dynamic) ou calibration statique.
- Latence p99 élevée malgré batching: vérifier max_queue_delay_microseconds, et le comportement tail-latency lié au garbage collector côté Python ou au multi-tenancy.
Métriques à mesurer
Mesurez systématiquement :
- p50, p95, p99 latency (end-to-end)
- Throughput (req/s) en conditions stables
- GPU/CPU utilization, mémoire utilisée
- Taux d'erreur et timeouts
Un pipeline de bench simple : scripts de charge (wrk/locust), enregistrement Prometheus + Grafana, et tests A/B entre version quantifiée et baseline non-quantifiée.
Bonnes pratiques sécurité et fiabilité
- Isoler les serveurs d'inférence (namespace, nœuds GPU dédiés) pour éviter l'interférence entre tenants.
- Mettre en place des quotas et circuit breakers côté API gateway pour protéger le backend.
- Maintenir un chemin de rollback (serveur non quantifié) et des tests de non-régression automatiques après chaque build d'artefact.
- Instrumenter logs et traces pour diagnostiquer latence tail (OpenTelemetry possible).
Exemple de checklist avant mise en production
- Conversion et vérification ONNX effectuées
- Quantization testée et acceptée par tests qualité
- Config Triton/serveur validée (max_batch_size, dynamic batching)
- Déploiement containerisé et tests de charge passés
- Monitoring (latence/throughput), alerting et rollback prêts
Ressources et liens utiles
- Documentation NVIDIA Triton : developer.nvidia.com/nvidia-triton-inference-server
- Quantization ONNX Runtime : onnxruntime.ai/docs/performance/quantization.html
- Guide export & déploiement Hugging Face : consultez la documentation officielle Hugging Face pour l'export des modèles.
Cas réel (illustratif)
Sur un prototype interne, l'équipe a réduit la mémoire GPU nécessaire et doublé le throughput en combinant quantization dynamique + dynamic batching, tout en maintenant des tests qualité automatisés. Les gains exacts varient fortement selon le modèle et la séquence d'entrée ; il est donc impératif de bencher sur vos scénarios réels.
Conseils rapides pour commencer
- 1. Testez la quantization sur un clone du modèle et comparez outputs sur un échantillon métier.
- 2. Mettez en place un serveur d'inférence local (Triton en Docker) pour itérer rapidement.
- 3. Automatiser les benchmarks dans votre CI/CD pour détecter les régressions perf.
Pour aller plus loin, Novane accompagne la mise en production (architecture, devops, monitoring) et l'intégration d'assistants IA dans les SaaS et ERP. Consultez notre page services IA pour les détails techniques et opérationnels : Novane — intelligence artificielle. Pour un audit rapide de votre architecture d'inférence, vous pouvez demander une séance de consulting ou nous contacter.
En résumé : combinez conversion/ONNX, quantization prudente, dynamic batching et une orchestration adaptée (Triton/Kubernetes) ; mesurez p50/p95/p99 et itérez jusqu'à l'équilibre coût/perf attendu.

