Torna al blog AI Infrastructure

Come stimare la memoria GPU per l’inferenza LLM self-hosted

Stima i pesi del modello, la cache KV, la concorrenza e l’overhead del runtime, quindi verifica i calcoli con un carico di inferenza rappresentativo prima di scegliere l’infrastruttura GPU.

Diagramma che mostra come pesi del modello, cache KV, richieste concorrenti e overhead del runtime contribuiscono all’uso della memoria GPU

Perché la dimensione del modello, da sola, non determina la memoria GPU necessaria

Il numero di parametri di un modello offre una prima stima utile, ma non costituisce un budget completo della memoria GPU. Durante l’inferenza serve memoria anche per la cache key-value (KV) e per le attivazioni, mentre il runtime, l’architettura del modello e la configurazione del servizio possono influire sull’uso effettivo. Una scomposizione di queste componenti è descritta nello [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator).

Un modello che entra in memoria al caricamento può comunque superare la memoria disponibile quando arrivano le richieste. Le sequenze più lunghe e un maggior numero di richieste attive aumentano il fabbisogno della cache KV. Anche altri carichi di lavoro GPU e l’overhead del runtime competono per la memoria.

Considera ogni calcolo una stima per la pianificazione, non una garanzia sull’hardware. Lo strumento di stima citato segnala che il metodo è euristico, è limitato alle architetture transformer standard e può variare nella pratica. Il risultato dipende dal modello specifico, dal runtime di inferenza e dalla configurazione del servizio.

  • Stima separatamente i pesi e la cache KV.
  • Descrivi il carico di lavoro, incluse le lunghezze delle sequenze e la concorrenza, prima di confrontare le stime con la memoria GPU disponibile.
  • Verifica la configurazione pianificata nell’ambiente di distribuzione previsto, senza basarti soltanto sul nome o sul numero di parametri del modello.
Perché la dimensione del modello, da sola, non determina la memoria GPU necessaria

Stima la memoria dei pesi del modello, tenendo conto della quantizzazione

Per una prima stima, moltiplica il numero di parametri del modello per i byte utilizzati per parametro. Una corrispondenza approssimativa comune è: FP32 a 4 byte, FP16 a 2 byte, INT8 a 1 byte e INT4 a 0,5 byte per parametro. La formula e queste corrispondenze sono riportate nello [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator).

Per esempio, un ipotetico modello da 8 miliardi di parametri avrebbe una stima teorica dei pesi di 16 GB con 2 byte per parametro, 8 GB con 1 byte oppure 4 GB con 0,5 byte. Sono stime aritmetiche in unità decimali e riguardano soltanto i pesi; non includono la cache KV, le attivazioni o le esigenze del runtime.

