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

un

invité
1 / ?
retour aux leçons

La largeur se divise entre les têtes

Une seule tête voit un motif

L'activité 67 a couvert l'attention par produit scalaire normalisé : un vecteur requête Q, un vecteur clé K, un vecteur valeur V ; calculer Q·Kᵀ/√d_k, masquage, softmax, pondérer V. Une tête apprend un motif de relation : peut-être accord sujet-verbe, peut-être appariement de ponctuation, peut-être rien d'utile.


L'attention multi-têtes exécute cette même opération en parallèle, plusieurs fois, sur différentes tranches de la représentation d'un token. Douze têtes parallèles. Douze motifs de relation possibles. Les têtes se spécialisent par la pression d'entraînement seule ; aucun architecte ne dit à la tête 4 de regarder le temps des verbes.


La Relation de Division

ANDREA-120M définit d_model = 768 & n_head = 12. L'attention multi-têtes divise 768 en 12 chunks de 64 chacun :


head_dim = d_model / n_head
64       = 768     / 12

Chaque tête opère sur des vecteurs de 64 dimensions. La division s'applique proprement : d_model doit être divisible par n_head sans reste. Les configurations qui violent cela échouent à la validation de configuration, pas à l'exécution.


Trois Modèles, Trois Divisions


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

Remarque : ANDREA-12M & ANDREA-120M conservent n_head=12 constant ; seul d_model & donc head_dim évoluent. ANDREA-480M double le nombre de têtes à 24, en conservant head_dim=64 identique à ANDREA-120M.

Calcul de head_dim

Supposons une variante hypothétique ANDREA-240M utilisant `d_model=1024` & `n_head=16`. Calculez `head_dim`. Puis expliquez en une phrase ce qui se passerait lors de la validation de configuration si un collègue proposait `d_model=1024` & `n_head=15`.

Trois matrices par tête, ou une grande matrice

Vue par tête

Chaque tête a besoin de sa propre projection de requête, projection de clé et projection de valeur. Pour la tête h :


Q_h = X · W_Q^h    où W_Q^h a la forme [d_model, head_dim]
K_h = X · W_K^h    où W_K^h a la forme [d_model, head_dim]
V_h = X · W_V^h    où W_V^h a la forme [d_model, head_dim]

X porte la forme d'entrée [batch, seq_len, d_model]. Après projection, Q_h, K_h, V_h portent chacun la forme [batch, seq_len, head_dim].


Vue Fusionnée

Les matrices par tête sont juxtaposées les unes à côté des autres en mémoire. Une matrice fusionnée unique W_Q de forme [d_model, d_model] produit toutes les têtes en une seule fois :


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

Le matmul fusionné effectue un seul appel BLAS au lieu de 12. Les cœurs de tenseur CUDA atteignent leur débit maximal sur des matmuls de cette taille ; les matmuls par tête sous-utiliseraient le matériel.


Nombre de paramètres

Trois matrices fusionnées W_Q, W_K, W_V, chacune de taille d_model × d_model. Plus la projection de sortie W_O, également d_model × d_model. Pour ANDREA-120M :


params par couche d'attention = 4 × 768² = 2,359,296 ≈ 2,36M
params sur 12 couches      = 12 × 2,36M ≈ 28,3M

Environ un quart des paramètres totaux d'ANDREA-120M se trouvent dans les projections d'attention. Les trois quarts restants se trouvent dans la sous-couche MLP & les embeddings.

Nommer les Projections

ANDREA-120M a `d_model=768` & `n_head=12`. Nommez les quatre matrices de projection dans la sous-couche d'attention d'un bloc transformer & donnez la forme de chacune (lignes × colonnes). Puis indiquez laquelle des quatre utilise l'entrée X & laquelle utilise les sorties des têtes concaténées.

Douze Vecteurs Deviennent Un

Multi-Head Attention Flow


Après le calcul de chaque tête

Chaque tête produit un tenseur de sortie de forme [batch, seq_len, head_dim]. Douze têtes produisent douze tenseurs de ce type. La concaténation le long de la dimension des caractéristiques les réunit à nouveau :


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

Concat inverse le split. La dimension totale des caractéristiques revient à d_model. Pas de perte d'information dans les dimensions ; la différence réside dans ce que contient chaque chunk : le chunk de la tête 1 reflète le motif d'attention appris de la tête 1.


La Projection de Sortie W_O

La concaténation seule laisse les têtes isolées : la sortie de la tête 4 est juxtaposée à celle de la tête 7, sans qu'elles soient conscientes l'une de l'autre. La projection de sortie W_O de forme [d_model, d_model] les mélange :


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

