Elaborazione del prompt di llama.cpp 35 volte più lenta? Correggi la KV cache q5_1
Flash attention più una KV cache q5_1 possono spostare l'attenzione sulla CPU. Come confermarlo, correggerlo con q8_0 e quando un'API è più semplice.

In questa pagina
Il tuo modello locale risponde bene, ma ogni prompt lungo ora resta lì per un minuto e mezzo mentre la GPU non fa nulla. Se esegui llama.cpp con -fa on e una KV cache q5_1, probabilmente è questa la causa: la build CUDA predefinita non ha un kernel flash-attention per quel tipo di cache, quindi il passo di attenzione viene eseguito silenziosamente sulla CPU. Passando la cache a q8_0 un utente è passato da 38 a 1348 token/s nell'elaborazione del prompt.
I numeri seguenti provengono dalla issue #28455 di llama.cpp (aperta il 5 settembre 2026, build 10791, verificata il 28 ottobre 2026). Un solo utente, una sola RTX 4080, un solo modello da 27B, quindi leggili come un esempio pratico, non come una legge. Anche l'analisi della causa radice è la loro: un maintainer l'ha definita "un problema noto" e ha chiuso la issue il giorno dopo.
Come si presenta sullo schermo#
La configurazione era ordinaria. Qualcuno voleva un contesto di 131072 token su una singola scheda da 16 GB, quindi ha ridotto la KV cache a q5_1:
llama-server -m model.gguf -ngl 99 -fa on -c 131072 -np 4 \
--cache-type-k q5_1 --cache-type-v q5_1Poi ha inviato un prompt di 3,6K token. L'elaborazione del prompt girava a 38,4 token/s e il decoding a 6,5 token/s. Fai la divisione: 3.600 ÷ 38,4 = 93,75, quindi circa 94 secondi prima della prima parola. Con q8_0 lo stesso prompt girava a 1348 token/s: 3.600 ÷ 1.348 = 2,67, meno di tre secondi.
L'indizio è nel task manager. Durante le esecuzioni lente la GPU restava vicino allo 0% mentre la CPU mostrava circa il 930% (nove o dieci core occupati). Una GPU che resta inattiva mentre stai "eseguendo sulla GPU" è il sintomo da cercare.

