GGUF / GGML (llama.cpp)#
TL;DR — GGUF (GPT-Generated Unified Format) est le format de fichier standard pour distribuer des LLMs quantifiés. Développé par Georgi Gerganov pour llama.cpp, il offre des dizaines de niveaux de quantification (de 2 à 8 bits) et tourne sur n'importe quelle plateforme — du CPU laptop au GPU datacenter.
Qu'est-ce que GGUF ? (expliqué pour un néophyte)#
Un modèle de langage « normal » (comme Llama-2-70B en FP16) pèse ~140 GB. Pour le faire tourner chez toi, il te faut des GPU coûteux.
GGUF est un format de fichier qui compresse ce modèle à ~20-40 GB en réduisant la précision des poids à 2-8 bits. Le moteur llama.cpp sait lire ces fichiers et faire de l'inférence — sans GPU si nécessaire, juste sur ton CPU.
Llama-2-70B
~140 GB
16 bits/poids
GPU requis"] A -->|"quantification"| B["Modèle GGUF Q4_K_M
Llama-2-70B
~40 GB
~4.5 bits/poids
CPU ou GPU ok"]
C'est devenu le standard de facto pour distribuer des modèles open-source : Hugging Face, Ollama, LM Studio — tous utilisent GGUF.
GGML → GGUF : l'évolution#
| GGML | GGUF | |
|---|---|---|
| Période | 2023 (début) | Août 2023 → |
| Structure | Format ad hoc, parsing fragile | Format key-value structuré et extensible |
| Extensibilité | Casser le format à chaque changement | Métadonnées typées, backward-compatible |
| Statut | Déprécié | Actif et recommandé |
GGUF a remplacé GGML car le premier format nécessitait de recompiler llama.cpp à chaque changement de structure. GGUF utilise un système de paires clé-valeur typées qui permet d'ajouter des métadonnées sans casser la compatibilité.
Les quant types : tableau complet#
Le grand force de GGUF est la variété de ses types de quantification. Trois familles principales :
Types Legacy (uniformes par bloc de 32)#
Quantification uniforme simple. Rapide, pas de calibration, mais qualité limitée aux bas bits.
K-quants (importance-aware, bloc de 256)#
Quantification par blocs de 256 avec scale factors à précision variable. Les suffixes _S, _M, _L indiquent le compromis taille/qualité.
I-quants (importance matrix)#
Utilisent une matrice d'importance (calibration) pour guider la quantification. Meilleure qualité à bas bitrate (2-3 bits).
Tableau de référence#
| Type | Bits/poids | Taille relative | Famille | Notes |
|---|---|---|---|---|
Q2_K |
~2.6 | ~19% | K-quants | Minimum viable, perte notable |
Q3_K_S |
~2.9 | ~21% | K-quants | |
Q3_K_M |
~3.1 | ~23% | K-quants | Bon ratio pour petits modèles |
Q3_K_L |
~3.3 | ~24% | K-quants | |
Q4_0 |
4.0 | ~28% | Legacy | Le plus rapide, qualité correcte |
Q4_1 |
4.5 | ~31% | Legacy | Avec zero-point, meilleur que Q4_0 |
Q4_K_S |
~4.1 | ~29% | K-quants | |
Q4_K_M |
~4.8 | ~34% | K-quants | ★ Sweet spot — recommandé |
Q5_0 |
5.0 | ~35% | Legacy | |
Q5_1 |
5.5 | ~38% | Legacy | |
Q5_K_S |
~5.1 | ~36% | K-quants | |
Q5_K_M |
~5.5 | ~38% | K-quants | Très haute qualité |
Q6_K |
~6.6 | ~45% | K-quants | Quasi-lossless |
Q8_0 |
8.5 | ~57% | Legacy | Lossless pratique |
IQ2_XXS |
~2.0 | ~14% | I-quants | Extrême, nécessite importance matrix |
IQ2_XS |
~2.2 | ~16% | I-quants | |
IQ2_S |
~2.4 | ~17% | I-quants | |
IQ3_XXS |
~3.0 | ~21% | I-quants | |
IQ3_XS |
~3.2 | ~23% | I-quants | |
IQ3_S |
~3.4 | ~24% | I-quants | |
IQ4_XS |
~4.2 | ~29% | I-quants | Compétitif avec Q4_K_M |
IQ4_NL |
~4.5 | ~31% | I-quants | Non-linear, bonne qualité |
F16 |
16.0 | ~100% | N/A | FP16 natif (pas de quantification) |
Règle empirique :
Q4_K_Mest le sweet spot universel — meilleur compromis qualité/taille pour la majorité des modèles. Si tu as de la RAM, monte àQ5_K_MouQ6_K. Si tu es très limité, descends àQ3_K_Mou les I-quants.
Visualisation du trade-off#
Q4_K_Mest le sweet spot — meilleur compromis qualité/taille pour la majorité des modèles.
Architecture llama.cpp#
Pourquoi llama.cpp est devenu le standard#
(modèle quantifié)"] F --> C["llama.cpp core
(C/C++ pur, ~0 dep)"] C --> B1["Backend CPU
(SIMD AVX2/NEON/AVX512)"] C --> B2["Backend GPU
(CUDA / ROCm)"] C --> B3["Backend GPU
(Metal / Vulkan)"] B1 --> D1["Laptop CPU
Raspberry Pi
Edge devices"] B2 --> D2["Serveur NVIDIA
AMD"] B3 --> D3["Mac M1/M2/M3
iPhone / iPad
Android"]
Atouts clés :
- Zéro dépendance — C/C++ pur, compile partout (laptop, serveur, mobile, edge)
- CPU inference — pas besoin de GPU ! SIMD (AVX2, AVX-512, ARM NEON) pour la vitesse
- Multi-backend — CUDA, Metal, Vulkan, OpenCL, ROCm, SYCL
- Portabilité absolue — tourne sur Mac, Linux, Windows, Android, iOS
- Écosystème riche — Ollama, LM Studio, KoboldCpp, text-generation-webui
- Single-file — tout le modèle dans un seul fichier
.gguf(poids + tokenizer + métadonnées) - Pas de calibration pour les types legacy et K-quants
Structure interne d'un fichier GGUF#
• Magic number: GGUF
• Version du format
• Nombre de tenseurs
• Nombre de paires clé-valeur"] block:K["Métadonnées (KV)
• general.name = Llama-2-70B
• llama.context_length = 4096
• tokenizer.ggml.model = llama
• quantization_type = Q4_K_M"] block:T["Données des tenseurs
• token_embd.weight [Q4_K_M]
• blk.0.attn_q.weight [Q4_K_M]
• blk.0.attn_k.weight [Q4_K_M]
• ...
• output.weight [Q6_K]"] block:TK["Données du tokenizer
• Vocabulaire
• BPE merges
• Tokens spéciaux"] H --> K --> T --> TK
Le format KV permet à n'importe quelle application de lire les métadonnées sans connaître la structure interne du modèle.
Le format KV permet à n'importe quelle application de lire les métadonnées sans connaître la structure interne du modèle.
Exemple pratique#
Installation de llama.cpp#
# Cloner et compiler (avec support CUDA optionnel)
git clone https://github.com/ggerganov/llama.cpp.git
cd llama.cpp
# CPU seulement (le plus simple)
make -j$(nproc)
# Avec CUDA
make GGML_CUDA=1 -j$(nproc)
# Avec Metal (macOS)
make GGML_METAL=1 -j$(nproc)
Conversion d'un modèle HF vers GGUF#
# 1. Télécharger un modèle au format Hugging Face
huggingface-cli download meta-llama/Llama-2-7B-hf --local-dir ./llama-7b
# 2. Convertir en GGUF (format FP16 d'abord)
python convert_hf_to_gguf.py ./llama-7b --outfile llama-7b-fp16.gguf
# 3. Quantifier en Q4_K_M (le sweet spot)
./llama-quantize llama-7b-fp16.gguf llama-7b-q4_k_m.gguf Q4_K_M
# Autres quant types populiers :
./llama-quantize llama-7b-fp16.gguf llama-7b-q5_k_m.gguf Q5_K_M # haute qualité
./llama-quantize llama-7b-fp16.gguf llama-7b-q8_0.gguf Q8_0 # quasi-lossless
./llama-quantize llama-7b-fp16.gguf llama-7b-q2_k.gguf Q2_K # minimum viable
./llama-quantize llama-7b-fp16.gguf llama-7b-iq3_s.gguf IQ3_S # bas bit intelligent
Inférence avec llama.cpp#
# Mode interactif (chat)
./llama-cli \
-m llama-7b-q4_k_m.gguf \
-p "Explique la quantification en une phrase :" \
-n 200 \
--temp 0.7
# Mode serveur (API compatible OpenAI)
./llama-server \
-m llama-7b-q4_k_m.gguf \
--host 0.0.0.0 --port 8080 \
-c 4096 \
-ngl 33 # nombre de couches offloadées sur GPU (-1 = tout)
# Appel API
curl http://localhost:8080/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "llama-7b",
"messages": [{"role": "user", "content": "Bonjour !"}],
"temperature": 0.7
}'
Avec Ollama (le plus simple)#
# Installer Ollama
curl -fsSL https://ollama.com/install.sh | sh
# Lancer un modèle (télécharge automatiquement le GGUF Q4_K_M)
ollama run llama3.1:8b
# Lister les modèles disponibles
ollama list
# Modèle avec quant type spécifique
ollama pull llama3.1:8b-q5_K_M
Via Python (llama-cpp-python)#
from llama_cpp import Llama
# Charger le modèle GGUF
llm = Llama(
model_path="llama-7b-q4_k_m.gguf",
n_ctx=4096, # Contexte
n_gpu_layers=-1, # -1 = offload tout sur GPU si dispo
verbose=False,
)
# Génération
response = llm(
"Qu'est-ce que la quantification NF4 ?",
max_tokens=200,
temperature=0.7,
stop=["\n\n"],
)
print(response["choices"][0]["text"])
Avantages et inconvénients#
✅ Avantages#
- Déploiement universel — CPU, GPU, mobile, edge, navigateur (WASM)
- Pas besoin de GPU — inférence CPU viable avec SIMD
- Large choix de quant types — du 2-bit au lossless
- Single-file — un
.ggufcontient tout - Écosystème mature — Ollama, LM Studio, countless GUIs
- Pas de calibration pour les types legacy et K-quants
- Format extensible — backward-compatible
⚠️ Inconvénients#
- Pas un papier académique — documentation sur GitHub/wiki uniquement
- Moins optimisé que GPTQ/AWQ pour GPU pur (kernels moins spécialisés)
- I-quants nécessitent une matrice d'importance (calibration)
- Performance CPU limitée pour les très grands modèles (>70B)
- Choix de quant type peut être déroutant pour un débutant
Quel quant type choisir ?#
Quel type choisir ?"] --> B{"Beaucoup de RAM/VRAM ?"} B -->|"OUI"| C["Q6_K ou Q8_0
(quasi-lossless)"] B -->|"NON"| D{"Meilleure qualité possible ?"} D -->|"OUI"| E["Q5_K_M
(excellent ratio)"] D -->|"NON"| F{"Meilleur compromis standard ?"} F -->|"OUI"| G["★ Q4_K_M ★
(recommandé par défaut)"] F -->|"NON"| H{"Très limité en mémoire ?"} H -->|"Modèle > 30B"| I["Q3_K_M
(acceptable)"] H -->|"Modèle ≤ 13B"| J["IQ3_S ou IQ4_XS
(intelligent)"] H -->|"Minimum absolu"| K["Q2_K ou IQ2_XXS
(perte notable mais fonctionnel)"]
Références#
- Évaluation des quants — "Which Quantization Should I Use? A Unified Evaluation of llama.cpp Quantization Types" — arXiv:2601.14277
- llama.cpp — github.com/ggerganov/llama.cpp
- Spécification GGUF — github.com/ggerganov/llama.cpp/blob/master/gguf.md
- Ollama — ollama.com
- LM Studio — lmstudio.ai
- llama-cpp-python — github.com/abetlen/llama-cpp-python
- Page de référence — Voir aussi Quantification LLM pour le panorama complet des méthodes