Fine-tuning di LLM in locale: esempio passo passo LoRA / QLoRA
Il fine-tuning locale di un LLM con LoRA e QLoRA permette di adattare un modello da 8-9B (come Qwen 3.5 9B) al tuo lessico professionale, al tuo stile di scrittura o a un formato di risposta specifico — tutto su una RTX 3090 usata. Non serve più un cluster A100. Questa guida ti accompagna dai primi passi, senza alcuna esperienza, fino al modello GGUF caricato in Ollama, passando per il formato del dataset, il notebook Unsloth passo passo e l’esportazione finale.
#Perché fare fine-tuning di un LLM locale?
Un LLM di base è versatile, ma non è perfetto per il tuo uso specifico. Il prompt engineering e il RAG risolvono l'80% dei casi — il fine-tuning serve per il restante 20%. Dovresti valutare il fine-tuning quando il tuo modello deve rispondere in un formato rigoroso (JSON, tag, struttura interna), rispettare uno stile aziendale (tono, vocabolario), padroneggiare un ambito specialistico (medico, giuridico, tecnico del tuo settore) o riprodurre comportamenti che nessun prompt riesce davvero a stabilizzare.
Al contrario, non usare il fine-tuning per inserire conoscenze fattuali (il RAG lo fa meglio e rimane aggiornato), correggere una singola allucinazione (basta un prompt migliore) o competere con GPT-5 sui benchmark (non vincerai).
#LoRA vs full fine-tune: perché LoRA vince
Il tuo ChatGPT privato e gratuito sulla tua macchina in 1 ora — LM Studio, Ollama, Open WebUI, i tuoi documenti, senza cloud.
- Spazio online a vita
- PDF + file
- Aggiornamenti a vita
Il full fine-tuning aggiorna tutti i parametri del modello. Per un 7B in FP16, servono 14 GB per i pesi + circa 30 GB per i gradienti e l'ottimizzatore Adam. Totale: un minimo di 40–60 GB di VRAM. Inaccessibile senza una A100 80GB o una H100.
LoRA (Low-Rank Adaptation) congela i pesi originali e addestra solo piccole matrici di adattamento di rango r, inserite negli strati di attenzione. In pratica, per un modello 7B con r=16, addestri circa 20 milioni di parametri invece di 7 miliardi, cioè lo 0,3% del modello. La VRAM necessaria per i gradienti e l'ottimizzatore si riduce drasticamente.
- Fine-tune completo 7B
- ~60 GB VRAM, 2-4× A100, diverse ore, file di output da 14 GB.
- LoRA 7B
- ~16 GB di VRAM, una RTX 4080 basta, da 30 min a 2 ore, adattatore di soli 30-200 MB.
- QLoRA 7B
- ~6 GB di VRAM, RTX 3060 12 GB sufficiente, qualità quasi identica a quella di LoRA classico.
#QLoRA: la rivoluzione VRAM
QLoRA va oltre: il modello base viene caricato in 4 bit (NF4, NormalFloat 4 bit) invece di FP16. Durante l'addestramento, i pesi rimangono quantizzati; solo gli adattatori LoRA in FP16 ricevono i gradienti. Risultato: un 7B entra in 5-6 GB di VRAM, un 13B in 10 GB, un 70B in 48 GB.
La perdita di qualità è trascurabile grazie a due tecniche: la quantizzazione NF4 (calibrata sulla distribuzione gaussiana dei pesi) e la doppia quantizzazione (le costanti di quantizzazione sono a loro volta quantizzate). In pratica, nella maggior parte dei benchmark, QLoRA si discosta da LoRA FP16 di meno dell'1%.
#VRAM necessaria in base alla dimensione del modello
I numeri qui sotto sono valori minimi realistici con Unsloth, batch size 2, sequenza di 2048 token e gradient checkpointing attivato. Aggiungi un margine del 20% per i picchi e il sistema operativo.
- Modello 2-3B (Qwen 3.5 2B, Granite 4.2 3B)
- QLoRA: 4 GB VRAM · LoRA FP16: 8 GB · GTX 1660 6 GB o RTX 3050 sono sufficienti in QLoRA.
- Modello 8-9B (Granite 4.2 8B, Qwen 3.5 9B)
- QLoRA: 6 GB di VRAM · LoRA FP16: 16 GB · RTX 3060 12 GB con un buon margine, RTX 3090 ideale.
- Modello 12B (Gemma 4 12B)
- QLoRA: 10 GB VRAM · LoRA FP16: 28 GB · RTX 3090/4090 24 GB in QLoRA, A100 40GB in LoRA.
- Modello 27-35B (Qwen 3.8 27B, Qwen 3.6 35B-A3B)
- QLoRA: 22 GB di VRAM · LoRA FP16: impossibile su hardware consumer · RTX 3090/4090 o RTX 5090 esclusivamente con QLoRA.
- Modello 70B (denso di fascia alta)
- QLoRA: 48 GB VRAM · 2× RTX 3090 o 1× A100 80GB · multi-GPU obbligatorio con Unsloth Pro.
Per questa guida, l'obiettivo è un modello da 8–9B in QLoRA su una RTX 3090 da 24 GB. È la combinazione più universale: basta anche una RTX 3060 da 12 GB, ma una 3090 usata (prezzo variabile) consente di gestire comodamente tutte le taglie fino a 12B in QLoRA. Una RTX 4090 o 5090 offre un'accelerazione da 1,5 a 2×, ma non è indispensabile.
#Requisiti hardware e software
- GPU NVIDIA con CUDA 11.8+
- RTX 3060 12 GB come minimo, RTX 3090 consigliata. Le GPU AMD con ROCm funzionano parzialmente, ma Unsloth è ottimizzato per CUDA — per questa prima guida, resta su NVIDIA.
- Python 3.10 o 3.11
- Non 3.12 (incompatibilità con bitsandbytes al momento della stesura). Usa conda o pyenv.
- 32 GB di RAM di sistema
- 16 GB possono bastare ma il caricamento iniziale del modello e la preparazione del dataset sono più comodi con 32 GB.
- 50 GB di spazio disco
- Modello base + checkpoint + adattatore fuso + esportazione GGUF Q4_K_M. Prevedi un ampio margine di spazio.
- Connessione adeguata
- Il download iniziale del modello 8-9B pesa 5-8 GB. Una sola volta.
Dal lato software, si utilizza Unsloth (github.com/unslothai/unsloth), un framework che riscrive i kernels Triton per guadagnare 2× di velocità e 60% di memoria rispetto al standard Hugging Face PEFT. Installazione in un ambiente dedicato:
#Preparare il dataset nel formato JSONL
Il formato standard per il fine-tuning basato su istruzioni è JSONL (un oggetto JSON per riga). Sono comuni tre varianti:
Per un primo fine-tune, scegli Alpaca: un solo turno, formato chiaro, supportato nativamente da Unsloth. Alcune regole fondamentali per la qualità:
- Volume minimo
- 300 esempi per osservare un effetto, 1000-5000 per un fine-tune solido, 10.000+ per un risultato serio. Meno di 300, perdi il tuo tempo.
- Qualità > quantità
- 100 esempi impeccabili battono 5000 esempi rumorosi. Rileggi. Fai rileggere. Il modello impara letteralmente il tuo dataset, difetti inclusi.
- Diversità degli input
- Se tutti i tuoi input iniziano con 'Traduci', il modello non saprà più fare nulla di diverso. Varia le formulazioni.
- Lunghezze bilanciate
- Se tutti i tuoi output sono di 2 frasi, il modello non saprà più produrre risposte lunghe. Varia.
- Riserva il 10% per la validazione
- Suddividi in modo casuale i dati tra train.jsonl e val.jsonl per misurare l'overfitting.
#Il notebook Unsloth commentato
Ecco uno script completo e minimale per eseguire il fine-tuning di Qwen 3.5 9B in QLoRA sul tuo dataset. Da eseguire come file .py o in un notebook Jupyter.
Unsloth ospita versioni pre-quantizzate a 4 bit della maggior parte dei modelli popolari su Hugging Face (prefisso unsloth/). Download più veloce, avvio immediato. La prima esecuzione scarica circa 5 GB.
Il rango r=16 è un buon valore predefinito. Aumentalo a 32 o 64 se hai molti dati (>10k) e un dominio molto distante da quello del preaddestramento. Un rango più alto = più parametri addestrabili = maggiore capacità ma maggiore rischio di sovraddestramento.
Su una RTX 3090 con un dataset di 1000 esempi e 3 epoche, considera da 20 a 40 minuti. Su una RTX 4090, da 12 a 25 minuti. Su una RTX 5090, circa da 8 a 15 minuti. Monitora la loss: deve diminuire regolarmente e poi stabilizzarsi. Se aumenta sul set di validazione, il modello sta andando in overfitting.
#Esportazione GGUF verso Ollama
Il tuo adattatore LoRA si trova in outputs/. È un file di qualche decina di MB, separato dal modello di base. Per usarlo in Ollama, due passaggi: fondere l'adattatore con il modello, poi convertire il risultato in GGUF quantizzato.
Unsloth si occupa di tutto: fusione adattatore + base, conversione tramite llama.cpp, quantizzazione Q4_K_M. Il risultato: un file mon-modele-gguf/unsloth.Q4_K_M.gguf di circa 5,3 GB per un 9B. Q5_K_M e Q8_0 sono disponibili se vuoi maggiore precisione (e maggiore peso).
Per caricarlo in Ollama, che è in ascolto su localhost:11434, crea un Modelfile minimale e poi registra il modello:
#Suggerimenti e risoluzione dei problemi
- OutOfMemoryError all'avvio
- Riduci per_device_train_batch_size a 1 e aumenta gradient_accumulation_steps in proporzione. Riduci max_seq_length a 1024 se i tuoi esempi sono brevi.
- Loss che non diminuisce
- Tasso di apprendimento troppo basso (prova 5e-4) o formato del prompt errato. Stampa 2-3 esempi di ds[0]["text"] e verifica visivamente che assomiglino a ciò che desideri.
- Perdita che esplode (NaN)
- Tasso di apprendimento troppo alto. Riportalo a 1e-4. Oppure attiva bf16 se usavi fp16 su Ampere+ — fp16 tende a causare overflow.
- Modello che ripete all'infinito
- Token EOS mancante durante l'addestramento, o parametro stop mancante nel Modelfile. I due problemi si verificano spesso insieme.
- Overfitting evidente
- La loss di training scende, quella di validazione risale. Interrompi all’epoca in cui divergono. Riduci epochs o aumenta lora_dropout a 0.05.
- Esportazione GGUF che va in crash
- Unsloth scarica llama.cpp automaticamente al primo utilizzo — assicurati di avere git, cmake e build-essential installati su Linux. Su Mac, esegui xcode-select --install.
- Modello che ignora le nuove istruzioni
- Dataset non abbastanza vario o rango LoRA troppo basso. Imposta r=32 e lora_alpha=64 e riesegui l'addestramento.
#Per approfondire
Hai un primo modello fine-tuned che funziona in Ollama. Tre percorsi naturali per approfondire:
- Scegliere la quantizzazione giusta
- Hai esportato per default in Q4_K_M. Il manuale sulla scelta della quantizzazione confronta Q4_K_M, Q5_K_M, Q8_0 e FP16 — utile per decidere se la qualità del tuo fine-tune merita Q5 o Q8.
- RAG piuttosto che fine-tune per la conoscenza
- Se vuoi che il modello conosca i tuoi documenti (e non solo uno stile), la guida introduttiva al RAG locale spiega perché il RAG è quasi sempre preferibile al fine-tuning per introdurre informazioni fattuali.
- Hardware per passare ai grandi modelli
- Per effettuare il fine-tuning di modelli da 32B o 70B in QLoRA, servono rispettivamente 24 GB e 48 GB di VRAM. La guida «Quale LLM per 24 GB di VRAM» illustra ciò che è fattibile su RTX 3090, 4090 e RX 7900 XTX.
Un feedback, un errore, una precisazione? Facci sapere, così la guida migliora per tutti.