Quatre challengers pour llama.cpp sur CPU : ce qui passe et ce qui casse
Quatre challengers pour llama.cpp sur CPU : ce qui passe et ce qui casse
TL;DR
Après les 50 benchs de llama.cpp et ik_llama.cpp du premier article de cette série, une question logique : est-ce qu’un autre moteur CPU pourrait faire mieux que llama.cpp HEAD sur mon Ryzen 5 3600 ? J’ai testé quatre candidats régulièrement cités :
| Moteur | Promesse | Résultat sur Ryzen Zen 2 | Verdict |
|---|---|---|---|
| vLLM CPU | Continuous batching multi-request | Échec d’install (3 tentatives) | À reprendre via Docker |
| CTranslate2 | Mature, INT8 historique | -46 % vs llama.cpp | Pas un challenger |
| OpenVINO GenAI | Optimisé Intel AMX/AVX-512 | -11 % vs llama.cpp | Probable winner sur Intel, pas AMD |
| PowerInfer | Sparsité activationnelle, claims ×10 | +96 % tg sur 7B ⭐ | Vrai gain — mais piège dans les modèles requis |
Un seul des quatre fait significativement mieux. Et la raison pour laquelle il fait mieux n’est pas applicable à tous les modèles. Détails et chiffres bruts dans la suite.
1. Le contexte
Mon SOC agentique asp-forge tourne sur un Ryzen 5 3600 (Zen 2, 8 vCPU passthrough) avec Qwen 2.5 3B Q4_K_M servi par llama.cpp HEAD (tag b9165). Throughput de référence après les optimisations de l’article 1 :
- pp256 (prompt) : 93 t/s à
-t 8ou 101 t/s avec ik_llama.cpp-t 6 - tg64 (génération) : 17 t/s, plafond bande passante mémoire (cf. article 2)
La question : ces chiffres sont-ils vraiment ce qu’on peut tirer de mieux d’un Ryzen Zen 2 modeste en CPU pur ? Ou est-ce qu’un autre moteur — vLLM (continuous batching), OpenVINO (Intel-tuné), CTranslate2 (mature INT8), PowerInfer (sparsité) — sortirait du chapeau quelque chose de meilleur ?
Pour le savoir, j’ai monté une nouvelle session sur la même VM breach-1-llm-lab, bumpée à 12 GB de RAM (le temps de la session), et installé chaque moteur avec son modèle natif compatible. Méthodologie identique à la session 1 : Qwen 2.5 3B Q4_K_M quand possible, sinon un modèle équivalent en taille, et même profil pp/tg.
2. vLLM CPU — un cauchemar d’installation hors Docker
vLLM est l’un des moteurs serveur LLM les plus cités, avec son architecture PagedAttention + continuous batching qui le rend redoutable pour servir plusieurs utilisateurs concurrents. La version CPU existe depuis fin 2024 — sur le papier, c’est exactement ce qu’il faudrait pour ASP-forge si on monte en charge multi-agents.
Dans la pratique, trois tentatives, trois échecs :
2.1 Wheel pip standard
pip install vllm
python -c "from vllm import LLM; LLM(model='...', device='cpu')"
Résultat :
WARNING libcuda.so.1: cannot open shared object file: No such file or directory
TypeError: EngineArgs.__init__() got an unexpected keyword argument 'device'
Le wheel pip distribué est buildé pour CUDA. Le paramètre device='cpu' n’existe plus dans cette version 0.21.0. Ça ne marche tout simplement pas en mode CPU pur.
2.2 Build from source avec VLLM_TARGET_DEVICE=cpu
Documentation officielle vLLM CPU :
git clone https://github.com/vllm-project/vllm.git
cd vllm
VLLM_TARGET_DEVICE=cpu pip install -v --no-build-isolation .
Résultat :
configuration error: `project.license` must be valid exactly by one definition
error: metadata-generation-failed
Incompatibilité entre le pyproject.toml de vLLM HEAD et la version de setuptools (66.x de Debian 12). Downgrade setuptools à <70 : même erreur. Checkout d’un tag stable v0.21.0 : impossible car clone shallow (--depth=1).
2.3 Verdict
vLLM CPU est techniquement possible — mais demande un environnement bien spécifique (probablement Ubuntu 24.04 avec setuptools précis, ou plus simplement le Docker vllm/vllm-openai:cpu-latest). Sur ma VM Debian 12 stable, pas exploitable sans Docker.
Je reporte le test dans le backlog. La valeur potentielle — continuous batching pour servir plusieurs analystes ASP-forge simultanés — reste pertinente pour quand le projet sortira du PoC mono-utilisateur.
Leçon généralisable : pour bencher vLLM CPU rapidement, n’essayez pas le pip. Lancez direct un container Docker officiel.
3. CTranslate2 — mature, mais largement battu en 2026
CTranslate2 (par OpenNMT, Systran) a une histoire respectable : mature depuis 2019, INT8 historique, conçu pour la traduction (T5, BART, M2M100) puis étendu aux LLMs génératifs.
Setup trivial :
pip install ctranslate2 transformers
ct2-transformers-converter \
--model /opt/llm-lab/engines/models \
--output_dir /opt/llm-lab/engines/models-ct2-int8 \
--quantization int8
Conversion en ~3 min, output 2.9 GB. Modèle Qwen 2.5 3B INT8 chargé proprement par la classe ctranslate2.Generator.
Bench combined (prompt 28 tokens + 64 tokens générés, t=6) :
| Moteur + quant | Combined t/s | vs llama.cpp |
|---|---|---|
| llama.cpp b9165 Q4_K_M (référence) | ~15.7 (calculé pp+tg) | baseline |
| CTranslate2 4.7.1 INT8 | 8.5 | -46 % |
CT2 est presque deux fois plus lent que llama.cpp sur Qwen 2.5 3B. C’est cohérent avec l’évolution du paysage : CT2 reste excellent pour les modèles encodeur-décodeur de traduction (son terrain d’origine), mais les optimisations des kernels matmul pour les architectures décodeur autoregressif modernes (SwiGLU + grouped-query attention) — qui dominent en 2026 — n’ont pas suivi le rythme de llama.cpp upstream.
Verdict : pas un challenger en 2026 pour les LLMs génératifs. À garder en tête pour les pipelines de traduction où CT2 reste compétitif.
4. OpenVINO GenAI — challenger crédible, mais pas sur AMD
OpenVINO GenAI 2026.1.0 est le toolkit d’inférence d’Intel, désormais accompagné d’une API LLMPipeline orientée LLM. Setup pip simple :
pip install openvino openvino-genai openvino-tokenizers optimum[openvino]
optimum-cli export openvino \
--model /opt/llm-lab/engines/models \
--task text-generation-with-past \
--weight-format int4 --group-size 128 \
/opt/llm-lab/engines/models-ov-int4
Conversion en ~1 min vers IR INT4 (90 % int4_asym + 10 % int8_asym pour les couches sensibles). Output 1.7 GB.
Bench combined sur Zen 2 @ t=6 :
| Moteur + quant | Combined t/s | vs llama.cpp |
|---|---|---|
| llama.cpp b9165 Q4_K_M (référence) | ~15.7 | baseline |
| OpenVINO GenAI 2026.1 INT4 | 13.9 | -11 % |
OpenVINO se défend bien — beaucoup mieux que CT2 — mais reste 11 % en dessous de llama.cpp sur AMD Zen 2.
L’explication : OpenVINO est conçu et optimisé pour Intel, en particulier les Xeon Scalable avec AVX-512 (et de plus en plus AMX sur Sapphire Rapids+). Sur AMD Zen 2 qui n’a que AVX2, les kernels Intel-tunés perdent leur avantage architectural. Les seules optimisations qui restent sont celles génériques x86, où llama.cpp reste maître.
Hypothèse à valider : sur un Hetzner cx33 (Intel Xeon Skylake avec AVX-512), OpenVINO pourrait probablement dépasser llama.cpp. À re-tester quand l’occasion se présentera — l’écart pourrait s’inverser à +20-30 % en faveur d’OpenVINO sur Intel récent. Mais ce n’est pas la conclusion pour le silicium d’aujourd’hui de mon SOC.
Verdict : pas un challenger sur AMD modeste. À reconsidérer absolument si scale-out vers Intel Xeon.
5. PowerInfer — le vrai gain, et son piège
PowerInfer est le projet le plus ambitieux des quatre. Pour comprendre pourquoi il est à la fois fascinant et délicat à adopter, il faut commencer par regarder ce qui se passe dans un LLM pendant la génération d’un token.
5.1 Pourquoi la sparsité activationnelle change la donne
Un Transformer décodeur classique (Llama, Qwen, Mistral…) alterne, à chaque couche, un bloc d’attention et un bloc feed-forward (FFN) — aussi appelé MLP. Sur un modèle 7B en Q4_K_M, le FFN représente environ 65 % du compute par token et 70 % des poids chargés depuis la RAM. C’est le gros morceau du coût d’inférence.
Le FFN suit toujours le même pattern :
x → Linear(d_model, d_ff) → activation → Linear(d_ff, d_model) → x'
Avec, sur Llama-2-7B, d_model = 4096 et d_ff = 11008 — donc le tenseur intermédiaire fait 11 008 neurones par couche × 32 couches = ~350 000 neurones à calculer pour chaque token généré.
Ce qu’a observé l’équipe SJTU (papier PowerInfer, SOSP 2024) : sur les modèles à activation ReLU, la grande majorité de ces neurones intermédiaires sortent 0 pour un token donné. Concrètement, sur ReluLLaMA-7B :
- ~80-95 % des neurones FFN ont une activation nulle pour le token courant
- Les 5-20 % qui s’activent ne sont pas les mêmes d’un token à l’autre, mais suivent une distribution power-law : ~10 % des neurones (les “hot neurons”) s’activent dans la majorité des cas, les autres ("cold neurons") sont occasionnels et dépendent fortement du contexte
Si on pouvait prédire à l’avance quels neurones vont s’activer et ne calculer qu’eux, on économiserait 80-90 % du compute FFN. Et — beaucoup plus important sur CPU — on économiserait autant de bande passante mémoire, puisqu’il faut charger les poids depuis la RAM pour chaque neurone calculé. Or comme l’a montré l’article 2 de cette série, la BW mémoire est le mur fondamental de l’inférence LLM CPU.
C’est exactement ce que fait PowerInfer.
5.2 Le mécanisme : predictor + neurones tièdes/froids
L’architecture PowerInfer ajoute deux ingrédients à un modèle ReLU :
1. Un predictor neural (MLP léger, ~2 % du nombre de paramètres) attaché à chaque couche FFN. Avant d’exécuter le FFN d’une couche, on fait passer l’input par le predictor, qui sort un vecteur de probabilités d’activation pour chaque neurone intermédiaire. On garde seulement ceux qui passent un seuil (typiquement 0.5).
x → predictor → mask (vecteur binaire 11008 neurones)
→ FFN_sparse(x, mask) → x' # ne calcule que les neurones avec mask=1
Le predictor a un taux de précision typique de 95-98 % sur ReluLLaMA et Bamboo, ce qui veut dire qu’il rate très rarement un neurone vraiment important (faux négatif) et qu’il inclut parfois des neurones inutiles (faux positifs). L’erreur tolérable : un faux négatif sur un neurone faiblement actif change peu la sortie.
2. Un layout RAM optimisé “hot / cold” : les neurones les plus fréquemment activés sont identifiés par profilage offline (sur un dataset de prompts représentatifs) et placés contiguous dans le binaire .powerinfer.gguf. Au moment de la décode, ces neurones sont gardés en cache CPU (L2/L3) entre tokens, ce qui évite des trips RAM répétés. Les neurones froids sont chargés à la demande quand le predictor les sélectionne.
La combinaison “predictor + layout hot/cold” donne un gain pratique de ×2 à ×3 sur tg/s mesuré sur 7B en CPU pur (sans GPU offloading), ce qui colle avec mes 14.3 t/s mesurés vs 7.3 t/s de llama.cpp sur le même hardware.
5.3 Pourquoi ReLU et pas SwiGLU
Le détail technique qui explique pourquoi votre Qwen 2.5 préféré n’est pas compatible : PowerInfer dépend de l’existence d’une activation strictement nulle pour la majorité des neurones. Or les activations modernes sont précisément conçues pour ne pas être nulles.
| Activation | Formule | Sparsité naturelle | Modèles |
|---|---|---|---|
| ReLU | max(0, x) | ~85-95 % | LLaMA-1, ReluLLaMA, Bamboo, ProSparse |
| GELU | x · Φ(x) | ~0-2 % | GPT-2, BERT, OPT |
| SiLU / Swish | x · σ(x) | ~0-2 % | Llama 2, Llama 3, Qwen 2/2.5, Mistral |
| SwiGLU | SiLU(xW₁) · (xW₂) | ~0-2 % | Llama 2/3, Qwen 2/2.5, Mistral, Mixtral |
ReLU est “binaire” — soit le neurone produit 0 (court-circuit), soit il propage la valeur d’entrée. Les architectures modernes ont remplacé ReLU par SiLU/SwiGLU précisément parce que ces activations gradient-non-nul partout convergent mieux pendant l’entraînement et donnent ~1-2 % de score perplexity en plus.
C’est un échange explicite : les concepteurs des LLMs modernes ont sacrifié la sparsité naturelle pour gagner en qualité. PowerInfer doit donc soit utiliser des modèles construits avec ReLU dès le départ, soit re-sparsifier un modèle SwiGLU.
5.4 Re-sparsifier un modèle existant
Si vous tenez à utiliser Qwen 2.5 ou Llama 3, ce n’est pas complètement bloqué — mais c’est du travail. Trois familles de techniques existent :
(a) ReLUfication par fine-tuning (cf. ReLU Strikes Back, Mirzadeh et al. 2024)
On remplace mécaniquement toutes les activations SwiGLU par ReLU dans le modèle, puis on fait un fine-tuning de récupération sur ~5-10 % du dataset d’entraînement initial. Coût : 100-1000 GPU-heures pour un 7B, avec une perte de qualité de 1-3 % en perplexity. Le modèle redevient sparse à ~70-80 % (moins bien que natif ReLU mais utilisable).
C’est ce qu’a fait l’équipe THUNLP pour produire ProSparse-Llama-2-7B/13B — voir leur article.
(b) TurboSparse / dReLU-fication (cf. Turbo Sparse, SJTU 2024)
Méthode plus subtile : on remplace SwiGLU par dReLU (ReLU(xW₁) · ReLU(xW₂)), une variante double-ReLU qui préserve la structure multiplicative de SwiGLU tout en introduisant deux points de zéro. Le fine-tuning de récupération coûte ~3-5× moins cher qu’en (a), et la sparsité atteinte est proche de 90 %. C’est la méthode utilisée pour TurboSparse-Mistral-47B qui atteint 11.68 tok/s sur smartphone.
(c) Pre-training natif sparse
Approche SJTU pour Bamboo : entraîner le modèle dès le départ avec ReLU + sparsity regularization dans la loss. La sparsité finale est maximale (~95 %), la qualité est compétitive avec Llama 2 de taille équivalente. Mais évidemment, c’est un pre-training complet — des centaines de milliers de GPU-heures, hors de portée d’un opérateur self-hosted.
Pour ASP-forge spécifiquement, le chemin (a) est le plus accessible : ~200 € de GPU rental (RunPod / Vast.ai) pour ReLUfier Qwen 2.5 3B + 1-2 jours de débug. Coût raisonnable pour ×2 sur le tg/s en prod.
5.5 Setup et exécution
git clone https://github.com/Tiiny-AI/PowerInfer.git pi-src
cd pi-src
cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=ON
cmake --build build --config Release -j 6
Build propre en ~5 min — le projet est forké de llama.cpp d’une ancienne version (mi-2024) et conserve les outils familiers llama-bench, main, server. La sparsité est gérée par un patch interne sur ggml_mul_mat qui consulte le predictor avant chaque appel.
La liste des modèles compatibles out-of-the-box :
ReluLLaMA-7B/13B/70B(LLaMA 2 ReLU-ifié)Bamboo-7B(modèle SJTU pre-trained sparse)ProSparse-Llama-2-7B/13B(THUNLP, méthode (a))TurboSparse-Mistral-47B(méthode (b), ~25 GB en Q4)SmallThinker-4BA0.6B-Instructet21BA3B(modèles MoE sparses, mais nécessitent leur framework customsmallthinker/— pas le binaire PowerInfer principal)SparseQwen2-7B(port communautaire DevQuasar — basé sur Qwen2 7B, pas 2.5 ni 3B)
Notre Qwen 2.5 3B standard utilise SwiGLU → strictement incompatible. Premier essai avec SmallThinker-4BA0.6B-Instruct.Q4_0.powerinfer.gguf : unknown model architecture: 'smallthinker'. Confirmé.
Fallback sur le modèle canonique Bamboo-7B-DPO-v0.1 (~4.4 GB) :
wget https://huggingface.co/PowerInfer/Bamboo-DPO-v0.1-gguf/resolve/main/bamboo-7b-dpo-v0.1.Q4_0.powerinfer.gguf
./build/bin/main -m bamboo-7b-dpo-v0.1.Q4_0.powerinfer.gguf -t 6 -p "..." -n 64
Cette fois ça charge — le predictor est embarqué dans le GGUF, le runtime PowerInfer se met en place automatiquement.
5.6 Les chiffres
Comparaison PowerInfer + Bamboo 7B vs llama.cpp HEAD + Qwen 2.5 7B (modèles différents mais taille équivalente 7B), tous deux Q4_0/Q4_K_M @ t=6 sur Ryzen Zen 2 :
| Moteur + modèle | pp256 t/s | tg64 t/s |
|---|---|---|
| llama.cpp b9165 + Qwen 7B Q4_K_M | 35.4 | 7.3 |
| PowerInfer + Bamboo 7B Q4_0 sparse | 26.9 | 14.3 |
Sur la génération, PowerInfer double presque le throughput (+96 %). C’est le seul gain spectaculaire de cette session.
Sur le prompt processing, llama.cpp reste meilleur de +32 %. La raison est éclairante : le prompt processing fait du matmul matrice-matrice (le prompt entier est traité en parallèle, ~256 tokens à la fois), où skipper des neurones n’aide quasiment pas — toutes les colonnes sont sollicitées par au moins un token du batch. La sparsité bénéficie au matmul matrice-vecteur de la génération token-par-token, où chaque token sollicite individuellement seulement 5-20 % des colonnes.
C’est cohérent avec l’analyse BW de l’article 2 : pp est compute-bound (toutes les colonnes utilisées → BW totale lue est inévitable), tg est memory-bound (skipper 80 % des colonnes = lire 80 % moins de poids = throughput proportionnel).
5.7 Coûts cachés et compromis qualité
Trois aspects rarement mentionnés dans les chiffres marketing :
(a) Quality drop mesurée. Les modèles ReLUfiés (a) perdent typiquement 1-3 % en MMLU vs leur base SwiGLU. Bamboo (c), pre-trained sparse, est à -2 à -5 % vs Llama 2 7B de référence. Pour un usage technique ciblé (mon SOC), c’est acceptable. Pour un assistant général, c’est perceptible.
(b) Coût du predictor à l’exécution. Le predictor ajoute ~2 % de compute par couche. Sur un workload mixte (long prompt + courte génération), la latence du predictor peut manger une partie du gain. C’est marginal mais à considérer si votre cas d’usage est très orienté prompt.
(c) Latence first-token plus haute. Le warmup PowerInfer (chargement du layout hot/cold + premier passage predictor) prend ~200-400 ms de plus que llama.cpp en cold-start. Acceptable pour un serveur qui tourne, problématique pour des invocations CLI ponctuelles.
5.8 Le caveat global
Donc PowerInfer gagne effectivement — mais à condition d’accepter une combinaison de coûts :
- Une base modèle complètement différente. Pas de drop-in replacement de Qwen ou Llama 3 ou Mistral. Vous devez migrer vers Bamboo, ReluLLaMA, ProSparse ou TurboSparse — ou ReLUfier votre modèle (~200 € de GPU + 1-2 jours dev).
- Re-entraîner vos LoRA. Si vous avez investi dans des LoRA spécialisés (comme moi avec WireGuard / OPNsense / CrowdSec pour ASP-forge), il faut les re-entraîner sur la nouvelle base, ce qui coûte du temps et du compute GPU.
- Un écosystème étroit. Beaucoup moins de modèles compatibles, beaucoup moins de quants disponibles, beaucoup moins de contributeurs. Vous êtes en avant-garde — quand le projet upstream stagne pendant 3 mois, vous n’avez pas vraiment d’alternative.
- Un compromis qualité. 1-5 % de score perplexity en moins selon la méthode de sparsification.
Pour ASP-forge : pas de gain immédiat. Mais c’est sérieusement une piste pour une version 2 si la performance sur 7B devient critique (par exemple en migrant d’un Qwen 3B vers un Bamboo 7B pour gagner en qualité de raisonnement tout en gardant le même throughput tg/s).
Si vous avez 200 € à investir en re-training et que votre cas d’usage tolère -2 % de qualité pour ×2 sur le throughput génération, c’est le seul levier algorithmique disponible aujourd’hui qui apporte un vrai gain mesurable sur CPU.
Verdict : le seul vrai challenger de la session — avec un asterisque substantiel sur l’effort de migration.
6. Tableau récapitulatif
| Moteur | Effort install | Modèle utilisé | tg/s combined | vs llama.cpp |
|---|---|---|---|---|
| llama.cpp b9165 (réf 3B) | déjà là | Qwen 2.5 3B Q4_K_M | ~15.7 | baseline |
| PowerInfer + Bamboo 7B | ~10 min | Bamboo 7B Q4_0 sparse | 14.3 sur 7B (vs llama 7.3) | +96 % sur 7B |
| OpenVINO GenAI 2026.1 | ~5 min | Qwen 2.5 3B INT4 | 13.9 | -11 % |
| CTranslate2 4.7.1 | ~5 min | Qwen 2.5 3B INT8 | 8.5 | -46 % |
| vLLM CPU | échec | — | — | non mesurable |
Tous les chiffres sont sur le même hardware (Ryzen 5 3600 / Zen 2 / 8 vCPU passthrough / 12 GB).
7. Recommandations pratiques
7.1 Si vous avez un Ryzen / AMD Zen 2-3 avec Qwen ou Llama standard
Restez sur llama.cpp HEAD + -march=native. C’est le meilleur choix. Aucun des challengers testés ne le bat sur AMD avec un modèle standard.
7.2 Si vous avez un Xeon Intel récent (Sapphire Rapids+ AMX, Cascade Lake AVX-512)
Mesurez OpenVINO GenAI sérieusement. Sur AMD modeste il perd, mais le toolkit est conçu pour Intel et exploite des instructions (AMX, AVX-512 BF16) que ni llama.cpp ni les autres n’exploitent à fond. L’écart pourrait s’inverser à +20-30 % en faveur d’OpenVINO. À mesurer — pas à supposer.
7.3 Si vous êtes prêt à migrer la base modèle pour doubler le throughput génération
PowerInfer + Bamboo-7B est une vraie option. Coût : re-entraîner vos LoRA, accepter un écosystème étroit. Bénéfice : +96 % sur tg64 vs llama.cpp/Qwen 7B. Pour un workload streaming-intensif (chatbot, génération longue), ça change la viabilité éco du déploiement.
7.4 Si vous voulez servir plusieurs utilisateurs concurrents
vLLM CPU avec Docker mérite d’être testé sérieusement. PagedAttention + continuous batching peut sortir 3-5× le throughput agrégé d’un llama-server qui sérialise les slots. Pas testable en pip sans douleur — passez direct par vllm/vllm-openai:cpu-latest. (Article futur prévu si je trouve le temps de monter le Docker dans un cas concret.)
7.5 Quand ne PAS utiliser CTranslate2
Pour les LLMs autoregressifs modernes (Qwen, Llama 3, Mistral). Restez sur llama.cpp. CT2 reste pertinent pour les pipelines de traduction encodeur-décodeur — c’est son cœur de métier — mais a pris du retard sur les LLMs génératifs.
8. Méthode de reproduction
Toutes les conversions et les benches sont reproductibles en une dizaine de commandes. Les scripts de bench Python (bench-ct2.py, bench-ov.py) sont disponibles dans le repo asp-forge (cf. docs/llm-bench-cpu-2026-05.md pour les chiffres bruts CSV/markdown).
Pour PowerInfer + Bamboo :
# Build PowerInfer
git clone https://github.com/Tiiny-AI/PowerInfer.git
cd PowerInfer && cmake -B build -DCMAKE_BUILD_TYPE=Release -DGGML_NATIVE=ON
cmake --build build --config Release -j $(nproc)
# Download Bamboo
wget https://huggingface.co/PowerInfer/Bamboo-DPO-v0.1-gguf/resolve/main/bamboo-7b-dpo-v0.1.Q4_0.powerinfer.gguf
# Bench
./build/bin/main -m bamboo-7b-dpo-v0.1.Q4_0.powerinfer.gguf -t 6 -p "<your prompt>" -n 64
5 minutes, vous avez vos chiffres tg/s sur votre propre hardware.
9. Conclusion de la série
Cette série de quatre articles tourne autour d’une question concrète : quel est l’optimum d’inférence LLM CPU en 2026 pour un opérateur self-hosted modeste ? Les réponses cumulées :
- Article 1 : llama.cpp HEAD bat ses propres versions anciennes de +50-130 %. Sept résultats contre-intuitifs sur OpenBLAS, IQ4_XS, SMT, AVX-512.
- Article 2 : la génération est bandwidth-bound. ~470 MB/(t/s) sur x86, ~650 sur ARM. Formule empirique pour le capacity planning.
- Article 3 : FreeBSD ≈ Linux pour l’inférence CPU. Pas de pénalité pour les appliances BSD.
- Cet article : sur les quatre challengers à llama.cpp, un seul (PowerInfer) fait significativement mieux — et seulement sur des modèles sparses spécifiques.
L’image cohérente qui ressort : llama.cpp HEAD avec -march=native reste l’optimum pratique en 2026 pour le CPU généraliste. Les vraies optimisations restantes sont architecturales (sparsité comme PowerInfer) ou matérielles (bande passante mémoire comme dans l’article 2). Le tuning algorithmique pur sur le hardware existant est largement saturé.
Pour ASP-forge, ça veut dire : statu quo recommandé (llama.cpp b9165), et les vraies marges de progression sont du côté du re-entraînement modèle (PowerInfer-compatible) ou du hardware (Threadripper / EPYC plus de canaux mémoire), pas du changement de moteur d’inférence.
Fin de la série. Repo de référence : asp-forge, commit avec données brutes : e6ff3d7. Discussions et corrections bienvenues.
