Aller au contenu principal

Quantification

Quantification avancée des LLM

GGUF K-quants, nomenclature Q4_K_M et UD-Q5_K_XL, GPTQ, AWQ, EXL2/EXL3, REAP : panorama des méthodes de quantification et de leurs compromis.

Par Antoine Michéa, Fondateur & ingénieur infrastructure ·

La quantification réduit la précision des poids d’un modèle (de 32 bits à 4 bits, par exemple) pour diminuer l’empreinte mémoire et accélérer l’inférence. Plusieurs méthodes coexistent, chacune avec ses compromis entre taille, vitesse et qualité.

Pourquoi quantifier ?

Un modèle de 7 milliards de paramètres en précision FP16 (16 bits) occupe environ 14 Go de mémoire. Quantifié en 4 bits, ce même modèle ne nécessite plus que ~4 Go, le rendant exécutable sur du matériel grand public.

Taille mémoire = Nb_paramètres × (bits_par_poids / 8) + overhead
MétriqueValeur
Réduction mémoire (FP16 → 4 bits)-75 %
Accélération inférence2 à 5x
Perte qualité (Q4_K_M)< 1 %

Sur un modèle moderne comme Qwen3.6-27B (dense) ou Qwen3.6-35B-A3B (MoE, 3B actifs par token), ces ratios se retrouvent quasiment à l’identique.

GPTQ — quantification post-training précise

GPTQ (GPT Quantization) est une méthode de quantification post-entraînement qui utilise des informations de second ordre (matrice hessienne) pour minimiser l’erreur de quantification couche par couche.

  1. Calibration : utilise un petit dataset (128 segments de 2048 tokens du dataset C4) pour analyser les activations.
  2. Quantification par couche : chaque ligne de la matrice de poids est quantifiée indépendamment.
  3. Optimisation hessienne : minimise l’erreur quadratique moyenne via les informations de courbure.
  4. Compensation : les erreurs sont compensées sur les colonnes suivantes (ordre d’activation).

L’option --act-order quantifie les colonnes par ordre décroissant de magnitude d’activation, améliorant significativement la qualité (par exemple, perplexité de 7,15 → 6,09 sur Llama 7B).

Avantages : excellente précision à 4 bits, inférence rapide via ExLlama, bien supporté (AutoGPTQ). Inconvénients : quantification lente (plusieurs heures), nécessite une calibration, GPU NVIDIA uniquement.

AWQ — Activation-Aware Weight Quantization

AWQ est une méthode développée par le MIT Han Lab qui identifie et protège les poids « saillants » (importants) en se basant sur la distribution des activations, et non sur la magnitude des poids eux-mêmes.

Tous les poids ne sont pas égaux : protéger seulement 1 % des poids saillants réduit drastiquement l’erreur de quantification. L’importance est déterminée par l’amplitude des activations, pas des poids.

1. Collecter les statistiques d'activation (offline)
2. Identifier les canaux avec les plus grandes activations
3. Scaler UP ces canaux saillants avant quantification
4. Scaler DOWN les activations de manière équivalente
   → Transformation mathématiquement équivalente
   → Mais erreur de quantification réduite sur les poids importants

Avantages : meilleure précision que GPTQ, pas de backpropagation, bonne généralisation, MLSys 2024 Best Paper Award. Inconvénients : VRAM plus élevée que GPTQ, GPU NVIDIA requis, vitesse légèrement inférieure.

EXL2 — quantification mixte optimisée

EXL2 est le format de quantification d’ExLlamaV2, offrant un contrôle fin sur le compromis taille/qualité grâce à une quantification à bits-per-weight (bpw) variable.

  • Précision mixte par couche : chaque couche peut avoir un bpw différent.
  • Calibration par hessienne : optimise la distribution des bits selon l’importance.
  • Contrôle fin : on spécifie le bpw cible (4.0, 4.25, 4.65, 5.0…).
  • Performance GPU : kernels CUDA optimisés, le plus rapide en full GPU.

