LLM local : Llama 3 et Mistral en production — Guide complet
Déploiement avancé de LLM locaux : llama.cpp, LM Studio API, quantization GGUF, offload GPU, optimisation throughput et intégration CI/scripts Python.
Llama 3 et Mistral en local : déploiement technique avancé
Ce guide couvre le déploiement technique de LLM en local : llama.cpp natif, quantization GGUF, offload GPU partiel, serveur API compatible OpenAI, et scripts d'automatisation. On suppose que vous savez ce qu'est un LLM et avez déjà testé Ollama ou LM Studio.
Prérequis
- Linux/macOS (les commandes sont identiques, Windows via WSL2)
- Python 3.10+
- Git installé
- 16 Go de RAM minimum (32 Go pour les modèles 13B+ à Q8)
- Optionnel : GPU NVIDIA avec 8 Go+ VRAM ou Apple Silicon (Metal)
Option 1 : llama.cpp — L'inférence bare-metal
Llama.cpp est la référence pour l'inférence locale sans overhead. Compilé en C++, il exploite directement SIMD (AVX2/AVX512 sur x86, NEON sur ARM) et supporte l'offload GPU partiel couche par couche.
Compilation
## Cloner le repo
git clone https://github.com/ggml-org/llama.cpp.git
cd llama.cpp
## Compilation CPU optimisée (AVX2 activé par défaut sur x86)
cmake -B build -DLLAMA_NATIVE=ON
cmake —build build —config Release -j$(nproc)
## Avec support CUDA (NVIDIA)
cmake -B build -DGGML_CUDA=ON -DLLAMA_NATIVE=ON
cmake —build build —config Release -j$(nproc)
## Avec support Metal (Apple Silicon)
cmake -B build -DGGML_METAL=ON
cmake —build build —config Release -j$(nproc)Télécharger un modèle GGUF
Les modèles sont hébergés sur Hugging Face. Utilisez huggingface-cli pour télécharger proprement :
## Installer huggingface-hub
pip install huggingface-hub
## Télécharger Mistral 7B Instruct v0.3 en Q4_K_M
huggingface-cli download \
bartowski/Mistral-7B-Instruct-v0.3-GGUF \
Mistral-7B-Instruct-v0.3-Q4_K_M.gguf \
—local-dir ~/models/
## Télécharger Llama 3.1 8B Instruct Q5_K_M
huggingface-cli download \
bartowski/Meta-Llama-3.1-8B-Instruct-GGUF \
Meta-Llama-3.1-8B-Instruct-Q5_K_M.gguf \
—local-dir ~/models/Lancer l'inférence en ligne de commande
## Inférence simple, 4 threads, context 4096 tokens
./build/bin/llama-cli \
—model ~/models/Mistral-7B-Instruct-v0.3-Q4_K_M.gguf \
—prompt "[INST] Explique Docker en 3 lignes [/INST]" \
—n-predict 256 \
—threads 4 \
—ctx-size 4096
## Avec offload GPU (NVIDIA) : 20 couches sur GPU, reste en RAM
./build/bin/llama-cli \
—model ~/models/Mistral-7B-Instruct-v0.3-Q4_K_M.gguf \
—n-gpu-layers 20 \
—prompt "[INST] Explique Docker en 3 lignes [/INST]" \
—n-predict 256
## Avec Apple Silicon Metal (offload total)
./build/bin/llama-cli \
—model ~/models/Meta-Llama-3.1-8B-Instruct-Q5_K_M.gguf \
—n-gpu-layers 99 \
—prompt "<|start_header_id|>user<|end_header_id|>\nBonjour<|eot_id|><|start_header_id|>assistant<|end_header_id|>\n" \
—n-predict 128Option 2 : Serveur HTTP compatible OpenAI (llama.cpp server)
llama.cpp embarque un serveur HTTP qui expose une API compatible /v1/chat/completions.
## Démarrer le serveur sur le port 8080
./build/bin/llama-server \
—model ~/models/Mistral-7B-Instruct-v0.3-Q4_K_M.gguf \
—host 0.0.0.0 \
—port 8080 \
—ctx-size 8192 \
—n-gpu-layers 20 \
—threads 4 \
—parallel 2
## Tester l'API
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "mistral",
"messages": [
{"role": "system", "content": "Tu es un assistant concis."},
{"role": "user", "content": "Qu\'est-ce que Docker ?"}
],
"max_tokens": 256,
"temperature": 0.7
}'
## Vérifier les modèles chargés
curl http://localhost:8080/v1/modelsOption 3 : LM Studio headless (API uniquement)
Si vous préférez LM Studio pour sa gestion des modèles, activez uniquement le serveur :
Lancez LM Studio → onglet "Local Server" → sélectionnez le modèle → Start Server.
Le serveur écoute sur http://localhost:1234 avec le même format OpenAI.
Intégration Python
#!/usr/bin/env python3
"""Client Python pour LLM local compatible OpenAI"""
from openai import OpenAI
## Pointer sur le serveur local (llama.cpp ou LM Studio)
client = OpenAI(
base_url="http://localhost:8080/v1",
api_key="local" # Requis par l'API mais non vérifié en local
)
def query_llm(prompt: str, system: str = "Tu es un assistant utile.") -> str:
response = client.chat.completions.create(
model="mistral", # Ignoré par llama-server mais requis
messages=[
{"role": "system", "content": system},
{"role": "user", "content": prompt}
],
max_tokens=512,
temperature=0.7,
stream=False
)
return response.choices[0].message.content
if __name__ == "__main__":
result = query_llm("Résume Docker en 3 points")
print(result)Version streaming
def stream_llm(prompt: str) -> None:
stream = client.chat.completions.create(
model="mistral",
messages=[{"role": "user", "content": prompt}],
max_tokens=512,
stream=True
)
for chunk in stream:
if chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
print() # Newline finale
stream_llm("Explique les conteneurs Docker")Optimisation des paramètres d'inférence
Choix de quantization selon VRAM/RAM disponible
| Format | Taille 7B | Taille 8B | Qualité | Usage |
|————|—————-|—————-|————-|———-|
| Q2_K | ~2.8 Go | ~3.2 Go | Faible | RAM < 6 Go |
| Q4_K_S | ~4.0 Go | ~4.5 Go | Bonne | RAM 6-8 Go |
| Q4_K_M | ~4.4 Go | ~5.0 Go | Bonne+ | RAM 8 Go recommandé |
| Q5_K_M | ~5.1 Go | ~5.7 Go | Très bonne | RAM 10 Go |
| Q6_K | ~5.9 Go | ~6.6 Go | Excellente | RAM 12 Go |
| Q8_0 | ~7.7 Go | ~8.6 Go | Max | RAM 16 Go |
Paramètres clés llama-server
## Production : configuration complète avec tous les paramètres importants
./build/bin/llama-server \
—model ~/models/Meta-Llama-3.1-8B-Instruct-Q5_K_M.gguf \
—host 127.0.0.1 \
—port 8080 \
—ctx-size 8192 \
—n-gpu-layers 99 \
—threads 8 \
—batch-size 512 \
—ubatch-size 512 \
—parallel 4 \
—mlock \
—flash-attn
# —mlock : empêche le swapping du modèle sur disque
# —flash-attn : active Flash Attention 2 (réduit l'usage VRAM)
# —parallel N : requêtes simultanées maxScript systemd — Service permanent
## Créer le fichier service
sudo tee /etc/systemd/system/llama-server.service << 'EOF'
[Unit]
Description=llama.cpp Inference Server
After=network.target
[Service]
Type=simple
User=llm
Group=llm
WorkingDirectory=/opt/llama.cpp
ExecStart=/opt/llama.cpp/build/bin/llama-server \
—model /home/llm/models/Meta-Llama-3.1-8B-Instruct-Q5_K_M.gguf \
—host 127.0.0.1 \
—port 8080 \
—ctx-size 8192 \
—n-gpu-layers 99 \
—threads 4 \
—parallel 2
Restart=on-failure
RestartSec=5
Environment=GGML_METAL_PATH_RESOURCES=/opt/llama.cpp/build/bin
[Install]
WantedBy=multi-user.target
EOF
## Activer et démarrer
sudo systemctl daemon-reload
sudo systemctl enable llama-server
sudo systemctl start llama-server
## Vérifier l'état
sudo systemctl status llama-serverReverse proxy Nginx (HTTPS + auth basique)
Pour exposer l'API sur le réseau local ou internet :
## /etc/nginx/sites-available/llm-api
server {
listen 443 ssl;
server_name llm.monserveur.fr;
ssl_certificate /etc/letsencrypt/live/llm.monserveur.fr/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/llm.monserveur.fr/privkey.pem;
# Auth basique optionnelle
auth_basic "LLM API";
auth_basic_user_file /etc/nginx/.htpasswd;
location / {
proxy_pass http://127.0.0.1:8080;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# Streaming SSE requis pour les réponses en temps réel
proxy_buffering off;
proxy_cache off;
proxy_read_timeout 300s;
}
}## Créer le fichier htpasswd pour l'auth basique
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd utilisateurBenchmarking
## Mesurer la vitesse d'inférence (tokens/s)
./build/bin/llama-bench \
—model ~/models/Meta-Llama-3.1-8B-Instruct-Q5_K_M.gguf \
—n-gpu-layers 99 \
—threads 4
## Output exemple :
## pp512 : 245 tokens/s (prefill)
## tg128 : 58 tokens/s (génération)Dépannage
CUDA out of memory : réduisez —n-gpu-layers (ex: 20 au lieu de 99). Chaque couche GPU consomme environ 100-200 Mo de VRAM selon le modèle.
Compilation échoue avec CUDA : vérifiez nvcc —version et que libcuda.so est dans /usr/lib. Reinstallez les CUDA toolkit headers si manquants.
Performances médiocres en CPU : activez —mlock pour prévenir le swapping, et assurez-vous que le modèle tient entièrement en RAM physique (pas de swap).
Tokens incohérents avec Llama 3 : le prompt template doit suivre exactement le format Llama 3 (<|start_header_id|>...<|eot_id|>). LM Studio gère ça automatiquement ; en CLI, construisez le prompt manuellement ou utilisez l'option —chat-template llama3.
Le serveur répond lentement sous charge : augmentez —parallel et —batch-size. Attention : chaque slot parallèle consomme autant de VRAM que le contexte alloué.
Script de healthcheck
#!/bin/bash
## ~/.local/bin/check-llm.sh
## Vérifie que le serveur LLM répond correctement
RESPONSE=$(curl -s -o /dev/null -w "%{http_code}" \
-X POST http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{"model":"local","messages":[{"role":"user","content":"ping"}],"max_tokens":5}')
if [ "$RESPONSE" -eq 200 ]; then
echo "[OK] LLM server opérationnel"
exit 0
else
echo "[ERREUR] LLM server non joignable (HTTP $RESPONSE)"
# Redémarrer le service si mort
systemctl restart llama-server
exit 1
fichmod +x ~/.local/bin/check-llm.sh
## Cron toutes les 5 minutes
(crontab -l 2>/dev/null; echo "*/5 * * * * ~/.local/bin/check-llm.sh >> /var/log/llm-health.log 2>&1") | crontab -À lire aussi
Fine-tuner un modèle IA avec LoRA : le guide pas à pas
Apprenez à personnaliser un modèle d'IA en le fine-tunant avec LoRA, même avec une carte graphique modeste. Guide complet pour débutants.
Fine-tuning LoRA/QLoRA : configuration avancée et optimisation
Guide technique complet pour fine-tuner un LLM avec LoRA : quantification QLoRA, hyperparamètres, multi-GPU, troubleshooting et déploiement GGUF.
Bot Discord + Claude API : architecture complète et production
Architecture robuste d'un bot Discord alimenté par Claude. Gestion d'erreurs, rate limiting, Docker, déploiement VPS et bonnes pratiques de production.