La quantizzazione può ridurre la memoria occupata dai pesi usando meno bit per parametro, ma la stima non descrive in modo completo il modello distribuito. Verifica il formato effettivo del modello e il runtime e considera i compromessi in termini di precisione per decidere se una configurazione quantizzata è adatta. Per una panoramica del compromesso tra bit usati per i pesi e precisione, consulta il tutorial [Hardware & VRAM Budgeting](https://github.khronos.org/Vulkan-Site/tutorial/latest/AI_Assisted_Vulkan/03_model_selection_specialization/03_hardware_vram.html) di Khronos.

  • Annota il numero di parametri e il formato di precisione o quantizzazione che intendi usare per il servizio.
  • Calcola i pesi come: numero di parametri × byte per parametro.
  • Mantieni coerenti le unità: i GB decimali e i GiB binari sono unità diverse e gli strumenti GPU possono riportare la memoria in modi differenti.
  • Non considerare il risultato come la memoria totale necessaria per gestire le richieste.
Stima la memoria dei pesi del modello, tenendo conto della quantizzazione

Tieni conto della lunghezza del contesto e della cache KV

Durante l’inferenza, la cache KV memorizza i dati di chiavi e valori relativi ai token delle sequenze attive. Il suo consumo di memoria dipende dalla dimensione del batch, dalla lunghezza della sequenza, dal numero di layer, dal numero di teste KV, dalla dimensione della testa e dai byte per elemento della cache.

Una stima utile è: byte della cache KV = 2 × dimensione del batch × lunghezza della sequenza × numero di layer × numero di teste KV × dimensione della testa × byte per elemento della cache. Il fattore 2 rappresenta chiavi e valori. Questa formula e le sue variabili sono riportate nello [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator); si tratta di una stima, non di una misura del consumo effettivo di uno specifico runtime.

Consideriamo un esempio esplicitamente ipotetico: supponiamo che una configurazione abbia 32 layer, 8 teste KV, una dimensione della testa di 128, elementi della cache da 2 byte, una sequenza di 4.096 token e una dimensione del batch pari a 1. La formula restituisce 536.870.912 byte, ovvero circa 0,5 GiB. Con un batch di dimensione 4 e tutte le altre ipotesi invariate, la stima è di circa 2 GiB. Questi valori servono solo a illustrare il calcolo e non descrivono un modello specifico.

Per la pianificazione, usa la lunghezza della sequenza che il runtime potrebbe mantenere in memoria in un dato momento, includendo sia i token del prompt sia quelli generati. Un limite di contesto elevato non significa che ogni richiesta lo sfrutterà per intero, ma le richieste con sequenze vicine alla lunghezza massima possono determinare il picco di fabbisogno della cache.

  • Cerca il numero di layer del modello, il numero di teste KV e la dimensione della testa nella documentazione o nella configurazione del modello.
  • Usa il tipo di dati della cache e il comportamento del servizio previsti per il runtime scelto.
  • Stima sia le lunghezze tipiche delle sequenze sia quelle massime che prevedi di gestire.
  • Se il modello usa l’attenzione a query raggruppate (grouped-query attention), usa il numero di teste KV invece di presumere che corrisponda al numero di teste di query.

Considera richieste concorrenti, batching e carichi di lavoro GPU condivisi

La formula della cache KV cresce sia con la dimensione del batch sia con la lunghezza della sequenza. Di conseguenza, diverse richieste attive possono richiedere molta più cache di una sola, soprattutto quando hanno contesti lunghi. Questa dipendenza da batch e lunghezza è parte della formula proposta dallo [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator).

Concorrenza e dimensione del batch sono correlate, ma non vanno considerate intercambiabili senza verificare la configurazione del servizio. Un server può raggruppare le richieste in batch o gestire le sequenze attive in altri modi. Basa la stima sul comportamento previsto per il runtime effettivo.

Tieni conto anche di tutto ciò che usa la GPU. Un altro processo o modello può consumare memoria che altrimenti sarebbe disponibile per l’inferenza. La frammentazione della memoria e le scelte relative al runtime possono inoltre determinare se una configurazione che sembra rientrare nei limiti sulla carta funzionerà nella pratica; il [planner delle risorse LLM](https://pypi.org/project/llm-resource-planner/) elenca questi fattori tra le possibili cause di variazione.

  • Annota il numero medio e il picco previsto di richieste attive, non soltanto il volume giornaliero delle richieste.
  • Includi le lunghezze delle sequenze associate a quelle richieste attive.
  • Verifica se il batching è abilitato e in che modo il runtime di servizio gestisce richieste con lunghezze di sequenza diverse.
  • Elenca gli altri processi e carichi di lavoro GPU che potrebbero sovrapporsi all’inferenza.

Includi l’overhead del runtime e dell’hardware senza presumere una quota fissa

Non esiste un overhead fisso universalmente affidabile da aggiungere a ogni stima. Il consumo effettivo di memoria può variare in base al motore di inferenza, alle ottimizzazioni del runtime, alla strategia di batching, all’architettura del modello e alla frammentazione della memoria. Questi fattori sono descritti anche dal [planner delle risorse LLM](https://pypi.org/project/llm-resource-planner/), che non stabilisce una quota universale applicabile a ogni configurazione.

Invece di aggiungere una percentuale arbitraria e considerare definitivo il risultato, tratta l’overhead come un’incognita da misurare. Parti dai calcoli dei pesi e della cache, poi confrontali con l’uso osservato nel runtime e sotto il carico previsti.

Controlla la memoria effettivamente utilizzabile della GPU così come viene riportata nell’ambiente in cui sarà eseguito il servizio. La capacità nominale non indica quanta memoria resterà disponibile dopo le allocazioni del runtime e degli altri carichi di lavoro.

  • Documenta il motore di inferenza, la configurazione del modello e le impostazioni del servizio usati per la stima.
  • Individua i carichi di lavoro che condivideranno la GPU e verifica se verranno eseguiti contemporaneamente.
  • Non presentare un margine di sicurezza non testato come requisito universale.
  • Usa i risultati dei test per definire un margine operativo adeguato al tuo carico di lavoro.

Definisci il profilo del carico di lavoro prima di scegliere l’infrastruttura

Una stima utile parte dalla descrizione del carico di lavoro, non soltanto dal nome del modello. Raccogli i dettagli architetturali necessari per calcolare la cache, la precisione dei pesi e le lunghezze e il livello di concorrenza che il servizio deve gestire. Le variabili del calcolo della cache e le assunzioni su sequenza e batch sono elencate nello [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator).

Distingui l’uso tipico dai picchi. Se il sistema gestisce richieste diverse, una singola lunghezza media delle sequenze può nascondere il fabbisogno di memoria dei prompt lunghi o di più richieste lunghe simultanee. Prova sia un pattern rappresentativo sia il caso massimo credibile che devi supportare.

  • Modello: numero di parametri, dettagli architetturali necessari per la formula della cache KV e precisione o quantizzazione dei pesi.
  • Prompt: lunghezza tipica e massima del prompt in token.
  • Output: lunghezza prevista e massima dei token generati.
  • Sequenza: lunghezza complessiva del prompt e dell’output che il runtime potrebbe dover mantenere in memoria.
  • Servizio: numero tipico e massimo previsto di richieste attive, comportamento del batch e impostazioni pertinenti del runtime.
  • Ambiente: memoria GPU disponibile per il processo ed eventuali altri carichi di lavoro che condividono la GPU.

Verifica la stima con un test rappresentativo

Esegui il modello effettivo con il runtime di inferenza e la configurazione del servizio previsti prima di fare affidamento sulla stima. Inizia con un carico di lavoro normale, quindi prova le sequenze più lunghe e il livello di concorrenza più elevato che rappresentano il picco previsto. Lo [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator) raccomanda di testare i modelli effettivi e monitorare l’uso della memoria nelle distribuzioni reali.

Osserva la memoria GPU durante il caricamento del modello e mentre le richieste sono attive. Registra la configurazione insieme alle misurazioni, così che i risultati siano utili quando cambierai modello, limiti del contesto, quantizzazione, runtime o batching.

Il successo di una singola richiesta non dimostra che il sistema possa gestire il carico di picco. Ripeti il test con richieste concorrenti rappresentative e analizza eventuali aumenti imprevisti del consumo di memoria o errori prima di considerare pronta la configurazione.

  • Prova lo stesso formato del modello, la stessa precisione, lo stesso runtime e le stesse impostazioni previsti per la distribuzione.
  • Includi lunghezze realistiche di prompt e output, poi prova il livello massimo di concorrenza previsto.
  • Monitora il consumo effettivo di memoria durante il caricamento e la gestione delle richieste, non soltanto all’avvio.
  • Ripeti le misurazioni dopo modifiche sostanziali al modello o alla configurazione del servizio.

Quando il carico di lavoro supera la memoria GPU disponibile

Per prima cosa, individua quale componente del carico di lavoro causa l’eccesso. Se il problema sono le sequenze lunghe, ridurre la lunghezza del contesto o limitare le richieste eccezionalmente lunghe può ridurre il fabbisogno della cache KV, che nella formula cresce con la lunghezza della sequenza. Se prevalgono i pesi del modello, la quantizzazione può ridurre la memoria dei pesi, ma occorre valutare il compromesso in termini di precisione per il modello e l’attività. Questi effetti generali sono coerenti con la formula dello [strumento di stima](https://github.com/david-xinyuwei/llm-memory-estimator) e con la panoramica di Khronos sulla [quantizzazione e il budget VRAM](https://github.khronos.org/Vulkan-Site/tutorial/latest/AI_Assisted_Vulkan/03_model_selection_specialization/03_hardware_vram.html).

Altre possibilità sono ridurre il picco di concorrenza o modificare la configurazione del servizio. Ogni scelta cambia il comportamento del servizio: verifica quindi che i limiti del contesto, la gestione delle richieste e la qualità dell’output restino compatibili con i requisiti dell’applicazione.

Se queste modifiche non soddisfano le esigenze del carico di lavoro, rivaluta la capacità GPU o la progettazione della distribuzione. Non presumere che lo scaricamento su altre risorse, una specifica impostazione del runtime o una determinata GPU risolvano il problema senza test: le stime fornite non definiscono una raccomandazione hardware universale.

Dopo ogni modifica, ripeti il test con un carico rappresentativo. Una configurazione che rientra nei limiti con concorrenza o contesto ridotti deve comunque soddisfare i requisiti effettivi dell’applicazione.

  • Riduci la lunghezza del contesto se il carico di lavoro può tollerare prompt o output più brevi.
  • Valuta la quantizzazione dei pesi, verificandone il compromesso in termini di precisione per il tuo caso d’uso.
  • Riduci il numero massimo di richieste concorrenti o modifica il batching, quindi verifica l’effetto sul servizio.
  • Se il carico di lavoro richiesto continua a non rientrare nella memoria disponibile, confronta le opzioni di distribuzione sulla base di risultati misurati, non di un calcolo limitato ai pesi.

Domande frequenti

Il numero di parametri del modello basta per stimare la memoria GPU?

No. Il numero di parametri e la precisione dei pesi consentono una prima stima della memoria occupata dai pesi del modello. L’inferenza richiede memoria anche per la cache KV e le attivazioni, mentre runtime, architettura e configurazione del servizio influenzano l’uso effettivo. Lo [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator) descrive questa scomposizione, ma la stima non sostituisce una misurazione sul carico effettivo.

In che modo la lunghezza del contesto influisce sulla memoria GPU?

Il fabbisogno della cache KV cresce con la lunghezza della sequenza. Prompt e sequenze generate più lunghi possono quindi usare più memoria; l’effetto aumenta con il numero di sequenze attive. La formula e le variabili sono riportate nello [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator).

La quantizzazione riduce il fabbisogno di memoria GPU?

Può ridurre la memoria occupata dai pesi usando meno bit per parametro. Non elimina le esigenze della cache KV o del runtime e comporta un compromesso in termini di precisione, che va valutato per il modello e l’attività previsti. Per il rapporto generale tra quantizzazione e precisione, consulta il tutorial [Hardware & VRAM Budgeting](https://github.khronos.org/Vulkan-Site/tutorial/latest/AI_Assisted_Vulkan/03_model_selection_specialization/03_hardware_vram.html) di Khronos.

Quanta memoria GPU aggiuntiva dovrei riservare per l’overhead del runtime?

Non esiste una quota fissa universale valida per ogni modello e runtime. Misura la memoria con il motore di inferenza, il modello e la configurazione del servizio previsti, includendo richieste concorrenti rappresentative e altri carichi di lavoro GPU. Il [planner delle risorse LLM](https://pypi.org/project/llm-resource-planner/) elenca fattori di variazione come runtime, batching e frammentazione.

Qual è il modo migliore per verificare una stima della memoria GPU?

Prova il modello e il runtime effettivi con lunghezze realistiche di prompt e output, quindi ripeti il test al livello massimo di concorrenza previsto monitorando la memoria. Registra le impostazioni e ripeti il test quando cambiano. Lo [strumento di stima della memoria per l’inferenza LLM](https://github.com/david-xinyuwei/llm-memory-estimator) raccomanda di provare i modelli effettivi e monitorarne l’uso della memoria.

Fonti e approfondimenti

  1. LLM Inference Memory Estimation Tool — GitHub project
  2. llm-resource-planner — Python Package Index
  3. SelfHostLLM GPU Memory Calculator — GitHub project
  4. Hardware & VRAM Budgeting — Khronos Group