ai-ml-model-optimization-guide
Skill28 starsChanged 14 days agoMITView on GitHub
Optimisation de modèles ML pour l'inférence (quantization, pruning, distillation, ONNX) — guide opérationnel avec snippets copiables, critères de choix et anti-patterns. Se déclenche avec \"quantization\", \"pruning\", \"distillation\", \"ONNX\", \"optimiser un modèle\", \"inférence rapide\". Se déclenche avec "quantization", "pruning", "distillation", "ONNX", "optimiser un modèle", "inférence rapide". Also triggers on "optimize inference", "quantize a model", "faster model serving".
We split this skill into the rules it gives an agent
4 rules. About 0 are common, 4 are distinctive, and 0 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
0
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 305
Never say "happy to help", "sure!", "great question", "let me", or similar.
- Distinctive: line 308
Stop when done. No summary, no recap, no trailing commentary.
- Distinctive: line 309
No politeness wrappers. Direct and blunt.
- Distinctive: line 312
No emoji unless asked.
≈ “Common” is an estimate: at least 1 in 5 of the 308,232 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Model Optimization Guide
Guide opérationnel pour réduire la taille et accélérer l'inférence d'un modèle ML sans régresser les métriques métier.
Critères de décision rapides
| Contrainte principale | Technique recommandée |
| Déploiement sans GPU, CPU seul | PTQ INT8 + ONNX Runtime (OpenVINO EP) |
| Latence < 20 ms sur GPU NVIDIA | TensorRT FP16 ou INT8 |
| Modèle trop gros pour mémoire edge | Pruning structuré + TFLite/CoreML |
| LLM > 7B à servir sur 1 GPU | GPTQ 4-bit ou AWQ |
| Contrainte de qualité stricte (< 0,5 % drop) | QAT ou distillation |
| Pipeline cross-framework | ONNX export + ORT |
Workflow en 7 étapes
1. Profiler et fixer les objectifs
Avant toute optimisation, mesurer la baseline sur le hardware de production.
# PyTorch Profiler (CPU+GPU)
import torch
from torch.profiler import profile, ProfilerActivity
with profile(activities=[ProfilerActivity.CPU, ProfilerActivity.CUDA],
record_shapes=True, profile_memory=True) as prof:
model(inputs)
print(prof.key_averages().table(sort_by="cuda_time_total", row_limit=15))
prof.export_chrome_trace("trace.json") # ouvrir dans chrome://tracingGrille d'objectifs à remplir avant de commencer :
| Métrique | Valeur actuelle | Cible | Tolérance dégradation |
| Latence P95 (ms) | ? | ? | +0 % |
| Taille modèle (MB) | ? | ? | — |
| Accuracy / F1 | ? | — | -0,5 % max |
| VRAM / RAM (MB) | ? | ? | — |
2. Quantification (technique la plus rapide)
PTQ INT8 — PyTorch (sans réentraînement)
import torch.quantization as tq
model.eval()
model.qconfig = tq.get_default_qconfig('fbgemm') # CPU x86
# ou 'qnnpack' pour ARM/mobile
tq.prepare(model, inplace=True)
# Calibration : passer ~100-500 exemples représentatifs
for batch in calibration_loader:
model(batch)
tq.convert(model, inplace=True)
torch.save(model.state_dict(), "model_int8.pt")PTQ FP16 — ONNX Runtime (le plus portable)
from onnxruntime.quantization import quantize_dynamic, QuantType
quantize_dynamic(
"model.onnx",
"model_int8.onnx",
weight_type=QuantType.QInt8
)LLM — bitsandbytes 4-bit (Hugging Face)
from transformers import AutoModelForCausalLM, BitsAndBytesConfig
bnb_config = BitsAndBytesConfig(
load_in_4bit=True,
bnb_4bit_quant_type="nf4",
bnb_4bit_compute_dtype=torch.bfloat16,
bnb_4bit_use_double_quant=True,
)
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.1",
quantization_config=bnb_config,
device_map="auto")QAT (quand PTQ dégrade > seuil)
model.train()
model.qconfig = tq.get_default_qat_qconfig('fbgemm')
tq.prepare_qat(model, inplace=True)
# Fine-tune 3-5 epochs avec LR réduit (~10x)
trainer.train()
tq.convert(model.eval(), inplace=True)3. Pruning (élagage)
Choix de la stratégie :
- Non structuré → sparsité maximale, gains réels seulement avec bibliothèques sparse (cuSPARSE, SparseML)
- Structuré (filtres/couches) → gains directs sur CPU/GPU classiques ✓
- 2:4 semi-structuré → gain x2 sur GPU NVIDIA Ampere+ via sparsité matérielle ✓
import torch.nn.utils.prune as prune
# Pruning structuré : supprimer 30 % des filtres conv
prune.ln_structured(model.layer1[0].conv1, name='weight', amount=0.3, n=2, dim=0)
# Pruning global non structuré (tous les modules conv+linear)
parameters_to_prune = [
(module, 'weight')
for module in model.modules()
if isinstance(module, (torch.nn.Conv2d, torch.nn.Linear))
]
prune.global_unstructured(parameters_to_prune,
pruning_method=prune.L1Unstructured,
amount=0.4)
# Rendre le pruning permanent
for module, _ in parameters_to_prune:
prune.remove(module, 'weight')Après pruning, fine-tuner obligatoirement 3-10 epochs avec LR = 1/10 du LR d'origine.
4. Distillation de connaissances
Quand on veut un modèle student 5-10x plus petit avec < 1 % de dégradation.
import torch.nn.functional as F
def distillation_loss(student_logits, teacher_logits, labels,
temperature=4.0, alpha=0.7):
# Soft loss (KL divergence sur les distributions adoucies)
soft_targets = F.softmax(teacher_logits / temperature, dim=-1)
soft_student = F.log_softmax(student_logits / temperature, dim=-1)
kd_loss = F.kl_div(soft_student, soft_targets, reduction='batchmean') * (temperature ** 2)
# Hard loss (cross-entropy sur les vrais labels)
ce_loss = F.cross_entropy(student_logits, labels)
return alpha * kd_loss + (1 - alpha) * ce_lossValeurs de départ : temperature=4, alpha=0.7. Augmenter temperature si le teacher est très confiant.
5. Export ONNX et optimisation du graphe
import torch
import onnx
from onnxruntime.tools.optimizer import optimize_model
# Export
dummy_input = torch.randn(1, 3, 224, 224)
torch.onnx.export(
model, dummy_input, "model.onnx",
opset_version=17,
input_names=["input"], output_names=["output"],
dynamic_axes={"input": {0: "batch_size"}, "output": {0: "batch_size"}}
)
# Vérification
onnx.checker.check_model("model.onnx")
# Optimisation du graphe (fusion conv+bn, élimination nœuds morts)
optimized = optimize_model("model.onnx", model_type="bert") # ou "gpt2", "vit"
optimized.save_model_to_file("model_opt.onnx")Benchmark ONNX Runtime vs PyTorch :
import onnxruntime as ort, time, numpy as np
sess = ort.InferenceSession("model_opt.onnx",
providers=["CUDAExecutionProvider", "CPUExecutionProvider"])
inp = {"input": np.random.randn(1, 3, 224, 224).astype(np.float32)}
# Warmup
for _ in range(10): sess.run(None, inp)
t0 = time.perf_counter()
for _ in range(200): sess.run(None, inp)
print(f"ORT latency: {(time.perf_counter()-t0)/200*1000:.2f} ms")6. Optimisations hardware spécifiques
TensorRT (GPU NVIDIA) :
# Convertir ONNX → TensorRT engine FP16
trtexec --onnx=model_opt.onnx \
--saveEngine=model_fp16.trt \
--fp16 \
--workspace=4096 \
--minShapes=input:1x3x224x224 \
--optShapes=input:8x3x224x224 \
--maxShapes=input:32x3x224x224OpenVINO (Intel CPU/GPU) :
mo --input_model model.onnx \
--compress_to_fp16 \
--output_dir openvino_model/TFLite (mobile Android/iOS) :
converter = tf.lite.TFLiteConverter.from_saved_model("saved_model/")
converter.optimizations = [tf.lite.Optimize.DEFAULT]
converter.target_spec.supported_types = [tf.float16]
tflite_model = converter.convert()
open("model.tflite", "wb").write(tflite_model)7. Validation et benchmarking final
# Checklist de validation avant déploiement
import numpy as np
def validate_optimization(original_model, optimized_runner, test_loader, tol=1e-3):
diffs = []
for inputs, _ in test_loader:
ref = original_model(inputs).detach().numpy()
opt = optimized_runner(inputs)
diffs.append(np.abs(ref - opt).max())
print(f"Max output diff: {max(diffs):.6f} (tol={tol})")
assert max(diffs) < tol, "REGRESSION NUMERIQUE DETECTEE"Métriques à documenter impérativement :
| Métrique | Avant | Après | Delta |
| Accuracy / F1 | |||
| Latence P95 ms | |||
| Taille fichier MB | |||
| VRAM peak MB | |||
| Throughput img/s |
Anti-patterns et pièges
1. Optimiser sans mesurer sur le hardware cible INT8 sur CPU x86 peut être plus lent que FP32 si les opérateurs ne sont pas supportés nativement. Toujours mesurer sur le vrai hardware.
2. Combiner toutes les techniques d'un coup Quantification + pruning + distillation ensemble = impossible de diagnostiquer la source de dégradation. Une technique à la fois, mesurer entre chaque.
3. Calibration non représentative pour PTQ Calibrer sur le jeu de test → fuite d'information. Calibrer sur un sous-ensemble du train. 100-500 exemples suffisent ; plus n'améliore pas.
4. Ignorer les couches sensibles
Premières et dernières couches du réseau sont souvent très sensibles à la quantification. Utiliser per-channel plutôt que per-tensor, ou les laisser en FP32.
5. Oublier le dynamic batching
Un modèle optimisé pour batch=1 peut ne pas bénéficier du throughput à batch=32. Configurer dynamic_axes à l'export ONNX et profiler les deux cas.
6. Ne pas vérifier la cohérence numérique Les exporteurs ONNX ont des bugs sur certains opérateurs (attention masks, custom layers). Toujours comparer les sorties sur un jeu fixe.
7. Pruning non structuré sans framework sparse PyTorch met les poids à zéro mais la couche reste dense en mémoire. Gain réel uniquement avec SparseML, DeepSparse ou en convertissant vers un format sparse explicite.
Bonnes pratiques 2026
- llm.int8() / bitsandbytes : standard de facto pour les LLM > 3B sur GPU avec mémoire limitée.
- AWQ (Activation-aware Weight Quantization) : meilleure qualité que GPTQ à 4-bit, privilégier pour les LLM critiques.
- torch.compile() (PyTorch 2.x) : avant toute optimisation manuelle, tester
model = torch.compile(model, mode="reduce-overhead")— gain gratuit 10-40 % sans perte de qualité. - Flash Attention 2/3 : pour les transformers, remplacer l'attention standard par
flash_attnréduit la mémoire quadratique en linéaire et accélère x2-x4. - Continual calibration : pour les modèles en production, recalibrer la quantification PTQ à chaque dérive significative de la distribution des données.
Communication Rules — MANDATORY
- Ultra-concise. No filler, no preamble, no pleasantries.
- Never say "happy to help", "sure!", "great question", "let me", or similar.
- Tool first, talk second. Act before explaining.
- Result first. Lead with outcome, not process.
- Stop when done. No summary, no recap, no trailing commentary.
- No politeness wrappers. Direct and blunt.
- Minimum words. If one word works, do not use ten.
- No unsolicited explanations.
- No emoji unless asked.
In this repository347 other files it gives its agents.
- agent-a2a-protocol-guideSkill
- agent-agent-observabilitySkill
- agent-api-caller-subagentSkill
- agent-autogen-guideSkill
- agent-browser-agent-builderSkill
- agent-claude-code-extension-builderSkill
- agent-code-review-subagentSkill
- agent-coding-agent-builderSkill
- agent-conflict-resolverSkill
- agent-consensus-builderSkill
- agent-context-managerSkill
- agent-cost-optimizerSkill
- agent-crewai-expertSkill
- agent-customer-support-agentSkill
- agent-data-analyst-agentSkill
- agent-database-query-subagentSkill
- agent-deployment-guideSkill
- agent-email-agent-builderSkill
- agent-evaluation-frameworkSkill
- agent-file-processor-subagentSkill
- agent-handoff-designerSkill
- agent-hierarchy-designerSkill
- agent-human-in-the-loop-designerSkill
- agent-langgraph-designerSkill
- agent-load-balancerSkill
- agent-marketplace-creatorSkill
- agent-mcp-server-builderSkill
- agent-memory-designerSkill
- agent-message-protocolSkill
- agent-monitoring-setupSkill
- agent-multi-agent-orchestratorSkill
- agent-openai-assistants-builderSkill
- agent-pipeline-composerSkill
- agent-pool-managerSkill
- agent-prompt-tunerSkill
- agent-research-agent-designerSkill
- agent-result-aggregatorSkill
- agent-retry-strategistSkill
- agent-sales-agent-builderSkill
- agent-security-hardenerSkill
- agent-semantic-kernel-guideSkill
- agent-skill-creatorSkill
- agent-skill-routerSkill
- agent-spawnerSkill
- agent-state-synchronizerSkill
- agent-subagent-delegatorSkill
- agent-supervisor-builderSkill
- agent-task-decomposerSkill
- agent-testing-frameworkSkill
- agent-tool-calling-architectSkill
- agent-voice-agent-builderSkill
- agent-web-scraper-subagentSkill
- agent-workflow-automation-agentSkill
- ai-ml-anomaly-detection-builderSkill
- ai-ml-computer-vision-guideSkill
- ai-ml-dataset-builderSkill
- ai-ml-ml-experiment-trackerSkill
- ai-ml-model-fine-tunerSkill
- ai-ml-nlp-pipeline-designerSkill
- api-gateway-kong-api-gatewaySkill
- The first 60 shown.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

