Vai al contenuto principale

Tutorial sulla Multi-Token Prediction: come velocizzare gli LLM

Esegui Qwen3.6 27B su una RTX 3090 e scopri come la Multi-Token Prediction (MTP) con llama.cpp può quasi raddoppiare l'inferenza locale degli LLM senza aggiornare la tua GPU.
Aggiornato 14 mag 2026  · 9 min leggi

E se potessi far girare i large language model più velocemente senza aggiornare la GPU, cambiare macchina o passare a un modello più piccolo?

È quello che testeremo in questa guida usando la Multi-Token Prediction, o MTP. Nel mio benchmark, lo stesso modello Qwen3.6 27B sulla stessa configurazione RunPod RTX 3090 è passato da 38 token/sec a 65 token/sec dopo aver abilitato MTP. Si tratta di un miglioramento di 1,71x, ovvero circa il 71% di throughput in più, senza perdita visibile di qualità dell'output.

In questa guida, faremo:

  • Configurare una macchina RunPod RTX 3090
  • Clonare e passare al branch MTP
  • Compilare llama.cpp con supporto CUDA
  • Scaricare il modello Qwen3.6 27B MTP GGUF
  • Eseguire il modello senza MTP per ottenere una velocità di base
  • Abilitare MTP e testare di nuovo il modello
  • Confrontare la velocità di generazione dei token con e senza MTP
  • Esaminare TurboQuant come possibile passo successivo per ulteriori ottimizzazioni

Cos'è la Multi-Token Prediction?

La maggior parte degli LLM genera testo un token alla volta. Il modello predice il token successivo, lo aggiunge al contesto e ripete lo stesso processo. È affidabile, ma può essere lento perché ogni nuovo token richiede solitamente un altro step di decoding.

La Multi-Token Prediction cambia questo meccanismo permettendo al modello di guardare avanti e proporre più token futuri invece di uno solo. Questi token proposti vengono poi verificati dal processo principale di decoding. Se le previsioni sono corrette, il modello può accettare più token in un colpo solo. Se un token è errato, il modello torna al percorso normale da quel punto.

In pratica, MTP funziona come un meccanismo di drafting integrato. Il modello abbozza alcuni probabili token successivi, li verifica e mantiene quelli validi. Più token di bozza vengono accettati, meno step completi di decoding servono, il che può aumentare i token al secondo senza cambiare la qualità finale dell'output.

In parole semplici:

  • Senza MTP: Genera token 1 → genera token 2 → genera token 3
  • Con MTP: Abbozza più token → verificali → accetta insieme i token validi

Ecco perché MTP può rendere l'inferenza locale degli LLM molto più rapida. Invece di costringere il modello ad avanzare un passettino alla volta, gli permette di saltare in sicurezza quando le previsioni di bozza sono corrette. 

Senza MTP vs con MTP

In strumenti come llama.cpp e implementazioni in stile vLLM-style, ciò è strettamente legato allo speculative decoding, dove i token di bozza vengono accettati solo quando corrispondono all'output del verificatore. 

1. Configura una macchina RunPod RTX 3090

Per questa guida ho usato un'istanza GPU RunPod con una RTX 3090. Puoi usare un'altra GPU compatibile con CUDA, ma i risultati del benchmark in questo tutorial si basano su una configurazione con RTX 3090.

Per prima cosa, crea un nuovo pod RunPod e seleziona una GPU RTX 3090.

Prima del deploy del pod, modifica le impostazioni del template:

  • Aumenta la dimensione del disco volume a 100 GB

  • Aggiungi una porta HTTP aggiuntiva: 8910

  • Aggiungi una variabile d'ambiente chiamata HF_TOKEN e imposta come valore il tuo access token di Hugging Face. 

La porta HTTP extra ti permetterà di accedere al server e alla web UI di llama.cpp dal browser. Il token di Hugging Face aiuta ad autenticare la richiesta di download e può migliorare la velocità di scaricamento del modello, soprattutto per i file GGUF di grandi dimensioni.

Configurazione RunPod

Dopo aver aggiornato il template, effettua il deploy del pod. Una volta in esecuzione, attendi che RunPod ti dia accesso all'istanza JupyterLab. Apri JupyterLab, quindi lancia un nuovo terminale.

