Domande e Risposte

Questioni architetturali, strategiche e tecniche emerse durante lo sviluppo del progetto SLM.

Q

Un modello da 46 milioni di parametri ma con più layer (ad esempio 24 invece di 12) sarebbe in grado di fare più cose? E a quale costo computazionale?

Come sono distribuiti i parametri nell'architettura attuale

Con d_model=512 e 12 layer, ogni layer occupa circa 3,15 milioni di parametri: 1,05M per i meccanismi di attenzione (quattro proiezioni Q, K, V, O di dimensione 512×512) e 2,10M per la rete feed-forward (due proiezioni da 512 a 2048 e viceversa). L'embedding occupa i restanti 8,19M.

Cosa succede con più layer e meno d_model

Se si vuole mantenere lo stesso budget di parametri aumentando la profondità, è necessario ridurre d_model. Tre configurazioni a confronto:

ConfigurazioneLayerd_modeld_k per testaParametri totali
Attuale1251264~46M
Più profonda2438448~48M
Intermedia1844856~47M

Cosa compra la profondità

Il numero di layer determina quante volte il modello può rielaborare la rappresentazione di un token prima di produrre output. Più layer migliorano le dipendenze a lungo raggio, la coerenza sintattica su più frasi e la capacità di composizione gerarchica. Il numero di parametri, invece, determina la ricchezza di ogni singola rappresentazione: meno d_model significa vettori-token più poveri, con meno dimensioni disponibili per ogni testa di attenzione.

Il problema a 46 milioni di parametri

Le leggi di scaling empiriche (Kaplan et al. 2020, Chinchilla 2022) indicano che per un budget fisso di parametri esiste un rapporto ottimale tra profondità e larghezza, e quel rapporto è già vicino a quello della configurazione attuale (12 layer, d_model 512). Portare a 24 layer con d_model 384 significa ridurre le teste di attenzione a 48 dimensioni ciascuna, contro le 64 attuali: un calo che annulla il vantaggio della profondità.

Il limite categoriale di questo modello non è la struttura, è il numero totale di parametri. Il salto da "non sa fare X" a "sa fare X" avviene aumentando il budget complessivo, non redistribuendolo in verticale.

Costo computazionale

