Quantization : Réduire la taille des modèles IA sans perdre en qualité
Le problème : Llama 3.1 70B pèse 140 GB en mémoire (format FP32). Impossible à charger sur un GPU consumer (RTX 4090 = 24 GB).
La solution : La quantization réduit ce modèle à 35 GB (format INT4) avec seulement 3-5% de perte de qualité.
La quantization est la technique clé qui a démocratisé l’IA locale. Elle permet d’exécuter des modèles puissants sur hardware accessible : MacBook, PC gaming, serveurs on-premise.
Pourquoi c’est crucial
Avantages :
- Réduction de taille : 4-8x plus petit → charge sur GPU/RAM limités
- Vitesse accrue : Opérations INT8/INT4 plus rapides que FP32
- Coûts réduits : Moins de VRAM nécessaire = GPU moins cher
- Économie d’énergie : Moins de calculs = moins de consommation
- IA locale accessible : Modèles 70B sur MacBook M2, RTX 3060
Cas d’usage :
- Exécution locale de Llama 70B sur GPU 24GB
- Déploiement edge (smartphones, IoT)
- Production cloud à coût optimisé
- Inference temps réel avec vLLM
Analogie : Compresser une photo de 16 millions de couleurs (24-bit) en 256 couleurs (8-bit). L’image reste reconnaissable, mais le fichier pèse 3x moins.

