Skip to content
AImpact
IT EN

Article · Technical guide

Quantizzazione e GGUF — Come Ridurre i LLM per l'Inferenza Locale

Original source: llama.cpp — Georgi Gerganov (GitHub) — summary and rework in own words.

ShareLinkedInX

Cos'è: La quantizzazione è la tecnica che permette di ridurre la precisione numerica dei pesi di un modello neurale — da 32 bit per parametro fino a 4 o meno — con perdita qualitativa controllata. GGUF è il formato file standard nato dall'ecosistema llama.cpp che ha reso l'inferenza locale di LLM praticamente accessibile su qualsiasi hardware consumer.

Il Problema Fondamentale: la RAM è il collo di bottiglia

Un Large Language Model è, nella sua forma più essenziale, una collezione enorme di numeri in virgola mobile: i pesi della rete neurale. Per eseguire inferenza — generare token — questi pesi devono essere caricati interamente in memoria (VRAM per GPU, RAM per CPU). Un modello da 7 miliardi di parametri in precisione piena FP32 occupa 28 GB (7B × 4 byte). Una GPU consumer RTX 4090 ha 24 GB di VRAM. Il calcolo è immediato: il modello non ci sta.

La quantizzazione risolve questo problema riducendo il numero di bit usati per rappresentare ogni peso. Il tradeoff è tra dimensione/velocità da un lato e qualità dell'output dall'altro. La sfida tecnica è minimizzare la degradazione qualitativa per ogni bit risparmiato.

La Scala della Precisione: FP32 → FP16 → INT8 → INT4

FP32 (float32, 32 bit/parametro) è la precisione usata in fase di training. Ogni peso è un numero IEEE 754 a virgola mobile a singola precisione: 1 bit di segno, 8 di esponente, 23 di mantissa. È il formato di riferimento per la qualità massima, ma anche il più pesante.

FP16 (float16, 16 bit/parametro) dimezza la memoria con perdita di qualità trascurabile in inferenza. È il formato standard per GPU moderne (A100, H100, RTX 30/40 series) e praticamente tutti i framework di deep learning lo usano come default per l'inferenza. Un modello 7B in FP16 occupa 14 GB.

INT8 (8 bit/parametro) porta il modello 7B a 7 GB. A questo livello la quantizzazione non è più banale: i pesi float vengono mappati su interi a 8 bit tramite un fattore di scala. Tecniche come LLM.int8() di Tim Dettmers usano la quantizzazione mista — la maggior parte dei pesi in INT8, ma le colonne con outlier numerici in FP16 — per preservare la qualità su modelli di grandi dimensioni.

INT4 (4 bit/parametro) porta il modello 7B a circa 3.5–4 GB. A 4 bit i valori possibili sono solo 16 per ogni peso. Tecniche avanzate come GPTQ (Group-wise Post-Training Quantization) e AWQ (Activation-aware Weight Quantization) ottimizzano il processo di quantizzazione minimizzando l'errore di ricostruzione, raggiungendo qualità sorprendentemente vicina all'FP16 su molti benchmark.

GGUF: il Formato che ha Democratizzato l'Inferenza Locale

GGUF (GGML Unified Format) è il formato file sviluppato da Georgi Gerganov per il progetto llama.cpp, scritto interamente in C/C++ senza dipendenze da framework pesanti come PyTorch o TensorFlow. È il successore di GGML (deprecato a agosto 2023) e risolve i problemi di estensibilità del predecessore.

Un file GGUF è self-contained: contiene i pesi quantizzati, i metadati del modello (architettura, tokenizer, parametri di sampling), e informazioni sul livello di quantizzazione usato. Questo significa che un singolo file è tutto il necessario per eseguire inferenza — nessuna configurazione aggiuntiva, nessun download separato del tokenizer.

L'importanza di llama.cpp e GGUF è difficile da sovrastimare: ha reso possibile eseguire modelli come LLaMA, Mistral, Gemma, Phi direttamente su MacBook, PC Windows senza GPU dedicata, e persino dispositivi mobili. L'integrazione con Ollama, LM Studio e Jan usa GGUF come formato sottostante, rendendo l'inferenza locale accessibile a utenti non tecnici.