Si le modèle tient entièrement en VRAM, EXL2 est souvent le meilleur choix : il offre les meilleures performances en vitesse et en qualité. AWQ 4 bits égale EXL2 4.0 bpw en qualité, surpassant tous les quants GGUF, y compris Q8.

EXL3 — la nouvelle génération

EXL3 est le format de quantification d’ExLlamaV3, une réécriture complète utilisant la technique QTIP (Quantization with Trellis-coded Inference Pairs) de Cornell RelaxML.

  • Codebook procédural : structures de treillis « tail-biting » pour encoder les vecteurs.
  • Conversion ultra-rapide : quelques minutes pour les petits modèles, quelques heures pour 70B+ (contre 720 GPU-heures pour AQLM).
  • Excellente qualité low-bitrate : Llama-3.1-70B reste cohérent à seulement 1,6 bpw.
  • Moins de 16 Go : un 70B utilisable avec un cache de 4096 tokens.
MétriqueValeur
Llama 70B cohérent1,6 bpw
VRAM pour 70B inférence< 16 Go
Vitesse vs AQLM~100x

HQQ — Half-Quadratic Quantization

HQQ est une méthode développée par Mobius Labs qui se distingue par sa rapidité : aucune calibration nécessaire, quantification en quelques minutes même pour les plus grands modèles.

Contrairement à GPTQ/AWQ qui minimisent l’erreur sur les activations de sortie, HQQ se concentre sur la minimisation directe de l’erreur sur les poids, avec une approche « half-quadratic » à solutions en forme fermée, évitant le calcul de gradients.

MétriqueValeur
Quantification Llama-2-70B< 5 min
Vitesse vs GPTQ50x
Précisions supportées1 à 8 bits
from transformers import AutoModelForCausalLM, HqqConfig

quant_config = HqqConfig(
    nbits=4,           # 4-bit quantization
    group_size=64,     # Taille des groupes
    axis=1             # Axe de quantification
)

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3.6-27B-Instruct",
    quantization_config=quant_config,
    device_map="auto"
)

Marlin — kernel CUDA optimisé pour GPTQ

Marlin n’est pas une méthode de quantification mais un kernel CUDA ultra-optimisé pour exécuter les modèles GPTQ. Il utilise les mêmes poids GPTQ mais avec des optimisations avancées (async-copy, optimisation cache L2) pour atteindre des performances exceptionnelles.

  • Async-copy : transferts mémoire asynchrones masquant la latence.
  • Cache L2 : réutilisation optimale des données en cache.
  • Fusion d’opérations : moins de passes kernel, plus d’efficacité.

Pour la production avec vLLM, Marlin est souvent le meilleur choix : c’est la seule méthode qui dépasse les performances du baseline FP16 tout en réduisant la mémoire de 75 %.

from vllm import LLM

llm = LLM(
    model="TheBloke/Llama-2-13B-GPTQ",
    quantization="marlin",  # Active le kernel optimisé
    dtype="half"
)

BitsandBytes — quantification à la volée

BitsandBytes quantifie les modèles à la volée pendant le chargement, sans nécessiter de modèle pré-quantifié. Elle utilise NF4 (NormalFloat 4-bit), optimisé pour les distributions normales des poids : les niveaux de quantification sont placés là où la majorité des poids se concentrent (près de zéro).

Avantages : meilleure qualité (perplexité +1,7 %), pas de modèle pré-quantifié requis, setup le plus simple, double quantification possible. Inconvénients : plus lent que le baseline (~0,4x), quantification à chaque chargement, GPU NVIDIA uniquement.

from transformers import AutoModelForCausalLM, BitsAndBytesConfig

bnb_config = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_quant_type="nf4",        # NormalFloat 4-bit
    bnb_4bit_compute_dtype="float16",
    bnb_4bit_use_double_quant=True    # Double quantification
)

model = AutoModelForCausalLM.from_pretrained(
    "Qwen/Qwen3.6-27B-Instruct",
    quantization_config=bnb_config,
    device_map="auto"
)

