🧙 Maestro Yoda Cap. 20 · Training, fine-tuning, allineamento

Puntata 215

Puntata 215 — SFT (Supervised Fine-Tuning)

Livello: 🧙 Maestro Yoda · Capitolo 20 · Training, fine-tuning, allineamento

Dopo il pretraining hai un modello che predice il prossimo token. È bravissimo, ma se gli scrivi “Ciao” risponde con ”…, come stai oggi? Sono contento di vederti.” Sa parlare, non sa rispondere. SFT è “imparare a essere un assistente”.

due chat affiancate. Sinistra: modello base, prompt “Spiegami la fotosintesi” → continua “in 500 parole con bibliografia.” (continua il pattern). Destra: stesso modello dopo SFT, risponde da assistente

Perché serve un secondo stadio

Un modello dopo pretraining è un completatore di sequenze. Se vede “Capitolo 1. C’era una volta”, continua come un libro. Se vede un dialogo, continua come un dialogo. Non sa che tu vuoi una risposta a una domanda.

L’utente vuole un’assistente conversazionale. Per ottenerlo:

  1. Costruisci un dataset di conversazioni di esempio: prompt + risposta ideale.
  2. Continui il training del modello base su questo dataset, sempre con next-token prediction.

Risultato: il modello impara a “rispondere come l’assistente delle conversazioni di esempio”.

Lo chiamiamo SFT (Supervised Fine-Tuning) o talvolta Instruction Tuning (se le conversazioni sono task istruttive).


Il dataset SFT

Componenti tipici:

  • Istruzioni varie: “Scrivi un riassunto”, “Traduci”, “Spiega come a un bambino”.
  • Dialoghi multi-turno: 2-10 turn user/assistant.
  • Risposte con catene di ragionamento: “Pensiamo passo passo… Risposta: X”.
  • Tool use: esempi in cui l’assistant invoca funzioni esterne.
  • Refusal: esempi in cui l’assistant rifiuta richieste dannose.
  • Persona / style: tone calmo, professionale, helpful.

Quantità: tipicamente 10k – 1M esempi. Phi-3 ha mostrato che anche con 100k esempi di altissima qualità si fanno modelli straordinariamente bravi. Llama-3 ne ha usati ~10M per la versione Instruct.

Fonti

  • Human-annotated (caro, lento, qualità altissima): es. dataset originali di InstructGPT, Anthropic HH-RLHF.
  • Sintetici generati da LLM più grandi (es. dataset generati da GPT-4 per addestrare modelli più piccoli). Esempi: Alpaca, ShareGPT, OpenHermes, Magpie. Approccio dominante oggi.
  • Curated da forum (StackExchange, Quora): testi reali ma in formato Q&A naturale.

Esempi celebri di dataset SFT open

  • Alpaca (Stanford 2023): 52k istruzioni generate da GPT-3.5. Storico, ormai obsoleto.
  • Dolly (Databricks): 15k istruzioni umane.
  • OpenAssistant: ~160k conversazioni multi-turn da volontari.
  • UltraChat / UltraFeedback (Tsinghua, 2023): conversazioni sintetiche su grande scala.
  • OpenHermes 2.5: ~1M conversazioni mixed source, curated.
  • Magpie (2024): generazione “self-instruct” da modello allineato senza prompt umano.
  • Tülu 3 (AI2, 2024): dataset open di stato dell’arte, ~1M esempi.

Format del dataset

Tipicamente JSON con questa struttura:

{
  "messages": [
    {"role": "system", "content": "Sei un assistente AI utile e ironico."},
    {"role": "user", "content": "Spiega la fotosintesi in 3 frasi."},
    {"role": "assistant", "content": "Le piante usano la luce..."}
  ]
}

Si applica il chat template del modello (es. ChatML, Llama format, Alpaca format) per concatenare i messaggi in una singola stringa di token:

<|im_start|>system
Sei un assistente AI utile e ironico.<|im_end|>
<|im_start|>user
Spiega la fotosintesi in 3 frasi.<|im_end|>
<|im_start|>assistant
Le piante usano la luce...<|im_end|>

I <|im_start|> <|im_end|> sono special tokens addestrati a delimitare i ruoli.


Il training loop

Quasi identico al pretraining, con due differenze:

  1. Loss solo sui token dell’assistant (non sul prompt). Mascheri i token user/system durante il calcolo della loss. Vuoi che il modello impari a generare le risposte, non a generare le domande.
  2. Learning rate molto più basso (10-100× rispetto al pretraining): tipicamente 2e-5 a 5e-6. Non vuoi destabilizzare la conoscenza appresa nel pretraining.

Durata: poche epoche (1-3) su tutto il dataset SFT. Pochi giorni di compute (vs settimane del pretraining).

Esempio loss masking:

Tokens:  [system tokens] [user tokens] [assistant tokens]
Loss?:   [    NO       ] [    NO     ] [    SÌ          ]

Effetto sul modello: il “fenomeno della disconnessione”

