Quantizzare il KV cache: risparmiare VRAM (lungo contexte)
Hai abbastanza VRAM per caricare il modello, ma appena porti il contesto a 16k o 32k token, la capacità disponibile viene superata. La colpevole è la cache KV: una memoria nascosta che cresce linearmente con il contesto e che, con prompt lunghi, può occupare tanto spazio quanto il modello stesso. La quantizzazione della cache KV la comprime in Q8 o Q4 per raddoppiare il contesto gestibile sulla stessa scheda. Ecco come attivarla in Ollama e llama.cpp, i guadagni espressi in cifre e l'impatto reale sulla qualità.
#Perché la cache KV consuma la tua VRAM
Quando un LLM genera del testo, non ricalcola l'attenzione su tutto il prompt a ogni nuovo token: mantiene in memoria i vettori delle chiavi (K) e dei valori (V) di ogni token già visto. È il KV cache, ed è ciò che rende veloce la generazione. Il problema: questa memoria cresce linearmente con la lunghezza del contesto. Se raddoppi il contesto, raddoppi il KV cache.
Con un prompt breve di qualche centinaio di token, è trascurabile. Ma appena si passa al RAG con documenti di grandi dimensioni, al riassunto di trascrizioni o ad agenti con memoria a lungo termine, il contesto cresce enormemente, e con esso la cache KV. Su un 70B con 32k di contesto, può superare i 10 GB da sola, oltre ai circa 40 GB del modello. Spesso è proprio la cache, e non il modello, a causare l'out of memory con i prompt lunghi.
#Quanto pesa la tua cache KV
Il tuo ChatGPT privato e gratuito sulla tua macchina in 1 ora — LM Studio, Ollama, Open WebUI, i tuoi documenti, senza cloud.
- Spazio online a vita
- PDF + file
- Aggiornamenti a vita
La dimensione della cache KV dipende da quattro fattori: il numero di strati del modello, la dimensione dell'attenzione, la lunghezza del contesto e la precisione di memorizzazione. In FP16 (l'impostazione predefinita), la formula approssimativa è: 2 (K e V) × strati × dim_kv × contesto × 2 byte. In pratica, tieni a mente questi ordini di grandezza in FP16 con un contesto di 32k token:
- 7-9B (es. Qwen 3.5 9B, Granite 4.2 8B)
- Circa 2–4 GB di cache KV a 32k, a seconda dell'architettura (GQA aiuta molto).
- 14B
- ≈ da 4 a 6 GB con 32k token.
- 32B
- Circa 8–10 GB con 32k token.
- 70B
- Da ≈ 10 a 16 GB con 32k token — spesso il fattore limitante.
#Cosa cambia con la quantizzazione della cache KV
L'idea è la stessa dei pesi del modello: al posto di memorizzare ogni valore del cache in 16 bit (FP16), lo si memorizza in 8 bit (Q8_0) o in 4 bit (Q4_0). Si divide meccanicamente la memoria del cache per 2 (Q8) o per 4 (Q4). Poiché il KV cache può rappresentare una grande parte della VRAM sui contesti lunghi, il guadagno è diretto: a VRAM costante, si può circa raddoppiare la lunghezza del contesto supportabile in Q8.
- FP16
- Precisione di riferimento, nessuna perdita, ma è quella che richiede più memoria. L’impostazione predefinita.
- Q8_0
- Metà della memoria, perdita di qualità quasi impercettibile sulla maggior parte dei modelli. Il miglior compromesso.
- Q4_0
- Quattro volte meno memoria, ma perdita di qualità misurabile, variabile in base al modello. Da riservare ai casi in cui la VRAM è veramente il fattore limitante.
#Attivare la quantizzazione KV in Ollama
Ollama espone la quantizzazione della cache KV tramite due variabili d'ambiente del daemon. È necessario attivare Flash Attention, poi scegliere il tipo di cache. Queste variabili vanno impostate sul servizio Ollama, non al momento di eseguire ollama run.
- 01Attivare Flash AttentionImposta OLLAMA_FLASH_ATTENTION=1 nell'ambiente del daemon. È il prerequisito per ogni cache non-FP16.
- 02Scegliere il tipo di cacheImposta OLLAMA_KV_CACHE_TYPE con il valore desiderato: f16 (predefinito), q8_0 (consigliato) o q4_0 (aggressivo).
- 03Riavviare il daemonLe variabili d'ambiente vengono lette soltanto all'avvio del servizio. Riavvia Ollama perché vengano applicate.
- 04Verificare il guadagnoCarica un modello con un grande contesto e controlla la VRAM con nvidia-smi o ollama ps. Devi essere in grado di aumentare il num_ctx rispetto al passato.
#Attivare in llama.cpp
Da riga di comando con llama.cpp, la quantizzazione della cache KV si controlla con due flag distinti per le chiavi (K) e i valori (V), più il flag Flash Attention. È possibile quantizzare K e V separatamente, ma in pratica si usa lo stesso livello per entrambi.
- -fa
- Attiva Flash Attention. Senza questo flag, l'uso di -ctk/-ctv con una precisione inferiore a f16 fallisce.
- -ctk q8_0
- Quantizza la cache delle chiavi a 8 bit. Valori possibili: f16, q8_0, q4_0, q4_1, q5_0, q5_1.
- -ctv q8_0
- Quantizza la cache dei valori. Stesso insieme di valori di -ctk.
- -c 32768
- La dimensione del contesto che stai cercando. È proprio questa che la quantizzazione ti permette di aumentare senza superare i limiti.
#Quanto contesto si guadagna: numeri reali
Il vantaggio concreto dipende dalla quota di VRAM occupata dalla cache KV. Con un modello che entra comodamente in memoria, quantizzare la cache libera solo un po’ di spazio. Con un modello che già satura la memoria, può fare la differenza tra 8k e 24k di contesto. Ecco alcuni ordini di grandezza osservati, a parità di VRAM:
- FP16 → Q8_0
- Cache diviso per 2. In pratica, contesto supportabile circa raddoppiato quando il cache dominava il budget.
- FP16 → Q4_0
- Cache divisa per 4. È possibile gestire un contesto fino a circa 3-4 volte più lungo, al prezzo di una perdita di qualità misurabile.
- Esempio 14B su RTX 4080 16GB
- Da circa 16k di contesto in FP16 a circa 32k o più in Q8_0, con il modello e tutto il resto che continuano a rientrare negli stessi 16 GB.
- Esempio 32B su RTX 4090 24GB
- Passare la cache a Q8_0 permette spesso di gestire documenti RAG lunghi senza offloading sulla CPU.
#L'impatto sulla qualità a seconda del modello
È questa la vera domanda. Quantizzare la cache introduce rumore nell'attenzione e non tutti i modelli reagiscono allo stesso modo. La regola empirica che emerge dai test della comunità:
- Q8_0 sulla cache
- Differenza quasi impercettibile sulla stragrande maggioranza dei modelli. Perplessità e qualità percepita quasi identiche a quelle di FP16. È l'impostazione da attivare per default, quasi senza pensarci.
- Q4_0 sulla cache
- Perdita visibile e variabile. Alcuni modelli la tollerano molto bene, altri iniziano a divagare su contesti molto lunghi, a perdere il filo o a generare più allucinazioni. Da testare sul TUO caso.
- Modelli con GQA
- Generalmente più robusti alla quantizzazione della cache, poiché la loro cache è già compatta e ben strutturata.
- Compiti sensibili (codice, calcolo, estrazione rigorosa)
- Più esposte al degrado con Q4. Resta in Q8 per tutto ciò che richiede precisione fattuale.
#Risoluzione dei problemi
- « flash attention required » o cache ignorata
- Hai dimenticato -fa (llama.cpp) o OLLAMA_FLASH_ATTENTION=1 (Ollama). La cache quantizzata viene riportata a FP16 senza alcun avviso, oppure viene segnalato un errore.
- Nessun risparmio di VRAM visibile
- Il tuo contesto è troppo breve perché la cache occupi una quantità significativa di memoria. Il vantaggio si vede solo con prompt lunghi. Aumenta num_ctx / -c per constatarlo.
- Qualità che si degrada sui prompt lunghi
- Probabilmente stai usando Q4 con un modello che la tollera male. Riporta K a q8_0 (o anche tutto a q8_0) e ripeti il test.
- Variabili Ollama senza effetto
- Vengono lette soltanto all'avvio del daemon. Riavvia il servizio dopo averle impostate e verifica che siano effettivamente visibili al processo ollama.
- Ancora in OOM nonostante la quantizzazione
- È il modello stesso a superare la memoria disponibile, non la cache. Quantizza anche i pesi (Q4_K_M) oppure passa a un modello di taglia inferiore.
#Per approfondire
La quantizzazione della cache KV è uno dei modi per gestire contesti ampi in locale. Queste guide completano il quadro:
- Flash Attention 2 su un LLM locale: attivare e misurare il guadagno con un benchmark
- Il prerequisito per la quantizzazione KV, che offre anche di per sé un risparmio di memoria e un aumento di velocità. Da leggere per primo se Flash Attention non è ancora attivo nel tuo ambiente.
- Scegliere la quantizzazione (Q4, Q5, Q8, FP16)
- Per quantizzare i pesi del modello — l'altra grande voce di consumo della VRAM, complementare alla quantizzazione della cache.
- Installare Ollama: Windows, macOS e Linux
- Se il tuo stack non è ancora configurato, con i requisiti GPU per dimensionarlo correttamente.
Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.