Programma
La quantizzazione è uno dei modi più pratici per eseguire grandi modelli linguistici su GPU consumer. Invece di usare pesi ad alta precisione che richiedono molta VRAM, possiamo usare modelli compressi a 4 bit che entrano in GPU come la NVIDIA RTX 4090. I modelli Gemma di Google fanno parte di questa spinta crescente per rendere più facile eseguire in locale potenti AI open.
In questo tutorial eseguiremo Gemma 4 12B in locale con llama.cpp e confronteremo la versione base del modello con un’altra versione messa a punto usando il Quantization-Aware Training (QAT).
Assicurati di leggere anche gli altri nostri tutorial sul modello di Google, Costruire un agente AI con Gemma 4 e Ollama, e Come fare fine-tuning di Gemma 4.
Cos'è la quantizzazione?
La quantizzazione è una tecnica di compressione dei modelli che riduce la precisione dei pesi.
I grandi modelli linguistici sono di solito archiviati in formati ad alta precisione come BF16 o FP16, che preservano la qualità ma richiedono molta memoria. La quantizzazione converte quei pesi in formati a meno bit, come 8 bit o 4 bit, così il modello usa meno VRAM e gira più facilmente in locale. Hugging Face osserva che la quantizzazione a 8 bit può dimezzare circa l’uso di memoria, mentre quella a 4 bit può ridurla ancora di più.
Il compromesso è che la minore precisione può talvolta ridurre la qualità dell’output, specialmente se il modello non è stato ottimizzato per la quantizzazione. In parole semplici, BF16 e FP16 in genere offrono la migliore qualità ma usano più memoria; i modelli a 8 bit sono più piccoli mantenendo spesso una buona qualità, e quelli a 4 bit sono molto più piccoli ma possono perdere un po’ di accuratezza o stabilità.
Per l’inferenza locale, questo compromesso spesso vale la pena perché permette di eseguire modelli più grandi su GPU consumer invece di richiedere costoso hardware da data center.
Cos'è il Quantization Aware Training?
Il Quantization-Aware Training (QAT) è una tecnica di training in cui il modello viene addestrato o messo a punto simulando il comportamento a bassa precisione. Questo aiuta il modello a rimanere più stabile dopo la quantizzazione e può migliorare le prestazioni di inferenza locale a bassi bit-width.
Cosa rende diverso il QAT?
L’approccio più comune, la quantizzazione post-training, comprime un modello dopo che è già stato addestrato. È semplice e pratico, ma il modello può perdere un po’ di qualità perché non è stato addestrato a gestire pesi a bassa precisione.
Secondo la documentazione di Google AI Edge, la quantizzazione post-training è un passaggio di conversione che può ridurre la dimensione del modello e migliorare la latenza, di solito con una perdita di accuratezza minima. Tuttavia, la qualità finale può comunque dipendere dal modello e dal livello di quantizzazione.
Il Quantization-Aware Training, o QAT, adotta un approccio diverso. Invece di quantizzare solo dopo l’addestramento, il QAT simula il comportamento a bassa precisione durante il training o il fine-tuning. Questo aiuta il modello a imparare come rimanere stabile quando viene poi convertito in un formato più piccolo. Minimizza la perdita di qualità quando il modello viene compresso.

Ecco perché Gemma 4 QAT è utile per l’AI locale. È costruito tenendo presente la quantizzazione, così può mantenere più qualità del modello originale usando meno memoria. Per chi esegue modelli su GPU consumer, questo può significare maggiore stabilità a pochi bit, minore uso di VRAM e un’inferenza locale più pratica.
Passo 1: installa le dipendenze e compila llama.cpp
Prima di scaricare i modelli, dobbiamo preparare il runtime locale. Questo tutorial è stato testato su una macchina con GPU NVIDIA RTX 4090 e 24 GB di VRAM. Useremo llama.cpp come runtime di inferenza, GGUF come formato del modello e i file del modello quantizzato UD-Q4_K_XL.
Configurazione testata:
- GPU: NVIDIA RTX 4090
- VRAM: 24 GB
- Runtime: llama.cpp
- Formato modello: GGUF
- Quantizzazione: UD-Q4_K_XL
Confronteremo i seguenti due modelli Unsloth GGUF:
- unsloth/gemma-4-12B-it-GGUF
- unsloth/gemma-4-12B-it-qat-GGUF
Per prima cosa, verifica che la tua GPU sia disponibile.
nvidia-smi

Poi, installa i pacchetti di sistema necessari per compilare llama.cpp.
apt-get update
apt-get install pciutils build-essential cmake curl libcurl4-openssl-dev -y
Clona il repository ufficiale di llama.cpp.
git clone https://github.com/ggml-org/llama.cpp
Ora compila llama.cpp con il supporto CUDA abilitato. Questo permette ai layer del modello di girare sulla GPU invece che solo sulla CPU.
cmake llama.cpp -B llama.cpp/build \
-DBUILD_SHARED_LIBS=OFF \
-DGGML_CUDA=ON
Compila i binari necessari.
cmake --build llama.cpp/build \
--config Release \
-j \
--clean-first \
--target llama-cli llama-mtmd-cli llama-server llama-gguf-split