Studi (Ouyang et al. 2022, Anthropic 2023+) mostrano che SFT:

  • Cambia drasticamente il comportamento: tono, format, refusal patterns.
  • Cambia poco la conoscenza: il sapere fattuale resta praticamente quello del pretraining.
  • Può degradare leggermente certe capacità (alignment tax): a volte il modello SFT-tuned è leggermente peggiore in matematica/codice rispetto al base, se il dataset SFT non li copre.

In pratica: SFT è “ridirezione delle capacità esistenti”, non “aggiunta di nuove capacità”.

Modelli base e modelli instruct sono quindi due tier diversi:

  • Base (es. Llama-3.2-3B): bravo a continuare sequenze, scarso a chattare. Ideale per fine-tuning custom.
  • Instruct (es. Llama-3.2-3B-Instruct): post-SFT (+RLHF), pronto per essere usato direttamente.

Quanto è importante la qualità dei dati SFT

Tantissimo. Tre evidenze:

  1. LIMA (Zhou et al., Meta, 2023): “Less Is More for Alignment”. 1000 esempi di altissima qualità, curated a mano. Risultato comparabile a modelli addestrati su 100k+ esempi mediocri. Quality > Quantity.
  2. Phi-3 (Microsoft, 2024): l’intero approccio è basato su “textbook quality data” sia in pretraining sia in SFT. Phi-3-mini (3.8B) batte modelli 10× più grandi.
  3. Tülu 3 (AI2, 2024): il paper mostra che ablation del 20% peggiore degli esempi migliora la quality.

Implicazione: spendere 1 settimana a curare 10k esempi vale spesso più di automatizzare la generazione di 1M esempi mediocri.


Strumenti pratici

Stack tipico per fare SFT nel 2026:

  • Framework: transformers + trl (HuggingFace), axolotl, unsloth, LLaMA-Factory.
  • Hardware: per un 7B SFT, una singola A100 80 GB basta. Per 70B, serve fine-tuning distribuito o PEFT (vedi 218).
  • Dataset format: HuggingFace Datasets library, JSONL, parquet.
  • Tracking: wandb, tensorboard.

Esempio (pseudocodice con trl):

from trl import SFTTrainer, SFTConfig

trainer = SFTTrainer(
    model="meta-llama/Llama-3.2-3B",
    train_dataset=dataset,  # con 'messages' chat format
    args=SFTConfig(
        learning_rate=2e-5,
        num_train_epochs=2,
        per_device_train_batch_size=4,
        gradient_accumulation_steps=4,
        bf16=True,
        gradient_checkpointing=True,
    ),
)
trainer.train()

In ~30 righe sei in piedi. La complicazione vera è il dataset.


SFT vs Full Fine-tuning vs Continued Pretraining vs DAPT

Famiglia confusa. Distinzioni:

  • Continued Pretraining: stesso obiettivo next-token su un nuovo corpus (es. solo italiano, solo medico). Per estendere conoscenza di dominio. Tipicamente milioni-miliardi di token.
  • DAPT (Domain-Adaptive Pretraining): stessa cosa con altro nome, dominio specifico.
  • SFT / Instruction Tuning: dataset di istruzioni-risposte, format chat. Per cambiare comportamento.
  • Full Fine-tuning: aggiorna tutti i pesi del modello.
  • PEFT (Parameter-Efficient Fine-Tuning, vedi 218): aggiorna solo una piccola frazione dei pesi (es. LoRA), risparmiando memoria.

Combinazione tipica per un modello custom: continued pretraining → SFT → eventualmente RLHF/DPO.


Glossario lampo

  • Chat template — il modo in cui i messaggi vengono concatenati in una stringa, con special tokens per i ruoli.
  • Loss masking — calcolare la loss solo su una parte dei token (assistant turn).
  • Alignment tax — perdita di capacità generale dovuta all’allineamento.
  • Instruction tuning — variante di SFT focalizzata su task istruttivi.
  • Self-instruct — usare un LLM per generare istruzioni e risposte automaticamente.

TEST hands-on

  1. Scarica meta-llama/Llama-3.2-3B (base) e meta-llama/Llama-3.2-3B-Instruct da HuggingFace.
  2. Manda lo stesso prompt a entrambi: “Spiegami la fotosintesi in 3 frasi.” Confronta le risposte. Il base continuerà il pattern (forse con “1. …, 2. …, 3. …”), l’instruct ti risponderà direttamente.
  3. Fai un fine-tuning SFT minimo: scarica un piccolo dataset (es. mlabonne/Alpaca-1k), usa trl’s SFTTrainer su una sola GPU. Verifica che il modello impari il “style” di Alpaca dopo 1 epoca.
  4. Misura alignment tax: confronta MMLU del base vs del tuo modello SFT-tuned. Aspettati una piccola regressione (1-3 punti).
  5. Bonus: leggi il “Tülu 3 paper” (arXiv:2411.15124) — è un esempio di SFT (+DPO+RLVR) di altissima qualità completamente open.

Take-away

SFT è il momento in cui un modello “diventa” un assistente. Non aggiunge intelligenza, redistribuisce comportamento. La grande lezione del 2023-26 è che la qualità del dataset di alignement vale più della quantità: 1000 esempi curati battono 100k esempi mediocri.


➡️ Prossima puntata: RLHF — PPO, reward model, e perché c’è un essere umano nel loop.