Un Embedding è un Lookup, non una Funzione
Un Primo Strato Dopo un Tokenizer
Un tokenizer fornisce al modello ID interi: [256, 1842, 7301, ...]. La prima cosa che fa un transformer è convertire ogni ID in un vettore di d_model numeri in virgola mobile. Quel vettore vive in uno spazio a d_model dimensioni (768 dimensioni per ANDREA-120M).
Un embedding layer è una tabella di lookup, non una funzione. Immagina una matrice gigante:
shape: (V, d_model)
riga 0: [e_0_0, e_0_1, ..., e_0_767]
riga 1: [e_1_0, e_1_1, ..., e_1_767]
...
riga 8448: [e_8448_0, e_8448_1, ..., e_8448_767]
L'ID del token i seleziona la riga i. Accesso diretto all'array. Nessuna operazione aritmetica, nessuna funzione di attivazione. Solo un indice.
Float addestrabili
Ogni voce in quella tabella inizia come un piccolo float casuale (tipicamente estratto da una distribuzione normale scalata per 1/sqrt(d_model)). La backpropagation aggiorna ogni riga ogni volta che il suo ID del token appare in un batch. Dopo l'addestramento, token simili (cat, dog, pet) finiscono con vettori simili; token non correlati (cat, Tuesday, xylophone) si posizionano lontani nello spazio vettoriale.
ANDREA-120M Costo dell'Embedding Token
| Quantità | Valore |
|---|---|
| V | 8,449 |
| d_model | 768 |
| Parametri | 6,488,832 |
Circa 6,5M parametri risiedono solo nella tabella di embedding dei token, circa il 5,4% del totale di ANDREA-120M. Ogni slot del vocabolario riceve questi 768 float.
Dimensionamento delle Tabelle di Embedding
I Prodotti Scalari Misurano la Somiglianza
Vettori come Frecce
Un vettore a 768 dimensioni vive in uno spazio che gli esseri umani non possono visualizzare, ma la stessa algebra funziona in qualsiasi dimensione. Due operazioni chiave sono importanti per i transformer:
Magnitudine (lunghezza di una freccia):
||v|| = sqrt(v_0² + v_1² + ... + v_767²)
Prodotto scalare (allineamento tra due vettori):
u · v = u_0 × v_0 + u_1 × v_1 + ... + u_767 × v_767
Cosa ti dice il Prodotto Scalare
Due fatti che valgono in qualsiasi dimensione:
- u · v = ||u|| × ||v|| × cos(theta), dove theta è l'angolo tra essi.
- Vettori che puntano nella stessa direzione danno prodotti scalari grandi e positivi.
- Vettori che puntano in direzioni opposte danno prodotti scalari grandi e negativi.
- Vettori ad angolo retto danno un prodotto scalare nullo.
Prodotto scalare = similarità non normalizzata. Due embedding addestrati per cat e dog finiscono con un prodotto scalare alto perché la backpropagation li ha avvicinati (entrambi predicono contesti legati agli animali domestici). cat e Tuesday finiscono quasi ortogonali perché predicono contesti diversi.
Perché un Transformer si preoccupa
L'Attività 5 (grow_a_language_model_attention) costruisce l'attenzione a partire dai prodotti scalari: un vettore query moltiplicato per i vettori chiave produce punteggi che indicano quali token passati sono rilevanti per prevedere il successivo. Gli embedding e i prodotti scalari insieme trasportano ogni interazione all'interno di un transformer.
Prevedi la Somiglianza
ANDREA Usa Positional Embeddings Apprese
Un Problema
Un token embedding indica al modello quale parola si trova in questa posizione. Non indica al modello dove si trova quella parola. Senza informazioni sulla posizione, un transformer tratta the cat sat on a mat e mat a on sat cat the in modo identico: lo stesso insieme di token, senza alcun segnale di ordine.
Nella letteratura sui transformer esistono tre soluzioni:
Sinusoidali (Vaswani 2017). Una formula matematica fissa basata su seni e coseni. La posizione 0 riceve un vettore specifico di 768 elementi; la posizione 1 ne riceve un altro; mai addestrati, mai aggiornati. Generalizza a qualsiasi posizione tramite la formula.
RoPE (Rotary Position Embedding). Ruota i vettori di query e key in base alla posizione. Utilizzato da LLaMA e Qwen. Nessun parametro aggiuntivo; la rotazione è integrata nell'attention.
Learned. Una tabella di embedding separata con forma (T, d_model), dove T è la lunghezza del contesto. Ogni riga viene addestrata tramite backpropagation, proprio come gli embedding dei token.
Scelta di ANDREA: Learned
ANDREA eredita un approccio con posizioni learned da microGPT, che a sua volta lo ha ereditato da nanoGPT, che lo ha ereditato da GPT-2. Una motivazione:
- Semplicità. Nessuna matematica speciale nell'attention. Una tabella delle posizioni è simile a una tabella dei token.
- Compatibilità con CUDA personalizzato. Il motore microgpt_cuda.cu di ANDREA gestisce due lookup di embedding in modo identico; non servono kernel sin/cos.
- Sufficiente per contesto fisso. ANDREA limita T a 1024. Una tabella appresa funziona bene per sequenze a lunghezza fissa.
Costo dell'Embedding di Posizione di ANDREA-120M
| Quantità | Valore |
|---|---|
| T (contesto) | 1,024 |
| d_model | 768 |
| Parametri | 786,432 |
0.79M parametri per la posizione. Combinati con gli embedding dei token: 6.49M + 0.79M = 7.27M parametri di embedding totali per ANDREA-120M.
Come si combinano
A ogni posizione t in una sequenza di input:
x_t = token_embedding[token_id_t] + position_embedding[t]
Due vettori di 768 elementi, sommati elemento per elemento. Il risultato, x_t, entra nel primo blocco transformer. Il modello non li separa mai più; impara a usare il segnale combinato.
Learned Versus Sinusoidal
Dove Vivono i Parametri degli Embedding
Un Livello di Embedding Completo ANDREA-120M
| Componente | Forma | Parametri |
|---|---|---|
| Tabella degli embedding dei token | 8.449 × 768 | 6.488.832 |
| Tabella degli embedding di posizione | 1.024 × 768 | 786.432 |
| Totale | 7.275.264 |
Circa 7,3M parametri. Il numero totale di parametri di ANDREA-120M: ~120M. Solo il livello di embedding: 6%. Il restante 94% si trova nei blocchi transformer (attention + MLP, trattati nelle attività 5-7).
Embedding separati vs condivisi
Molti design di transformer (GPT-2 incluso) legano un token embedding a una proiezione di output finale: la stessa matrice V × d_model viene usata sia in input che in output (logits sul vocabolario). Il tying risparmia parametri V × d_model e spesso migliora la qualità.
ANDREA usa embedding non legati: l’embedding di input e la proiezione di output vengono addestrati come matrici separate. L’attività 7 (grow_a_language_model_transformer_block) copre uno strato finale.
Un Passaggio in Avanti Finora
Input: ID dei token [256, 1842, 7301, ...] (1024 in totale). Ogni ID recupera un vettore di 768. Ogni posizione recupera un vettore di 768. Somma elemento per elemento. Risultato: una matrice (1024, 768) x di vettori token+posizione. x fluisce nel transformer block 1.
L’attività 5 (grow_a_language_model_attention) copre ciò che fa il block 1: scaled dot-product attention con maschera causale e softmax.