Perché una cache più piccola lo rende molto più lento#
Flash attention è un kernel GPU fuso. La build CUDA predefinita lo include solo per alcune coppie di tipi di KV cache. Per q4_0, q4_1, q5_0 e q5_1 non c'è alcun kernel, quindi llama.cpp non si ferma con un errore. Sposta quell'operazione sulla CPU e continua. Tutto funziona ancora, solo circa 35 volte più lento nell'elaborazione del prompt (1348 ÷ 38,4 = 35,1).
Quel "silenziosamente" è tutto il problema. Nulla nella risposta te lo dice. L'elaborazione del prompt cala di più (circa 35×), e anche la generazione rallenta: 6,5 token/s contro 30,1 con q8_0 nella stessa issue.
Verificalo in due minuti#
Esegui llama-bench con gli stessi tipi di cache che usi nel server, una volta per variante, e osserva la GPU in un altro terminale:
llama-bench -m model.gguf -ngl 99 -fa 1 -ctk q8_0 -ctv q8_0 -p 512 -n 0
llama-bench -m model.gguf -ngl 99 -fa 1 -ctk q5_1 -ctv q5_1 -p 512 -n 0
nvidia-smi -l 1I risultati pp512 dell'utente su un Qwen 27B Q5_K_XL: 1511,92 token/s per q8_0/q8_0, circa 197 per q5_1/q5_1 sulla build predefinita. Se le tue due righe mostrano un divario simile e nvidia-smi mostra la GPU inattiva durante la seconda, l'hai trovato.
Prima di correggere qualcosa, confronta ciò che vedi con la causa probabile:
Abbina le coppie
Abbina ogni sintomo alla sua causa
Tocca un elemento a sinistra, poi il suo abbinamento
- GPU a ~0%, CPU a ~930% durante un prompt lungoL'attenzione viene eseguita sulla CPU
- Il decoding scende a ~6,5 token/s contro 30,1 con
q8_0Anche la generazione rallenta, non solo l'elaborazione del prompt - Gli stessi flag sono veloci con
q8_0Questa coppia di tipi di cache non ha un kernel GPU flash-attention nella build predefinita
Correzione 1: usa q8_0 (o ricompila)#
La correzione più rapida è cambiare due flag e mantenere tutto il resto:
llama-server -m model.gguf -ngl 99 -fa on -c 131072 -np 4 \
--cache-type-k q8_0 --cache-type-v q8_0Nella issue questo ha dato 1348 token/s nell'elaborazione del prompt e 30,1 token/s nel decoding (in aumento da 6,5). Il prezzo è la memoria: una cache q8_0 è più grande di q5_1, quindi verifica che la tua lunghezza di contesto entri ancora nella VRAM.
Se devi mantenere q5_1 per motivi di memoria, ricompila con tutte le combinazioni di cache flash-attention incluse:
cmake -B build -DGGML_CUDA=ON -DGGML_CUDA_FA_ALL_QUANTS=ON
cmake --build build --config Release -jQuella build eseguiva q5_1 a 1509,70 token/s su pp512 e 1162 token/s sul prompt di 3,6K token, con decoding a 38,5 token/s. Un commentatore della issue ha fatto notare che spostare il lavoro tra backend potrebbe cambiare leggermente i risultati numerici e ha suggerito un confronto della perplessità tra le build. Se ti interessano output esatti, eseguine uno.
Confronta
Quale correzione si adatta alla tua scheda?
Cache q8_0
Cambia --cache-type-k e --cache-type-v in q8_0. Nessuna ricompilazione. Usa più VRAM di q5_1, quindi ricontrolla la dimensione del contesto che riesci a far entrare.
Ricompila con FA_ALL_QUANTS
Mantieni q5_1 e compila con -. Stessa VRAM di prima, ma gestisci la tua build e la compilazione richiede più tempo.
La risposta "problema noto" del maintainer non dice se le versioni attuali di llama.cpp hanno cambiato questo comportamento. Il controllo onesto è la coppia llama-bench qui sopra: se entrambe le righe sono vicine, sei a posto.
Quando il tuning smette di valere la pena#
Supponi di aver fatto funzionare la correzione, e ora stai valutando il prossimo giro: più flag, una seconda GPU, una quantizzazione più piccola. Se il lavoro è riassunti, code review o estrazione su prompt di qualche migliaio di token, chiediti quanto ti costa una richiesta in tempo e sforzo, non solo in watt.
Ecco un carico di lavoro dichiarato con cui confrontarti. Supponi che un job di riassunto invii 3.600 token di input e ne riceva 500 indietro, 1.000 volte. Su CheapTokens sono circa $0.104 su DeepSeek-V4-Flash (contesto 380K, fino a 32.768 token di output per risposta, un prezzo a qualsiasi ora) e circa $0.092 su GLM-5.3-Flash (contesto 390K). La tabella conta input e output insieme, con una colonna OpenRouter per confronto:
| Modello | Input $/1M | Output $/1M | Per richiesta | 1000 richieste | OpenRouter, 1000 richieste |
|---|---|---|---|---|---|
| GLM-5.3-Flash | $0.02 | $0.04 | $0.000092 | $0.092 | $0.187 |
| DeepSeek-V4-Flash | $0.015 | $0.10 | $0.0001 | $0.104 | $0.249 |
| MiniMax-M2.7 | $0.05 | $0.15 | $0.00026 | $0.255 | $1.68 |
3600 token di input e 500 token di output per richiesta. I prezzi per 1M di token sono attuali e cambiano insieme alle nostre tariffe; la colonna OpenRouter mostra i prezzi di riferimento per lo stesso carico di lavoro.
L'API non si preoccupa del tuo tipo di cache, della tua VRAM o dei tuoi flag di build; non c'è nulla da far ricadere sulla CPU. Invia prima una manciata dei tuoi prompt reali e giudica tu stesso le risposte. Il passo è piccolo: l'endpoint parla il formato OpenAI Chat Completions, quindi la maggior parte dei client locali ha solo bisogno di un nuovo base URL.
curl https://api.cheaptokens.dev/v1/chat/completions \
-H "Authorization: Bearer $CHEAPTOKENS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model": "deepseek-ai/DeepSeek-V4-Flash-0731", "messages": [{"role": "user", "content": "Summarize the text below in 5 bullets: ..."}], "max_tokens": 500}'La configurazione completa è nella documentazione di CheapTokens, e i prezzi attuali per modello sono nella pagina dei prezzi. Per uno sguardo più approfondito su hardware e API, vedi Eseguire DeepSeek in locale o usare un'API. Se vuoi vedere come input e output vengono fatturati separatamente, token di input vs output lo spiega.
L'ordine in cui procedere#
Metti in ordine
Metti in ordine i passaggi di risoluzione dei problemi
Trascina gli elementi o usa le frecce
- Esegui llama-bench per q8_0 e q5_1 e osserva nvidia-smi
- Cambia entrambi i tipi di cache in q8_0
- Verifica che la lunghezza del contesto entri ancora nella VRAM
- Ricompila con GGML_CUDA_FA_ALL_QUANTS=ON solo se hai bisogno di q5_1
- Confronta lo stesso prompt su un'API se la configurazione locale non vale ancora lo sforzo
Un'ulteriore cautela sulle fonti: l'intera diagnosi si basa su una sola issue pubblica e una sola GPU. Considera 1348 e 38,4 come ciò che è successo lì, e misura la tua scheda prima di fidarti di entrambi.