Nel terminale, installa i pacchetti di sistema richiesti:

apt update
apt install -y git cmake build-essential curl wget python3-pip

Avvio del RunPod

2. Clona e passa al branch MTP

Poi, spostati nella directory di lavoro in cui installeremo e compileremo llama.cpp:

cd /workspace

Clona il repository di llama.cpp:

git clone --depth 1 https://github.com/ggml-org/llama.cpp.git
cd llama.cpp

Le modifiche MTP sono ancora in fase di test tramite una pull request dedicata di llama.cpp, quindi recuperiamo e passiamo a quel branch per usare l'implementazione MTP più recente prima che entri nella build principale standard.

Recupera localmente il branch MTP:

git fetch origin pull/22673/head:mtp-pr
git checkout mtp-pr

Questo commuta la tua build locale di llama.cpp alla versione con MTP abilitato, che useremo per il resto della guida.

Passaggio alla versione di llama.cpp con MTP abilitato

3. Compila llama.cpp con supporto CUDA

Ora che sei sul branch con MTP abilitato, compila llama.cpp con supporto CUDA. Questo permette al modello di usare la GPU RTX 3090 invece di eseguire l'inferenza sulla CPU.

Esegui la configurazione di build con CMake:

cmake -B build -DGGML_CUDA=ON -DCMAKE_BUILD_TYPE=Release

Poi compila i due target di cui abbiamo bisogno per questa guida:

cmake --build build --target llama-cli llama-server -j

Compilazione di llama.cpp con supporto CUDA

Questo compila:

  • llama-cli per eseguire rapidi test a riga di comando

  • llama-server per avviare un server compatibile con OpenAI accessibile dal browser

Una volta completata la build, copia il binario llama-server nella directory principale di llama.cpp:

cp ./build/bin/llama-server ./llama-server

Questo rende più semplice avviare il server dalla root del progetto nei prossimi passaggi.

4. Scarica il modello Qwen3.6-27B-MTP

Ora scarica il modello Qwen3.6 27B MTP GGUF che useremo per i test. Eseguiremo prima questo modello senza MTP, e poi di nuovo con MTP abilitato, per confrontare la differenza di velocità.

Per prima cosa, installa gli strumenti di download di Hugging Face:

pip install -U "huggingface_hub[hf_xet]" hf-xet hf_transfer

Poi abilita download più veloci da Hugging Face:

export HF_HUB_ENABLE_HF_TRANSFER=1

Questo aiuta ad accelerare il download di modelli di grandi dimensioni, in particolare quando si lavora con file GGUF.

Ora crea una directory dedicata per il modello:

mkdir -p /workspace/models/qwen3.6-mtp

Scarica il modello Qwen3.6 27B MTP GGUF:

hf download froggeric/Qwen3.6-27B-MTP-GGUF \
 Qwen3.6-27B-Q4_K_M-mtp.gguf \
 --local-dir /workspace/models/qwen3.6-mtp

Qwen3.6-27B scaricato correttamente

Se ti interessa il fine-tuning degli LLM, dai un'occhiata al mio tutorial sul fine-tuning di Qwen3.6 su un dataset di Q&A medico.

5. Esegui Qwen3.6-27B senza MTP abilitato

Siamo arrivati alla parte principale della guida: testare la velocità del modello prima e dopo l'abilitazione di MTP.

Per prima cosa, eseguiremo il modello senza MTP. Questo ci dà una baseline pulita per poter confrontare successivamente la differenza di velocità. Usiamo lo stesso modello, la stessa GPU, la stessa dimensione del contesto e le stesse impostazioni del server. L'unica modifica sostanziale nel passaggio successivo sarà abilitare MTP.

Torna nella directory llama.cpp:

cd /workspace/llama.cpp

Avvia il server senza MTP:

./llama-server \
-m "/workspace/models/qwen3.6-mtp/Qwen3.6-27B-Q4_K_M-mtp.gguf" \
--alias qwen3.6-27b-no-mtp \
--host 0.0.0.0 \
--port 8910 \
-ngl 99 \
-c 100000 \
--cache-type-k q8_0 \
--cache-type-v q8_0 \
-np 1 \
-b 2048 \
-ub 512 \
-t 8 \
-fa on \
--temp 0.7 \
--top-k 20 \
--top-p 0.95 \
--repeat-penalty 1.1 \
--metrics

