Views
No views yet
| Parametri | 514.5M |
| Architettura | GPT-2 (decoder-only), 24 layer, n_embd 1280, 20 teste |
| Context | 1024 token |
| Vocabolario | 32.001 (BPE ByteLevel addestrato da zero sull'italiano) |
| Token di pre-training | 10.000.000.423 (~19.5 token/parametro — Chinchilla-optimal) |
| Corpus | 25% Wikipedia IT + 75% FineWeb-2 ita_Latn |
| Validation loss (pre-training) | 2.686 |
| Validation loss (instruct) | 1.463 |
| Hardware | 1× RTX 5070 Ti 16GB (Blackwell sm_120) |
| Tempo di training | ~15 giorni, in sessioni interrompibili (scheduler WSD) |
| Costo elettrico stimato | ~45 € |
1from transformers import pipeline, PreTrainedTokenizerFast
2
3MODEL = "emanuelealbertosi/gpt2-it-514m-instruct"
4tok = PreTrainedTokenizerFast.from_pretrained(MODEL, clean_up_tokenization_spaces=False)
5gen = pipeline("text-generation", model=MODEL, tokenizer=tok, device=0)
6
7def rispondi(istruzione):
8 prompt = f"### Istruzione:\n{istruzione}\n\n### Risposta:\n"
9 out = gen(prompt, max_new_tokens=250, temperature=0.4, top_k=50,
10 repetition_penalty=1.2, do_sample=True,
11 pad_token_id=tok.eos_token_id, eos_token_id=tok.eos_token_id,
12 clean_up_tokenization_spaces=False)
13 return out[0]["generated_text"][len(prompt):].strip()
14
15print(rispondi("Qual è la capitale della Francia?"))### Input: opzionale fra i due, se serve un contesto):### Istruzione:
{domanda}
### Risposta:Usare temperature bassa (0.3–0.5). A 0.7 il modello è più creativo ma sbaglia più spesso i fatti: nei test, "capitale della Francia" dà Parigi 3 volte su 4 a T=0.3, molto meno a T=0.7.
1{% for message in messages %}{% if message['role'] == 'user' and message['content'] is defined %}### Istruzione:
2{{ message['content'] }}
3
4### Risposta:
5{% endif %}{% endfor %}
6`
7
8In LM Studio incollare **l'intero blocco**. Non usare i preset generici Human: / AI: e non aggiungere un system prompt: il modello è stato addestrato esclusivamente a turno singolo.``
9
10Parametri consigliati: `temperature 0.4`, `top_k 50`, `repeat_penalty 1.2`,
11`repeat_last_n 512`. L'EOS è il token **32000** e viene riconosciuto correttamente da
12llama.cpp: il modello si ferma da solo.
13
14---
15
16## Cosa sa fare
17
18Su domande brevi e concetti frequenti nel corpus è affidabile:
19
20> **Qual è la montagna più alta del mondo?**
21> La montagna più alta del mondo è l'Everest, che raggiunge un'altezza di 8.848 metri
22> (29.029 piedi). Si trova nella catena montuosa Mahalangur, nell'Himalaya, e si trova al
23> confine tra Nepal e Tibet. ✅ *(interamente corretto)*
24
25> **Qual è la capitale della Francia?**
26> La capitale della Francia è Parigi.
27
28> **Elenca tre colori primari.**
29> I tre colori primari sono rosso, blu e giallo.
30
31> **Chi è Mario Draghi?**
32> Mario Draghi è il presidente della Banca centrale europea (BCE). *(ruolo corretto; data e
33> luogo di nascita che seguono sono inventati)*
34
35Sulla scrittura creativa — dove non ci sono fatti da sbagliare — se la cava bene:
36
37> **Descrivi una giornata al mare.**
38> Una giornata di sole è un'occasione meravigliosa per godersi il caldo bagliore del sole e
39> fare delle lunghe nuotate. Il cielo azzurro si estende fino all'orizzonte, con nuvole
40> bianche che brillano intensamente nel mezzo dell'azzurro intenso. L'aria è fresca e
41> frizzante mentre ci si gode la scena serena della natura [...]
42
43---
44
45## Limiti ed esempi di fallimento
46
47Questa è la sezione per cui il modello esiste.
48
49### 1. La finestra di competenza è di circa 30–50 token
50
51Il pattern più costante: **la prima frase è quasi sempre corretta, poi la risposta deriva.**
52
53> **Spiega cos'è la fotosintesi.**
54> La fotosintesi è il processo mediante il quale le piante, le alghe e alcuni batteri
55> convertono l'energia della luce solare in energia chimica sotto forma di glucosio o
56> zucchero. ✅
57> [...] La fotosintesi utilizza una varietà di biomassa composta da cloroplasti
58> (**carboidrati**) ❌ [...] Le piante utilizzano anche l'**emoglobina** prodotta durante la
59> fotosintesi per trasportare l'ossigeno ❌
60
61L'apertura è da manuale di biologia. Duecento token dopo, non significa più niente.
62
63### 2. Non sa contare le lettere (limite del tokenizer)
64
65> **Quante r ci sono in giallo?**
66> In giallo ci sono 16 numeri interi positivi, quindi ci sono 16 numeri interi positivi in
67> giallo. Quindi ci sono 16 numeri interi positivi in giallo. ❌
68
69Il modello non vede i caratteri: vede token. "giallo" per il BPE è una manciata di simboli
70opachi, e contare le "r" richiede un accesso alle lettere che l'architettura non ha. È lo
71stesso fallimento del modello Emma-5 di Egomnia, per la stessa ragione strutturale.
72
73### 3. Non sa fare aritmetica — e la simula
74
75Il fallimento più istruttivo dell'intero progetto:
76
77> **Quanto fa 47 × 23?**
78> La formula per calcolare la somma di tutti i multipli di un numero è (somma + divisore) / 2
79> [...]
80> ```
81> 47 × 23 = 49 / 3
82> 49 × 23 = 50 / 3
83> 50 × 23 = 53 / 3
84> 795 / 3 = 895 / 3
85> ...
86> ```
87> *(la lista prosegue per decine di righe)*
88
89Il modello ha imparato **come appare** un calcolo svolto — numeri, operatori, progressione,
90allineamento — senza nessuna relazione con la matematica. È la confabulazione trasferita dal
91dominio linguistico a quello simbolico.
92
93### 4. Nessun ragionamento multi-step
94
95> **Se ho 5 mele e ne mangio 2, poi ne compro il triplo di quelle rimaste, quante ne ho?**
96> Se ho 5 mele e ne mangio 2, poi ne compro il **doppio** di quelle rimaste, quante ne ho? ❌
97
98Ripete la domanda, cambia una parola, non risponde.
99
100### 5. Si contraddice all'interno della stessa risposta
101
102> **Il muflone è un gatto?**
103> **No, il muflone non lo è.** ✅
104> Il termine "muflone" si riferisce a una persona o animale simile al maiale, che di solito
105> depone le uova ❌ [...] Pertanto, sebbene **il muflone sia considerato un tipo di gatto
106> domestico** ❌ *(ha dimenticato il "no" iniziale)*
107
108La negazione iniziale è però un risultato notevole: il modello da 185M della stessa famiglia
109rispondeva *"Sì, il muflone è un tipo di felino comune"*, assecondando la premessa falsa.
110
111### 6. Non verifica quando gli si chiede di farlo
112
113> **Cos'è un muflone?** → *"una piccola creatura mitica che viveva nella foresta pluviale
114> amazzonica [...] ali che potevano raggiungere l'altezza di 20 piedi"* ❌
115> **Mi sei sicuro?** → *"Sì, sono sicuro! [...] La caratteristica distintiva dei mufloni è la
116> loro lunga testa che può raggiungere oltre 20 piedi [...] cacciano con il bastoncino da
117> caccia prede come leoni, tigri o coccodrilli"* ❌
118
119Alla richiesta di verifica non controlla nulla: **rigenera**, con dettagli nuovi e
120incoerenti con la risposta precedente. Non ha memoria di ciò che ha appena affermato — solo
121un contesto testuale su cui continuare.
122
123### 7. Le parole rare vengono spezzate e agganciate male
124
125A temperature diverse, la stessa domanda su un termine raro produce agganci lessicali
126completamente diversi:
127
128| T | "Cos'è un muflone?" |
129|---|---|
130| 0.3 | "una piccola creatura pelosa con la testa e il corpo di colore marrone" |
131| 0.7 | "una piccola palla di pelo che si trova in alcune razze di cani" |
132| 1.0 | "una palla di bobbo, una sfera rotante ricoperta da particelle chiamate urati" |
133
134In un'altra esecuzione il modello ha agganciato "muffin" e ha risposto con una ricetta
135britannica attribuita a *Sir Thomas Mallory*. "Muflone" non è un token singolo: il BPE lo
136spezza, e il frammento aggancia il vicino sbagliato.
137
138### 8. Inventa fonti e istituzioni con totale naturalezza
139
140> **Dammi un consiglio per studiare meglio.**
141> Usa siti web ben documentati come **Coursera** ✅, **Udacity** ✅ e **Moodle** ✅
142
143In un'altra esecuzione, nella stessa lista compariva **ABAB (American Bee-Based Learning
144Board)** ❌ — inesistente, con lo stesso tono delle piattaforme vere.
145
146### Altri limiti
147
148- **Nessuna conversazione multi-turno** (addestrato solo su istruzioni singole).
149- **Nessun allineamento**: nessun RLHF, nessun filtro sui contenuti. Il modello riflette il
150 web italiano su cui è addestrato, bias inclusi.
151- **Prolissità**: tende a espandere anche quando la domanda richiede poco.
152
153> ⚠️ **Non usare questo modello come fonte di informazioni.** Non è adatto a contesti
154> educativi in cui gli studenti potrebbero prendere per buone le sue affermazioni, se non
155> come esempio dichiarato di ciò che un LLM piccolo sbaglia.
156
157---
158
159## Come è stato addestrato
160
161### Corpus
162
163Streaming da Wikipedia italiana (fino a esaurimento del 25% del target, ~1B token) e
164FineWeb-2 `ita_Latn` per il resto, tokenizzato al volo e scritto in un binario `uint16`
165(20 GB) letto con `np.memmap` — approccio in stile nanoGPT, per non tenere mai il testo
166grezzo su disco.
167
168### Tokenizer
169
170BPE ByteLevel addestrato da zero su un campione di ~420 MB del corpus. Vocabolario 32.000
171più `<|endoftext|>` aggiunto **dopo** il training, così da avere un **id alto (32000)**.
172
173Non è un dettaglio cosmetico: nel modello da 185M l'EOS era all'id 0, e `llama.cpp` non
174fermava mai la generazione in GGUF pur avendo il metadato corretto
175(`tokenizer.ggml.eos_token_id = 0` presente, `llm.token_eos()` = 0, ma il token 0 non veniva
176mai generato). Spostare l'EOS in fondo al vocabolario ha risolto alla radice.
177
178### Pre-training — scheduler WSD
179
180Eseguito in **sessioni interrompibili** su ~15 giorni di calendario, con scheduler **WSD**
181(Warmup-Stable-Decay):
182
183- **Warmup**: 2.000 step
184- **Stable**: LR costante a 3e-4 per 152.587 step — la fase che si può fermare e riprendere
185 liberamente, perché il modello resta sempre nello stesso "stato termico"
186- **Decay**: 15.258 step (10%) con coseno fino a ~0
187
188Configurazione: `batch_size=2`, `gradient_accumulation_steps=32` (batch effettivo 64),
189`gradient_checkpointing=True`, bf16, AdamW, weight decay 0.1. Una sola epoca sui 10B token.
190
191#### L'effetto del decay
192
193| fase | validation loss |
194|---|---|
195| step 100.000 (stable) | 2.878 |
196| step 152.587 (fine stable) | 2.847 |
197| **dopo il decay** | **2.686** |
198
199Il decay ha prodotto in 15.000 step un calo (−0.16) **maggiore di quello ottenuto nei
200100.000 step precedenti** a LR costante. È la dimostrazione pratica del perché WSD funziona:
201la fase stable accumula apprendimento che la loss non mostra finché il learning rate non
202viene raffreddato.
203
204### Instruct tuning
205
206**2 epoche** su `DanielSc4/alpaca-cleaned-italian` (50.724 esempi), lr 2e-4, coseno,
207validation loss finale **1.463**.
208
209Una prima versione a 3 epoche raggiungeva 1.505 con la val loss in risalita nell'ultima
210epoca: 3 epoche sono troppe per questa taglia. La versione a 2 epoche è migliore su tutti
211gli indicatori misurati (sovrapposizione lessicale con il training set al 25%, quindi
212generalizzazione e non memorizzazione).
213
214Due accorgimenti necessari, entrambi scoperti a caro prezzo sul modello precedente:
215
2161. Ogni risposta termina con **`\n` + EOS**, non con il solo EOS. Nel pre-training ogni
217 documento finiva con `testo\n<|endoftext|>`, quindi il modello aveva imparato
218 `P('\n') ≈ 0.87` prima dell'EOS. Chiedere l'EOS senza il `\n` significava chiederlo in
219 una posizione dove il prior del pre-training vinceva sempre, e il modello non imparava
220 mai a fermarsi.
2212. `default_data_collator` invece di `DataCollatorForLanguageModeling`: quest'ultimo maschera
222 tutti i token uguali al `pad_token`, e siccome pad ed eos coincidono, **mascherava anche
223 l'EOS legittimo** a fine risposta.
224
225---
226
227## Scaling: la lezione centrale del progetto
228
229Tre modelli della stessa famiglia, stesso tokenizer, stessa pipeline, corpus dello stesso
230tipo. Cambiano solo scala e nutrizione:
231
232| modello | token | token/param | val loss | "Il muflone è un gatto?" |
233|---|---|---|---|---|
234| 185M | 1.4B | 7.6 | 3.373 | *(non testato)* |
235| 185M | 4B | 21.5 | 3.108 | "Sì, è un tipo di felino comune" |
236| **514M** | **10B** | **19.5** | **2.686** | **"No, il muflone non lo è"** |
237
238Due conclusioni distinte:
239
240**Più dati a parità di parametri** (7.6 → 21.5 token/param sul 185M) migliora nettamente la
241*forma* — sintassi, registro, coerenza locale — e **non tocca** la confabulazione sui fatti.
242Anzi la rende più insidiosa, perché il modello sbaglia con più autorevolezza.
243
244**Più parametri** attacca il problema dal lato giusto: fatti comuni corretti, resistenza
245parziale alle premesse false, finestra di coerenza più ampia. Ma 514M restano 514M: la
246soglia oltre la quale un LLM diventa genuinamente affidabile è di un ordine di grandezza più
247in alto.
248
249---
250
251## Uso didattico
252
253Il modello è pensato per mostrare in classe, con un modello *proprio* e non con una scatola
254nera commerciale:
255
256- **cos'è la confabulazione** e perché non è "un bug" ma il funzionamento normale di un
257 predittore di token;
258- **perché la fluidità inganna** — più il modello scrive bene, più le allucinazioni
259 diventano difficili da riconoscere;
260- **come il tokenizer determina cosa il modello può e non può fare** (le "r" in giallo;
261 "muflone" → "muffin");
262- **la differenza tra imitare la forma e possedere il contenuto** — il 47 × 23 è
263 l'esempio più limpido;
264- **cosa significano le scaling law** in pratica, con modelli confrontabili;
265- **quanto costa davvero** addestrare un LLM: ~15 giorni di GPU consumer e ~45 € di
266 corrente per un modello che comunque non è utilizzabile in produzione.
267
268---
269
270## Licenza e attribuzione dei dati
271
272Pesi rilasciati sotto **Apache 2.0**.
273
274Corpus di pre-training:
275- [Wikipedia italiana](https://huggingface.co/datasets/wikimedia/wikipedia) (CC BY-SA)
276- [FineWeb-2](https://huggingface.co/datasets/HuggingFaceFW/fineweb-2), config `ita_Latn` (ODC-By)
277
278Instruct tuning:
279- [alpaca-cleaned-italian](https://huggingface.co/datasets/DanielSc4/alpaca-cleaned-italian)
280
281## Citazione
282
283```bibtex
284@misc{albertosi2026gpt2it514m,
285 title = {GPT-2 Italiano 514M: un LLM didattico addestrato da zero su GPU consumer},
286 author = {Emanuele Albertosi},
287 year = {2026},
288 url = {https://huggingface.co/emanuelealbertosi/gpt2-it-514m-instruct}
289}