BPE: Come Funziona l'Algoritmo che Taglia le Parole
Byte Pair Encoding decide come GPT, Claude e Llama vedono il testo. Da compressione 1994 a cuore di ogni LLM. Step-by-step con esempi e trappole.
Alessandro Saiani
Human in the Loop

Nell'articolo sui token abbiamo visto che un token non è una parola, non è un carattere, e che la tokenizzazione costa soldi. Abbiamo anche visto che l'algoritmo più diffuso si chiama BPE — Byte Pair Encoding.
Ma l'abbiamo visto in 30 secondi. Ora andiamo a fondo.
Perché BPE merita un articolo intero? Perché è l'algoritmo che decide come l'AI vede il testo. Ogni decisione che BPE prende durante l'addestramento — quali coppie fondere, quante volte, in quale ordine — determina il vocabolario del modello. E il vocabolario determina cosa il modello può "vedere" e cosa gli è invisibile.
Se "strawberry" diventa ["str", "aw", "berry"], il modello non sa quante 'r' ci sono. Se "SolidGoldMagikarp" diventa un singolo token, il modello impazzisce quando glielo chiedi. Se l'italiano consuma il 40% di token in più dell'inglese, è perché BPE ha visto più inglese durante il training.
Tutto parte da qui.
Da Compressione a Linguaggio: La Storia
BPE nasce nel febbraio 1994. Philip Gage pubblica "A New Algorithm for Data Compression" sul C Users Journal — una rivista per programmatori C. L'idea è semplice: prendi un file, trova la coppia di byte adiacenti più frequente, sostituiscila con un byte nuovo. Ripeti. Il file si comprime.
Per 21 anni, nessuno pensa di usarlo per il linguaggio naturale.
Poi, nel 2015, tre ricercatori dell'Università di Edimburgo — Rico Sennrich, Barry Haddow e Alexandra Birch — hanno un problema: la traduzione automatica non sa gestire le parole rare. Se il modello non ha mai visto "Donaudampfschifffahrtsgesellschaft" (una parola tedesca reale), non può tradurla.
La loro intuizione: non servono parole intere. Servono pezzi di parole. E BPE è perfetto per trovarli — basta applicarlo ai caratteri del testo invece che ai byte di un file.
Il paper "Neural Machine Translation of Rare Words with Subword Units" viene pubblicato all'ACL 2016 e cambia tutto. Da quel momento, BPE (e le sue varianti) diventa il tokenizzatore standard di GPT, GPT-2, RoBERTa, e praticamente ogni LLM che usi oggi.
L'Algoritmo Step-by-Step
Facciamolo insieme, a mano. Niente codice per ora — solo carta e penna (mentale).
Il Corpus di Training
Supponiamo di voler addestrare un tokenizzatore su questo mini-corpus (con le frequenze di ogni parola):
"hug" (10 volte)
"pug" (5 volte)
"pun" (12 volte)
"bun" (4 volte)
"hugs" (5 volte)
Passo 0: Vocabolario Iniziale
Partiamo dai singoli caratteri. Ogni carattere è un token:
Vocabolario: [b, g, h, n, p, s, u]
Corpus tokenizzato:
h u g (×10)
p u g (×5)
p u n (×12)
b u n (×4)
h u g s (×5)
Passo 1: Conta le Coppie
Contiamo quante volte ogni coppia di token adiacenti appare:
| Coppia | Frequenza | Calcolo |
|---|---|---|
| (h, u) | 15 | hug(10) + hugs(5) |
| (u, g) | 20 | hug(10) + pug(5) + hugs(5) |
| (p, u) | 17 | pug(5) + pun(12) |
| (u, n) | 16 | pun(12) + bun(4) |
| (b, u) | 4 | bun(4) |
| (g, s) | 5 | hugs(5) |
La coppia (u, g) vince con 20 occorrenze. La fondiamo.
Regola di merge #1: u + g → ug
Vocabolario: [b, g, h, n, p, s, u, ug]
Corpus:
h ug (×10)
p ug (×5)
p u n (×12)
b u n (×4)
h ug s (×5)
Passo 2: Ricontiamo
| Coppia | Frequenza |
|---|---|
| (h, ug) | 15 |
| (p, ug) | 5 |
| (p, u) | 12 |
| (u, n) | 16 |
| (b, u) | 4 |
| (ug, s) | 5 |
Vince (u, n) con 16.
Regola di merge #2: u + n → un
Vocabolario: [b, g, h, n, p, s, u, ug, un]
Corpus:
h ug (×10)
p ug (×5)
p un (×12)
b un (×4)
h ug s (×5)
Passo 3: Ancora
| Coppia | Frequenza |
|---|---|
| (h, ug) | 15 |
| (p, ug) | 5 |
| (p, un) | 12 |
| (b, un) | 4 |
| (ug, s) | 5 |
Vince (h, ug) con 15.
Regola di merge #3: h + ug → hug
Vocabolario: [b, g, h, n, p, s, u, ug, un, hug]
Corpus:
hug (×10)
p ug (×5)
p un (×12)
b un (×4)
hug s (×5)
Potremmo continuare — la prossima merge sarebbe p + un → pun (12), poi hug + s → hugs (5), e così via. Ma il principio è chiaro: le sequenze più comuni vengono fuse prima, creando token sempre più lunghi.
Il Risultato
Dopo abbastanza iterazioni, il vocabolario contiene:
- I caratteri base (sempre presenti come fallback)
- I subword appresi:
ug,un,hug,pun,hugs... - Una lista ordinata di regole di merge che dice esattamente come ricostruire ogni token
Il numero di merge è un iperparametro: GPT-2 ne ha 50.000, GPT-4o ne ha circa 200.000. Più merge = vocabolario più grande = parole più lunghe diventano singoli token.
Come Funziona a Runtime (Encoding)
Ok, il tokenizzatore è addestrato. Ora arriva una parola nuova: "unhug". Come la tokenizza?
Applica le regole di merge nell'ordine esatto in cui sono state apprese:
Input: u n h u g
Merge #1 (u+g → ug): u n h ug
Merge #2 (u+n → un): un h ug
Merge #3 (h+ug → hug): un hug
Risultato: ["un", "hug"]
Il modello "vede" un + hug — che è esattamente la struttura morfologica corretta (prefisso + radice). BPE l'ha scoperta statisticamente, senza sapere nulla di linguistica.
Un altro esempio: "bugs". Non l'abbiamo mai vista nel corpus di training.
Input: b u g s
Merge #1 (u+g → ug): b ug s
Nessun'altra merge applicabile.
Risultato: ["b", "ug", "s"]
BPE non conosce "bug", ma sa che "ug" è un pezzo comune. Questo è il punto chiave: non servono parole intere nel vocabolario. I sottopezzi bastano per rappresentare qualsiasi testo.
Byte-Level BPE: L'Innovazione di GPT-2
Il BPE di Sennrich partiva dai caratteri. Ma Unicode ha oltre 150.000 caratteri — emoji, kanji, cirillico, arabo. Se il training corpus non contiene un carattere, diventa [UNK] (sconosciuto). Addio.
Nel 2019, il paper di GPT-2 (Radford et al.) introduce una variante cruciale: Byte-Level BPE (BBPE).
L'idea: invece di partire dai caratteri, parti dai byte. Ogni file di testo è una sequenza di byte UTF-8. E i byte possibili sono solo 256 (da 0x00 a 0xFF).
Questo cambia tutto:
- Il vocabolario base è sempre 256, indipendentemente dalla lingua
- Non esistono token sconosciuti — qualsiasi testo Unicode è una sequenza di byte
- Emoji, codice, formule matematiche, anche dati binari: tutto tokenizzabile
Come GPT-2 Gestisce gli Spazi
Un trucco elegante: OpenAI mappa ogni byte a un carattere Unicode stampabile. Lo spazio (byte 0x20) viene mappato al carattere Ġ. Quindi la parola " Hello" (con spazio iniziale) diventa internamente "ĠHello".
Perché? Perché così lo spazio non è invisibile — è un carattere come gli altri, e BPE può includerlo nelle merge. La maggior parte dei token nel vocabolario di GPT ha lo spazio iniziale incorporato: il token per "the" è in realtà " the" (con spazio).
Composizione del Vocabolario GPT-2
| Componente | Quantità |
|---|---|
| Token byte base | 256 |
| Merge BPE apprese | 50.000 |
| Token speciali | 1 (<|endoftext|>) |
| Totale | 50.257 |
I Vocabolari dei Modelli: Chi Ha Cosa
Ogni modello ha il suo vocabolario. Le dimensioni variano enormemente:
| Modello | Vocabolario | Anno |
|---|---|---|
| GPT-2 | 50.257 | 2019 |
| GPT-3 | 50.257 (stesso di GPT-2) | 2020 |
| Llama 2 (Meta) | 32.000 | 2023 |
| GPT-3.5 / GPT-4 | ~100.277 | 2022-23 |
| Claude 3 (Anthropic) | ~65.000 | 2024 |
| Llama 3 (Meta) | 128.256 | 2024 |
| GPT-4o | ~200.000 | 2024 |
| Gemini / Gemma 3 (Google) | 256.000+ | 2025 |
Il trend è chiaro: i vocabolari crescono. GPT-2 aveva 50K token, GPT-4o ne ha 200K, Gemini supera i 256K.
Perché? Un vocabolario più grande significa:
- Meno token per lo stesso testo → risparmi soldi e contesto
- Migliore efficienza multilingue → meno "tassa linguistica" per le lingue non-inglesi
- Più sequenze comuni diventano singoli token → "tokenization" che prima era 2 token diventa 1
Ma c'è un costo: la matrice di embedding (che assegna un vettore a ogni token) cresce proporzionalmente. Più token = più parametri = modello più grande. E token rari rischiano di essere sotto-addestrati — il che ci porta dritti al prossimo argomento.
Le Trappole di BPE
Il Problema "Strawberry"
Nel 2024, un test virale ha mostrato che i migliori LLM non sapevano contare le lettere 'r' in "strawberry". Rispondevano 2 invece di 3.
Perché? Perché "strawberry" viene tokenizzato come ["straw", "berry"] (o ["str", "aw", "berry"] a seconda del modello). Il modello processa vettori di token, non singoli caratteri. Sa che "straw" e "berry" formano "strawberry", ma non ha accesso diretto alle lettere all'interno di ciascun token.
Le informazioni a livello di carattere sono perse ai confini dei token.
I modelli più recenti (GPT-4o, Claude 3.5+) spesso rispondono correttamente, grazie al chain-of-thought e probabilmente a training mirato. Ma il limite fondamentale della tokenizzazione resta.
I Glitch Token: SolidGoldMagikarp
Inizio 2023, dei ricercatori scoprono che chiedere a ChatGPT di ripetere la stringa "SolidGoldMagikarp" causa comportamenti bizzarri — il modello risponde come se gli avessi chiesto di ripetere "distribute".
La spiegazione: SolidGoldMagikarp era un utente Reddit molto attivo. Il suo username appariva migliaia di volte nel corpus di training. BPE ha creato un token dedicato — ma il modello ha visto quel token solo come prefisso di URL Reddit e tag HTML, mai in contesto linguistico normale.
Risultato: il token esiste nel vocabolario, ma il suo embedding è essenzialmente casuale perché non è mai stato addestrato su testo significativo. Quando il modello lo incontra, va in cortocircuito.
Altri glitch token scoperti: TheNitromeFan, InstallShield, ForgeModLoader. Tutti nomi utente o stringhe tecniche che BPE ha trasformato in token che il modello non sa usare.
A febbraio 2026, un framework chiamato GlitchMiner (presentato ad AAAI 2026) ha trovato sistematicamente glitch token in GPT-4, Llama 2, Mistral e DeepSeek-V3. Non è un problema risolto — è strutturale a BPE.
La Tassa Multilingue
BPE impara le merge dal corpus di training. E il corpus è prevalentemente in inglese. Questo significa che le coppie di caratteri inglesi vengono fuse prima e più spesso:
- Inglese: ~4 caratteri per token (efficiente)
- Italiano: ~3 caratteri per token (~40% più token)
- Ucraino: ~3x più token per la stessa frase
- Hindi, Thai: ancora peggio
Non è un bug — è una conseguenza diretta dell'algoritmo. BPE ottimizza per le sequenze più frequenti nel training data, e se il training data è 60-70% inglese, l'inglese vince.
Il passaggio da GPT-3.5 (100K token) a GPT-4o (200K token) ha migliorato la situazione per molte lingue, ma il divario resta.
Le Alternative: WordPiece e Unigram
BPE non è l'unico approccio. Due alternative importanti:
WordPiece (Google / BERT)
Usato da BERT, DistilBERT, Electra.
La differenza chiave: BPE fonde la coppia più frequente. WordPiece fonde la coppia che massimizza la verosimiglianza del corpus — cioè non guarda solo la frequenza della coppia, ma quanto quella merge migliora la probabilità complessiva dei dati.
In pratica: WordPiece è statisticamente più sofisticato, ma produce risultati simili. Usa il prefisso ## per i sottopezzi non iniziali: "playing" diventa ["play", "##ing"].
Unigram / SentencePiece (Google)
Usato da T5, XLNet, Llama (via SentencePiece).
L'approccio opposto a BPE: invece di partire piccolo e costruire verso l'alto (merge), parte da un vocabolario grande e lo riduce eliminando i token che contribuiscono meno alla rappresentazione del testo.
Il vantaggio: genera tokenizzazioni probabilistiche — la stessa parola può essere tokenizzata in modi diversi, con probabilità diverse. Questo permette il subword regularization: durante il training, ogni volta che il modello vede una parola, la vede tokenizzata in modo leggermente diverso. Come un data augmentation gratuito.
Perché BPE Ha Vinto
- Semplicità: l'algoritmo è banale da implementare e capire
- Determinismo: stesso input → stesso output (importante per caching e riproducibilità)
- BBPE: la variante byte-level ha eliminato il problema dei token sconosciuti
- Inerzia industriale: GPT-2 l'ha reso lo standard, e tutti hanno seguito
- Implementazioni veloci: tiktoken (Rust + Python) tokenizza gigabyte in secondi
Il Futuro: Oltre BPE
La ricerca sta esplorando due direzioni.
BPE Migliorate
- SuperBPE (COLM 2025): impara token che attraversano i confini delle parole. Risultato: 33% meno token, +4% di performance media su 30 benchmark, 27% in meno di compute a inference
- BoundlessBPE (COLM 2025): elimina completamente il vincolo dei confini parola, permettendo merge libere. Fino al 15% in più di byte per token
- SCRIPT-BPE: affronta l'ingiustizia multilingue, riducendo il gap di costo tra lingue da 6.4% a 1.1%
Modelli Senza Tokenizzazione
L'idea più radicale: eliminare la tokenizzazione del tutto.
- EvaByte (gennaio 2025, HKU NLP): il primo modello byte-level open source che pareggia i modelli con tokenizzatore. 6.5B parametri, funziona direttamente sui byte UTF-8. Niente tokenizzatore, niente vocabolario, niente glitch token
- Byte Latent Transformer (Meta, ICLR 2025): raggruppa byte dinamicamente in "patch" basandosi sull'entropia — comprime le parti prevedibili, usa tutta la potenza del modello solo dove il testo è complesso. Pareggia Llama 3 a parità di scala
Se funzionano a scala, questi approcci renderebbero BPE obsoleto. Ma per ora, nel 2026, BPE e le sue varianti restano al cuore di ogni modello che usi.
Strumenti Pratici
Vuoi vedere come i modelli tokenizzano il tuo testo? Ecco gli strumenti:
tiktoken (OpenAI): la libreria di riferimento. Rust + Python, 3-6x più veloce delle alternative.
import tiktoken
enc = tiktoken.encoding_for_model("gpt-4o")
tokens = enc.encode("Ciao, come funziona BPE?")
print(len(tokens)) # quanti token
print(tokens) # gli ID
print([enc.decode([t]) for t in tokens]) # ogni token decodificato
Tokenizer Playground — Interfacce web per visualizzare la tokenizzazione:
- platform.openai.com/tokenizer (OpenAI ufficiale)
- tiktokenizer.app (multi-modello, visualizzazione a colori)
Anthropic Token Counter — API ufficiale per contare i token Claude:
from anthropic import Anthropic
client = Anthropic()
result = client.messages.count_tokens(
model="claude-sonnet-4-5-20250514",
messages=[{"role": "user", "content": "Il tuo testo qui"}]
)
print(result.input_tokens)
minbpe di Karpathy — Implementazione educativa minimale, perfetta per capire BPE dal codice. Accompagnata da un video di 2 ore su YouTube.
Il Filo Rosso
BPE è nato per comprimere file nel 1994. Trent'anni dopo, è l'algoritmo che decide come ogni LLM sul pianeta vede il linguaggio.
Non è perfetto — crea glitch token, penalizza le lingue non-inglesi, perde informazioni a livello di carattere. Ma è semplice, veloce, e funziona abbastanza bene da essere sopravvissuto a ogni tentativo di sostituzione.
Nell'articolo sui token abbiamo visto cosa sono i token e quanto costano. Ora sai come vengono creati — l'algoritmo che trasforma "intelligenza artificiale" in ["intell", "ig", "enza", " artificial", "e"].
Il prossimo passo della catena è capire cosa succede dopo la tokenizzazione: come quei token diventano vettori numerici su cui il modello può ragionare. Questo ci porta dritti al pre-training — ma prima, se non l'hai ancora letto, recupera Word2Vec e Embeddings per capire lo spazio vettoriale in cui quei token vivranno.
Fonti e approfondimenti:
- Philip Gage - A New Algorithm for Data Compression (1994) — Il paper originale
- Sennrich et al. - Neural Machine Translation of Rare Words with Subword Units (2016) — Il paper che ha portato BPE nel NLP
- Hugging Face - BPE Tokenization — Tutorial interattivo step-by-step
- Karpathy - minbpe — Implementazione educativa con video
- tiktoken — Tokenizzatore BPE di OpenAI
- Sebastian Raschka - BPE Tokenizer From Scratch (2025) — Guida pratica
- GlitchMiner - AAAI 2026 — Framework per trovare glitch token
- SuperBPE - COLM 2025 — BPE con merge cross-word
- EvaByte - HKU NLP (2025) — Primo modello byte-level competitivo
- Byte Latent Transformer - Meta (ICLR 2025) — Architettura byte-level dinamica