Questo avvia un server llama.cpp compatibile con OpenAI sulla porta 8910.

Il modello potrebbe impiegare un po' a caricarsi perché il server deve caricare i pesi nella memoria della GPU. Quando tutto è pronto, il terminale mostrerà che il server è disponibile sulla porta 8910.

server disponibile

Poiché abbiamo esposto questa porta durante la configurazione del template RunPod, non devi configurare altro. Torna alla tua dashboard RunPod e fai clic sul link associato alla porta 8910. Si aprirà la web UI di llama.cpp nel browser, con il modello locale già caricato.

web UI di llama.cpp

Da qui, puoi iniziare a testare i prompt direttamente nel browser, come in una classica interfaccia chat.

Interfaccia chat

Nel mio test di base, il modello ha generato risposte a circa 38,86 token/sec senza MTP. Anche con un prompt più complesso, la velocità è rimasta più o meno nella stessa fascia. 

Per un modello da 27B eseguito su una RTX 3090, è già un risultato utilizzabile, soprattutto considerando che la GPU è più lenta e ha memoria limitata rispetto alle schede dei data center più recenti. 

6. Esegui Qwen3.6-27B con MTP abilitato

Ora eseguiremo di nuovo lo stesso modello, ma questa volta con MTP abilitato.

Torna al terminale in cui è in esecuzione il server e arrestalo con:

CTRL + C

La cosa importante è che non stiamo cambiando modello, GPU, quantizzazione o la maggior parte delle impostazioni di runtime. Aggiungiamo solo due flag legati a MTP:

--spec-type mtp
--spec-draft-n-max 3

Il primo flag dice a llama.cpp di usare lo speculative decoding in stile MTP. Il secondo imposta a 3 il numero massimo di token di bozza. Significa che il modello può tentare di abbozzare fino a tre token futuri prima della verifica.

Ora riavvia il server con MTP abilitato:

./llama-server \
-m "/workspace/models/qwen3.6-mtp/Qwen3.6-27B-Q4_K_M-mtp.gguf" \
--alias qwen3.6-27b-mtp \
--host 0.0.0.0 \
--port 8910 \
-ngl 99 \
-c 100000 \
--spec-type mtp \
--spec-draft-n-max 3 \
--cache-type-k q8_0 \
--cache-type-v q8_0 \
-np 1 \
-b 2048 \
-ub 512 \
-t 8 \
-fa on \
--temp 0.7 \
--top-k 20 \
--top-p 0.95 \
--repeat-penalty 1.1 \
--metrics

Quando il server è pronto, aggiorna la pagina del browser. Se la pagina non si riconnette automaticamente, chiudila e riapri il link della porta 8910 dalla tua dashboard RunPod. 

Ora testa di nuovo il modello usando lo stesso tipo di prompt.

Test di Qwen3.6 con MTP

Con MTP abilitato, la velocità è aumentata sensibilmente. Per un semplice prompt di saluto, il modello ha raggiunto circa 65–67 token/sec. Rispetto alla baseline di circa 38,86 token/sec, è un miglioramento notevole ottenuto aggiungendo solo due flag da riga di comando. 

Output del modello

Per un prompt più complesso, ad esempio chiedere al modello di creare un semplice gioco in Python, la velocità è stata leggermente inferiore ma comunque molto più alta rispetto alla baseline senza MTP. In quel test, il modello ha generato a circa 56–61 token/sec, che è comunque un ottimo risultato per un modello da 27B su una RTX 3090. 

Nel complesso, abilitare MTP ha portato Qwen3.6 27B da circa 38 token/sec a 65 token/sec sulla configurazione RunPod con RTX 3090. Questo equivale a un boost di 1,71x, ovvero circa il 71% di throughput in più, senza cambiare l'hardware o passare a un modello più piccolo. 

7. Consiglio: ulteriore ottimizzazione della velocità con TurboQuant

