English· Español· Deutsch· Nederlands· Français· 日本語· ქართული· 繁體中文· 简体中文· Português· Русский· العربية· हिन्दी· Italiano· 한국어· Polski· Svenska· Türkçe· Українська· Tiếng Việt· Bahasa Indonesia

un

ospite
1 / ?
torna alle lezioni

Larghezza Divisa tra le Teste

Una Singola Testa Vede un Pattern

L'Attività 67 ha trattato l'attenzione scaled dot-product: un vettore query Q, un vettore key K, un vettore value V; calcola Q·Kᵀ/√d_k, maschera, softmax, pondera V. Una testa impara un pattern di relazione: magari accordo soggetto-verbo, magari accoppiamento di punteggiatura, magari nulla di utile.


L'attenzione multi-testa esegue quella stessa operazione in parallelo, più volte, su diverse fette della rappresentazione di un token. Dodici teste parallele. Dodici possibili pattern di relazione. Le teste si specializzano solo attraverso la pressione dell'addestramento; nessun architetto dice alla testa 4 di guardare il tempo verbale.


La Relazione di Split

ANDREA-120M imposta d_model = 768 & n_head = 12. L'attenzione multi-head divide 768 in 12 chunk da 64 ciascuno:


head_dim = d_model / n_head
64       = 768     / 12

Ogni testa opera su vettori a 64 dimensioni. Lo split si applica in modo pulito: d_model deve essere divisibile per n_head senza resto. Le configurazioni che violano questa regola falliscono nella validazione della configurazione, non durante l'esecuzione.


Tre Modelli, Tre Split


Variantd_modeln_headhead_dim
ANDREA-12M3841232
ANDREA-120M7681264
ANDREA-480M15362464

Nota: ANDREA-12M & ANDREA-120M mantengono n_head=12 costante; solo d_model & quindi head_dim scalano. ANDREA-480M raddoppia il numero di head a 24, mantenendo head_dim=64 uguale a ANDREA-120M.

Calcolo di head_dim

Supponi una variante ipotetica ANDREA-240M che usa `d_model=1024` & `n_head=16`. Calcola `head_dim`. Poi spiega in una frase cosa succederebbe alla validazione della configurazione se un collega proponesse `d_model=1024` & `n_head=15`.

Tre Matrici Per Testa, O Una Grande Matrice

Visione Per-Testa

Ogni testa ha bisogno della propria proiezione query, proiezione key e proiezione value. Per la testa h:


Q_h = X · W_Q^h    dove W_Q^h ha forma [d_model, head_dim]
K_h = X · W_K^h    dove W_K^h ha forma [d_model, head_dim]
V_h = X · W_V^h    dove W_V^h ha forma [d_model, head_dim]

X porta la forma di input [batch, seq_len, d_model]. Dopo la proiezione, Q_h, K_h, V_h portano ciascuna la forma [batch, seq_len, head_dim].


Vista Fusa

Le matrici per testa sono disposte una accanto all'altra in memoria. Una singola matrice fusa W_Q di forma [d_model, d_model] produce tutte le teste contemporaneamente:


Q_fused = X · W_Q              # [batch, seq_len, d_model]
Q_per_head = reshape(Q_fused)  # [batch, n_head, seq_len, head_dim]

Il matmul fuso esegue una sola chiamata BLAS invece di 12. I tensor core di CUDA raggiungono il picco di throughput su matmul di questa dimensione; i matmul per testa sottoutilizzerebbero l'hardware.


Conteggio Parametri

Tre matrici fuse W_Q, W_K, W_V, ognuna d_model × d_model. Più la proiezione di output W_O, anch'essa d_model × d_model. Per ANDREA-120M:


parametri per attention di un layer = 4 × 768² = 2,359,296 ≈ 2.36M
parametri su 12 layer             = 12 × 2.36M ≈ 28.3M

Circa un quarto dei parametri totali di ANDREA-120M risiede nelle proiezioni di attenzione. I restanti tre quarti risiedono nel sottolayer MLP ed embeddings.

Nominare le Proiezioni

ANDREA-120M ha `d_model=768` & `n_head=12`. Nomina le quattro matrici di proiezione nel sottolayer di attenzione di un blocco transformer e indica la forma di ciascuna (righe × colonne). Poi specifica quale delle quattro usa l'input X e quale usa le uscite concatenate delle teste.

Dodici Vettori Diventano Uno

Multi-Head Attention Flow


Dopo che Ogni Head Ha Calcolato

Ogni head produce un tensore di output di forma [batch, seq_len, head_dim]. Dodici head producono dodici tensori di questo tipo. La concatenazione lungo la dimensione delle feature li rimette insieme:


concat_output = concat(head_1, head_2, ..., head_12)
shape         = [batch, seq_len, n_head × head_dim]
= [batch, seq_len, 768]    # for ANDREA-120M

Concat inverte lo split. La dimensione totale delle feature ritorna a d_model. Nessuna perdita di informazione nelle dimensioni; la differenza risiede in ciò che contiene ogni chunk: il chunk della testa 1 riflette il pattern di attenzione appreso dalla testa 1.