BitsandBytes est idéal pour l’expérimentation : on peut tester n’importe quel modèle Hugging Face en 4 bits sans chercher de version pré-quantifiée. Pour la production à haut débit, on préfère Marlin ou EXL2.

REAP — pruning d’experts pour modèles MoE

REAP (Router-weighted Expert Activation Pruning) est une technique de compression de Cerebras Research conçue spécifiquement pour les modèles Mixture of Experts (MoE) comme Qwen3.6-35B-A3B, Qwen3-Coder, Kimi-K2, DeepSeek-V3 ou MiniMax-M2.

Contrairement aux idées reçues, le pruning d’experts est supérieur au merging pour les tâches génératives : le merging cause un « effondrement du sous-espace fonctionnel », car le routeur perd son contrôle indépendant sur chaque expert.

REAP calcule un score de saillance pour chaque expert :

saillance = router_gate_value × activation_norm
  1. Calibration : passage de samples représentatifs à travers le modèle.
  2. Analyse : enregistrement des experts activés et de leur magnitude.
  3. Scoring : calcul de la saillance (poids du routeur × norme d’activation).
  4. Pruning : suppression des experts à faible saillance.

Attention : les experts sont spécialisés par tâche (code, JSON, multi-turn…). Si les données de calibration ne contiennent pas de code, les experts spécialisés en code seront prunés. Il faut utiliser un mix représentatif du cas d’usage.

CompressionExperts restantsTaille (MiniMax-M2)Perte qualité
25 %~120~620 GoMinimale
40 %~96~500 GoFaible
50 %~80~420 GoNear-lossless*

*Near-lossless sur les tâches de génération de code et tool-calling avec une calibration appropriée.

pip install llmcompressor

python -m llmcompressor.transformers.oneshot \
    --model_id "MiniMax/MiniMax-M2" \
    --compression-ratio 0.50 \
    --prune-method reap \
    --distance_measure cosine \
    --calibration_dataset "evol-codealpaca-v1,xlam-function-calling-60k" \
    --output_dir "./MiniMax-M2-REAP-50"

K-Quants GGUF — la famille Q4_K_M

Les K-quants sont les méthodes de quantification natives de llama.cpp/GGUF, utilisant une précision mixte intelligente pour optimiser le rapport qualité/taille.

Qwen3.6-27B-Instruct-Q4_K_M.gguf
                     |    |   |
                     |    |   +-- M = Medium (mix de précision)
                     |    +------ K = K-quant (méthode avancée)
                     +----------- Q4 = 4-bit (précision)

Précision (Q2 à Q8)

  • Q2 (2 bits) : très petit, perte de qualité importante.
  • Q3 (3 bits) : petit, perte notable.
  • Q4 (4 bits) : bon équilibre taille/qualité (recommandé).
  • Q5 (5 bits) : excellente qualité, taille raisonnable.
  • Q6 (6 bits) : très bonne qualité.
  • Q8 (8 bits) : quasi identique au FP16.

Méthode de quantification (0, 1, K)

  • _0 : symétrique — un seul scale par bloc (legacy, simple mais moins précis).
  • _1 : asymétrique — scale + zero-point par bloc (legacy, meilleur pour distributions non centrées).
  • _K : K-quant — schéma à deux niveaux avec super-blocs, le standard moderne.

Les K-quants utilisent une hiérarchie à deux niveaux : les poids sont groupés en blocs de 32, eux-mêmes regroupés en super-blocs de 256. Chaque niveau a son propre scale, permettant une approximation affine par morceaux qui capture mieux les variations locales et globales. C’est pourquoi Q4_K_M surpasse Q4_0/Q4_1 malgré un bpw similaire.

Variantes de mix (S, M, L) et XL

Les suffixes S/M/L indiquent le niveau de précision mixte entre les tenseurs :

  • _S (Small) : presque tout en 4 bits, fichier compact.
  • _M (Medium) : tenseurs sensibles (attention, couches finales) en 5-6 bits — recommandé.
  • _L (Large) : encore plus de tenseurs en précision élevée.

