Call-Informatique
Call-Informatique
Le média tech
 LLM local : Llama 3 et Mistral en production — Guide complet
Intelligence ArtificielleGuides8 min de lecture

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

bash
## 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 :

bash
## 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

bash
## 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 128

Option 2 : Serveur HTTP compatible OpenAI (llama.cpp server)

llama.cpp embarque un serveur HTTP qui expose une API compatible /v1/chat/completions.

bash
## 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/models

Option 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

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

python
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

bash
## 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 max

Script systemd — Service permanent

bash
## 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-server

Reverse proxy Nginx (HTTPS + auth basique)

Pour exposer l'API sur le réseau local ou internet :

nginx
## /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;
    }
}
bash
## Créer le fichier htpasswd pour l'auth basique
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd utilisateur

Benchmarking

bash
## 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

bash
#!/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
fi
bash
chmod +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 -
Sur le même sujet

À lire aussi

#tutoriel#guide-technique#llm-local#llama-cpp#gguf#quantization#ia-inference