Skip to content
/ airelien.dev
Go back
Aurélien AMSELLEM

Qwen3.6-27B MTP via llama.cpp PR #22673 sur Blackwell consumer — 78 t/s sans aucun fork ni patch

MTP arrive enfin dans llama.cpp upstream (PR #22673 par am17an, 4 mai). Bench sur Olares One RTX 5090M sm_120 : 78 t/s avec un GGUF MTP-enabled, +123% vs baseline. Pas de Lucebox, pas de Genesis, pas de fork custom permanent.

Salut les amis !

Hier soir sur r/LocalLLaMA, u/ilintar annonce que la PR MTP de am17an passe en beta. 334 upvotes en quelques heures. Le tweet final : “expect most performance gaps between llama.cpp and vLLM… to be erased.”

Spoiler : sur ma machine, baseline llama.cpp = 35 t/s. Avec PR #22673 + le bon GGUF MTP : 78 t/s. +123%. Sans toucher à Genesis, à Lucebox, à HAMi. Voilà comment.

Le contexte : MTP était dans vLLM, pas dans llama.cpp

Multi-Token Prediction est une technique de speculative decoding où le modèle apprend à prédire plusieurs tokens en avant dans une seule forward pass. Au moment de servir, on utilise ces prédictions comme “draft” gratuit : le modèle vérifie en parallèle, accepte les bons, jette les mauvais. Si l’acceptance est bonne, c’est ~2× plus rapide.

Qwen a entraîné Qwen3.6 avec une tête MTP intégrée. vLLM sait l’utiliser depuis longtemps (--speculative-config '{"method":"mtp","num_speculative_tokens":3}'). llama.cpp ne savait pas — jusqu’à la PR #22673 d’Aman Gupta, ouverte le 4 mai 2026.

La PR ajoute :

Aman teste sur DGX Spark. Communauté Reddit teste rapidement :

Pas de bench Blackwell consumer. Mon Olares One avec son RTX 5090M est le candidat.

Le build : am17an/mtp-clean + sm_120

PR #22673 vit sur la branche mtp-clean du fork am17an/llama.cpp. Cinq commits :

1a4fe4e  llama: allow partial seq_rm for GDN models for spec decoding
589490f  add enum for part sequence removal
c5e0227  rename rollback to rs_seq
10829db  llama + spec: MTP support
f8c6b03  add qwen35moe_mtp

Plutôt que de cherry-picker dans buun-llama-cpp (mon fork DFlash habituel), je build directement depuis cette branche en mode minimal — juste llama-server pour Qwen3.6 27B + sm_120 native :

FROM nvidia/cuda:13.1.0-devel-ubuntu22.04 AS build
RUN git clone --depth 1 --branch mtp-clean \
    https://github.com/am17an/llama.cpp /src/llama.cpp
WORKDIR /src/llama.cpp
RUN cmake -B build \
    -DGGML_CUDA=ON -DGGML_CUDA_NO_VMM=ON \
    -DCMAKE_CUDA_ARCHITECTURES=120 \
    -DLLAMA_CURL=ON \
    -DCMAKE_EXE_LINKER_FLAGS="-Wl,-rpath-link,/usr/local/cuda/lib64/stubs" \
    -DCMAKE_BUILD_TYPE=Release && \
    cmake --build build -j$(nproc) --target llama-server

2h de cross-compile sur OrbStack Mac. Image aamsellem/llamacpp-mtp:0.1.0, 2,62 Go.

Pas de Genesis patches, pas de DFlash custom kernels, pas de Lucebox. Juste llama.cpp + une PR.

Le GGUF : RDson/Qwen3.6-27B-MTP-Q4_K_M-GGUF

Détail important : pour utiliser MTP via llama.cpp, le GGUF doit inclure la tête MTP. Le Qwen3.6-27B Q4_K_M de unsloth ne l’inclut pas (la tête MTP a été retirée à la quantization standard).

Heureusement, RDson l’a fait quantize avec ik_llama :

am17an a aussi publié un Q8_0 sur sa propre repo, mais 28 Go = pas pour 24 Go.

La config llama-server

llama-server \
  --model /models/Qwen3.6-27B-MTP-Q4_K_M.gguf \
  --host 0.0.0.0 --port 8000 \
  --n-gpu-layers 99 \
  --ctx-size 32000 \
  --threads 16 \
  --batch-size 256 --ubatch-size 64 \
  --parallel 1 \
  --flash-attn on --jinja \
  --spec-type mtp \
  --spec-draft-n-max 4 \
  --chat-template-kwargs '{"enable_thinking": false}'

Notes :

Le bench

Trois prompts Space Invaders, max_tokens=800, temp=0.6, top_p=0.95 :

Run 1: 800 tok in 10,68s = 74,91 t/s
Run 2: 800 tok in  9,93s = 80,60 t/s
Run 3: 800 tok in 10,15s = 78,78 t/s

AVG 78,1 t/s [74,9-80,6].

Comparaison sur la même machine (Olares One, RTX 5090M 24GB sm_120)

Stackt/s avgComplexité stack
llama.cpp standard (sans spec)33-36upstream pur
llama.cpp + MTP (PR #22673)78,1upstream pur + 1 PR
buun-llama-cpp DFlash + Q8_0 GGUF drafter80fork llama.cpp
vLLM Turbo (Genesis 28 patches + TurboQuant K8V4 + MTP n=3)88,0vLLM + 28 patches + custom image
Lucebox v1.6.0 (PR #94 + q4_0 KV + DDTree 22)88,7engine custom + libvgpu hot-swap + 4 workarounds

+123% MTP llama.cpp vs baseline. Plus que les +75% Strix Halo de alexandrupetraru — la 5090M a probablement plus de marge à tirer parce que le baseline est lower (bandwidth contraint plus que sm_122).

Pourquoi 78 < 88 ? Parce que MTP est plus modeste que DFlash custom

MTP donne ~2× sur la baseline (acceptance ~75% × 4 draft tokens). DFlash bien tuné (Lucebox, drafter dédié, kernels custom) donne ~2,5-3×. Au-dessus de MTP llama.cpp, on a :

Tous ont besoin d’un fork ou de patches. MTP llama.cpp = la seule version qui sera mergée upstream dès que la PR review se complète.

Le vrai message

Dès que PR #22673 merge dans ggml-org/llama.cpp master, n’importe qui qui pull ghcr.io/ggml-org/llama.cpp:server-cudaXY-bNNNN et qui télécharge un GGUF Qwen3.6-MTP-enabled aura ~78 t/s sur consumer Blackwell mobile 24 Go, sans rien à fork.

C’est pas le record absolu (Lucebox 88,7), mais c’est :

C’est ce qui change vraiment la donne pour les utilisateurs end-user. Les forks restent la bonne réponse pour les benchmarks records ; MTP upstream sera la bonne réponse pour la distribution massive.

Pour suivre le merge

Crédits

Voilà ! Si vous tournez sur 5090M / 4080M / 3090 24 Go et que vous reproduisez ces 78 t/s (ou battez avec un sweep --spec-draft-n-max), envoyez-moi vos chiffres. À très vite !


Disclosure — Tous les benchmarks de ce post tournent sur mon propre Olares One. Si le contenu vous a été utile et que vous envisagez d’en acheter un, commander via ce lien de parrainage vous donne 400 $ de réduction (3 599 $ au lieu de 3 999 $) et me rapporte 200 $. Je le mentionne par transparence — et oui, accessoirement, ça aide à faire vivre le blog (hébergement, domaine, et le temps que je passe à écrire ici). Lien valable jusqu’à fin juin 2026 environ.

Share this post on:

Commentaires