Certains curateurs publient des variantes « dynamiques » comme UD-Q5_K_XL (Unsloth Dynamic) : le suffixe XL pousse encore plus loin la sélectivité de la précision par tenseur, en gardant en haute précision les couches les plus sensibles. C’est ce type de quant qui se révèle souvent optimal en pratique (voir l’expérience plus bas).

TQ1_0 — quantification ternaire

Pour les très grands modèles comme DeepSeek-V3, on trouve parfois des versions TQ1_0 qui encodent les poids en ternaire (valeurs {−1, 0, +1}), atteignant ~1,6-1,7 bpw : la compression maximale possible tout en gardant un modèle fonctionnel.

Importance matrix (imatrix)

L’importance matrix (imatrix) est une technique de calibration qui améliore significativement la qualité des quantifications GGUF, particulièrement pour les quants agressifs (Q2, Q3, IQ2, IQ3). Elle analyse un dataset de calibration pour mesurer l’importance réelle de chaque poids lors de l’inférence : les poids fréquemment activés avec de fortes magnitudes reçoivent plus de précision.

Modèle FP16 + dataset → llama-imatrix → fichier .imatrix → llama-quantize --imatrix → GGUF optimisé
# 1. Générer l'importance matrix (calibration)
llama-imatrix \
    -m model-f16.gguf \
    -f calibration_data.txt \
    -o model.imatrix \
    --chunks 500

# 2. Quantifier en utilisant l'imatrix
llama-quantize \
    --imatrix model.imatrix \
    model-f16.gguf \
    model-Q4_K_M.gguf Q4_K_M
  • Fortement recommandé pour : IQ1, IQ2, IQ3, Q2, Q3.
  • Amélioration notable pour : Q4_K_S, Q4_K_M, IQ4_XS.
  • Gain marginal pour : Q5, Q6, Q8 (déjà très précis).

Attention : deux modèles avec le même label (par exemple IQ3_XS) peuvent différer si l’un a été calibré avec un dataset généraliste et l’autre avec un dataset trop spécifique. Un dataset trop spécialisé réduira la qualité sur les tâches générales. Les bons curateurs utilisent des datasets diversifiés (wiki, code, conversations).

I-Quants — quantification non-linéaire

Les I-quants (IQ2_XXS, IQ2_XS, IQ2_S, IQ2_M, IQ3_, IQ4_) vont au-delà de l’affine en utilisant des lookup tables et des règles de déquantification non-linéaires, permettant un meilleur fit des distributions non-gaussiennes des poids.

CritèreIQ4_XSQ4_K_M
Bits/weight~4,25 bpw~4,89 bpw
Taille (8B)~4,2 Go~4,6 Go
GénérationUn peu plus rapideStandard
Prompt processingUn peu plus lentPlus rapide
Sensibilité imatrixÉlevéeModérée
RecommandationVRAM limitéeDéfaut fiable

IQ4_NL est une variante non-linéaire (~4,5 bpw) à blocs plus petits, optimisée pour les performances CPU.

Sur Hugging Face, les principaux curateurs de GGUF de qualité sont Unsloth (quants dynamiques avec imatrix), Bartowski (large catalogue) et, historiquement, TheBloke.

Tableau comparatif des méthodes

MéthodeCalibrationTemps quant.Vitesse inf.Qualité 4-bitHardware
GGUF K-quantsNonMinutes★★★★★★★CPU/GPU universel
GPTQOui (C4)Heures★★★★★★★★GPU NVIDIA
AWQOuiHeures★★★★★★★★★GPU NVIDIA
EXL2OuiHeures★★★★★★★★★★GPU NVIDIA
EXL3OuiMinutes-Heures★★★★★★★★★★GPU NVIDIA
HQQNonMinutes★★★★★★★★GPU NVIDIA
Marlin (kernel)Non (GPTQ)★★★★★+★★★★GPU NVIDIA
BitsandBytesNon (à la volée)Au chargement★★★★★★★★GPU NVIDIA
REAP (MoE)OuiMinutes-Heures★★★★★★★★★GPU (pruning experts)

