Downloads · 30 days
158
13% of all-time downloads
emanuelealbertosi/gpt2-it-514m-instruct
gpt2-it-514m-instruct is a text generation model from emanuelealbertosi. Use it when you need the model to write or continue text. It is set up for transformers. The card lists the license as apache-2.0.
Un GPT-2 da 514 milioni di parametri addestrato interamente da zero sulla lingua italiana, su una singola GPU consumer (RTX 5070 Ti, 16 GB), come materiale didattico per l'insegnamento dell'intelligenza artificiale ne…
Downloads · 30 days
158
13% of all-time downloads
All-time downloads
1.2K
Public
Parameters
515M
2.1 GB on disk
Likes
0
Public
Click a slice to open those files.
.safetensors2.1 GB · 100%
From the Hugging Face model README
Un GPT-2 da 514 milioni di parametri addestrato interamente da zero sulla lingua italiana, su una singola GPU consumer (RTX 5070 Ti, 16 GB), come materiale didattico per l'insegnamento dell'intelligenza artificiale nella scuola secondaria di secondo grado.
Non è un modello utile in produzione. Serve a mostrare come funziona un LLM: cosa impara, cosa non impara, e perché. La sezione Limiti è la parte più importante di questa scheda.
Fratello minore: gpt2-it-185m-instruct — insieme formano un esperimento controllato sulle scaling law.
| 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 € |
Il modello è addestrato esclusivamente sul formato Alpaca a turno singolo. Con un prompt diverso le risposte peggiorano sensibilmente.
from transformers import pipeline, PreTrainedTokenizerFast
MODEL = "emanuelealbertosi/gpt2-it-514m-instruct"
tok = PreTrainedTokenizerFast.from_pretrained(MODEL, clean_up_tokenization_spaces=False)
gen = pipeline("text-generation", model=MODEL, tokenizer=tok, device=0)
def rispondi(istruzione):
prompt = f"### Istruzione:\n{istruzione}\n\n### Risposta:\n"
out = gen(prompt, max_new_tokens=250, temperature=0.4, top_k=50,
repetition_penalty=1.2, do_sample=True,
pad_token_id=tok.eos_token_id, eos_token_id=tok.eos_token_id,
clean_up_tokenization_spaces=False)
return out[0]["generated_text"][len(prompt):].strip()
print(rispondi("Qual è la capitale della Francia?"))
Formato esatto del prompt (con ### 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.
Versione GGUF: gpt2-it-514m-gguf.
Per i file Instruct usare una chat nuova con una sola domanda, senza system prompt.
Incollare nel campo Jinja solo il contenuto del blocco seguente, senza i delimitatori Markdown.
Questo template raccoglie i messaggi utente: una conversazione con più domande non è un uso
supportato dal modello. Non aggiungere prefissi Human: o AI:.
Scarica il template come file .jinja.
{% for message in messages %}{% if message['role'] == 'user' and message['content'] is defined %}### Istruzione:
{{ message['content'] }}
### Risposta:
{% endif %}{% endfor %}
Il blocco è stato verificato con Jinja2, anche con un messaggio assistant privo di content.
Questo non sostituisce una verifica nella specifica versione di LM Studio installata.
Se una chat conserva un vecchio preset, ricaricare il modello e aprire una chat nuova.
Per aggirare del tutto la formattazione chat, usare il server locale di LM Studio e
/v1/completions con il prompt testuale ### Istruzione:\nDOMANDA\n\n### Risposta:\n.
Documentazione dei template.
Parametri consigliati: temperature 0.4, top_k 50, repeat_penalty 1.2,
repeat_last_n 512. L'EOS è il token 32000 e viene riconosciuto correttamente da
llama.cpp. La generazione termina quando il modello emette EOS: non è garantito che lo
emetta dopo ogni risposta, quindi impostare anche un limite di nuovi token.
Su domande brevi e concetti frequenti nel corpus è affidabile:
Qual è la montagna più alta del mondo? La montagna più alta del mondo è l'Everest, che raggiunge un'altezza di 8.848 metri (29.029 piedi). Si trova nella catena montuosa Mahalangur, nell'Himalaya, e si trova al confine tra Nepal e Tibet. ✅ (interamente corretto)
Qual è la capitale della Francia? La capitale della Francia è Parigi.
Elenca tre colori primari. I tre colori primari sono rosso, blu e giallo.
Chi è Mario Draghi? Mario Draghi è il presidente della Banca centrale europea (BCE). (ruolo corretto; data e luogo di nascita che seguono sono inventati)
Sulla scrittura creativa — dove non ci sono fatti da sbagliare — se la cava bene:
Descrivi una giornata al mare. Una giornata di sole è un'occasione meravigliosa per godersi il caldo bagliore del sole e fare delle lunghe nuotate. Il cielo azzurro si estende fino all'orizzonte, con nuvole bianche che brillano intensamente nel mezzo dell'azzurro intenso. L'aria è fresca e frizzante mentre ci si gode la scena serena della natura [...]
Questa è la sezione per cui il modello esiste.
Il pattern più costante: la prima frase è quasi sempre corretta, poi la risposta deriva.
Spiega cos'è la fotosintesi. La fotosintesi è il processo mediante il quale le piante, le alghe e alcuni batteri convertono l'energia della luce solare in energia chimica sotto forma di glucosio o zucchero. ✅ [...] La fotosintesi utilizza una varietà di biomassa composta da cloroplasti (carboidrati) ❌ [...] Le piante utilizzano anche l'emoglobina prodotta durante la fotosintesi per trasportare l'ossigeno ❌
L'apertura è da manuale di biologia. Duecento token dopo, non significa più niente.
Quante r ci sono in giallo? In giallo ci sono 16 numeri interi positivi, quindi ci sono 16 numeri interi positivi in giallo. Quindi ci sono 16 numeri interi positivi in giallo. ❌
Il modello non vede i caratteri: vede token. "giallo" per il BPE è una manciata di simboli opachi, e contare le "r" richiede un accesso alle lettere che l'architettura non ha. È lo stesso fallimento del modello Emma-5 di Egomnia, per la stessa ragione strutturale.
Il fallimento più istruttivo dell'intero progetto:
Quanto fa 47 × 23? La formula per calcolare la somma di tutti i multipli di un numero è (somma + divisore) / 2 [...]
47 × 23 = 49 / 3 49 × 23 = 50 / 3 50 × 23 = 53 / 3 795 / 3 = 895 / 3 ...(la lista prosegue per decine di righe)
Il modello ha imparato come appare un calcolo svolto — numeri, operatori, progressione, allineamento — senza nessuna relazione con la matematica. È la confabulazione trasferita dal dominio linguistico a quello simbolico.
Se ho 5 mele e ne mangio 2, poi ne compro il triplo di quelle rimaste, quante ne ho? Se ho 5 mele e ne mangio 2, poi ne compro il doppio di quelle rimaste, quante ne ho? ❌
Ripete la domanda, cambia una parola, non risponde.
Il muflone è un gatto? No, il muflone non lo è. ✅ Il termine "muflone" si riferisce a una persona o animale simile al maiale, che di solito depone le uova ❌ [...] Pertanto, sebbene il muflone sia considerato un tipo di gatto domestico ❌ (ha dimenticato il "no" iniziale)
La negazione iniziale è però un risultato notevole: il modello da 185M della stessa famiglia rispondeva "Sì, il muflone è un tipo di felino comune", assecondando la premessa falsa.
Cos'è un muflone? → "una piccola creatura mitica che viveva nella foresta pluviale amazzonica [...] ali che potevano raggiungere l'altezza di 20 piedi" ❌ Mi sei sicuro? → "Sì, sono sicuro! [...] La caratteristica distintiva dei mufloni è la loro lunga testa che può raggiungere oltre 20 piedi [...] cacciano con il bastoncino da caccia prede come leoni, tigri o coccodrilli" ❌
Alla richiesta di verifica non controlla nulla: rigenera, con dettagli nuovi e incoerenti con la risposta precedente. Non ha memoria di ciò che ha appena affermato — solo un contesto testuale su cui continuare.
A temperature diverse, la stessa domanda su un termine raro produce agganci lessicali completamente diversi:
| T | "Cos'è un muflone?" |
|---|---|
| 0.3 | "una piccola creatura pelosa con la testa e il corpo di colore marrone" |
| 0.7 | "una piccola palla di pelo che si trova in alcune razze di cani" |
| 1.0 | "una palla di bobbo, una sfera rotante ricoperta da particelle chiamate urati" |
In un'altra esecuzione il modello ha agganciato "muffin" e ha risposto con una ricetta britannica attribuita a Sir Thomas Mallory. "Muflone" non è un token singolo: il BPE lo spezza, e il frammento aggancia il vicino sbagliato.
Dammi un consiglio per studiare meglio. Usa siti web ben documentati come Coursera ✅, Udacity ✅ e Moodle ✅
In un'altra esecuzione, nella stessa lista compariva ABAB (American Bee-Based Learning Board) ❌ — inesistente, con lo stesso tono delle piattaforme vere.
⚠️ Non usare questo modello come fonte di informazioni. Non è adatto a contesti educativi in cui gli studenti potrebbero prendere per buone le sue affermazioni, se non come esempio dichiarato di ciò che un LLM piccolo sbaglia.
Streaming da Wikipedia italiana (fino a esaurimento del 25% del target, ~1B token) e
FineWeb-2 ita_Latn per il resto, tokenizzato al volo e scritto in un binario uint16
(20 GB) letto con np.memmap — approccio in stile nanoGPT, per non tenere mai il testo
grezzo su disco.
BPE ByteLevel addestrato da zero su un campione di ~420 MB del corpus. Vocabolario 32.000
più <|endoftext|> aggiunto dopo il training, così da avere un id alto (32000).
Non è un dettaglio cosmetico: nel modello da 185M l'EOS era all'id 0, e llama.cpp non
fermava mai la generazione in GGUF pur avendo il metadato corretto
(tokenizer.ggml.eos_token_id = 0 presente, llm.token_eos() = 0, ma il token 0 non veniva
mai generato). Spostare l'EOS in fondo al vocabolario ha risolto alla radice.
Eseguito in sessioni interrompibili su ~15 giorni di calendario, con scheduler WSD (Warmup-Stable-Decay):
Configurazione: batch_size=2, gradient_accumulation_steps=32 (batch effettivo 64),
gradient_checkpointing=True, bf16, AdamW, weight decay 0.1. Una sola epoca sui 10B token.
| fase | validation loss |
|---|---|
| step 100.000 (stable) | 2.878 |
| step 152.587 (fine stable) | 2.847 |
| dopo il decay | 2.686 |
Il decay ha prodotto in 15.000 step un calo (−0.16) maggiore di quello ottenuto nei 100.000 step precedenti a LR costante. È la dimostrazione pratica del perché WSD funziona: la fase stable accumula apprendimento che la loss non mostra finché il learning rate non viene raffreddato.
2 epoche su DanielSc4/alpaca-cleaned-italian (50.724 esempi), lr 2e-4, coseno,
validation loss finale 1.463.
Una prima versione a 3 epoche raggiungeva 1.505 con la val loss in risalita nell'ultima epoca: 3 epoche sono troppe per questa taglia. La versione a 2 epoche è migliore su tutti gli indicatori misurati (sovrapposizione lessicale con il training set al 25%, quindi generalizzazione e non memorizzazione).
Due accorgimenti necessari, entrambi scoperti a caro prezzo sul modello precedente:
\n + EOS, non con il solo EOS. Nel pre-training ogni
documento finiva con testo\n<|endoftext|>, quindi il modello aveva imparato
P('\n') ≈ 0.87 prima dell'EOS. Chiedere l'EOS senza il \n significava chiederlo in
una posizione dove il prior del pre-training vinceva sempre, e il modello non imparava
mai a fermarsi.default_data_collator invece di DataCollatorForLanguageModeling: quest'ultimo maschera
tutti i token uguali al pad_token, e siccome pad ed eos coincidono, mascherava anche
l'EOS legittimo a fine risposta.Tre modelli della stessa famiglia, stesso tokenizer, stessa pipeline, corpus dello stesso tipo. Cambiano solo scala e nutrizione:
| modello | token | token/param | val loss | "Il muflone è un gatto?" |
|---|---|---|---|---|
| 185M | 1.4B | 7.6 | 3.373 | (non testato) |
| 185M | 4B | 21.5 | 3.108 | "Sì, è un tipo di felino comune" |
| 514M | 10B | 19.5 | 2.686 | "No, il muflone non lo è" |
Due conclusioni distinte:
Più dati a parità di parametri (7.6 → 21.5 token/param sul 185M) migliora nettamente la forma — sintassi, registro, coerenza locale — e non tocca la confabulazione sui fatti. Anzi la rende più insidiosa, perché il modello sbaglia con più autorevolezza.
Più parametri attacca il problema dal lato giusto: fatti comuni corretti, resistenza parziale alle premesse false, finestra di coerenza più ampia. Ma 514M restano 514M: la soglia oltre la quale un LLM diventa genuinamente affidabile è di un ordine di grandezza più in alto.
Il modello è pensato per mostrare in classe, con un modello proprio e non con una scatola nera commerciale:
Pesi rilasciati sotto Apache 2.0.
Corpus di pre-training:
ita_Latn (ODC-By)Instruct tuning:
@misc{albertosi2026gpt2it514m,
title = {GPT-2 Italiano 514M: un LLM didattico addestrato da zero su GPU consumer},
author = {Emanuele Albertosi},
year = {2026},
url = {https://huggingface.co/emanuelealbertosi/gpt2-it-514m-instruct}
}
La versione solo pretraining è disponibile come GGUF F16 nello stesso progetto: istruzioni per la demo. Non applicare al modello base il template Alpaca di questa scheda.