A parità di parametri totali, il costo di training e di inferenza è sostanzialmente identico: il numero di operazioni per forward pass è proporzionale ai parametri totali, non alla profondità isolata. La profondità è sequenziale (ogni layer dipende dall'output del precedente) ma il costo dominante rimane la moltiplicazione matriciale complessiva, che non cambia.

Risposta sintetica: no, più layer con lo stesso budget non sblocca nuove categorie di capacità. Offre margini di qualità minimi (forse −0,1/−0,2 di val loss) a fronte di rappresentazioni per-token più povere. La configurazione attuale è già vicina all'ottimo per questo budget.

Q

Sarà possibile in futuro aumentare il numero di parametri del modello senza doverlo ricostruire da zero?

Il caso diretto: no

Caricare un checkpoint esistente (ad esempio best.pt con d_model=512 e 12 layer) in un'architettura più grande (ad esempio d_model=1024 e 24 layer) produce un errore immediato. Le matrici peso hanno dimensioni diverse: W_Q è 512×512 nel modello piccolo, 1024×1024 in quello grande. I dizionari dei parametri non sono compatibili e il caricamento fallisce.

Ma esistono tecniche che sfumano la risposta

La più rilevante si chiama Net2Net (Chen et al., 2015) ed è una trasformazione function-preserving: permette di espandere un modello senza perdere ciò che ha già imparato.

Per espandere la larghezza (d_model da 512 a 1024): ogni neurone viene duplicato e i pesi in uscita corrispondenti vengono dimezzati. La somma rimane invariata, quindi il modello espanso produce output matematicamente identici all'originale al momento dell'inizializzazione. Da quel punto si riprende il training: si parte già dalla qualità del modello piccolo, non da zero.

Per aggiungere layer: i nuovi layer vengono inseriti come funzioni identità, con i pesi della parte trainable inizializzati a zero. L'output del nuovo layer è uguale al suo input, e il training impara gradualmente a usarli.

TecnicaFunziona?Costo reale
Net2Net width expansionSì, formalmente correttoImplementazione non banale, poi servono molti token di fine-tuning
Identity layer insertionSì, sempliceConvergenza lenta: i nuovi layer partono senza conoscenza
LoRA su modello esistenteSì, ma non è espansioneAggiunge parametri trainabili senza modificare i pesi base
Caricamento diretto in architettura diversaNoErrore di shape incompatibile

Il risparmio è reale ma parziale

Anche con Net2Net, il vantaggio è concreto ma non trasforma il problema. Per passare da 46M a 200M parametri, anche partendo dal checkpoint corrente, servono comunque centinaia di milioni di token aggiuntivi di training. Il risparmio stimato rispetto a una partenza da zero è del 20–40% di token, non una continuazione trasparente.

Alternativa più pratica per questo progetto: se in futuro si vuole un modello più grande, la strada più diretta è usare il modello da 46M come teacher per generare dati di training sintetici per un'architettura più grande (knowledge distillation). È la tecnica usata da Microsoft per Phi-3: un modello grande che genera esempi, uno piccolo che impara da quegli esempi, ottenendo qualità sproporzionata rispetto alla dimensione.

Risposta sintetica: tecnicamente esistono percorsi (Net2Net) che evitano la ricostruzione completa, ma nella pratica il risparmio è parziale e l'implementazione ha un costo. Per un salto significativo di parametri, la knowledge distillation è più conveniente della re-inizializzazione progressiva.

Q

Si potrebbe abbassare ancora la perplexity del modello attuale?

Al termine di Run #6 il modello ha val loss 3.2965, perplexity ~27. La curva di apprendimento non era piatta: l'ultimo shard (ag) aveva il minimo a step 8000, l'ultimo disponibile, con la loss ancora in discesa. Esistono almeno tre leve distinte per ridurla ulteriormente, con costi e ritorni diversi.

Leva 1 — Più dati

Run #6 ha processato circa 917 milioni di token, raggiungendo la parità Chinchilla per un modello da 46 milioni di parametri (la legge Chinchilla indica 20 token per parametro come ottimo di efficienza). Tuttavia la parità Chinchilla è un ottimo di efficienza, non un limite assoluto: continuare ad addestrare oltre quel punto ha rendimenti decrescenti, ma non nulli.

Il corpus italiano più ricco disponibile senza licenze restrittive è CulturaX IT, che contiene circa 60 miliardi di token dopo filtraggio. Usarne anche solo una frazione significativa, 3–5 miliardi di token in un Run #7, porterebbe la val loss probabilmente sotto 3.1, con perplexity ~22–24. Il costo stimato su RTX 4090: 3–4 ore, circa 5 euro.

Il limite di questa leva: oltre una certa quantità di dati, il modello da 46M parametri non ha la capacità di memorizzare ulteriori pattern. La curva si appiattisce e continuare non porta vantaggi misurabili.

Leva 2 — Architettura più grande

Ogni architettura ha un pavimento di perplexity che non può superare indipendentemente da quanti dati riceve. Per il modello attuale (d_model=512, 12 layer, 46M param) quel pavimento è probabilmente intorno a 3.0–3.1 sul corpus italiano corrente.

Passare a 125M parametri (d_model=768, 12–16 layer) abbassa strutturalmente quel pavimento. Non è un miglioramento marginale: è un cambio di categoria. Con lo stesso volume di training data, un modello da 125M raggiunge perplexity intorno a 18–20 sullo stesso corpus. Con il corpus Chinchilla-ottimale per 125M (2.5 miliardi di token), si scende ulteriormente.

Il costo è significativo: ricostruzione completa del modello, nuovo training da zero, 10–15 ore su RTX 4090 per il solo pre-training Chinchilla. È la leva più potente ma anche la più costosa.

Leva 3 — Qualità e mix del corpus

Il corpus di Run #6 mescola Wikipedia italiana e testi web generici (CulturaX). La qualità non è uniforme: i testi web includono contenuti ridondanti, errori grammaticali, formati strutturati (tabelle HTML, codice, metadati) che il modello deve "imparare a ignorare".

Sostituire una frazione del corpus web con testi più curati, saggistica, giornalismo di qualità, narrativa contemporanea, migliora la perplexity su testo italiano standard anche senza aumentare il volume totale. La stima è un guadagno di 0.1–0.2 di val loss rispetto al corpus attuale, a parità di step.

Questa leva è anche la più rilevante per applicazioni specifiche: un modello addestrato su testi giornalistici ha perplexity più bassa su articoli di giornale, anche se la perplexity complessiva su Wikipedia non cambia. La qualità del corpus definisce il dominio dove il modello è più fluente.

Quale percorso è più conveniente

Dipende dall'obiettivo. Se si vuole abbassare la perplexity con il minimo sforzo sul modello da 46M: Run #7 con 2–3 miliardi di token di CulturaX IT filtrato è il passo più diretto. Se si vuole un salto qualitativo vero, con un modello capace di rispondere a domande semplici anche senza fine-tuning, la strada è scala a 125M parametri. Le due leve non si escludono: si può fare Run #7 ora e scala in un momento successivo.

Risposta sintetica: sì, la perplexity può scendere ulteriormente. Le tre leve sono più dati (Run #7, ~5 euro, perplexity ~22–24), architettura più grande (125M param, costo maggiore, perplexity ~18–20) e corpus di qualità superiore (guadagno marginale di 0.1–0.2 senza costi di compute aggiuntivi). La leva più conveniente nell'immediato è il corpus: costa zero in compute e migliora la qualità del testo generato anche se la val loss scende poco.

Q

Per l'inferenza è necessario usare il modello quantizzato?

No, non è necessario. Il modello fp32 da 218 MB è perfettamente usabile per l'inferenza, anche su hardware consumer. La domanda più utile non è "devo quantizzare?" ma "quale formato conviene in questo contesto?"

Cosa cambia tra fp32 e Q8_0

Il formato fp32 (virgola mobile a 32 bit) è quello prodotto direttamente dalla conversione del checkpoint PyTorch. Ogni peso occupa 4 byte. Il formato Q8_0 quantizza ogni peso a 8 bit con un fattore di scala per blocco, riducendo la dimensione a circa un quarto.

Per un modello da 46 milioni di parametri la differenza in megabyte è limitata: 218 MB fp32 contro 55 MB Q8_0. Entrambi entrano interamente nella RAM unificata di un M2, anche nei tagli base.

Perché Q8_0 è preferibile per l'inferenza su Apple Silicon

Il collo di bottiglia dell'inferenza su Metal non è la capacità di calcolo della GPU ma la banda memoria: quanto velocemente si riesce a spostare i pesi dalla RAM alle unità di calcolo per ogni token generato. Un modello più compatto occupa meno spazio in cache e richiede meno trasferimenti per token.

Il risultato è controintuitivo: Q8_0 è più veloce di fp32 anche quando la RAM è abbondante, perché riduce la pressione sulla banda memoria. La differenza è misurabile: nell'ordine del 20–40% di token al secondo in più.

La perdita di qualità con Q8_0 è trascurabile a questa scala

La quantizzazione a 8 bit introduce un errore di approssimazione sui pesi. Su modelli grandi (7B+) questo errore può essere misurabile sulla perplexity. Su un modello da 46M parametri l'errore è sotto la soglia percepibile: la perplexity varia di meno di 0.01, una differenza invisibile nell'output generato.

Questo perché i modelli piccoli hanno pesi con range di valori più regolari e distribuzioni più strette: il quantizzatore a 8 bit li rappresenta con alta fedeltà. La perdita di precisione diventa rilevante solo su modelli con distribuzioni di pesi irregolari o outlier estremi, caratteristica dei modelli molto grandi.

Quando usare il fp32

Il fp32 è necessario in tre casi: fine-tuning e calcolo di gradienti (la backpropagation richiede precisione piena), export verso formati che non supportano la dequantizzazione (alcuni framework di deployment), e debug di anomalie nell'output dove si vuole escludere artefatti di quantizzazione come causa.

Per tutti gli altri usi — inferenza locale, server API, test, dimostrazione — Q8_0 è il formato corretto.

Risposta sintetica: no, non è obbligatorio, ma Q8_0 è la scelta migliore per l'inferenza su Apple Silicon: più veloce del fp32 per la minore pressione sulla banda memoria, e senza perdita di qualità misurabile su un modello da 46M parametri. Il fp32 serve solo per fine-tuning o operazioni che richiedono precisione piena sui pesi.

Q

Qual è la differenza tra SFT e LoRA? Sono alternativi o si combinano?

SFT e LoRA rispondono a domande diverse

SFT (Supervised Fine-Tuning) è una strategia di addestramento: definisce il formato dei dati (coppie prompt → completion con loss mascherata sul solo completion) e l'obiettivo (modificare il comportamento del modello, non la sua conoscenza del mondo). Non dice niente su quali parametri vengono aggiornati.

LoRA (Low-Rank Adaptation) è un metodo di ottimizzazione: definisce quanti parametri aggiornare e come. Non dice niente sul formato dei dati.

Sono ortogonali. Si combinano: il fine-tuning più usato in pratica è SFT con LoRA, cioè addestramento su coppie prompt/completion con aggiornamento solo dei parametri LoRA.

Pre-training vs SFT — la differenza fondamentale

Durante il pre-training il modello impara a fare una cosa sola: predire il token successivo. Sa continuare il testo, non sa rispondere. Se gli scrivi "Chi ha scritto la Divina Commedia?" risponde con un'altra domanda — perché nel corpus le liste di domande sono frequenti e continuarle è statisticamente plausibile.

SFT cambia il comportamento senza cambiare la conoscenza. Il modello sa già cos'è Dante. Non sa ancora che deve rispondere invece di continuare liberamente. Il dataset SFT lo insegna.

La loss mascherata

La differenza tecnica rispetto al pre-training è la masked loss: la cross-entropy viene calcolata solo sui token del completion, non sul prompt. I token del prompt ricevono target=-100, che F.cross_entropy ignora per convenzione. L'obiettivo è che il modello impari a produrre risposte giuste, non a predire le domande.

Il rischio del full fine-tuning: catastrophic forgetting

Con SFT senza LoRA (full fine-tuning), tutti i parametri del modello vengono aggiornati su ogni esempio del dataset. Con un dataset piccolo (100–200 esempi) e un modello da 45.9M parametri, il rischio è che il modello dimentichi il pre-training: i pesi si spostano verso il nuovo comportamento e le connessioni per il vocabolario generale si indeboliscono.

LoRA risolve il problema del catastrophic forgetting

Invece di aggiornare direttamente la matrice W, LoRA aggiunge una perturbazione a basso rango:

W_aggiornato = W_frozen + (α/r) · B · A

Dove A ha shape (r × d_in) e B ha shape (d_out × r), con r piccolo (tipicamente 4–16). W rimane congelato. Solo A e B vengono addestrati.

Per una matrice 512×512 con r=8:

  • Full fine-tuning: 262 144 parametri trainabili
  • LoRA: 512×8 + 8×512 = 8 192 parametri trainabili — 32× meno

Per il modello medium (12 layer × 4 matrici per layer):

  • Full: 45.9M parametri trainabili, checkpoint da 175 MB
  • LoRA r=8: ~393k parametri trainabili, adapter da ~1.5 MB

Il vantaggio architetturale di LoRA: adapter multipli

Poiché W non cambia mai, il base model può restare fisso in RAM. Adapter diversi (uno per dominio, uno per task) vengono caricati sopra lo stesso modello di base a runtime. Il costo di ogni specializzazione è ~1.5 MB di RAM aggiuntiva e zero overhead sul base model.

Confronto sintetico

Full SFTSFT + LoRA
Parametri aggiornati45.9M~393k
Checkpoint size175 MB (copia completa)~1.5 MB (solo A e B)
Catastrophic forgettingAlto rischio con dataset piccoliBasso — W è frozen
Adapter multipli su stesso base modelNoSì — swap a runtime
Adatto a dataset piccoli (<500 esempi)NoSì

Risposta sintetica: SFT e LoRA non sono alternativi. SFT descrive il formato dei dati e l'obiettivo; LoRA descrive quali parametri aggiornare. In produzione si usano insieme. Il full SFT (senza LoRA) è utile per capire il comportamento di base del fine-tuning prima di aggiungere l'astrazione di LoRA — è il percorso che seguiamo nella roadmap: Phase 09 (full SFT) → Phase 10 (LoRA).

Q

Se volessimo ripartire da zero con un modello più grande, qual è la dimensione massima realistica data l'infrastruttura attuale?

Il vincolo reale: il corpus, non la GPU

La legge di Chinchilla dice che per addestrare bene un modello servono circa 20 token per parametro. Con i 210M di token attualmente disponibili, il punto di ottimale Chinchilla è intorno ai 10M di parametri. Il modello attuale da 45,9M parametri è già sovradimensionato rispetto al corpus — è Chinchilla-ottimale per 918M token, che è esattamente il target di espansione corpus che avevamo pianificato.

Scalare a 350M parametri senza espandere il corpus significherebbe avere 0,6 token per parametro: il modello sarebbe drasticamente undertrainato e produrrebbe risultati peggiori dell'attuale.

La mappa parametri → corpus → costo

ParametriArchitettura indicativaToken Chinchilla-ottimaliTempo su RTX 4090Costo Vast.ai
45,9M (attuale)d=512, L=12918M~76 min~$2
150Md=768, L=183B~6 ore~$9
350Md=1024, L=247B~18 ore~$27
700Md=1280, L=3214B~48 ore~$72

Limite VRAM su RTX 4090 (24 GB)

In addestramento bf16 con gradient accumulation (Phase 07), la memoria per pesi + gradienti + stati AdamW è circa 16 byte per parametro. Per 1B parametri: 16 GB — entra in 24 GB con margine. Il collo di bottiglia reale è il corpus, non la VRAM.

Risposta sintetica

Dimensione massima realistica dato il corpus attuale: 150–200M parametri, previa espansione corpus a ~3B token italiani (ottenibile da CulturaX IT completo in pochi giorni).
Dimensione massima prima di costi seri: 350M — taglia di Minerva, già benchmarkato — richiede ~7B token e ~$27 per run.
Costo in codice: zero. Basta cambiare d_model, num_layers, num_heads in GPTConfig. Il sistema di preset è già parametrizzato.
Q

Che caratteristiche di reasoning e comprensione avrebbe un modello da 150M, 350M, 700M e 1B parametri, assumendo training Chinchilla-ottimale?

Questi sono modelli base (solo pre-training). Le capacità descritte si riferiscono alla generazione di completamento, non all'instruction following. Per quest'ultimo serve SFT o RLHF sopra il base model.

150M — linguaggio fluente, nessun ragionamento

CapacitàStato
Morfologia italiana (accordo, coniugazione)✓ solida
Completamento coerente a livello di frase✓
Registro stilistico consistente✓ parziale
Coerenza a livello di paragrafo✗ si perde dopo 3–4 frasi
Recall di fatti dal corpus✗ inaffidabile
Inferenza logica semplice✗
Tracking di entità attraverso il testo✗

Il modello sa come si scrive l'italiano molto meglio dell'attuale, ma non sa ancora di cosa sta scrivendo. Con SFT: adatto a task strutturati semplici (classificazione, NER, formato fisso).

350M — coerenza di paragrafo, conoscenza fattuale parziale

Questo è il range già osservato empiricamente nel benchmark con Minerva 350M. I risultati di quel confronto (ricetta della pasta funziona, crisi del '29 confusa; Puglia con dettagli, Ungaretti corretto) riflettono esattamente questa soglia.

CapacitàStato
Coerenza di paragrafo✓
Recall di fatti comuni dal corpus✓ selettivo
Registro appropriato per dominio✓
Inferenza logica in-context✗ quasi mai
Tracking entità su più paragrafi~ inaffidabile
Con SFT: generalizzazione a istruzioni non viste~ parziale
Ragionamento causale ("perché/quindi")✗

700M — soglia di emergenza parziale

Qui cominciano ad apparire comportamenti che assomigliano al ragionamento, ma rimangono fragili e non generalizzano in modo affidabile.

CapacitàStato
Coerenza multi-paragrafo (3–5 paragrafi)✓
Tracking entità e coreference✓
Inferenza semplice in-context~ emerge, non affidabile
Ragionamento causale a un passo~ emergente
Aritmetica semplice in linguaggio naturale~ emergente
Con SFT: istruzioni multi-step✓ miglioramento netto
Comprensione di testi argomentativi✗ pattern, non comprensione

1B — in-context learning, reasoning limitato emergente

CapacitàStato
In-context learning da pochi esempi (few-shot)✓ più affidabile
Tracking di plot su testi lunghi✓
Ragionamento causale a più passi~ compare, non generalizza
Aritmetica in linguaggio naturale✓ semplice
Comprensione testi argomentativi~ struttura sì, implicazioni no
Meta-ragionamento✗ non emerge sotto 7B

La soglia che conta davvero

Il ragionamento multi-step affidabile e il meta-ragionamento non emergono prima dei 7–13B parametri con training adeguato. Sotto quella soglia si ottengono miglioramenti graduali nella fluenza e nella conoscenza fattuale, ma il "ragionamento" rimane essenzialmente pattern matching su testo simile al corpus.

Per i use case concreti del progetto (intent recognition, calendari, RAG locale): 150M è sufficiente con SFT su dati di qualità. 350M aggiunge robustezza. 700M–1B ha senso solo se il task richiede comprensione contestuale profonda o istruzioni multi-step complesse.

Q

Il ragionamento degli LLM è reale o solo simulazione dovuta al calcolo probabilistico? Come può una matrice di probabilità diventare ragionamento logico? E la proprietà emergente dipende dal corpus di training?

Meta-ragionamento — cosa significa e come si misura

Il meta-ragionamento è la capacità di ragionare sul proprio processo di ragionamento: "non sono sicuro di questo, rivedo", "questo approccio non funziona, cambio strategia", "so di non sapere X". Negli LLM si manifesta come chain-of-thought spontaneo, calibrazione dell'incertezza, auto-correzione, rilevamento di contraddizioni nel proprio output.

Come si misura:

  • Calibrazione: quando il modello dice "sono sicuro", quanto spesso ha ragione? La curva P(corretto | sicuro) vs P(corretto | incerto) deve essere separata e monotona.
  • Self-consistency: domande equivalenti formulate diversamente producono risposte consistenti?
  • CoT fidelity: il ragionamento esplicito nel chain-of-thought è realmente la causa della risposta finale? La ricerca empirica dice spesso che è confabulato — il modello produce la risposta e poi genera una spiegazione plausibile, non il contrario.

Simulazione o ragionamento reale?

La domanda contiene un'assunzione da esaminare. Il ragionamento umano è impulsi elettrochimici che seguono leggi fisiche in reti neurali biologiche. Se si applica l'argomento "è solo X, non ragionamento vero" ricorsivamente all'essere umano, si arriva a un regresso che svuota il concetto di ragionamento di qualsiasi significato.

Il punto filosoficamente rilevante non è il substrato (silicio vs carbonio, probabilità vs elettrochimica), ma la struttura: il sistema implementa operazioni che producono output consistenti con l'inferenza logica e che generalizzano oltre gli esempi visti?

La risposta empirica è: parzialmente sì, con limiti precisi. I LLM falliscono sistematicamente su problemi che richiedono consistenza logica rigorosa su contesti lunghi o aritmetica con grandi numeri. Ma generalizzano su ragionamento analogico e inferenza da contesto. Questo pattern è incompatibile sia con "puro pappagallo statistico" sia con "ragionamento formale vero".

Come una matrice di probabilità diventa ragionamento

Nessun singolo peso della rete codifica "implicazione logica". Ma la composizione di miliardi di pesi, addestrata su testo umano che contiene ragionamento, può implementare il ragionamento come proprietà emergente.

L'emergenza è il meccanismo centrale. Nessuna singola molecola d'acqua è "bagnata": la bagnatura emerge dall'interazione collettiva. Analogamente, il ragionamento negli LLM non è localizzato in nessun componente — è distribuito sull'intera rete. Non è simulazione della bagnatura: è bagnatura.

Il corpus come educazione — il parallelo con l'umano

Il ragionamento umano dipende da fattori biochimici (hardware), condizionamenti esperienziali (corpus di training) e scelte volitive (analogamente: SFT, RLHF, contesto di inferenza). Una persona educata secondo determinati principi può scegliere di seguirli o distaccarsene.

Questo parallelo illumina direttamente gli LLM:

  • Il carattere generale del ragionamento emergente è prevedibile dal corpus. Il nostro modello ha un registro enciclopedico e formale perché Wikipedia era dominante — non per caso.
  • Un modello addestrato su testi scientifici tende a ragionare per falsificazione. Uno addestrato su testi di autorità tende a ragionare per argomento dall'autorità. Non perché "creda" in qualcosa, ma perché i pattern di ragionamento del corpus sono stati estratti e distribuiti nei pesi.
  • Quando il contesto di inferenza spinge verso una conclusione diversa dal "default" del corpus, il modello spesso segue il contesto — funzionalmente simile alla scelta di distaccarsi dall'educazione ricevuta, ma senza soggetto agente dietro.

I risultati sono prevedibili?

Parzialmente, con un limite preciso:

  • Carattere generale del ragionamento: prevedibile dal corpus. Corpus enciclopedico → registro formale e ragionamento per precedenti. Corpus tecnico → ragionamento strutturato. Corpus narrativo → coerenza di plot.
  • Capacità specifiche che emergono alla scala: non prevedibili per estrapolazione. Wei et al. (2022) mostrano che certe capacità appaiono improvvisamente superata una soglia di parametri — la curva non è liscia. Questo suggerisce che l'emergenza non è solo "più corpus → più di quello che già c'era", ma una riorganizzazione qualitativa.
  • Output specifici: non prevedibili per definizione (per questo esiste la temperatura di campionamento).
Implicazione pratica per il progetto: possiamo progettare il tipo di ragionamento che vogliamo nel modello scegliendo consapevolmente il corpus. Non possiamo garantire esattamente quale forma prenderà. La cura del corpus è l'atto più importante nella costruzione di un LLM — più dell'architettura, più degli iperparametri.
9

Se faccio un run di pre-training aggiuntivo, impatta SFT e LoRA già prodotti?

Sì, in modo irreversibile. L'ordine corretto è una pipeline a senso unico:

Pre-training  →  SFT (opzionale)  →  LoRA

Perché il pre-training invalida l'SFT

L'SFT modifica tutti i pesi W del modello su un punto di convergenza specifico. Se riprendi il pre-training su un corpus più grande, quel punto cambia — anche di poco — e l'allineamento sintattico e semantico introdotto dall'SFT si disintegra. Va rifatto.

Perché il pre-training invalida i LoRA adapter

Un adapter LoRA è calibrato per sommarsi a specifici pesi W: ΔW = (α/r) · B @ A. Se W cambia, la somma porta il modello in un punto diverso dello spazio dei parametri. Il risultato può essere degradazione delle performance, output incoerenti, o entrambe le cose. L'adapter non è portabile tra versioni del base model.

Ordine corretto e perché

StepCosa faDipende da
Pre-trainingApprende lingua, morfologia, semantica su corpus ampioCorpus generale
SFTOrienta il modello al formato istruzione/rispostaBase model stabile
LoRASpecializza su dominio specifico con pochi parametri trainabiliBase model stabile (+ SFT se presente)

Regola pratica

Prima di qualsiasi run di pre-training aggiuntivo, considera tutti gli adapter LoRA e i checkpoint SFT esistenti come deprecati. LoRA è sempre l'ultimo passo della pipeline. Se vuoi specializzare dominio senza perdere il lavoro fatto, l'unica strada è freezare il base model e fare LoRA — non pre-training.

Caso reale per questo progetto: best.pt (Run #4, val 3.5861) è il base model. Run #6 o successivi che lo sostituiscono rendono il LoRA adapter prodotto in Phase 10 incompatibile. Salvare sempre il base model prima di produrre un adapter che si intende riutilizzare.
10

Il modello estrae "domani" o la data risolta? Chi converte le espressioni temporali?

Il modello estrae l'espressione temporale così come appare nel testo: "date": "domani", "date": "venerdì prossimo", "deadline": "primo del mese". Non risolve mai le date in valori assoluti. Questo è il contratto corretto tra il layer di comprensione del linguaggio e il layer applicativo.

I due livelli del sistema

Un assistente calendario completo ha due livelli distinti con responsabilità separate:

LayerInputOutputStrumento
NLU (questo modello)Frase in italianoJSON con intent + entità grezzeLoRA adapter SLM
Date resolverEspressione temporale + data correnteData ISO assolutadateparser o logica custom
Calendar APIJSON con date assoluteEvento creatoGoogle Calendar, CalDAV…

Perché non far risolvere le date al modello

Tre ragioni concrete:

  1. Il modello non conosce la data corrente. Per risolvere "venerdì prossimo" serve sapere che oggi è sabato 10 ottobre. Quella informazione va iniettata nel prompt — e allora il modello deve anche fare aritmetica su date, un task che richiede reasoning non garantito a 46M parametri.
  2. Ridondanza inutile. La risoluzione delle espressioni temporali italiane è un problema deterministico risolto da librerie come dateparser. Addestrare un modello a fare la stessa cosa è spreco di capacità parametrica.
  3. Fragilità al cambio di data. Un modello addestrato con date assolute nel training set apprende pattern specifici ("31 ottobre" ricorre spesso) invece di generalizzare la struttura relativa.

Il resolver in pratica

Con dateparser (supporto italiano nativo) la risoluzione è tre righe:

import dateparser
from datetime import datetime

def resolve(expr: str, anchor: datetime = None) -> str | None:
    dt = dateparser.parse(expr, languages=["it"], settings={
        "PREFER_DATES_FROM": "future",
        "RELATIVE_BASE": anchor or datetime.now(),
    })
    return dt.date().isoformat() if dt else None

resolve("venerdì prossimo")   # → "2026-10-16"
resolve("primo del mese")     # → "2026-11-01"
resolve("domani")             # → "2026-10-11"
resolve("31 ottobre")         # → "2026-10-31"

Pipeline completa

Utente:  "Crea appuntamento con Marco venerdì alle 15"
          ↓  SLM + LoRA adapter
          {"intent":"create_event","contact":"Marco","date":"venerdì","time":"15:00"}
          ↓  date resolver (anchor = oggi 2026-10-10)
          {"contact":"Marco","start":"2026-10-16T15:00:00","end":"2026-10-16T16:00:00"}
          ↓  Calendar API
          Evento creato ✓
Implicazione sul dataset SFT: gli esempi di training sono corretti con espressioni temporali grezze. Il LoRA impara a estrarre l'espressione linguistica fedele all'input — non a risolverla. La data corrente non deve mai comparire nel dataset.