GGUF: il formato che fa stare i modelli sul tuo hardware

Hai scaricato un file con l'estensione .gguf — probabilmente da Hugging Face — e l'hai trascinato in Ollama, LM Studio o llama.cpp. Funziona. Ma cosa c'è davvero dentro quel file? Perché un solo file, di pochi GB, contiene un modello che in origine occupava centinaia di gigabyte? In questo articolo apri la "scatola": capisci cosa contiene un file .gguf, perché è un formato pensato apposta per l'inferenza locale, come si legge un nome file e come scegliere la dimensione giusta per la tua memoria.
Se ti interessa il "perché" numerico della compressione — cosa fa la quantizzazione e dove perde qualità — ti rimando all'articolo su Quantizzazione. Qui parliamo del contenitore, non della matematica.
Cosa c'è dentro un file .gguf
GGUF sta per "GGML Unified Format". È il formato di file standard in cui i modelli per l'inferenza locale vengono distribuiti oggi: un unico file binario che racchiude tutto ciò che serve per caricare ed eseguire il modello. Il nome deriva dal motore GGML, su cui si basano llama.cpp e la gran parte degli strumenti di inferenza locale.
GGUF è il successore di tre formati precedenti (GGML senza versione, GGMF e GGJT). La scelta è guidata da un requisito preciso: essere non ambiguo, cioè contenere tutte le informazioni necessarie per caricare il modello, e estendibile, cioè poterci aggiungere nuove informazioni in futuro senza rompere i file già esistenti.
Il file è organizzato in tre blocchi, uno dopo l'altro:
- L'intestazione (header). Comincia con una firma di 4 byte che contiene la scritta
GGUF(i byte0x47 0x47 0x55 0x46, letti come un numero intero in little-endian danno0x46554747). È il "salto in testa" che dice al programma: "sì, questo è un file GGUF". Seguono la versione del formato (oggi3, che ha introdotto anche il supporto big-endian), il numero di tensor nel file e il numero di coppie chiave-valore di metadati. - I metadati e l'indice dei tensor. I metadati sono coppie chiave-valore tipizzate: nome del modello, architettura, lunghezza di contesto, dimensione delle testate di attenzione, tokenizer e molto altro. Subito dopo c'è l'elenco dei tensor: per ognuno, nome, dimensioni, tipo di dati e offset (dove inizia nei dati grezzi).
- I dati grezzi dei tensor. Il corpo vero del file: tutti i pesi, già nella loro rappresentazione finale (punto flottante o quantizzata), disposti in modo da poter essere caricati con un semplice accesso alla memoria.
Un dettaglio che conta in pratica: il file usa un allineamento globale (di default 32 byte) e ogni tensor inizia a un offset multiplo di quell'allineamento. Questo non è un vezzo: è esattamente ciò che serve al sistema operativo per caricare il file in modo efficiente, come vedrai sotto.
Perché un solo file conta
Tre proprietà rendono GGUF il formato giusto per l'uso locale:
- Tutto in un file. Non serve un file di configurazione a parte, un tokenizer separato o una cartella di pesi. Apri il
.ggufe hai il modello completo, pronto. Per distribuirlo basta una copia; per caricarlo basta un percorso. - Compatibile con
mmap.mmap("memory map") è il meccanismo con cui il sistema operativo associa un file alla memoria del programma senza caricarlo tutto in una volta. Grazie all'allineamento dei tensor,llama.cpppuò caricare un modello di decine di GB semplicemente "mappandolo": il caricamento è quasi istantaneo e la memoria si usa solo per le parti che servono davvero. Questo è uno dei motivi per cui un modello quantizzato si avvia in pochi secondi anche su un disco lento. - Estendibile. Le nuove versioni di GGUF possono aggiungere metadati o tipi di tensor senza invalidare i file vecchi. Un file
.ggufche scarichi oggi resterà leggibile dagli strumenti di domani.
I tensor e i tipi di quantizzazione
Ogni tensor ha un tipo, che dice come i suoi pesi sono rappresentati in memoria. Ci sono i tipi "classici" in punto flottante (F16, BF16) e una famiglia di tipi quantizzati: Q8_0, Q4_K_M, Q5_K_M, Q6_K e via dicendo, fino a formati molto recenti a 4 bit come MXFP4. Il tipo è un numero; il formato lo registra per ogni tensor, così il lettore sa esattamente come decodificarlo.
Quanto pesa davvero ogni tipo? La tabella sotto è la misurazione ufficiale di llama.cpp per un modello da circa 8 miliardi di parametri (Llama 3.1 8B). Righe = tipo, colonne = bit per peso e dimensione in GiB:
| Tipo | Bit/peso | Dimensione (GiB) |
|---|---|---|
| Q4_K_M | 4.89 | 4.58 |
| Q5_K_M | 5.70 | 5.33 |
| Q6_K | 6.56 | 6.14 |
| Q8_0 | 8.50 | 7.95 |
| F16 | 16.00 | 14.96 |
Leggi così: un modello 8B a piena precisione (F16) occupa circa 15 GiB; nello stesso file, allo stesso modello, quantizzato a Q4_K_M, occupa 4.58 GiB. È la stessa rete di pesi, impacchettata in meno bit. I numeri esatti per i modelli da 70B e 405B sono utili quando ti sposti su dimensioni grandi: per Llama 3.1, il file originale passa da 280.9 GB a 43.1 GB in Q4_K_M, e da 1625.1 GB a 249.1 GB per il modello da 405B.
Come si legge il nome di un file .gguf
I file .gguf seguono una convenzione sui nomi pensata per essere letta a colpo d'occhio, composta da pezzi separati da trattini. L'ordine tipico è: NomeModello-Dimensione-Finetune-Versione-Quantizzazione[-Tipo][-Frammento]. Un esempio reale:
Llama-3.1-8B-Instruct-v2.0-Q4_K_M.gguf
Llama-3.1— il modello base8B— la classe di parametri (8 miliardi)Instruct— il fine-tune (modello istruito per seguire le istruzioni)v2.0— la versioneQ4_K_M— l'encoding, cioè il livello di quantizzazione
Quando un modello è troppo grande per un solo file, viene diviso in frammenti (shard) con la notazione -00001-of-00005: il primo di cinque, il secondo di cinque, e così via. In quel caso i file vanno tutti nella stessa cartella e lo strumento li carica insieme.
Come scegliere la dimensione per la tua memoria
La regola pratica che lega questo formato al tuo hardware: la dimensione del file in GiB, più una scorta per la cache di contesto e per il sistema operativo, deve stare dentro la memoria di cui disponi. Per una GPU, "disponi" significa la VRAM; per una CPU, la RAM.
Parti dal modello che ti interessa e dal tipo che ti serve (di solito Q4_K_M è il punto di partenza sensato). Poi fai due conti:
- 8B in Q4_K_M ≈ 4.58 GiB di file. Con un contesto medio, entra comodamente in una GPU da 8 GB.
- 70B in Q4_K_M ≈ 43.1 GiB di file. Serve memoria molto più grande, oppure un mix CPU+GPU che distribuisce i tensor.
- 405B in Q4_K_M ≈ 249.1 GiB di file. Territorio workstation, non consumer.
La buona notizia: perché il formato registra ogni tensor per nome e per tipo, gli strumenti di inferenza possono spargere i tensor tra GPU e CPU — i layer che stanno in VRAM in GPU, gli altri in RAM — e il file resta unico. È il motivo per cui un modello più grande della tua VRAM può comunque girare, solo un po' più lento.
Come si arriva a un .gguf
Due strade, entrambe comuni. La prima è la più pratica: scarichi il file già pronto da un repository su Hugging Face (molte organizzazioni pubblicano la famiglia di quantizzazioni del loro modello, e lo spazio ufficiale ggml-org permette persino di costruirti un quant su misura). La seconda, per chi vuole farlo da sé, è in due fasi: si converte il modello originale in formato GGUF ad alta precisione (con convert_hf_to_gguf.py), e poi si applica la quantizzazione con llama-quantize, scegliendo il tipo di output. In entrambe i casi il risultato è quello stesso file .gguf che hai trascinato nel tuo strumento.
In sintesi
- Un file
.ggufè tutto in un file: pesi, metadati e tokenizer, pronti per l'inferenza locale. - L'intestazione porta la firma
GGUF, la versione, il numero di tensor e di metadati; i tensor sono allineati per il caricamento rapido viammap. - Ogni tensor ha un tipo (F16, Q8_0, Q4_K_M, …) che determina quanto pesa il file: per un modello 8B, da 14.96 GiB a F16 a 4.58 GiB a Q4_K_M.
- Il nome file si legge a colpo d'occhio: modello, dimensione, fine-tune, versione, quantizzazione, eventuale frammento.
- Per scegliere: dimensione del file + cache di contesto + sistema, dentro la tua VRAM o RAM. Il formato permette di spargere i tensor tra GPU e CPU.
Fonti e lettura approfondita: Specifiche ufficiali GGUF e guida alla quantizzazione di llama.cpp, che contiene i numeri esatti di dimensione per tipo.
Articolo generato con IA
In questi percorsi
Ti è piaciuto questo articolo?
Iscriviti alla newsletter per ricevere nuovi tutorial e guide.
Articoli Correlati

Nemotron-Parse: la famiglia OCR di NVIDIA per leggere i documenti in locale
NVIDIA ha rieditato Nemotron Parse (v1.1, v1.2, 2.0) nella stessa settimana del 20 ottobre: meno di 1 miliardo di parametri, struttura della pagina inclusa. Setup in locale con vLLM e limiti onesti.

MiniCPM-V 4.7: il MoE da 35B che gira sullo smartphone con 3 GB di RAM
Il primo MoE open da 35B (3B attivi) che gira fluido su smartphone: 13+ tok/s con 3 GB di RAM su iPhone 17 Pro Max, OCR, video e GGUF Q4_K_M da 21,8 GB per il desktop. I numeri, le tre tecniche e i limiti.