Benchmark vLLM (H200, Qwen2.5-32B)

Benchmarks réalisés par JarvisLabs sur GPU H200 avec Qwen2.5-32B-Instruct. TTFT = Time To First Token. Perplexité : plus bas = meilleur.

MéthodePerplexitéHumanEvalThroughputTTFT
Baseline FP166,5656,1 %461 tok/s57,7 ms
BitsandBytes6,6751,8 %168 tok/s135 ms
AWQ6,8451,8 %68 tok/s278 ms
GPTQ6,9046,3 %277 tok/s107 ms
Marlin6,9745,7 %712 tok/s52 ms
GGUF Q4_K_M7,0254,3 %81 tok/s1178 ms

GGUF dans vLLM est lent car optimisé pour llama.cpp. À retenir : Marlin utilise les mêmes poids que GPTQ mais tourne 2,6x plus vite grâce à ses kernels CUDA. Les kernels comptent souvent plus que l’algorithme.

Benchmark llama.cpp (RTX 3090, 7B)

Source : benchmark oobabooga. Un écart de perplexité < 0,1 est imperceptible.

TypePerplexitéVRAMTokens/sTaille disque
EXL2-4.9bpw4,318,89 Go52-576,98 Go
AWQ-4bit4,339,62 Go39-416,67 Go
Q4_K_M.gguf4,338,99 Go31-353,80 Go
GPTQ-4bit4,347,94 Go64 (ExLlama)6,50 Go

Quel quant en pratique ? L’expérience SoberCloud

Sur Strix Halo (AMD Ryzen AI MAX+ 395, iGPU gfx1151, 128 Gio UMA, bandwidth-bound), nous avons mesuré un sweep de quants GGUF dynamiques pour Qwen3.6-35B-A3B (MoE) via llama.cpp Vulkan. Les scores correspondent à trois suites internes BenchLocal : Tool-Calling / Instruction-Following / Data-Extraction.

QuantTailleTool / Instr / ExtractDébit
Q4_K_XL22,9 Go93 / 74 / 5963 t/s
Q5_K_XL27 Go100 / 80 / 91~73 t/s
Q6_K_XL32,6 Go100 / 80 / 93~58 t/s
Q8_K_XL39,1 Go100 / 80 / 91~51 t/s

Deux enseignements forts :

  • Q4 casse l’extraction de données : le score chute à 59. Le gain de mémoire ne vaut pas la régression de fiabilité.
  • En régime bandwidth-bound, plus de bits = moins de débit. Q5_K_XL est le point retenu sur le front de Pareto : qualité au plafond (ou presque) et meilleur débit (~73 t/s) que Q6/Q8 plus lourds. Q6 grappille un point d’extraction mais coûte 5,6 Go et 15 t/s.

C’est exactement le type d’arbitrage que la nomenclature seule ne suffit pas à trancher : il faut mesurer sur sa propre charge.

Recommandations par cas d’usage

PrioritéMeilleur choixRuntimeNotes
Production vLLMMarlin (GPTQ)vLLMPlus rapide que FP16, -75 % VRAM
Qualité maximaleBitsandBytes / AWQTransformers / vLLMPerplexité la plus proche du baseline
Local (Apple/CPU)GGUF Q4_K_Mllama.cpp / OllamaSeul format avec offload CPU efficace
ExpérimentationBitsandBytesTransformersPas de modèle pré-quantifié requis
Full GPU (desktop)EXL2 / EXL3ExLlamaV2/V3Meilleur compromis vitesse/qualité
Low bitrate extrêmeEXL3 / GGUF IQ2ExLlamaV3 / llama.cpp70B en < 16 Go VRAM
MoE (DeepSeek, Qwen)REAPvLLM / TransformersPruning experts, -50 % taille

Pour aller plus loin

← Toutes les découvertes