Instructions to use emanuelealbertosi/gpt2-it-514m-instruct with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use emanuelealbertosi/gpt2-it-514m-instruct with Transformers:
# Use a pipeline as a high-level helper from transformers import pipeline pipe = pipeline("text-generation", model="emanuelealbertosi/gpt2-it-514m-instruct")# Load model directly from transformers import AutoTokenizer, AutoModelForCausalLM tokenizer = AutoTokenizer.from_pretrained("emanuelealbertosi/gpt2-it-514m-instruct") model = AutoModelForCausalLM.from_pretrained("emanuelealbertosi/gpt2-it-514m-instruct", device_map="auto") - Notebooks
- Google Colab
- Kaggle
- Local Apps Settings
- vLLM
How to use emanuelealbertosi/gpt2-it-514m-instruct with vLLM:
Install from pip and serve model
# Install vLLM from pip: pip install vllm # Start the vLLM server: vllm serve "emanuelealbertosi/gpt2-it-514m-instruct" # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:8000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "emanuelealbertosi/gpt2-it-514m-instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker
docker model run hf.co/emanuelealbertosi/gpt2-it-514m-instruct
- SGLang
How to use emanuelealbertosi/gpt2-it-514m-instruct with SGLang:
Install from pip and serve model
# Install SGLang from pip: pip install sglang # Start the SGLang server: python3 -m sglang.launch_server \ --model-path "emanuelealbertosi/gpt2-it-514m-instruct" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "emanuelealbertosi/gpt2-it-514m-instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }'Use Docker images
docker run --gpus all \ --shm-size 32g \ -p 30000:30000 \ -v ~/.cache/huggingface:/root/.cache/huggingface \ --env "HF_TOKEN=<secret>" \ --ipc=host \ lmsysorg/sglang:latest \ python3 -m sglang.launch_server \ --model-path "emanuelealbertosi/gpt2-it-514m-instruct" \ --host 0.0.0.0 \ --port 30000 # Call the server using curl (OpenAI-compatible API): curl -X POST "http://localhost:30000/v1/completions" \ -H "Content-Type: application/json" \ --data '{ "model": "emanuelealbertosi/gpt2-it-514m-instruct", "prompt": "Once upon a time,", "max_tokens": 512, "temperature": 0.5 }' - Docker Model Runner
How to use emanuelealbertosi/gpt2-it-514m-instruct with Docker Model Runner:
docker model run hf.co/emanuelealbertosi/gpt2-it-514m-instruct
GPT-2 Italiano 514M — modello didattico addestrato da zero
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.
In breve
| 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 € |
Come si usa
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.
GGUF / LM Studio
Versione GGUF: gpt2-it-514m-gguf.
Template Jinja (turno singolo — il modello non ha mai visto conversazioni multi-turno):
{% for message in messages %}{% if message['role'] == 'user' and message['content'] is defined %}### Istruzione:
{{ message['content'] }}
### Risposta:
{% endif %}{% endfor %}
`
In 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.``
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: il modello si ferma da solo.
---
## Cosa sa fare
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 [...]
---
## Limiti ed esempi di fallimento
Questa è la sezione per cui il modello esiste.
### 1. La finestra di competenza è di circa 30–50 token
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.
### 2. Non sa contare le lettere (limite del tokenizer)
> **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.
### 3. Non sa fare aritmetica — e la simula
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.
### 4. Nessun ragionamento multi-step
> **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.
### 5. Si contraddice all'interno della stessa risposta
> **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.
### 6. Non verifica quando gli si chiede di farlo
> **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.
### 7. Le parole rare vengono spezzate e agganciate male
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.
### 8. Inventa fonti e istituzioni con totale naturalezza
> **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.
### Altri limiti
- **Nessuna conversazione multi-turno** (addestrato solo su istruzioni singole).
- **Nessun allineamento**: nessun RLHF, nessun filtro sui contenuti. Il modello riflette il
web italiano su cui è addestrato, bias inclusi.
- **Prolissità**: tende a espandere anche quando la domanda richiede poco.
> ⚠️ **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.
---
## Come è stato addestrato
### Corpus
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.
### Tokenizer
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.
### Pre-training — scheduler WSD
Eseguito in **sessioni interrompibili** su ~15 giorni di calendario, con scheduler **WSD**
(Warmup-Stable-Decay):
- **Warmup**: 2.000 step
- **Stable**: LR costante a 3e-4 per 152.587 step — la fase che si può fermare e riprendere
liberamente, perché il modello resta sempre nello stesso "stato termico"
- **Decay**: 15.258 step (10%) con coseno fino a ~0
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.
#### L'effetto del decay
| 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.
### Instruct tuning
**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:
1. Ogni risposta termina con **`\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.
2. `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.
---
## Scaling: la lezione centrale del progetto
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.
---
## Uso didattico
Il modello è pensato per mostrare in classe, con un modello *proprio* e non con una scatola
nera commerciale:
- **cos'è la confabulazione** e perché non è "un bug" ma il funzionamento normale di un
predittore di token;
- **perché la fluidità inganna** — più il modello scrive bene, più le allucinazioni
diventano difficili da riconoscere;
- **come il tokenizer determina cosa il modello può e non può fare** (le "r" in giallo;
"muflone" → "muffin");
- **la differenza tra imitare la forma e possedere il contenuto** — il 47 × 23 è
l'esempio più limpido;
- **cosa significano le scaling law** in pratica, con modelli confrontabili;
- **quanto costa davvero** addestrare un LLM: ~15 giorni di GPU consumer e ~45 € di
corrente per un modello che comunque non è utilizzabile in produzione.
---
## Licenza e attribuzione dei dati
Pesi rilasciati sotto **Apache 2.0**.
Corpus di pre-training:
- [Wikipedia italiana](https://huggingface.co/datasets/wikimedia/wikipedia) (CC BY-SA)
- [FineWeb-2](https://huggingface.co/datasets/HuggingFaceFW/fineweb-2), config `ita_Latn` (ODC-By)
Instruct tuning:
- [alpaca-cleaned-italian](https://huggingface.co/datasets/DanielSc4/alpaca-cleaned-italian)
## Citazione
```bibtex
@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}
}
- Downloads last month
- 280