Il benchmark in questa guida usa la configurazione MTP originale di llama.cpp, senza aggiungere TurboQuant, patch personalizzate o altre ottimizzazioni a livello di runtime. Questo mantiene il test semplice, riproducibile e focalizzato sul guadagno di velocità dato solo dall'abilitazione di MTP.

Per spingere ulteriormente le prestazioni, la prossima ottimizzazione da esplorare è MTP insieme a TurboQuant. MTP migliora il throughput consentendo al modello di accettare più token previsti, mentre TurboQuant aiuta a ridurre la pressione sulla KV-cache durante l'inferenza. 

Questo può essere particolarmente utile per modelli più grandi, prompt con contesti lunghi e GPU come la RTX 3090, dove la banda di memoria e la VRAM possono diventare fattori limitanti.

Ecco perché alcuni risultati della community r/LocalLLaMA riportano più token/sec rispetto a questa guida. Quelle configurazioni spesso combinano MTP con TurboQuant, build patchate, impostazioni diverse della KV-cache o GPU più veloci. Poiché questo tutorial si concentra su un benchmark pulito solo-MTP, TurboQuant va considerato come il prossimo esperimento consigliato, non come parte della configurazione attuale.

Considerazioni finali 

Ultimamente ho seguito i post nella community Reddit LocalLLaMA, ed è incredibile vedere quanto sia avanzata l'inferenza locale degli LLM. Ora molte persone eseguono modelli come Qwen3.6 27B come agenti di coding locali, anche su GPU meno recenti con VRAM limitata. Alcuni usano configurazioni simili su sistemi Mac, e i risultati sono davvero impressionanti.

Dopo aver testato MTP personalmente, capisco perché c'è così tanto entusiasmo. Con lo stesso modello e la stessa configurazione su RTX 3090, abilitare la Multi-Token Prediction ha migliorato la velocità di generazione da circa 38 token/sec a 65 token/sec. Quasi un raddoppio senza aggiornare la GPU o passare a un modello più piccolo.

Questa guida si è concentrata su una configurazione MTP semplice e riproducibile usando llama.cpp, ma sembra solo l'inizio. Il prossimo passo è sperimentare con una quantizzazione GGUF migliore, MTP, TurboQuant e impostazioni di runtime più affinate per vedere fin dove si può spingere la velocità dell'inferenza locale.

Per me, la parte più entusiasmante è ciò che questo significa per gli agenti di coding locali. Puoi eseguire modelli potenti sull'hardware che già possiedi, ridurre il costo per query, mantenere privato il tuo codice e usare un assistente di coding AI senza dipendere del tutto da API via internet. Gli LLM locali stanno diventando più veloci, più pratici e molto più utili rispetto a poco tempo fa.

FAQ sulla Multi-Token Prediction

Ho bisogno di un modello di bozza separato per MTP?

No. Con Qwen3.6-27B, MTP è integrato nel modello stesso, quindi non è necessario un secondo modello.

Di quanto MTP rende più veloce il modello?

Nella nostra configurazione RunPod con RTX 3090, abilitare MTP ha migliorato la velocità di generazione da ~38 token/sec a ~65 token/sec, un aumento di 1,71x, ovvero ~71% di throughput in più.

Qual è la differenza tra MTP e speculative decoding?

MTP in llama.cpp è una forma di speculative decoding. I token di bozza dalle MTP head del modello vengono accettati solo se superano la verifica. La differenza chiave rispetto allo speculative decoding tradizionale è che non serve un modello di bozza esterno.

Posso ottenere velocità ancora maggiori oltre a quanto offre MTP?

Sì. Combinare MTP con TurboQuant, che riduce la pressione sulla KV-cache durante l'inferenza, è il prossimo passo consigliato per ulteriori guadagni di velocità, soprattutto su GPU con memoria limitata come la RTX 3090.

Argomenti

Impara l'AI Engineering con DataCamp!

Programma

Ingegnere AI associato per sviluppatori

26 h
Scopri come integrare l'intelligenza artificiale nelle applicazioni software utilizzando API e librerie open-source. Inizia oggi il tuo percorso per diventare un ingegnere AI!
Vedi dettagliRight Arrow
Inizia il corso
Mostra altroRight Arrow