𝗞𝗩 𝗖𝗮𝗰𝗵𝗲 𝗮𝗻𝗱 𝗣𝗮𝗴𝗲𝗱𝗔𝘁𝘁𝗲𝗻𝘁𝗶𝗼𝗻: 𝗪𝗵𝘆 𝗬𝗼𝘂𝗿 𝗟𝗟𝗠 𝗦𝗲𝗿𝘃𝗲𝗿 𝗦𝗹𝗼𝘄𝘀 𝗗𝗼𝘄𝗻
Your LLM server is running slow.
You deployed a 70B model on four A100 GPUs. Everything looks fine at 8 AM. By lunch, latency doubles. You check your memory. Most of it is taken up by "tensor buffers." These are actually cached states from old conversations.
This is the KV cache problem. It is the biggest bottleneck in production LLM serving.
What is the KV cache?
Every transformer model generates tokens one by one. To create a new token, the model needs the Key and Value tensors from all previous tokens. Recomputing these every time is too slow. Instead, the engine stores them. This storage is the KV cache.
The memory problem:
For a Llama 3.1 70B model, a single 4096-token sequence needs about 1.3 GB of memory.
If you have 256 users at once, you need 336 GB of memory. This is more than four A100 GPUs can hold. The KV cache grows so fast that it often uses more memory than the model weights themselves.
Traditional memory management fails because:
- Internal fragmentation: You allocate space for 4096 tokens but only use 300. You waste 93% of that space.
- No sharing: Two users with the same system prompt each store their own copy of that prompt.
- All-or-nothing eviction: When memory runs out, you must move the entire sequence to the CPU. This stalls the GPU.
How PagedAttention fixes this:
PagedAttention works like an operating system. It divides the KV cache into small, fixed-size blocks called pages.
This solves three main issues:
- On-demand allocation: A sequence only takes up pages as it grows. You do not waste memory on unused capacity.
- Shared prefix support: Multiple users can share the same physical pages for a common system prompt. This uses "copy-on-write" logic to save massive amounts of memory.
- Fine-grained eviction: When memory is full, the system moves small pages to the CPU instead of huge sequences.
The Result:
Using PagedAttention (the tech inside vLLM) can increase throughput by 2x to 4x compared to traditional methods.
When to use it:
- High concurrency.
- Sequences of different lengths.
- Prompts that share the same start.
When to skip it:
- Single-user local inference.
- Very small models.
- Tasks where every sequence is exactly the same length.
KV Cache e PagedAttention: cosa sono e perché sono importanti
Quando interagiamo con i Large Language Models (LLM), come GPT-4 o Llama 3, notiamo spesso che la generazione del testo avviene parola per parola (o meglio, token per token). Questo processo di generazione è computazionalmente costoso e richiede una gestione intelligente della memoria.
In questo articolo, esploreremo due concetti fondamentali che rendono l'inferenza degli LLM più efficiente: il KV Cache e PagedAttention.
Cos'è il KV Cache?
Per capire il KV Cache, dobbiamo prima guardare a come funziona il meccanismo di Attention (attenzione) nei Transformer.
Durante la generazione di un nuovo token, il modello deve calcolare l'attenzione rispetto a tutti i token precedenti nella sequenza. Il calcolo dell'attenzione richiede due componenti principali per ogni token:
- Key (Chiave)
- Value (Valore)
Senza un sistema di caching, il modello dovrebbe ricalcolare i vettori Key e Value per ogni singolo token della sequenza ogni volta che ne genera uno nuovo. Se stiamo generando il centesimo token, il modello ricalcolerebbe i primi 99, sprecando una quantità enorme di potenza di calcolo.
Il KV Cache risolve questo problema memorizzando i vettori Key e Value dei token già elaborati nella memoria (solitamente nella VRAM della GPU). In questo modo, per generare il token successivo, il modello deve solo calcolare il Key e il Value del token appena creato e recuperare quelli precedenti dalla cache.
Il costo del KV Cache
Sebbene il KV Cache acceleri drasticamente l'inferenza, ha un costo significativo: la memoria.
Man mano che la lunghezza della sequenza aumenta, la dimensione del KV Cache cresce linearmente. Per modelli con finestre di contesto molto ampie (come 128k token), il KV Cache può occupare decine di gigabyte di VRAM, lasciando poco spazio per il modello stesso o per gestire più utenti contemporaneamente (batching).
Il problema: Frammentazione della memoria
Il modo tradizionale di gestire il KV Cache è allocare un blocco di memoria contiguo per ogni richiesta di generazione. Tuttavia, questo approccio presenta due problemi critici:
- Frammentazione Interna: Spesso non sappiamo in anticipo quanti token genererà l'utente. Per sicurezza, i sistemi allocano memoria basandosi sulla lunghezza massima della finestra di contesto. Se l'utente genera solo 10 token ma il sistema ha allocato spazio per 2048, la maggior parte di quella memoria è sprecata e inutilizzabile per altri compiti.
- Frammentazione Esterna: Man mano che le richieste vengono create e terminate, la memoria viene allocata e deallocata, lasciando piccoli "buchi" di memoria libera che sono troppo piccoli per ospitare nuove richieste, anche se la somma totale della memoria libera è sufficiente.
Questo spreco di memoria limita drasticamente il throughput (il numero di token generati al secondo) del sistema.
La soluzione: PagedAttention
È qui che entra in gioco PagedAttention, una tecnica introdotta con la libreria vLLM.
L'idea di PagedAttention si ispira alla gestione della memoria virtuale (paging) utilizzata dai sistemi operativi moderni. Invece di richiedere un unico blocco di memoria contiguo e enorme per il KV Cache, PagedAttention divide il cache in piccoli blocchi di dimensione fissa.
Come funziona?
- Blocchi non contigui: I vettori Key e Value vengono memorizzati in blocchi che possono essere sparsi in diversi punti della memoria della GPU. Non è più necessario che siano vicini tra loro.
- Tabella delle pagine: Il sistema mantiene una "tabella delle pagine" (simile a una tabella delle pagine di un OS) che mappa i token logici della sequenza ai blocchi fisici nella memoria.
- Allocazione dinamica: La memoria viene allocata solo quando è effettivamente necessaria. Se un modello sta generando un nuovo token, il sistema assegna un nuovo blocco dalla lista dei blocchi liberi.
I vantaggi di PagedAttention
- Efficienza della memoria: Riduce drasticamente la frammentazione interna e quasi elimina quella esterna. Quasi tutta la memoria disponibile può essere utilizzata per i dati reali.
- Batching massiccio: Poiché la memoria è gestita in modo molto più efficiente, è possibile caricare molte più richieste contemporaneamente (batching) sulla stessa GPU.
- Condivisione della memoria (Copy-on-Write): PagedAttention permette a più sequenze di condividere gli stessi blocchi di memoria (ad esempio, durante il prompt engineering o il fine-tuning con istruzioni comuni), risparmiando ulteriormente spazio.
Conclusione
Senza il KV Cache, l'inferenza degli LLM sarebbe troppo lenta per essere utilizzata in applicazioni reali. Tuttavia, il KV Cache da solo crea un enorme problema di gestione della memoria.
PagedAttention rappresenta un salto tecnologico fondamentale, trasformando il modo in cui la memoria viene gestita e permettendo ai modelli di linguaggio di scalare in modo efficiente, servendo più utenti con meno risorse hardware.
Per approfondire le ultime novità sull'IA, unisciti alla nostra community: https://t.me/GyaanSetuAi
Source: https://dev.to/tech_nuggets/kv-cache-and-pagedattention-what-they-do-and-why-they-matter-jce