Planification GPU Ollama et gestion des ressources : optimisation VRAM, équilibrage multi-GPU

Avec une carte 8 Go de VRAM, vous chargez enfin un modèle 13B, puis après quelques inférences tout plante — l’écran affiche « CUDA out of memory ».
Ou vous avez investi dans deux GPU, convaincu de pouvoir enfin faire tourner de gros modèles, et nvidia-smi ne montre qu’une carte au travail pendant que l’autre reste inactive.
Au début avec Ollama, j’ai tombé dans ces pièges : VRAM insuffisante, multi-GPU inutilisé, vitesse d’inférence irrégulière. En creusant, j’ai compris la logique de planification GPU d’Ollama : ce n’est pas « configurer et oublier », il faut saisir ce que signifient les paramètres.
Cet article rassemble ces apprentissages pour répondre à des questions concrètes :
- Faire tourner un 13B de façon stable sur 8 Go de VRAM (sans OOM surprise)
- Configurer le multi-GPU pour qu’il serve vraiment (schéma d’équilibrage complet)
- Quels paramètres ajuster quand la VRAM manque (ordre de priorité)
- Ce qu’est l’offloading GPU (mécanisme llama.cpp sous le capot)
Prérequis : article assez technique ; une base GPU, CUDA et Ollama est utile. Si vous débutez, lisez d’abord les articles précédents de la série (surtout le n°6 sur l’optimisation des performances), puis revenez ici.
1. Gestion de la mémoire GPU : configuration des paramètres
La planification GPU d’Ollama repose sur quelques paramètres qui répartissent les couches entre GPU et CPU. Les maîtriser explique les OOM « alors que ça devrait passer » ou les ralentissements inexpliqués.
1.1 Paramètres clés
| Paramètre | Rôle | Valeur par défaut | Quand ajuster |
|---|---|---|---|
num_gpu | Nombre de couches exécutées sur le GPU | Détection auto | Réduire si VRAM insuffisante |
main_gpu | Index du GPU principal | 0 | Multi-GPU : choisir la carte |
low_vram | Mode faible VRAM | false | Recommandé sous 8 Go |
num_batch | Taille du batch | 512 | Réduire à 256 si VRAM serrée |
num_ctx | Longueur de contexte | 4096 | 2048 pour dialogues courts |
num_gpu prête à confusion : ce n’est pas le nombre de cartes, mais le nombre de couches du modèle calculées sur le GPU.
Exemple : Llama 2 7B a 32 couches. num_gpu: 32 = tout sur GPU. Avec num_gpu: 20, 20 couches sur GPU et 12 sur CPU — la vitesse baisse.
Avec low_vram, Ollama applique des astuces (ex. cache KV en RAM CPU plutôt qu’en VRAM). L’inférence ralentit un peu, mais le service tient.
1.2 Flux d’allocation VRAM
Au chargement :
- Détection : VRAM libre disponible
- Calcul des couches : combien de couches tiennent sur le GPU selon la taille du modèle
- Cache KV : espace réservé pour l’inférence (consomme aussi de la VRAM)
- Inférence : occupation dynamique, avec variations
Le point sensible est l’étape 2 : l’auto peut se tromper quand la VRAM est « juste assez » (8 Go + 13B). Là, fixez num_gpu à la main.
Pour voir l’offloading actuel :
ollama run llama3 --verbose
Une ligne du type llama_model_load: model loaded - layers: 40/40 on GPU indique 40 couches sur GPU.
1.3 Moteur llama.cpp
Ollama s’appuie sur llama.cpp. Comprendre l’offloading GPU clarifie pourquoi certains réglages changent peu.
Décision d’offloading
VRAM disponible = VRAM totale GPU - réserve système (quelques centaines de Mo)
taille par couche = paramètres du modèle / nombre de couches
couches possibles = min(couches totales, VRAM disponible / taille par couche)
Piège : le calcul ne compte souvent que le modèle, pas le cache KV, qui grossit avec la conversation. D’où chargement OK puis OOM après quelques tours.
Architecture hybride
GPU et CPU ne se partagent pas tout :
- GPU : produits matriciels, attention (charge lourde)
- CPU : embedding, normalisation (charge légère)
- Transferts : aller-retour GPU↔CPU à chaque frontière de couche
Offloading partiel = latence de transfert à chaque couche — d’où un ralentissement net.
mmap
llama.cpp charge souvent le fichier modèle en mmap :
- pas besoin de tout charger en RAM ; pages à la demande
- plusieurs processus peuvent partager la même image
- empreinte mémoire réduite
Pour désactiver mmap (cas particuliers) :
PARAMETER use_mmap false
2. Multi-GPU : architecture d’équilibrage
Avec deux GPU ou plus, la question est : comment Ollama les utilise-t-il tous ?
Fait important : Ollama ne supporte pas le parallélisme de modèle. Vous ne pouvez pas couper un modèle en deux moitiés sur GPU 0 et GPU 1. Une instance = une carte.
Le multi-GPU reste utile pour :
- Instances de modèles différents : GPU 0 = llama3, GPU 1 = mistral
- Plusieurs instances du même modèle : débit via équilibrage
2.1 Instance unique, plusieurs GPU (limites)
Reconnaître plusieurs GPU :
# Limiter Ollama aux GPU 0 et 1
CUDA_VISIBLE_DEVICES=0,1 ollama serve
Par défaut, le modèle va sur GPU 0 ; GPU 1 reste souvent inactif. main_gpu choisit la carte principale :
# Modelfile
FROM llama3
PARAMETER main_gpu 1 # GPU principal = carte 1
En pratique, vous changez surtout de carte — vous n’exploitez pas vraiment les deux en parallèle.
2.2 Plusieurs instances + équilibrage (recommandé)
La voie efficace : une instance Ollama par GPU, puis un répartiteur.
┌─────────┐
│ Client │ requêtes d'inférence
└────┬────┘
│
┌────▼────────────────────┐
│ Nginx (équilibrage) │ stratégie least_conn
│ Port: 8080 │
└────┬─────────┬──────────┘
│ │
┌────▼───┐ ┌──▼────┐
│Ollama 1│ │Ollama 2│
│GPU 0 │ │GPU 1 │ une carte par instance
│Port │ │Port │
│11434 │ │11435 │
└────────┘ └────────┘
Étape 1 : démarrer les instances
# Instance 1 — GPU 0, port 11434
CUDA_VISIBLE_DEVICES=0 OLLAMA_HOST=127.0.0.1:11434 ollama serve &
# Instance 2 — GPU 1, port 11435
CUDA_VISIBLE_DEVICES=1 OLLAMA_HOST=127.0.0.1:11435 ollama serve &
Les deux instances peuvent partager ~/.ollama : le mmap permet le partage du fichier modèle.
Étape 2 : Nginx
# /etc/nginx/conf.d/ollama.conf
upstream ollama_cluster {
least_conn; # connexions les plus faibles en priorité
server 127.0.0.1:11434;
server 127.0.0.1:11435;
}
server {
listen 8080;
location / {
proxy_pass http://ollama_cluster;
proxy_http_version 1.1;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
# réponse en flux
proxy_buffering off;
proxy_cache off;
}
}
least_conn envoie chaque requête vers l’instance avec le moins de connexions actives.
Étape 3 : client
# via Nginx (répartition automatique)
curl http://localhost:8080/api/generate -d '{
"model": "llama3",
"prompt": "Bonjour"
}'
Ou rediriger le client Ollama :
export OLLAMA_HOST=http://localhost:8080
ollama run llama3
2.3 Comparaison des stratégies
| Stratégie | Principe | Cas d’usage |
|---|---|---|
| Round-robin (défaut) | tour à tour | simple, modèles homogènes |
| least_conn | instance la plus libre | recommandé pour l’inférence |
| IP Hash | même IP → même instance | session persistante |
L’inférence a une durée variable (secondes à minutes). Le round-robin peut surcharger une instance. least_conn lisse la charge.
Avec bascule si une instance tombe :
upstream ollama_cluster {
least_conn;
server 127.0.0.1:11434 max_fails=3 fail_timeout=30s;
server 127.0.0.1:11435 max_fails=3 fail_timeout=30s;
}
Après 3 échecs consécutifs, Nginx retire l’instance 30 secondes.
3. Optimisation VRAM : quantification, contexte, batch
Ordre de priorité quand la VRAM manque : quantification > contexte > batch > couches GPU.
La quantification change le plus : Q4 vs FP16 ≈ −75 % de VRAM. Réduire num_gpu déplace le calcul vers le CPU : VRAM gagnée, vitesse perdue.
3.1 Niveau de quantification
Moins de bits par paramètre : FP16 = 16 bits, Q4 = 4 bits. Légère perte de précision ; en pratique Q4 ≈ 2–3 % sur la plupart des tâches.
| Quantification | VRAM (vs FP16) | Perte | Usage |
|---|---|---|---|
| Q4_K_M | ~25 % | 2-3 % | recommandé : bon compromis |
| Q5_K_M | ~33 % | 1-2 % | précision un peu plus haute |
| Q8_0 | ~50 % | ~0,5 % | proche du FP16 |
| FP16 | 100 % | aucune | recherche, benchmarks |
Référence Llama 2 13B :
- FP16 : ~26 Go
- Q4_K_M : ~8 Go
- Q8_0 : ~13 Go
8 Go + 13B Q4 tient à peine ; le cache KV fait souvent déborder en inférence.
Usage quotidien : Q4_K_M. Traduction, code : Q5_K_M ou Q8_0.
# Q4 (souvent par défaut)
ollama pull llama3
# Q8
ollama pull llama3:8b-q8_0
3.2 Longueur de contexte
Le cache KV stocke l’historique. Sa taille suit num_ctx.
Formule simplifiée :
VRAM cache KV ≈ num_ctx × num_layers × hidden_dim × 2 octets
Ex. Llama 2 7B : 32 couches, hidden_dim 4096, num_ctx 4096 → ~2 Go de cache KV. À 8192, ~4 Go. Doubler ctx double le cache KV.
Stratégies :
- Dialogues courts :
num_ctx: 2048— moitié de cache KV, suffisant pour Q&R simples - Longs documents : éviter ctx=16000 d’un coup ; découper (chunking) par morceaux
FROM llama3
PARAMETER num_ctx 2048
Mythe : un petit ctx ne dégrade pas la qualité si la conversation est courte — 2048 et 4096 donnent le même résultat pour quelques tours.
3.3 Batch et concurrence
num_batch = tokens traités par passe (défaut 512). Batch plus grand = meilleure efficacité parallèle, pic VRAM plus haut.
FROM llama3
PARAMETER num_batch 256
512 → 256 : pic VRAM ~−20 %, vitesse un peu plus basse (moins brutal que moins de couches GPU).
Concurrence
Ollama traite souvent les requêtes en série. Plusieurs requêtes simultanées = file d’attente.
Options :
- Multi-instances (section 2) : une requête active par instance
- File applicative (Redis Queue, etc.) :
import redis
from queue import Queue
r = redis.Redis()
r.lpush('ollama_queue', request_data)
request = r.rpop('ollama_queue')
ollama.generate(request)
4. Cas pratiques : trois scénarios
4.1 Scénario 1 : 13B stable sur 8 Go
Problème
RTX 3060 8 Go, Llama 2 13B Q4 (~8 Go au chargement). Quelques inférences puis OOM — le cache KV sature la VRAM.
Solution
Réduire le cache KV + pic d’allocation :
FROM llama2:13b-q4
PARAMETER num_gpu 30 # 40 couches, 30 sur GPU
PARAMETER low_vram true # cache KV en RAM CPU
PARAMETER num_ctx 2048 # contexte divisé par deux
PARAMETER num_batch 256 # pic VRAM plus bas
Occupation stable ~6 Go, ~2 Go de marge.
Résultat
- VRAM : ~8 Go → ~6 Go stable
- Débit : ~8 tokens/s (plus lent que full GPU, bien plus que CPU seul)
- Stabilité : plus d’OOM
10 couches sur CPU = transferts à chaque frontière ; acceptable plutôt qu’un crash.
4.2 Scénario 2 : double GPU, débit API
Problème
Deux RTX 3090 24 Go, API Ollama publique. Une instance = file d’attente aux heures de pointe. nvidia-smi : une carte ~70 %+, l’autre ~20 %.
Solution
Script de cluster (voir section 2) :
#!/bin/bash
# start_ollama_cluster.sh
CUDA_VISIBLE_DEVICES=0 \
OLLAMA_HOST=127.0.0.1:11434 \
OLLAMA_MODELS=/home/user/.ollama \
nohup ollama serve > ollama1.log 2>&1 &
CUDA_VISIBLE_DEVICES=1 \
OLLAMA_HOST=127.0.0.1:11435 \
OLLAMA_MODELS=/home/user/.ollama \
nohup ollama serve > ollama2.log 2>&1 &
sleep 5
curl http://127.0.0.1:11434/api/pull -d '{"name": "llama3"}'
curl http://127.0.0.1:11435/api/pull -d '{"name": "llama3"}'
echo "Cluster Ollama démarré sur 11434 et 11435"
Nginx en least_conn.
Résultat
- Débit global : ~+80 % (parallèle vs série)
- Utilisation GPU : ~40 % moyenne → ~80 % (les deux cartes actives)
- Latence aux pics : ~−50 % (moins de file)
100 requêtes : ~10 min en mono-instance, ~5 min en cluster.
4.3 Scénario 3 : offloading automatique
Problème
Plusieurs tailles de modèles ; à chaque changement, réglage manuel de num_gpu. Oubli = crash.
Solution
Script qui adapte le Modelfile à la VRAM libre :
#!/bin/bash
# auto_offload.sh
GPU_MEM_FREE=$(nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits | head -1)
declare -A MODEL_SIZES
MODEL_SIZES["llama3:8b-q4"]=5000
MODEL_SIZES["llama3:70b-q4"]=40000
MODEL_SIZES["mistral:7b-q4"]=4500
MODEL_NAME=$1
if [ -z "$MODEL_NAME" ]; then
echo "Usage: $0 <model_name>"
exit 1
fi
MODEL_SIZE=${MODEL_SIZES[$MODEL_NAME]}
if [ -z "$MODEL_SIZE" ]; then
echo "Unknown model size for $MODEL_NAME"
exit 1
fi
if [ $GPU_MEM_FREE -gt $MODEL_SIZE ]; then
echo "Using full GPU offloading (enough memory)"
cat > /tmp/modelfile_temp <<EOF
FROM $MODEL_NAME
PARAMETER num_gpu -1
PARAMETER low_vram false
EOF
else
OFFLOAD_RATIO=$((GPU_MEM_FREE * 100 / MODEL_SIZE))
echo "Using partial GPU offloading ($OFFLOAD_RATIO%)"
cat > /tmp/modelfile_temp <<EOF
FROM $MODEL_NAME
PARAMETER num_gpu $OFFLOAD_RATIO
PARAMETER low_vram true
PARAMETER num_ctx 2048
EOF
fi
ollama create "${MODEL_NAME}-auto" -f /tmp/modelfile_temp
echo "Created ${MODEL_NAME}-auto with auto config"
./auto_offload.sh llama3:70b-q4
Effet : adaptation auto, moins d’erreurs de config, changement de modèle simplifié. Extensions possibles : bascule low_vram si VRAM chute, préchargement nocturne.
5. Bonnes pratiques et surveillance
5.1 Configurations par taille de VRAM
| VRAM | Modèle conseillé | Quantif. | Couches GPU | Autres |
|---|---|---|---|---|
| 6 Go | 7B | Q4 | partiel (~50 %) | low_vram=true, ctx=2048 |
| 8 Go | 7B | Q4 | full GPU | ctx=2048 (prudent) |
| 8 Go | 13B | Q4 | partiel (~75 %) | low_vram=true, ctx=2048, batch=256 |
| 12 Go | 13B | Q4 | full GPU | ctx=4096 possible |
| 16 Go | 13B | Q8 ou Q5 | full GPU | ctx=4096 |
| 16 Go | 70B | Q4 | partiel (~50 %) | low_vram=true |
| 24 Go | 70B | Q4 | full GPU | ctx=4096 possible |
| 48 Go (bi-GPU) | 70B | Q4 | full GPU | multi-instances + équilibrage |
Estimations prudentes ; KV cache et réserve OS à prévoir. Dialogues longs → marge plus large.
5.2 Outils de surveillance
nvidia-smi -l 1
nvidia-smi --query-gpu=memory.used,memory.free --format=csv -l 1
ollama run llama3 --verbose
Cherchez GPU offloading: 40/40 layers, mmap, allocation KV.
#!/bin/bash
# monitor_gpu.sh
LOG_FILE="gpu_memory.log"
while true; do
TIMESTAMP=$(date '+%Y-%m-%d %H:%M:%S')
GPU_MEM=$(nvidia-smi --query-gpu=memory.used,memory.free --format=csv,noheader)
echo "$TIMESTAMP $GPU_MEM" >> $LOG_FILE
sleep 5
done
5.3 Dépannage
OOM en inférence
nvidia-smi— VRAM réellement saturée ?- Config : Q4 ? ctx ≤ 2048 ? batch 256 ? trop de couches GPU ?
- Sinon
low_vram=true
Priorité : quantification > ctx > batch > couches > low_vram
Inférence lente
ollama run your_model --verbose | grep "GPU offloading"
20/40 layers = moitié sur CPU, normal que ce soit lent. Solutions : plus de VRAM, moins de quantification (Q4→Q8), ou accepter le débit.
VRAM instable
Souvent le cache KV. Limiter num_ctx ou l’historique côté application (ex. 10 derniers tours).
Multi-GPU : une seule carte active
curl http://localhost:8080/api/tags
Vérifier least_conn, logs des instances, modèle préchargé sur les deux ports.
Résumé
- VRAM serrée → quantification d’abord : Q4 ≈ −75 % vs FP16, impact limité
- Surveiller le cache KV : lié à
num_ctxet à la longueur du dialogue - Multi-GPU → équilibrage : multi-instances + Nginx, pas le mode mono-instance multi-GPU
- llama.cpp : offloading = calcul par couches + coût des transferts
Config 8 Go stable :
PARAMETER num_gpu 30
PARAMETER low_vram true
PARAMETER num_ctx 2048
PARAMETER num_batch 256
Démarrage bi-GPU :
CUDA_VISIBLE_DEVICES=0 OLLAMA_HOST=127.0.0.1:11434 ollama serve &
CUDA_VISIBLE_DEVICES=1 OLLAMA_HOST=127.0.0.1:11435 ollama serve &
Pour aller plus loin : l’article 6 de la série couvre quantification et batch ; celui-ci approfondit le GPU. L’article 8 traitera le déploiement multi-modèles en parallèle.
Questions : Ollama GitHub Discussions ou commentaires sous l’article.
FAQ
Ollama peut-il répartir un modèle sur plusieurs GPU en parallèle ?
Pourquoi l'inférence provoque-t-elle un OOM après quelques requêtes alors que le chargement réussit ?
• Réduire num_ctx
• Activer low_vram
• Raccourcir l'historique de dialogue
Quel paramètre ajuster en premier quand la VRAM manque ?
num_gpu correspond-il au nombre de GPU que je possède ?
Quelle stratégie d'équilibrage pour le multi-GPU ?
Quelle taille de modèle avec 8 Go de VRAM ?
• 7B Q4 : GPU complet, ctx=2048
• 13B Q4 : GPU partiel (~75 %), low_vram + ctx=2048 + batch=256
• Modèles plus grands : plus de VRAM ou offloading CPU
10 min de lecture · Publié le: 11 avr. 2026 · Mis à jour le: 27 juil. 2026
Guide Ollama LLM local
Si vous arrivez depuis la recherche, le plus rapide est de passer à l’article précédent ou suivant de cette série.
Précédent
Accélération GPU Ollama : guide pratique CUDA, ROCm et Metal sur toutes les plateformes
Guide complet de l'accélération GPU Ollama : configuration NVIDIA CUDA, AMD ROCm et Apple Metal, avec étapes de vérification, réglage multi-GPU et dépannage pour multiplier par 10 à 20 la vitesse d'inférence LLM locale.
Partie 7 sur 18
Suivant
Optimisation des performances Ollama : guide complet quantification, batch et mémoire
Stratégies de quantification Q4/Q5/Q8 pour Ollama, configuration num_batch pour augmenter le débit de 50 à 150 %, gestion mémoire GPU et solutions OOM. Benchmarks par configuration matérielle.
Partie 9 sur 18



Commentaires
Connectez-vous avec GitHub pour laisser un commentaire