La Proiezione di Output W_O

La semplice concatenazione lascia le teste isolate: l'output della testa 4 si trova accanto all'output della testa 7, senza che nessuna sia consapevole dell'altra. La proiezione di output W_O di forma [d_model, d_model] le mescola:


attention_output = concat_output · W_O
shape            = [batch, seq_len, d_model]

Dopo W_O, ogni dimensione di output trasporta una combinazione lineare appresa di tutte e dodici le teste. Le informazioni fluiscono liberamente tra le teste attraverso questa singola moltiplicazione di matrici.


Perché le Teste si Specializzano
```

Niente nell'architettura forza la testa 4 a imparare il tempo verbale o la testa 9 a imparare la punteggiatura accoppiata. La specializzazione emerge dalla pressione del gradiente: durante l'addestramento, le teste che contribuiscono in modo ridondante ricevono gradienti più piccoli rispetto a quelle che contribuiscono in modo unico. In migliaia di passi, ogni testa si stabilizza in una nicchia che riduce la perdita totale nel modo più efficace.


Empiricamente, i transformer addestrati mostrano teste che gestiscono: pattern posizionali (la testa guarda il token precedente), pattern sintattici (la testa guarda la parentesi chiusa corrispondente), pattern semantici (la testa guarda l'entità nominata più recente). Nessuna etichetta addestra questa specializzazione. Il solo segnale di addestramento, propagato attraverso W_O, ordina le teste.

Perché Dodici Teste, Non Una Testa Più Larga

Immagina un'alternativa: sostituisci 12 teste di 64 dim ciascuna con 1 testa di 768 dim. Il numero totale di parametri nelle proiezioni rimane lo stesso. Dai due motivi distinti per cui la configurazione a 12 teste supera la configurazione a 1 testa nei compiti di modellazione del linguaggio. Fai riferimento ai pattern di attenzione o alle dinamiche di addestramento nella tua risposta.

Come CUDA Memorizza le Teste

Un Singolo Tensore, Rimodellato

Il motore di addestramento di ANDREA microgpt_cuda.cu non alloca dodici buffer separati per dodici teste. Alloca un tensore fuso unico & tratta la dimensione della testa come un pattern di stride:


// dopo Q = X · W_Q (un matmul, fuso tra le teste)
// Q ha forma [batch, seq_len, d_model]
// ridimensiona a    [batch, seq_len, n_head, head_dim]
// trasponi a  [batch, n_head, seq_len, head_dim]
// ogni testa ora è contigua nelle due dimensioni interne

Il trasponi sposta n_head prima di seq_len. Perché? Perché l'operazione successiva (Q_h · K_h^T) richiede che la fetta seq_len × head_dim di ogni testa sia contigua in memoria. I matmul CUDA sono più veloci sui tensori contigui.


Un Kernel, Molte Teste

Un singolo kernel CUDA di attention viene eseguito su tutte le teste in parallelo. Ogni thread block gestisce una coppia (batch, head); i thread all'interno del block collaborano sul tile seq_len × head_dim. Il kernel non sa mai di processare multiple teste; la griglia di lancio gestisce il parallelismo.


La Configurazione Riflette l'Hardware

La scelta di ANDREA-120M di n_head=12, head_dim=64 si allinea con i tensor core della RTX 4090, che preferiscono tile matmul in multipli di 16. head_dim=64 = 4 × 16 corrisponde esattamente alla forma del tile. head_dim=32 (ANDREA-12M) corrisponde anch'esso ma sottoutilizza il tile. head_dim=72 non corrisponderebbe e forzerebbe kernel di fallback.


Immagine Finale


StepOperationOutput shape
1. ProiezioneQ = X · W_Q (allo stesso modo K, V)[batch, seq, d_model]
2. Rimodellazione & trasposizionesuddividi d_model → (n_head, head_dim)[batch, n_head, seq, head_dim]
3. Attention per testaprodotto scalare scalato su ogni testa[batch, n_head, seq, head_dim]
4. Trasposizione & rimodellazioneunisci (n_head, head_dim) → d_model[batch, seq, d_model]
5. Proiezione di outputoutput = concat · W_O[batch, seq, d_model]

Cinque passaggi. Tre matmul toccano l'input (proiezioni Q, K, V). Una matmul tocca le teste concatenate (W_O). Un kernel di attention gestisce tutte le teste in parallelo. ANDREA-120M esegue tutti e cinque i passaggi una volta per layer, dodici layer in profondità, ad ogni forward pass.

Lettura del Pipeline

Descrivi cosa succede alla rappresentazione di un singolo token X[i] (un vettore a 768 dimensioni) mentre fluisce attraverso un singolo sottolayer di attenzione multi-head in ANDREA-120M. Menziona: le proiezioni che subisce, come viene diviso, cosa fa l'attenzione, e come ritorna a un vettore a 768 dimensioni. Mostra le dimensioni a ogni passo.