Après W_O, chaque dimension de sortie transporte une combinaison linéaire apprise de toutes les douze têtes. L'information circule librement entre les têtes grâce à cette unique multiplication matricielle.


Pourquoi les têtes se spécialisent
```

Rien dans l'architecture n'oblige la tête 4 à apprendre le temps des verbes ou la tête 9 à apprendre la ponctuation appariée. La spécialisation émerge de la pression des gradients : pendant l'entraînement, les têtes qui contribuent de manière redondante reçoivent des gradients plus petits que celles qui contribuent de manière unique. Sur des milliers d'étapes, chaque tête se niche dans un rôle qui réduit le plus efficacement la perte totale.


Empiriquement, les transformers entraînés montrent des têtes qui gèrent : des motifs positionnels (la tête regarde le token précédent), des motifs syntaxiques (la tête regarde la parenthèse fermante correspondante), des motifs sémantiques (la tête regarde l'entité nommée la plus récente). Aucune étiquette n'entraîne cette spécialisation. Le signal d'entraînement seul, propagé à travers W_O, trie les têtes.

Pourquoi douze têtes, et non une tête plus large

Imaginez une alternative : remplacez 12 têtes de 64 dim chacune par 1 tête de 768 dim. Le nombre total de paramètres dans les projections reste le même. Donnez deux raisons distinctes pour lesquelles la configuration à 12 têtes surpasse la configuration à 1 tête sur les tâches de modélisation linguistique. Référez-vous aux motifs d'attention ou à la dynamique d'entraînement dans votre réponse.

Comment CUDA stocke les têtes

Un seul tenseur, remodelé

Le moteur d'entraînement d'ANDREA microgpt_cuda.cu n'alloue pas douze tampons séparés pour douze têtes. Il alloue un tenseur fusionné & traite la dimension des têtes comme un motif de stride :


// après Q = X · W_Q (une multiplication matricielle, fusionnée à travers les têtes)
// Q a la forme [batch, seq_len, d_model]
// remodeler en    [batch, seq_len, n_head, head_dim]
// transposer en  [batch, n_head, seq_len, head_dim]
// chaque tête est maintenant contiguë dans les deux dimensions internes

La transposition place n_head avant seq_len. Pourquoi ? Parce que l'opération suivante (Q_h · K_h^T) nécessite que la tranche seq_len × head_dim de chaque tête soit contiguë en mémoire. Les matmuls CUDA s'exécutent plus rapidement sur des tenseurs contigus.


Un Kernel, Beaucoup de Têtes

Un seul noyau CUDA d'attention s'exécute sur toutes les têtes en parallèle. Chaque bloc de threads gère une paire (batch, tête) ; les threads à l'intérieur du bloc coopèrent sur la tuile seq_len × head_dim. Le noyau ne sait jamais qu'il traite plusieurs têtes ; la grille de lancement gère le parallélisme.


Configuration Reflects the Hardware

Le choix de n_head=12, head_dim=64 pour ANDREA-120M s'aligne avec les cœurs tenseurs de la RTX 4090, qui préfèrent les tuiles matmul en multiples de 16. head_dim=64 = 4 × 16 correspond exactement à la forme de la tuile. head_dim=32 (ANDREA-12M) correspond aussi mais sous-utilise la tuile. head_dim=72 ne correspondrait pas & forcerait des noyaux de repli.


Final Picture


ÉtapeOpérationForme de sortie
1. ProjetQ = X · W_Q (de même pour K, V)[batch, seq, d_model]
2. Redimensionner & transposerdiviser d_model → (n_head, head_dim)[batch, n_head, seq, head_dim]
3. Attention par têteproduit scalaire pondéré par tête[batch, n_head, seq, head_dim]
4. Transposer & redimensionnerfusionner (n_head, head_dim) → d_model[batch, seq, d_model]
5. Projection de sortiesortie = concat · W_O[batch, seq, d_model]

Cinq étapes. Trois multiplications matricielles touchent l'entrée (projections Q, K, V). Une multiplication matricielle touche les têtes concaténées (W_O). Un noyau d'attention gère toutes les têtes en parallèle. ANDREA-120M exécute les cinq étapes une fois par couche, douze couches de profondeur, à chaque passe avant.

Lecture du Pipeline

Parcourez ce qui arrive à la représentation d'un seul token X[i] (un vecteur de 768 dimensions) alors qu'il traverse une sous-couche d'attention multi-tête dans ANDREA-120M. Mentionnez : les projections qu'il subit, comment il est divisé, ce que fait l'attention, & comment il revient à un vecteur de 768 dimensions. Montrez les dimensions à chaque étape.