Personalizzare un modello di intelligenza artificiale sui propri dati - per fargli adottare un tono, conoscere il proprio dominio o rispondere in un formato preciso - sembra roba da grandi laboratori con cluster di GPU. Non e' piu' cosi'. Con Unsloth e una sessione gratuita di Google Colab puoi fare il fine-tuning di un modello aperto da 4-8 miliardi di parametri in meno di un'ora, senza spendere nulla e senza installare niente sul tuo computer.
Questa guida e' pensata per chi sa programmare un minimo in Python e vuole un percorso concreto, dal primo comando fino al modello pronto da usare in locale con Ollama. Non serve hardware: gira tutto nel browser.
A chi serve e cosa otterrai
Il fine-tuning serve quando il prompt engineering non basta: vuoi che il modello risponda sempre in un certo stile, che padroneggi un gergo aziendale, che produca un formato rigido (per esempio JSON con campi fissi) o che imiti esempi specifici. Al termine avrai un "adattatore" LoRA - un piccolo file che modifica il comportamento del modello base - e saprai come fonderlo ed esportarlo per usarlo offline.
Prerequisiti reali: un account Google (per Colab), un account gratuito su Hugging Face (per scaricare i modelli e, volendo, caricare il tuo), qualche decina o centinaia di esempi di addestramento, e la voglia di leggere i messaggi d'errore. La GPU gratuita di Colab (di solito una T4 da 16 GB) basta per modelli fino a 7-8 miliardi di parametri in modalita' QLoRA.
Quale strumento usare e perche' Unsloth
Per il fine-tuning di LLM ci sono diverse opzioni. Unsloth e' la prima scelta per chi inizia: e' una libreria che ottimizza l'addestramento rendendolo circa due volte piu' veloce e usando molta meno memoria, il che e' decisivo sulla GPU gratuita di Colab. Supporta i modelli aperti piu' diffusi (Llama, Gemma, Qwen, Mistral, Phi) e offre notebook gia' pronti.
- Unsloth - Pro: velocissimo, parco di memoria, notebook pronti, gratis. Contro: si concentra su una GPU alla volta.
- Axolotl e LLaMA-Factory - Pro: molto configurabili, adatti a setup multi-GPU. Contro: piu' complessi da impostare.
- PEFT + TRL "a mano" (le librerie di Hugging Face) - Pro: massimo controllo. Contro: piu' codice e meno ottimizzazioni automatiche.
Per un primo progetto su Colab, Unsloth e' il miglior equilibrio tra semplicita' e risultati.
Passo 1: prepara Colab e installa Unsloth
Vai su Google Colab, crea un nuovo notebook e imposta la GPU: menu Runtime > Cambia tipo di runtime > Acceleratore hardware > GPU. Poi installa la libreria nella prima cella:
!pip install unsloth
Passo 2: carica il modello base
Carichiamo un modello aperto in 4 bit (QLoRA) per risparmiare memoria. Qui usiamo una variante di Gemma gia' ottimizzata da Unsloth, ma puoi cambiare il nome con un altro modello presente su Hugging Face:
from unsloth import FastLanguageModel
import torch
max_seq_length = 2048
model, tokenizer = FastLanguageModel.from_pretrained(
model_name = "unsloth/gemma-3-4b-it-bnb-4bit",
max_seq_length = max_seq_length,
load_in_4bit = True,
)
Passo 3: aggiungi gli adattatori LoRA
Invece di riaddestrare tutti i miliardi di parametri (costoso e inutile), con LoRA ne addestriamo solo una piccola frazione. I valori sotto sono un buon punto di partenza:
model = FastLanguageModel.get_peft_model(
model,
r = 16,
target_modules = ["q_proj","k_proj","v_proj","o_proj",
"gate_proj","up_proj","down_proj"],
lora_alpha = 16,
lora_dropout = 0,
bias = "none",
use_gradient_checkpointing = "unsloth",
)
Passo 4: prepara il dataset
Il formato piu' comodo e' quello "chat": una lista di esempi con coppie utente/assistente. Puoi caricare un dataset da Hugging Face o crearne uno tuo. Ecco un mini esempio fatto a mano, utile per capire la struttura:
from datasets import Dataset
esempi = [
{"conversations": [
{"role": "user", "content": "Cos'e' un IBAN?"},
{"role": "assistant", "content": "L'IBAN e' il codice internazionale che identifica un conto bancario..."},
]},
# ...aggiungi decine o centinaia di esempi simili
]
def formatta(ex):
return {"text": tokenizer.apply_chat_template(
ex["conversations"], tokenize=False, add_generation_prompt=False)}
dataset = Dataset.from_list(esempi).map(formatta)
La regola pratica: meglio pochi esempi puliti e coerenti che migliaia di esempi sciatti. Per uno stile o un formato, anche 100-300 esempi ben fatti danno risultati visibili.
Passo 5: configura e avvia l'addestramento
Usiamo l'SFTTrainer di TRL, che Unsloth integra. Per un primo test bastano poche decine di passi:
from trl import SFTTrainer, SFTConfig
trainer = SFTTrainer(
model = model,
tokenizer = tokenizer,
train_dataset = dataset,
args = SFTConfig(
per_device_train_batch_size = 2,
gradient_accumulation_steps = 4,
warmup_steps = 5,
max_steps = 60, # alza questo valore per dataset reali
learning_rate = 2e-4,
logging_steps = 1,
output_dir = "outputs",
),
)
trainer.train()
Vedrai la loss (l'errore) scendere a ogni passo: e' il segno che il modello sta imparando. Su una T4, 60 passi richiedono pochi minuti.
Passo 6: prova il modello addestrato
FastLanguageModel.for_inference(model)
messaggi = [{"role": "user", "content": "Spiegami cos'e' un IBAN in una frase."}]
inputs = tokenizer.apply_chat_template(
messaggi, tokenize=True, add_generation_prompt=True, return_tensors="pt"
).to("cuda")
out = model.generate(input_ids=inputs, max_new_tokens=128)
print(tokenizer.decode(out[0], skip_special_tokens=True))
Il risultato atteso e' una risposta nel tono e nel formato dei tuoi esempi di addestramento.
Passo 7: salva ed esporta in Ollama
Puoi salvare il solo adattatore LoRA (pochi MB) oppure esportare il modello completo in formato GGUF, pronto per girare in locale con Ollama o LM Studio:
# adattatore LoRA
model.save_pretrained("mio-adattatore")
# esporta in GGUF quantizzato (per Ollama / llama.cpp)
model.save_pretrained_gguf("mio-modello", tokenizer, quantization_method="q4_k_m")
# carica su Hugging Face (richiede il token)
# model.push_to_hub_gguf("tuo-utente/mio-modello", tokenizer, token="hf_...")
Scaricato il file GGUF, crei un Modelfile per Ollama con la riga FROM ./mio-modello.gguf e lanci ollama create mio-modello -f Modelfile: avrai il tuo modello personalizzato utilizzabile offline.
Errori comuni e come risolverli
- "CUDA out of memory": riduci
per_device_train_batch_sizea 1, abbassamax_seq_length(es. 1024) e assicurati di usareload_in_4bit=True. - Il modello risponde in modo strano o ripetitivo: spesso e' un problema di chat template non applicato o dataset mal formattato. Verifica di usare
apply_chat_templatee che i ruoli (user/assistant) siano corretti. - Runtime disconnesso a meta': Colab gratuito stacca le sessioni inattive. Salva checkpoint frequenti e tieni la scheda attiva.
- "gated model" / accesso negato: alcuni modelli richiedono di accettare la licenza su Hugging Face e un token. Usa le varianti gia' pronte di Unsloth per evitare il problema.
Varianti, casi avanzati e quando NON farlo
Per dataset reali, alza max_steps (o passa a contare le epoche) e monitora la loss per evitare l'overfitting. Per modelli piu' grandi serve Colab Pro o una GPU dedicata. Tecniche avanzate come la DPO permettono di allineare il modello alle preferenze, mentre lo scaling del RoPE estende il contesto.
Attenzione pero': il fine-tuning non e' sempre la risposta. Se ti serve dare al modello conoscenza aggiornata o documenti specifici, spesso conviene la RAG (recupero dei documenti al momento della domanda), piu' economica e aggiornabile. Se devi solo cambiare tono o formato in modo occasionale, basta un buon prompt di sistema. Usa il fine-tuning quando il comportamento desiderato e' stabile, ripetitivo e difficile da ottenere a colpi di prompt: e' li' che ripaga davvero lo sforzo.