Al termine della compilazione, il binario principale che useremo è llama-server. Ci consente di eseguire il modello GGUF in locale ed espone un endpoint API compatibile con OpenAI che possiamo interrogare con curl.
Passo 2: scarica i modelli Gemma 4 12B Non-QAT e QAT
Ora che llama.cpp è pronto, possiamo scaricare entrambe le varianti del modello Gemma 4 12B da Hugging Face. Scaricheremo il modello instruction-tuned standard e la versione QAT in formato GGUF.
Per prima cosa, installa la CLI di Hugging Face Hub con supporto ai download più veloci.
pip install -U "huggingface_hub[hf_xet]" hf-xet hf_transfer
Abilita i download Xet ad alte prestazioni.
export HF_XET_HIGH_PERFORMANCE=1
Scarica il modello Gemma 4 12B instruction standard in formato GGUF.
hf download unsloth/gemma-4-12B-it-GGUF \
--local-dir models/gemma-4-12B-it-GGUF \
--include "*mmproj-BF16*" \
--include "*UD-Q4_K_XL*"
Poi, scarica la versione QAT usando lo stesso formato di quantizzazione.
hf download unsloth/gemma-4-12B-it-qat-GGUF \
--local-dir models/gemma-4-12B-it-qat-GGUF \
--include "*mmproj-BF16*" \
--include "*UD-Q4_K_XL*"
I flag --include assicurano che scarichiamo solo i file necessari per questo tutorial, invece di prelevare l’intero repository. Qui stiamo scaricando i file del modello GGUF UD-Q4_K_XL e i file mmproj-BF16 usati dal pacchetto del modello.
Al termine dei download, conferma che entrambe le cartelle dei modelli esistano.
ls models
Output previsto:
gemma-4-12B-it-GGUF
gemma-4-12B-it-qat-GGUF
A questo punto, sia il modello non-QAT che quello QAT sono disponibili in locale, e possiamo iniziare a servirli con llama-server.
Passo 3: esegui il modello Non-QAT con llama-server
Inizieremo eseguendo il modello Gemma 4 12B instruction standard. Questo ci dà un baseline per poterlo poi confrontare con la versione QAT usando le stesse impostazioni.
Avvia il modello non-QAT con llama-server.
./llama.cpp/llama-server \
-m models/gemma-4-12B-it-GGUF/*UD-Q4_K_XL*.gguf \
--host 0.0.0.0 \
--port 8001 \
--ctx-size 8192 \
--n-gpu-layers 99 \
--temp 1.0 \
--top-p 0.95 \
--top-k 64

Questo avvia un server locale compatibile con OpenAI su http://localhost:8001.
Apri un altro terminale e invia una richiesta al server locale.
time curl http://localhost:8001/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemma-4-12B-it",
"messages": [
{
"role": "system",
"content": "You are a helpful local AI assistant."
},
{
"role": "user",
"content": "Explain why quantization-aware training is useful for running LLMs on consumer GPUs."
}
],
"temperature": 1.0,
"top_p": 0.95,
"max_tokens": 512
}'
In questo comando usiamo l’endpoint locale /v1/chat/completions, che segue il formato dell’API compatibile con OpenAI. Il prompt chiede al modello di spiegare il quantization-aware training e max_tokens è impostato a 512 per garantire che entrambe le varianti del modello vengano testate con la stessa lunghezza di output.
Nel nostro test con RTX 4090, il modello non-QAT ha prodotto i seguenti risultati di timing:
- Token del prompt: 40
- Token della risposta: 512
- Velocità prompt: 510,22 token/sec
- Velocità generazione: 94,65 token/sec
- Tempo totale: 5,516 sec
L’utilizzo della memoria GPU è stato:
9247 MiB / 24564 MiB
Questo ci fornisce le prestazioni di base per il modello Gemma 4 12B standard. Nel prossimo passo eseguiremo la versione QAT con la stessa configurazione e confronteremo i risultati.
Passo 4: esegui e testa il modello QAT
Ora eseguiremo la versione QAT di Gemma 4 12B usando le stesse impostazioni di llama-server. Assicurati di fermare il server non-QAT precedente prima di avviare questo, perché entrambi i comandi usano la stessa porta.
Avvia il modello QAT.
./llama.cpp/llama-server \
-m models/gemma-4-12B-it-qat-GGUF/*UD-Q4_K_XL*.gguf \
--host 0.0.0.0 \
--port 8001 \
--ctx-size 8192 \
--n-gpu-layers 99 \
--temp 1.0 \
--top-p 0.95 \
--top-k 64
Questo avvia il modello QAT sullo stesso endpoint locale compatibile con OpenAI, http://localhost:8001.

Ora invia lo stesso prompt di test al modello QAT.
time curl http://localhost:8001/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "gemma-4-12B-it-qat",
"messages": [
{
"role": "system",
"content": "You are a helpful local AI assistant."
},
{
"role": "user",
"content": "Explain why quantization-aware training is useful for running LLMs on consumer GPUs."
}
],
"temperature": 1.0,
"top_p": 0.95,
"max_tokens": 512
}'
Nel nostro test con RTX 4090, il modello QAT ha prodotto i seguenti risultati di timing:
- Token del prompt: 40
- Token della risposta: 512
- Velocità prompt: 593,93 token/sec
- Velocità generazione: 101,65 token/sec
- Tempo totale: 5,114 sec
L’utilizzo della memoria GPU è stato:
8627 MiB / 24564 MiB
Puoi anche copiare l’URL del server locale (http://localhost:8001) e incollarlo nel tuo browser:

Questo apre la web UI integrata di llama.cpp, che ti offre una semplice interfaccia in stile ChatGPT per testare il modello locale. Puoi usarla per chattare con il modello QAT direttamente dal browser, sperimentare con i prompt e usare il modello come assistente AI locale quotidiano.
Confronto tra QAT e Non-QAT
Dopo aver testato entrambi i modelli con lo stesso prompt e le stesse impostazioni del server, possiamo confrontarne direttamente le prestazioni sulla RTX 4090.
|
Metrica |
Gemma 4 12B Non-QAT |
Gemma 4 12B QAT |
|
Quantizzazione |
UD-Q4_K_XL |
UD-Q4_K_XL |
|
Dimensione contesto |
8192 |
8192 |
|
Token del prompt |
40 |
40 |
|
Token della risposta |
512 |
512 |
|
Velocità prompt |
510,22 token/sec |
593,93 token/sec |
|
Velocità generazione |
94,65 token/sec |
101,65 token/sec |
|
Tempo totale |
5,516 sec |
5,114 sec |
|
Uso VRAM |
9247 MiB |
8627 MiB |
In questa esecuzione, il modello QAT è risultato sia più veloce che più leggero rispetto al modello non-QAT standard. Ha usato 620 MiB di VRAM in meno, riducendo l’uso di memoria di circa 6,7%. Questo è utile per l’inferenza locale perché ogni MiB di VRAM risparmiato aiuta quando si eseguono grandi modelli su GPU consumer.
Il modello QAT ha anche generato token più velocemente, passando da 94,65 token/sec a 101,65 token/sec. Si tratta di circa un +7,4% in velocità di generazione, riducendo il tempo di wall-clock da 5,516 secondi a 5,114 secondi.
Nell’uso quotidiano, il modello QAT è parso più fluido e reattivo. Anche la qualità delle risposte è sembrata più stabile in questo test, che è il motivo principale per cui il QAT è utile: aiuta il modello a gestire la quantizzazione a pochi bit con meno perdita di qualità, mantenendo al contempo i vantaggi di memoria e velocità di un modello compresso.
Considerazioni finali
Google sta facendo un lavoro straordinario per la community dell’AI locale. Con modelli come Gemma 4 e tecniche come il QAT, il sogno di eseguire potenti modelli di AI in locale, completamente offline e persino su hardware consumer, sta diventando realtà.
La parte più entusiasmante è che non si tratta solo di ridurre la dimensione del modello. Con il QAT, non stiamo semplicemente scendendo a compromessi sulla qualità per farci stare il modello. Otteniamo modelli pensati per funzionare meglio in formati a pochi bit, migliorando l’esperienza complessiva dell’AI locale. In questo test, il modello QAT è stato più veloce, più leggero e più piacevole da usare rispetto alla versione non-QAT.
Non vedo l’ora di testare la versione MTP del modello, che potrebbe aumentare ulteriormente la velocità, forse di 2x. Sarebbe molto più semplice spostare più parti del mio flusso di lavoro sull’AI locale. Potrei eseguire il modello in locale, collegarlo a strumenti come OpenCode e iniziare a modificare i file di progetto direttamente con un assistente locale privato.
Questa nuova ondata di AI locale sta cambiando il modo in cui pensiamo all’uso dei sistemi di AI. Attività che un tempo richiedevano grandi setup cloud, soprattutto workflow multimodali con input di testo, immagini e video, stanno lentamente diventando possibili su macchine locali. Per sviluppatori, ricercatori e builder che tengono a privacy, velocità e controllo, è una direzione davvero entusiasmante.
In quanto data scientist certificato, sono appassionato di sfruttare tecnologie all’avanguardia per creare applicazioni di machine learning innovative. Con una solida esperienza in riconoscimento vocale, analisi e reportistica dei dati, MLOps, AI conversazionale e NLP, ho affinato le mie competenze nello sviluppo di sistemi intelligenti in grado di avere un impatto concreto. Oltre alla mia expertise tecnica, sono anche un comunicatore efficace, con il talento di rendere chiari e sintetici concetti complessi. Di conseguenza, sono diventato un blogger molto seguito in ambito data science, condividendo idee ed esperienze con una community in crescita di professionisti dei dati. Attualmente mi concentro sulla creazione e sull’editing di contenuti, lavorando con large language model per sviluppare contenuti potenti e coinvolgenti che possano aiutare aziende e singoli a valorizzare al meglio i propri dati.