I Livelli di Quantizzazione Spiegati: Q4_K_M, Q5_K_M, Q8_0

La nomenclatura dei file GGUF segue una convenzione specifica. Prendendo Q4_K_M come esempio: Q4 indica 4 bit per peso; K indica che usa il metodo "k-quants" (quantizzazione per gruppo con scale factor separato, più precisa della INT4 lineare); M indica la dimensione della variante (S=small, M=medium, L=large) che controlla il tradeoff tra dimensione e qualità.

  • Q4_K_S: il più piccolo tra i Q4, aggressivo nella compressione. Qualità degradata su task complessi.
  • Q4_K_M: il punto dolce per la maggior parte degli use case. Buona qualità, dimensione contenuta. Per un 7B: ~4.1 GB.
  • Q5_K_M: 5 bit per peso, qualità molto vicina a FP16 su quasi tutti i benchmark. Per un 7B: ~5.0 GB. La scelta raccomandata quando si ha abbastanza RAM.
  • Q8_0: 8 bit lineari, qualità praticamente indistinguibile da FP16 in uso reale. Per un 7B: ~7.7 GB. Usato quando la precisione è critica e la memoria lo permette.
  • Q2_K: 2 bit, estrema compressione. Qualità significativamente degradata, adatto solo per test su hardware molto limitato.

Hardware Reale: cosa si può girare e con quale velocità

Le regole pratiche per l'inferenza locale nel 2024:

  • 8 GB VRAM (RTX 3070/4060 Ti): modelli 7B in Q4_K_M completi in VRAM. Velocità: 40–80 token/s. Modelli 13B parzialmente offloaded su CPU con rallentamento significativo.
  • 16 GB VRAM (RTX 3080/4080): modelli 13B in Q4_K_M completamente in VRAM (velocità: 30–60 t/s). Modelli 7B in Q8_0 agevolmente.
  • 24 GB VRAM (RTX 3090/4090): modelli 13B in Q8_0, modelli 34B in Q4_K_M. Il 4090 è la scelta più efficiente in assoluto per inferenza locale.
  • Apple M2 Pro / M3 Pro (18–36 GB RAM unificata): l'architettura unified memory è un vantaggio enorme. M2 Pro 32GB può girare LLaMA 70B Q4_K_M a 5–10 t/s — lento ma funzionale. M3 Max 96GB gestisce comodamente modelli fino a 70B in Q5.
  • CPU-only (RAM sistema): possibile ma lento. Un Llama 7B Q4 su i9-13900K produce ~5–8 t/s — usabile per applicazioni non real-time.

bfloat16 merita una menzione separata: è un formato a 16 bit con la stessa gamma dinamica di FP32 (8 bit di esponente) ma con mantissa ridotta a 7 bit. GPU NVIDIA dalla A100 in poi lo supportano nativamente in hardware (le serie RTX consumer no). È il formato di training preferito per i modelli moderni — più stabile di FP16 per i gradienti — ma per l'inferenza consumer rimane FP16 o quantizzazione la scelta pratica.

Impatto sui Benchmark: quanto si perde davvero?

I benchmark MMLU, HellaSwag e ARC mostrano pattern consistenti: da FP16 a Q8_0 la perdita è sotto 0.5 punti percentuali — statisticamente irrilevante. Da FP16 a Q4_K_M la perdita è tipicamente 1–3 punti su MMLU — percepibile ma raramente impattante in uso reale. Da FP16 a Q2_K la perdita può superare i 10 punti — visibilmente peggiore su task complessi di reasoning.

La degradazione è asimmetrica: colpisce di più task che richiedono precisione numerica e logica formale, meno la generazione creativa e la riformulazione. Per la stragrande maggioranza degli use case pratici, Q4_K_M o Q5_K_M rappresentano il punto ottimale dove il costo della riduzione di qualità è ampiamente ripagato dalla praticità dell'esecuzione locale.


Link alla fonte originale

llama.cpp — Georgi Gerganov (GitHub) →

Repository principale di llama.cpp con documentazione tecnica sui livelli di quantizzazione, script di conversione da safetensors/PyTorch a GGUF, e benchmark aggiornati su diverso hardware. I file GGUF dei modelli principali sono disponibili su Hugging Face nel profilo TheBloke e bartowski.