Les formats de précision
FP32 (32-bit Float)
Format standard d’entraînement (rarement utilisé en inference).
Représentation :
- 1 bit : Signe
- 8 bits : Exposant
- 23 bits : Mantisse
Plage : ±3.4 × 10³⁸ Précision : ~7 décimales
Taille modèle :
- Llama 8B : 32 GB
- Llama 70B : 280 GB
FP32 en inference : Rarement justifié. Gaspillage de ressources. Utilisez FP16/BF16 minimum.
FP16 (16-bit Float)
Standard actuel pour l’entraînement et inference de qualité.
Représentation :
- 1 bit : Signe
- 5 bits : Exposant
- 10 bits : Mantisse
Plage : ±65,504 Précision : ~3 décimales
Caractéristiques :
- ✅ 2x plus rapide que FP32
- ✅ 2x moins de mémoire
- ✅ Perte de qualité négligeable (<0.5%)
- ❌ Risque d’underflow (nombres très petits → 0)
import torch
# Charger modèle en FP16
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
torch_dtype=torch.float16, # ← FP16
device_map="auto"
)
# Taille : ~16 GB au lieu de 32 GB
BF16 (BFloat16)
Alternative à FP16, privilégiée par Google/NVIDIA.
Représentation :
- 1 bit : Signe
- 8 bits : Exposant (même que FP32 !)
- 7 bits : Mantisse (réduit vs FP16)
Avantages vs FP16 :
- ✅ Même plage que FP32 → pas d’underflow
- ✅ Stabilité entraînement supérieure
- ✅ Support natif GPU modernes (A100, H100, RTX 40xx)
Inconvénient :
- ❌ Précision légèrement inférieure à FP16 (mais rarement problématique)
# BF16 recommandé pour entraînement
model = AutoModelForCausalLM.from_pretrained(
"mistralai/Mistral-7B-v0.1",
torch_dtype=torch.bfloat16, # ← BF16
device_map="auto"
)
INT8 (8-bit Integer)
Premier niveau de vraie quantization.
Représentation :
- Entiers signés : -128 à 127
- Ou non-signés : 0 à 255
Caractéristiques :
- ✅ 4x plus petit que FP32
- ✅ 2x plus petit que FP16
- ✅ Perte minimale : 1-2% sur benchmarks
- ✅ Support hardware : Tensor Cores INT8 (NVIDIA)
- ✅ Bon compromis qualité/taille
# Quantization INT8 avec bitsandbytes
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
quantization_config = BitsAndBytesConfig(
load_in_8bit=True, # ← INT8
llm_int8_threshold=6.0 # Seuil pour quantization mixte
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
quantization_config=quantization_config,
device_map="auto"
)
# Taille : ~8 GB au lieu de 16 GB (FP16)
INT4 (4-bit Integer)
Quantization agressive, très populaire pour IA locale.
Représentation :
- Seulement 16 valeurs possibles (-8 à 7)
Caractéristiques :
- ✅ 8x plus petit que FP32
- ✅ 4x plus petit que FP16
- ✅ Perte acceptable : 3-5% sur benchmarks
- ✅ Permet modèles 70B sur GPU 24GB
- ⚠️ Techniques avancées requises (GPTQ, AWQ, GGUF)
# Quantization INT4 avec bitsandbytes
quantization_config = BitsAndBytesConfig(
load_in_4bit=True, # ← INT4
bnb_4bit_compute_dtype=torch.bfloat16, # Compute en BF16
bnb_4bit_use_double_quant=True, # Double quantization
bnb_4bit_quant_type="nf4" # NormalFloat 4-bit
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-70B",
quantization_config=quantization_config,
device_map="auto"
)
# Taille : ~35 GB (chargeable sur GPU 48GB ou split GPU+CPU)
INT2 (2-bit) et au-delà
Recherche expérimentale (BitNet, 1.58-bit LLMs).
État actuel :
- 📊 Papers : Résultats prometteurs en recherche
- ⚠️ Production : Pas encore stable/fiable
- 🔬 Futur : Potentiel de 16x compression
Défis :
- Perte de qualité significative (>10%)
- Nécessite re-entraînement ou distillation
- Hardware spécialisé requis pour gains de vitesse
Impact sur les performances
Benchmarks qualité
Llama 3.1 8B sur MMLU (connaissance générale) :
| Format | Taille | Score MMLU | Perte vs FP16 | Tokens/sec (RTX 4090) |
|---|---|---|---|---|
| FP32 | 32 GB | 68.2% | -0.1% | 45 |
| FP16 | 16 GB | 68.3% | 0% (baseline) | 78 |
| INT8 | 8 GB | 67.8% | -0.5% | 95 |
| INT4 (GPTQ) | 4.5 GB | 66.9% | -1.4% | 110 |
| INT4 (AWQ) | 4.5 GB | 67.5% | -0.8% | 108 |
Observations :
- ✅ INT8 : Négligeable (-0.5%), excellent choix
- ✅ INT4 : Acceptable (-1-2%), double vitesse vs FP16
- ⚠️ Q2 : Perte >5%, non recommandé production
Mistral 7B sur HumanEval (code) :
| Format | Score HumanEval | Perte vs FP16 |
|---|---|---|
| FP16 | 40.2% | 0% |
| INT8 | 39.8% | -0.4% |
| INT4 GPTQ | 38.1% | -2.1% |
| INT4 AWQ | 39.2% | -1.0% |
Conclusion : AWQ supérieur à GPTQ pour conservation de qualité.
Benchmarks vitesse
Latence génération (tokens/seconde) :
RTX 4090 24GB :
Llama 8B :
- FP16 : 78 t/s
- INT8 : 95 t/s (+22%)
- INT4 : 110 t/s (+41%)
Llama 70B :
- FP16 : Impossible (OOM)
- INT4 : 15 t/s
Apple M2 Max 96GB (unified memory) :
Llama 13B :
- FP16 : 28 t/s
- INT8 : 35 t/s
- INT4 : 45 t/s
Llama 70B :
- INT4 : 12 t/s
CPU Intel i9-13900K, 64GB RAM :
Llama 8B INT4 (GGUF) : 6-8 t/s (utilisable)
Llama 13B INT4 (GGUF) : 3-5 t/s
Techniques de quantization
Post-Training Quantization (PTQ)
Principe : Quantizer un modèle déjà entraîné sans réentraînement.
Avantages :
- ✅ Rapide (minutes à heures)
- ✅ Pas besoin de dataset d’entraînement complet
- ✅ Accessible (pas de GPU cluster)
Limites :
- ⚠️ Perte de qualité plus importante que QAT
- ⚠️ Peut nécessiter calibration dataset
Méthodes PTQ populaires :
- GPTQ : Optimal pour GPU inference
- AWQ : Meilleure qualité que GPTQ
- GGUF : Optimal CPU/Apple Silicon (llama.cpp)
- bitsandbytes : Facile, intégré Hugging Face
Quantization-Aware Training (QAT)
Principe : Entraîner le modèle en simulant la quantization.
Processus :
- Entraînement en FP32/FP16
- Simuler quantization pendant forward pass
- Gradient descent ajuste pour compenser perte de précision
- Quantization finale sans perte
Avantages :
- ✅ Qualité maximale : ~0.1% perte vs full precision
- ✅ Permet quantization aggressive (INT4, INT2)
Inconvénients :
- ❌ Coûteux : Réentraînement complet requis
- ❌ Temps : Jours/semaines sur GPU cluster
- ❌ Accès dataset : Nécessite données d’entraînement
Usage :
- Labs de recherche avec ressources
- Fine-tuning pour cas critiques
- Optimisation edge devices (smartphones)
GPTQ (GPT Quantization)
Méthode PTQ optimale pour inference GPU.
Principe :
- Analyser importance de chaque poids
- Quantizer poids moins importants plus agressivement
- Préserver poids critiques en haute précision
- Optimiser reconstruction error par couche
Implémentation :
# Installation
pip install auto-gptq optimum
from transformers import AutoTokenizer
from auto_gptq import AutoGPTQForCausalLM, BaseQuantizeConfig
# Configuration quantization
quantize_config = BaseQuantizeConfig(
bits=4, # INT4
group_size=128, # Taille groupe quantization
desc_act=False, # Activation ordering
damp_percent=0.01 # Damping factor
)
# Charger modèle FP16
model = AutoGPTQForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
quantize_config=quantize_config
)
tokenizer = AutoTokenizer.from_pretrained("meta-llama/Llama-3.1-8B")
# Dataset de calibration (petit échantillon)
from datasets import load_dataset
calibration_dataset = load_dataset("c4", split="train", streaming=True)
calibration_samples = [next(iter(calibration_dataset))["text"] for _ in range(128)]
# Quantizer (prend 10-30 min sur GPU)
model.quantize(
calibration_samples,
tokenizer=tokenizer,
batch_size=1
)
# Sauvegarder modèle quantizé
model.save_quantized("Llama-3.1-8B-GPTQ")
# Utilisation
from auto_gptq import AutoGPTQForCausalLM
model = AutoGPTQForCausalLM.from_quantized(
"Llama-3.1-8B-GPTQ",
device="cuda:0"
)
# Inference normale
output = model.generate(**inputs, max_new_tokens=100)
Modèles GPTQ pré-quantizés : TheBloke sur Hugging Face
# Utiliser modèle pré-quantizé
model = AutoGPTQForCausalLM.from_quantized(
"TheBloke/Llama-2-13B-chat-GPTQ",
device="cuda:0",
use_safetensors=True
)
AWQ (Activation-aware Weight Quantization)
Amélioration de GPTQ qui analyse aussi les activations.
Principe :
- Certains poids ont activations fortes → impact majeur
- Préserver précision pour ces “salient weights”
- Résultat : Meilleure qualité que GPTQ à même taille
Performance :
- +0.5-1% sur benchmarks vs GPTQ
- Légèrement plus lent à quantizer
- Vitesse inference similaire
Implémentation :
# Installation
pip install autoawq
from awq import AutoAWQForCausalLM
from transformers import AutoTokenizer
# Charger modèle
model_path = "meta-llama/Llama-3.1-8B"
quant_path = "Llama-3.1-8B-AWQ"
model = AutoAWQForCausalLM.from_pretrained(model_path)
tokenizer = AutoTokenizer.from_pretrained(model_path)
# Configuration quantization
quant_config = {
"zero_point": True,
"q_group_size": 128,
"w_bit": 4,
"version": "GEMM"
}
# Quantizer
model.quantize(
tokenizer,
quant_config=quant_config,
calib_data="pileval" # Dataset calibration
)
# Sauvegarder
model.save_quantized(quant_path)
tokenizer.save_pretrained(quant_path)
# Charger et utiliser
model = AutoAWQForCausalLM.from_quantized(
quant_path,
fuse_layers=True # Fusion kernel pour vitesse
)
GGUF/GGML (llama.cpp)
Format optimal pour CPU et Apple Silicon (Metal).
Caractéristiques :
- ✅ Optimisé CPU : AVX2, ARM NEON
- ✅ Apple Metal : GPU Apple Silicon natif
- ✅ Quantization variée : Q2_K à Q8_0
- ✅ Memory mapping : Charge seulement ce qui est nécessaire
- ✅ Compatible Ollama : Format par défaut
Variantes GGUF :
| Variante | Bits/weight | Qualité | Use case |
|---|---|---|---|
| Q2_K | ~2.6 | ⭐⭐ | RAM/VRAM extrême limite |
| Q3_K_M | ~3.5 | ⭐⭐⭐ | Compromis léger |
| Q4_K_M | ~4.5 | ⭐⭐⭐⭐ | Recommandé général |
| Q5_K_M | ~5.5 | ⭐⭐⭐⭐ | Qualité élevée |
| Q6_K | ~6.5 | ⭐⭐⭐⭐⭐ | Presque FP16 |
| Q8_0 | 8.0 | ⭐⭐⭐⭐⭐ | Maximum qualité |
Utilisation avec llama.cpp :
# Installation
git clone https://github.com/ggerganov/llama.cpp
cd llama.cpp
make
# Télécharger modèle GGUF (ou convertir depuis Hugging Face)
wget https://huggingface.co/TheBloke/Llama-2-13B-chat-GGUF/resolve/main/llama-2-13b-chat.Q4_K_M.gguf
# Inference
./main -m llama-2-13b-chat.Q4_K_M.gguf \
-p "Explain quantum computing simply" \
-n 256 \
-t 8 # Threads CPU
Avec Ollama (encore plus simple) :
# Ollama utilise GGUF en interne
ollama run llama3.1 # Télécharge automatiquement Q4_K_M
# Spécifier autre quantization
ollama pull llama3.1:8b-instruct-q8_0
ollama run llama3.1:8b-instruct-q8_0
bitsandbytes (Hugging Face)
Bibliothèque intégrée à Transformers pour quantization facile.
Features :
- ✅ INT8 : LLM.int8() method (zero degradation)
- ✅ INT4 : NF4 (NormalFloat 4-bit) optimal
- ✅ Double quantization : Quantizer aussi metadata
- ✅ Mixed precision : Layers critiques en FP16
Installation :
pip install bitsandbytes accelerate
Quantization INT8 :
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-8B",
load_in_8bit=True, # ← Simple !
device_map="auto"
)
# Inference normale
output = model.generate(**inputs)
Quantization INT4 optimisée :
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4", # NormalFloat 4-bit (optimal)
bnb_4bit_use_double_quant=True, # Double quant metadata
bnb_4bit_compute_dtype=torch.bfloat16 # Compute en BF16
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-70B",
quantization_config=bnb_config,
device_map="auto", # Auto split GPU/CPU si nécessaire
max_memory={0: "22GB", "cpu": "40GB"} # Limites explicites
)
QLoRA (Quantized LoRA) : Fine-tuning avec modèle quantizé INT4.
from peft import LoraConfig, get_peft_model, prepare_model_for_kbit_training
# Préparer modèle quantizé pour training
model = prepare_model_for_kbit_training(model)
# Configuration LoRA
lora_config = LoraConfig(
r=16, # Rank
lora_alpha=32,
target_modules=["q_proj", "v_proj"],
lora_dropout=0.05,
bias="none",
task_type="CAUSAL_LM"
)
model = get_peft_model(model, lora_config)
# Fine-tuner normalement (mais 4x moins VRAM)
trainer = Trainer(
model=model,
args=training_args,
train_dataset=train_dataset
)
trainer.train()
Quantization mixte
Idée : Ne pas quantizer toutes les couches uniformément.
Préserver couches critiques
Certaines couches sont plus sensibles à la quantization :
- Attention heads : Cruciales pour compréhension
- Première/dernière couche : Input/output encoding
- LayerNorms : Stabilité
Approche :
# Quantization mixte avec bitsandbytes
quantization_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_compute_dtype=torch.bfloat16,
llm_int8_skip_modules=["lm_head", "embed_tokens"] # Garder FP16
)
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-70B",
quantization_config=quantization_config,
device_map="auto"
)
Quantization progressive
Stratégie : Quantizer plus agressivement les couches moins critiques.
# Pseudo-code conceptuel
for layer_idx, layer in enumerate(model.layers):
if layer_idx < 5 or layer_idx > len(model.layers) - 5:
# Premières/dernières couches : INT8
quantize_layer(layer, bits=8)
else:
# Couches intermédiaires : INT4
quantize_layer(layer, bits=4)
Résultat : Économies mémoire importantes, dégradation minimale.
Cas d’usage par contrainte hardware
16 GB VRAM (RTX 4060 Ti, RTX 3060 12GB)
Modèles chargeables :
| Modèle | Quantization | VRAM utilisée | Performance |
|---|---|---|---|
| Llama 8B | Q4 | ~5 GB | Excellent |
| Llama 13B | Q4 | ~8 GB | Très bon |
| Mistral 7B | Q8 | ~9 GB | Excellent |
| CodeLlama 13B | Q4 | ~8 GB | Très bon |
| Mixtral 8x7B | Q2 | ~14 GB | Acceptable |
Recommandation : Llama 13B Q4 = meilleur compromis.
# Ollama
ollama pull llama3.1:13b-instruct-q4_K_M
ollama run llama3.1:13b
# Python
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-13B",
load_in_4bit=True,
device_map="auto"
)
24 GB VRAM (RTX 4090, RTX 3090)
Modèles chargeables :
| Modèle | Quantization | VRAM | Performance |
|---|---|---|---|
| Llama 70B | Q4 | ~22 GB | Très bon |
| Llama 34B | Q8 | ~20 GB | Excellent |
| Mixtral 8x7B | Q4 | ~18 GB | Très bon |
| Qwen 72B | Q4 | ~23 GB | Très bon |
Sweet spot : Llama 70B Q4 → Qualité proche GPT-3.5 en local.
# Llama 70B sur RTX 4090
model = AutoModelForCausalLM.from_pretrained(
"meta-llama/Llama-3.1-70B",
load_in_4bit=True,
device_map="auto"
)
# Génération : ~15 tokens/sec
32-64 GB RAM CPU (sans GPU)
Modèles chargeables (GGUF) :
| Modèle | Quantization | RAM | Vitesse (CPU i9) |
|---|---|---|---|
| Llama 8B | Q4 | 6 GB | ~8 t/s |
| Llama 13B | Q5 | 10 GB | ~5 t/s |
| Llama 13B | Q4 | 8 GB | ~6 t/s |
| Mistral 7B | Q8 | 9 GB | ~7 t/s |
Recommandation : Llama 8B Q4 = utilisable, latence acceptable.
# llama.cpp
./main -m llama-3.1-8b.Q4_K_M.gguf \
-t 16 \ # 16 threads CPU
-n 256 \
-p "Your prompt"
# Ollama (plus simple)
OLLAMA_NUM_GPU=0 ollama run llama3.1
# Force CPU, fonctionne bien
Apple Silicon (Unified Memory)
Avantage majeur : Unified memory = pas de limite VRAM/RAM séparée.
M1 Max 64GB :
- Llama 70B Q4 : ~20 t/s (Metal GPU)
- Llama 34B Q8 : ~25 t/s
M2 Ultra 192GB :
- Llama 70B FP16 : ~40 t/s (!)
- Llama 405B Q4 : ~8 t/s
M3 Max 128GB :
- Llama 70B Q5 : ~25 t/s
- Mixtral 8x7B Q8 : ~30 t/s
# Ollama détecte Metal automatiquement
ollama run llama3.1:70b
# Performances excellentes !
Tableau de correspondance complet
| VRAM/RAM | Modèle optimal | Quantization | Vitesse | Qualité |
|---|---|---|---|---|
| 4 GB | Phi-3 Mini | Q4 | Rapide | Bon |
| 8 GB | Llama 8B | Q4 | Rapide | Très bon |
| 12 GB | Llama 13B | Q4 | Bon | Très bon |
| 16 GB | Llama 13B | Q8 | Bon | Excellent |
| 24 GB | Llama 70B | Q4 | Moyen | Excellent |
| 40 GB | Llama 70B | Q8 | Bon | Excellent |
| 48 GB | Llama 70B | FP16 | Rapide | Parfait |
| 80 GB | Llama 405B | Q4 | Lent | Excellent |
Limites et précautions
Tâches sensibles
Ne pas quantizer agressivement pour :
- ❌ Mathématiques complexes : Précision numérique critique
- ❌ Code safety-critical : Médical, aéronautique
- ❌ Finance : Calculs précis requis
- ❌ Recherche : Reproductibilité extrême
Recommandation : FP16 ou INT8 maximum pour ces cas.
Mathématiques et INT4
# Test calcul mathématique
prompts = [
"Calculate: 45327 * 8912 = ?",
"What is the square root of 15241578750190521?",
"Solve: 2x^2 + 5x - 3 = 0"
]
# FP16 : Souvent correct
# INT4 : Erreurs fréquentes sur arithmétique précise
Solution : Tool calling vers calculatrice pour opérations complexes.
Tests nécessaires
Ne jamais déployer sans tester :
- Benchmarks standardisés (MMLU, HumanEval, etc.)
- Tests sur votre use case spécifique
- A/B test FP16 vs quantizé
- Monitoring qualité en production
# Exemple suite de tests
def evaluate_quantized_model(model_fp16, model_int4, test_dataset):
results = {"fp16": [], "int4": []}
for sample in test_dataset:
# FP16
output_fp16 = generate(model_fp16, sample["prompt"])
score_fp16 = evaluate_output(output_fp16, sample["expected"])
results["fp16"].append(score_fp16)
# INT4
output_int4 = generate(model_int4, sample["prompt"])
score_int4 = evaluate_output(output_int4, sample["expected"])
results["int4"].append(score_int4)
print(f"FP16 average: {np.mean(results['fp16']):.2%}")
print(f"INT4 average: {np.mean(results['int4']):.2%}")
print(f"Degradation: {np.mean(results['fp16']) - np.mean(results['int4']):.2%}")
return results
L’avenir de la quantization
1-bit LLMs (BitNet)
Recherche Microsoft : Modèles avec poids binaires (-1, 0, 1).
Avantages théoriques :
- 32x compression vs FP32
- Opérations ultra-rapides (pas de multiplication)
- Consommation énergétique drastiquement réduite
État actuel :
- 📄 Papers prometteurs (BitNet b1.58)
- 🔬 Pas encore production-ready
- 🚀 Futur probable : 2-3 ans
Quantization dynamique adaptative
Idée : Ajuster quantization en temps réel selon contexte.
- Tâche simple → Quant agressive
- Tâche complexe → Haute précision
Recherche en cours : Dynamic Neural Networks.
Hardware spécialisé
Tensor Cores INT4 (NVIDIA H100) :
- Accélération native INT4
- 2x vitesse vs INT8
Apple Neural Engine :
- Optimisé INT8/INT4
- On-device ML ultra-efficient
Google TPU v5 :
- INT8 natif, FP16 optionnel
- Inference à coût minimal
Exercices pratiques
Comparer quantizations
Objectif : Mesurer impact qualité selon quantization.
from transformers import AutoModelForCausalLM, AutoTokenizer
from datasets import load_dataset
import torch
def benchmark_quantization():
model_name = "meta-llama/Llama-3.1-8B"
tokenizer = AutoTokenizer.from_pretrained(model_name)
# Charger modèles
models = {
"fp16": AutoModelForCausalLM.from_pretrained(model_name, torch_dtype=torch.float16),
"int8": AutoModelForCausalLM.from_pretrained(model_name, load_in_8bit=True),
"int4": AutoModelForCausalLM.from_pretrained(model_name, load_in_4bit=True)
}
# Dataset de test
test_data = load_dataset("gsm8k", split="test[:100]") # Maths
# Évaluer chaque modèle
results = {}
for quant_type, model in models.items():
correct = 0
for sample in test_data:
output = generate_answer(model, tokenizer, sample["question"])
if check_answer(output, sample["answer"]):
correct += 1
results[quant_type] = correct / len(test_data)
print(f"{quant_type}: {results[quant_type]:.2%}")
return results
Quantizer un modèle custom
Objectif : Appliquer GPTQ à un modèle fine-tuné.
Étapes :
- Fine-tuner Llama 8B sur dataset custom
- Quantizer en INT4 avec GPTQ
- Comparer perplexity avant/après
- Tester sur cas d’usage réel
Optimiser pour hardware spécifique
Objectif : Trouver meilleur compromis pour votre GPU.
Tâche : Avec un RTX 4090 24GB, déterminer :
- Quel modèle (13B, 34B, 70B) ?
- Quelle quantization (Q4, Q5, Q8) ?
- Maximiser qualité tout en maintenant >10 tokens/sec
Conclusion
La quantization est la technologie qui a rendu l’IA locale accessible. Elle permet d’exécuter des modèles 70B sur un GPU gaming, avec seulement 3-5% de perte de qualité.
Points clés :
- Formats : FP16 (baseline), INT8 (1-2% perte), INT4 (3-5% perte)
- Techniques : GPTQ (GPU), AWQ (meilleure qualité), GGUF (CPU/Apple), bitsandbytes (facile)
- Compromis : Q4_K_M optimal (4x compression, 95%+ qualité)
- Hardware : INT4 débloque Llama 70B sur GPU 24GB
- Futur : 1-bit LLMs, quantization adaptative, hardware spécialisé
Recommandations par usage :
- Développement : INT4 (Q4_K_M), balance vitesse/qualité
- Production critique : INT8 ou FP16, sécurité maximale
- IA locale : GGUF Q4_K_M via Ollama, simplicité
- Edge devices : Q2-Q3, compromis extrême
- Recherche : FP16, reproductibilité
La quantization n’est pas juste une optimisation : c’est un enabler technologique qui démocratise l’accès aux modèles de pointe. Avec les bonnes techniques, vous pouvez exécuter localement des modèles rivalisant avec GPT-3.5, en toute confidentialité et sans coûts API.
Ressources
Articles liés :
Outils :
Modèles quantizés :
- TheBloke sur HF - 1000+ modèles GPTQ/GGUF
- Ollama Library
Papers :
- LLM.int8() - Dettmers et al. (2022)
- GPTQ - Frantar et al. (2022)
- AWQ - Lin et al. (2023)
- QLoRA - Dettmers et al. (2023)
- BitNet b1.58 - Microsoft (2024)