Attention og transformer-blokken, udledt fra et gennemsnit
Start med den billigste kontekst-opsummering — gennemsnittet — mål fejlen, og lad attention-formlen opstå af reparationen.
På denne side
Du kommer hertil med en tokenizer fra Kapitel 7, en embedding-tabel fra Kapitel 8, og det mål, der følger med dem: givet de hidtidige tokens skal der sættes en sandsynlighed på den næste.
Det, der mangler, er midten. For at forudsige token har modellen brug for én vektor, der opsummerer alt før den, og intet af det, du har bygget, producerer en sådan. embedding for token er det ikke — det er en bigram-model, og den kan ikke vide, at sætningen begyndte med et spørgsmål. En sammenkædning af alle tidligere embeddings er det heller ikke: deres antal ændrer sig ved hvert trin, og en fast vægtmatrix kan ikke tage et input med variabel længde.
Altså: én vektor med fast størrelse, der opsummerer et variabelt antal vektorer. Det er hele problemet, og attention er det, du får ved at løse det på den dovnest mulige måde og derefter reparere de to ting, der går i stykker.
Svaret feltet havde, og hvorfor vi ikke bygger det
Link til afsnittet: Svaret feltet havde, og hvorfor vi ikke bygger detFra 1997 til omkring 2017 var opsummeringen en rekurrent tilstand: behold en vektor og opdater den ved hver token, . Fast størrelse, variabelt input, præcis den rigtige form.
Den fejlede på tre måder, og dette kapitels arkitektur svarer på alle tre. Backpropagating gennem trin multiplicerer Jacobianer, så gradienten forsvinder eller eksploderer — den sygdom Kapitel 5 målte inde i en enkelt -node. LSTM1 blev designet netop imod det og skubbede den brugbare rækkevidde fra titals trin til hundredvis, uden at ændre ved, at information fra token 5 kun når token 500 ved at overleve 495 sekventielle opdateringer. Hele kilden skulle passe i én vektor: i sequence-to-sequence-oversættelse2 komprimerer en encoder inputtet til sin endelige tilstand. Bahdanau, Cho og Bengio navngav den flaskehals og rettede den i 2014, tre år før transformer, ved at lade decoder tage en vægtet sum af alle encoder-tilstande med vægte, den selv beregnede.3 Alt nedenfor er den idé, anvendt af en sekvens på sig selv, med rekurrensen slettet. Og opdateringen er sekventiel af konstruktion: kræver , og en GPU med ti tusind kerner kan intet stille op med det. Arkitekturen, der vandt, er ikke åbenlyst klogere; den er den, hvis dyre trin er en matrixmultiplikation.
Den anden klassiske induktive bias, convolution — at lade ét lille filter glide over hele inputtet, så et træk, der detekteres hvor som helst, detekteres overalt — bygges heller ikke her; den er næsten præcis rigtig til billeder og overlades til et visionskursus. Hverken rekurrens eller convolution dukker op igen efter denne side, og derfor får ingen af dem et kapitel: Kapitel 1 lovede, at udeladelserne ville blive erklæret frem for holdt skjult.
Den billigste opsummering, der findes
Link til afsnittet: Den billigste opsummering, der findesDen mest oplagte funktion af et variabelt antal vektorer, som returnerer én vektor, er gennemsnittet:
Et vilkårligt antal input, fast outputstørrelse, differentiabel, gratis. Embedding-tabel plus dette gennemsnit plus et lineært lag til ordforrådet er en komplet sprogmodel på femten linjer. Den er også forfærdelig, og måden den er forfærdelig på, er hele udledningen.
Korpusset nedenfor er én megabyte Shakespeare, 1.115.394 tegn, gennem en byte-level BPE-tokenizer af den slags, der blev bygget i Kapitel 7, med et ordforråd på 1024: 459.760 tokens ved 2,43 tegn hver, delt 90/10. Hver model er 128 bred, ser 128 tokens og træner i 3000 trin med AdamW ved med en batch på 64. Perpleksitet er på den holdte split.4
| model | parametre | valideringsperpleksitet |
|---|---|---|
| kun den aktuelle token, ingen context overhovedet | 263.168 | 59,71 |
| plus det uniforme gennemsnit af alt før den | 263.168 | 248,07 |
| plus lærte position embeddings | 279.552 | 245,93 |
| uniformt gennemsnit lagt til token i stedet for at erstatte den | 263.168 | 60,45 |
Læs anden række to gange. At gennemsnitliggøre context hjælper ikke lidt; det gør modellen fire gange dårligere end at ignorere context fuldstændigt. To grunde, begge beviselige snarere end empiriske.
Gennemsnittet kan ikke se orden. Addition kommuterer, så hvis vinduet blandes rundt, forbliver opsummeringen uændret — ikke omtrentligt:
A = torch.tril(torch.ones(T, T))
A = A / A.sum(1, keepdim=True) # rows of the averaging matrix
y = x[torch.randperm(T)] # the same tokens, shuffled
print((A[-1] @ x - A[-1] @ y).abs().max().item())2.9802322387695312e-08Floating-point-støj på en omordnet sum: de to opsummeringer er den samme vektor. En model, hvis eneste blik på context er et gennemsnit, kan ikke skelne hunden bed manden fra manden bed hunden. Række tre beviser, at dette ikke kan fikses ved at tilføje positioner til inputtene — en lært position embedding på hver token før gennemsnitliggørelse købte 2,14 point ud af 188. Positionerne går ind i summen, og summen glemmer dem.
Og gennemsnittet drukner nutiden. Ved position 100 er den aktuelle token en hundrededel af opsummeringen. Det har en billig løsning, du allerede ejer: behold token og læg opsummeringen til den — en residual connection, fra Kapitel 6, og række fire viser, hvad den gør. Med udvandingen repareret bidrager det uniforme gennemsnit overhovedet intet: 60,45 mod en baseline på 59,71. Hver token er derinde, vægtet lige, og lige vægtning er det samme som ingen information.
Problemet er ikke gennemsnittet. Det er vægtene.
Gennemsnittet er en matrixmultiplikation, og masken er en softmax
Link til afsnittet: Gennemsnittet er en matrixmultiplikation, og masken er en softmaxAt gennemsnitliggøre over et voksende præfiks ligner et loop. Det er én multiplikation med en nedre trekantsmatrix, hvis rækker summerer til én — og også, præcis, en softmax:
loop = torch.stack([x[:t + 1].mean(0) for t in range(T)]) # the obvious version
A = torch.tril(torch.ones(T, T))
A = A / A.sum(1, keepdim=True)
mat = A @ x # the same thing
S = torch.zeros(T, T).masked_fill(torch.tril(torch.ones(T, T)) == 0, float("-inf"))
soft = F.softmax(S, dim=-1) @ x # and the same thing againloop vs matmul max |diff| = 5.960464477539063e-08
loop vs softmax max |diff| = 5.960464477539063e-08
the averaging matrix A (rows sum to 1, upper triangle is zero):
1.000 0.000 0.000 0.000 0.000 0.000
0.500 0.500 0.000 0.000 0.000 0.000
0.333 0.333 0.333 0.000 0.000 0.000
0.250 0.250 0.250 0.250 0.000 0.000
0.200 0.200 0.200 0.200 0.200 0.000
0.167 0.167 0.167 0.167 0.167 0.167Tre navngivne komponenter i en transformer er nu på skærmen. Trekanten er causal mask, tvunget af målet: hvis position kunne se position , ville svaret være i inputtet — lækagen Kapitel 6 bad dig auditere for, bare inde i arkitekturen. softmax er måden, masken implementeres på: at sætte forbudte entries til sender dem præcis til nul og normaliserer resten, så maskering og normalisering er én operation. (Brug , ikke -1e9: det er den værdi maskeringen betyder, den overlever et cast til float16 som , og den sparer dig for at afgøre, om den konstant du valgte, er stor nok til det interval, du tilfældigvis befinder dig i — hvilket er Kapitel 2s floating-point-boks, der stiller et spørgsmål, du ikke behøver at svare på.) Og scorerne er den frie parameter. Det uniforme gennemsnit er det, du får, når hver tilladt score er det samme tal; sæt hvilke som helst tal derind, og softmax omdanner dem til gyldige vægte.
Resten af dette kapitel er ét spørgsmål: hvor kommer de tal fra?
Query, key, value
Link til afsnittet: Query, key, valueDe kan ikke være almindelige parametre. En lært -matrix ville være identisk for hver sætning — den kunne encode "look four tokens back", men aldrig "look at the noun this pronoun refers to". Vægten, der forbinder position med position , må afhænge af, hvad der er ved begge positioner, fordi relevans er en relation, ikke en egenskab: ordet it er ikke iboende relevant, det er relevant for noget.
Den billigste funktion af to vektorer, der returnerer et tal, er prikproduktet fra Kapitel 1. Score position for position som , og mekanismen virker — dårligt, på to måder der tvinger alt det andet frem. En vektors prikprodukt med sig selv er dens kvadrerede norm, så hver token ville attendere mest til sig selv. Og relationen ville være symmetrisk: hvis it attender stærkt til animal, så attender animal stærkt til it, hvilket er falsk om sprog, hvor et adjektiv har langt mere brug for sit substantiv, end substantivet har brug for adjektivet.
Giv derfor hver token to roller, som to lærte lineære maps af den: hvad denne position leder efter, , query; og hvad den tilbyder at blive fundet af, , key. Score , og symmetrien er væk, fordi : en token kan annoncere én ting og søge efter en anden.
Én ting er stadig forkert. Den vægtede sum var over selve , hvilket tvinger det, der bliver kopieret, til at være det, der bliver matchet. Matching vil have de features, der identificerer en token; kopiering vil have de features, der er nyttige downstream. Lær derfor et tredje map, , value, og summer dem.
Formlen er nu bogføring:
med som causal mask, nul på og under diagonalen og over. I kode er det tredive linjer, hvor tyve af dem er shapes:
class Head(nn.Module):
"""One head of causal self-attention."""
def __init__(self, d_model, d_head, block):
super().__init__()
self.q = nn.Linear(d_model, d_head, bias=False)
self.k = nn.Linear(d_model, d_head, bias=False)
self.v = nn.Linear(d_model, d_head, bias=False)
self.d_head = d_head
self.register_buffer("mask", torch.tril(torch.ones(block, block)).bool())
def forward(self, x):
T = x.shape[1]
q, k, v = self.q(x), self.k(x), self.v(x)
s = q @ k.transpose(-2, -1) / math.sqrt(self.d_head)
s = s.masked_fill(~self.mask[:T, :T], float("-inf"))
w = F.softmax(s, dim=-1)
return w @ v Score, maskér, normalisér, mix. Alt andet er en projektion.
Divisionen med kvadratroden, og hvad den forsvarer imod
Link til afsnittet: Divisionen med kvadratroden, og hvad den forsvarer imodNæsten enhver forklaring af siger "for at forhindre softmax i at saturere", hvilket er sandt og forklarer ingenting. Argumentet er to linjer af variansen fra Kapitel 2. Hvis entries i og er uafhængige med middelværdi nul og varians én, har hvert produkt varians én, og varianser af uafhængige ting lægges sammen:
Så scorerne har standardafvigelse . Målt over tyve tusind tilfældige par:
d Var(q.k) std sqrt(d)
4 3.975 1.994 2.000
16 16.071 4.009 4.000
64 64.249 8.016 8.000
256 253.065 15.908 16.000
1024 1015.562 31.868 32.000Hvorfor det betyder noget: softmax er skala-sensitiv på en måde, et lineært lag ikke er. At fordoble et lineært lags input fordobler dets output; at multiplicere scorer med ti før en softmax forvandler en blød blanding til et hårdt valg. Én række med 64 scorer, med og uden divisionen:
| største vægt, udivideret | entropi | effektive tokens | største vægt, divideret | entropi | effektive tokens | |
|---|---|---|---|---|---|---|
| 4 | 0,205 | 2,944 | 19,0 | 0,081 | 3,758 | 42,9 |
| 16 | 0,438 | 1,692 | 5,4 | 0,075 | 3,849 | 46,9 |
| 64 | 0,489 | 0,874 | 2,4 | 0,085 | 3,673 | 39,4 |
| 256 | 0,9999 | 0,0007 | 1,0 | 0,143 | 3,547 | 34,7 |
| 1024 | 1,0000 | 0,0000 | 1,0 | 0,132 | 3,644 | 38,3 |
"Effektive tokens" er eksponentialet af entropien: hvor mange positioner rækken reelt gennemsnitliggør over. Udivideret, ved , attender et frisk initialiseret head til præcis én token ud af 64, valgt af intet andet end den tilfældige lodtrækning.
Det er dårligt fremad og værre bagud, i en form Kapitel 5 allerede målte på en . En softmax, der er forpligtet til én entry, har næsten ingen afledt: diagonalen i dens Jacobian er , nul i begge ender. Over to tusind tilfældige rækker:
| udivideret | divideret | saturerede rækker (største vægt over 0,99) | |
|---|---|---|---|
| 4 | 0,8427 | 0,9568 | 0,2 % → 0,0 % |
| 64 | 0,2940 | 0,9609 | 17,9 % → 0,0 % |
| 256 | 0,1406 | 0,9609 | 49,1 % → 0,0 % |
| 1024 | 0,0681 | 0,9611 | 70,4 % → 0,0 % |
Ved er syv rækker ud af ti frosne, før træningen starter, og et head, der starter frosset, kan ikke lære, hvad det skal kigge på. Divideret ligger størrelsen fladt på 0,96 ved enhver bredde, og intet saturerer.
Nu den del, ingen publicerer: ændrer det den endelige perpleksitet? Slet divisionen og træn, ved fire head-bredder:
| head-bredde | udivideret | divideret med | divideret med |
|---|---|---|---|
| fire heads, | 37,29 | 38,07 | 37,89 |
| ét head, | 48,51 | 46,10 | 45,99 |
| ét head, | 65,37 | 47,53 | — |
| ét head, | 67,06 | 49,15 | — |
| ét head, | 76,69 | 59,17 | — |
De første to rækker kommer fra 3000-trins-budgettet ovenfor; de sidste tre er en kortere kørsel — 1500 trin, batch på 32, ét head, ingen normalisering før projektionerne — med begge varianter under identiske settings.
Ved er divisionen intet værd, og kørslen uden den ligger ganske lidt foran. Det er ikke en licens til at droppe den, for ved 256 er den 18 point perpleksitet værd, og ved 1024 er den 17 værd. Mekanismen er synlig i selve scorerne:
| score-std ved init | efter 1500 trin, udivideret | efter 1500 trin, divideret | saturerede rækker, udivideret | divideret | |
|---|---|---|---|---|---|
| 256 | 10,49 | 121,67 | 2,13 | 91,9 % | 0,8 % |
| 512 | 15,13 | 836,85 | 2,66 | 98,7 % | 1,3 % |
| 1024 | 21,15 | 5147,46 | 3,44 | 99,9 % | 16,5 % |
Det udividerede head kommer sig ikke. Det løber løbsk: standardafvigelsen for dets scorer går fra 21 ved initialisering til 5147, attention-entropien falder til nul, og 99,9 % af rækkerne lægger mere end 0,99 af deres vægt på en enkelt token. Når et head først er en hård selector, er dets gradient næsten nul, og intet trækker det tilbage, så kollapset er stabilt. Det dividerede head ligger på en score-standardafvigelse på 3,44 efter samme træning, hvilket er en blød blanding, der stadig kan ændres.
Vaswani et al. siger præcis dette og ikke mere — de mistænker, at produkterne "grow large in magnitude for large values of " og dividerer.5 Ordet large bærer vægten, og tabellerne siger, hvor stort starter: ingenting ved 32, alt ved 256.
Mere end én mening, og de to tredjedele ingen taler om
Link til afsnittet: Mere end én mening, og de to tredjedele ingen taler omÉt head er én softmax-række per position, så det holder ét svar på "hvad er relevant her". At forudsige ordet efter the i the animal that crossed the wet street kræver den syntaktiske plads, subjektet og den forrige token på én gang, og én sandsynlighedsfordeling kan ikke være koncentreret tre steder. Kør derfor flere heads parallelt, hver med bredde , sammenkæd dem, og mix med én matrix mere, : du har partitioneret bredden, ikke lagt til den.
Attention gør også præcis én ting — den flytter information mellem positioner. Hver operation i koden ovenfor er lineær langs feature-aksen, og Kapitel 5 beviste, hvad en stak lineære maps er. Så hver blok bærer også en lille MLP anvendt på hver position uafhængigt, der udvider bredden med fire og kommer tilbage, med en GELU i midten. Arbejdsdelingen er værd at huske: attention mixer på tværs af positioner, feed-forward-netværket beregner inden for en position.
Den fulde stige, hvor hver række lægger ét stykke til rækken over den:
| model | parametre | valideringsperpleksitet |
|---|---|---|
| uniformt gennemsnit, lagt til | 279.552 | 60,45 |
| ét attention head, erstatter token | 328.704 | 55,47 |
| ét attention head, lagt til | 328.704 | 46,10 |
| fire heads i stedet for ét | 345.216 | 43,21 |
| plus feed-forward-netværket | 476.928 | 39,87 |
| plus LayerNorm — den komplette blok | 477.696 | 38,07 |
Lærte vægte slår uniforme vægte med 14 point perpleksitet, hvilket er hele dette kapitels argument i én række. Fire heads køber yderligere 3 for 16.512 ekstra parametre. Og samme head er 9 point mere værd lagt til end erstattende: attention bringer information ind, den afgør ikke, hvad en position er.
Nu hvor parametrene faktisk sidder, hvilket overrasker folk, der kun har set diagrammet:
| bredde | heads | attention | feed-forward | total per blok |
|---|---|---|---|---|
| 128 | 4 | 65.664 (33,2 %) | 131.712 (66,6 %) | 197.888 |
| 768 | 12 | 2.360.064 (33,3 %) | 4.722.432 (66,6 %) | 7.085.568 |
| 4096 | 32 | 67.112.960 (33,3 %) | 134.238.208 (66,7 %) | 201.367.552 |
To tredjedele af hver transformer-blok er feed-forward-netværket, i enhver skala, fordi attention har fire -matricer, og MLP'en har ækvivalenten af otte. Uanset hvad en model ved, ligger de fleste af parametrene, der holder det, i den positionsvise MLP.
Residuals og LayerNorm, arvet fra Kapitel 6
Link til afsnittet: Residuals og LayerNorm, arvet fra Kapitel 6LayerNorm blev bygget og målt i Kapitel 6, og dette kapitel bruger det, som det blev efterladt der; residual connections blev navngivet og ablateret der, og bygges her. Rækkerne "lagt til, ikke erstattende" ovenfor er residual connections, 188 point perpleksitet værd for gennemsnittet og 9 for ét head. LayerNorm7 normaliserer hvert eksempel på tværs af dets features, og Kapitel 6 gav grundene til, at det og ikke BatchNorm overlevede her — ingen afhængighed af batch, ingen løbende statistik, identisk i træning og inferens, ligeglad med sekvenslængde — og hver eneste af dem bliver et krav, når du genererer én token ad gangen for én bruger, hvilket er der, Kapitel 13 ender. Det koster 768 parametre og køber 1,8 point perpleksitet.
class Block(nn.Module):
def forward(self, x):
x = x + self.att(self.ln1(x))
x = x + self.ff(self.ln2(x))
return xSe på, hvor normaliseringen sidder: på inputtet til hvert sub-layer, med residual-stien fra input til output aldrig normaliseret. Det er pre-norm. 2017-artiklen gør det modsatte, x = LayerNorm(x + Att(x)) — post-norm, som lægger en LayerNorm på selve residual-stien.
Xiong et al. forklarede forskellen gennem gradienten ved initialisering, som i et post-norm-netværk er dårligt skaleret med dybde — grunden til, at den oprindelige transformer overhovedet krævede learning-rate warmup for at træne.8 Tolv blokke, 1000 trin, learning rate :
gradient norm per block at initialisation, before any step
pre-norm block 1 0.0498 ... block 12 0.0657 ratio last/first 1.32
post-norm block 1 0.0977 ... block 12 0.1613 ratio last/first 1.65
pre-norm, no warmup perplexity 37.82
pre-norm, 200-step warmup perplexity 37.62
post-norm, no warmup perplexity 308.05
post-norm, 200-step warmup perplexity 37.88Post-norm uden warmup er otte gange værre, og post-norm med warmup matcher pre-norm præcis. Warmup er ikke en generel god praksis her; det er en patch til et specifikt arrangement af normaliseringen, og at flytte LayerNorm fjerner behovet for den. Derfor er i praksis hver model siden 2019 pre-norm, og derfor bør 2017-diagrammet læses som historie snarere end som en specifikation.
Hvor er en token?
Link til afsnittet: Hvor er en token?Slet position embeddings, og modellen træner stadig; den kan bare ikke se, hvor noget er, og det er en symmetri snarere end en træningsfejl. Intet i attention-scoren nævner selve eller , så en permutation af inputtet permuterer outputtet: self-attention er permutations-ækvivariant. Det er gennemsnittets ordensblindhed i en bedre forklædning — causal mask gendanner noget orden, eftersom hver position ser et forskelligt præfiks, men inden for et præfiks er alle rækkefølger ens.
Fire måder at injicere position på, trænet på 64-token-vinduer og evalueret ved 64, 128 og 256 — forbi enhver længde de så:
| positioner | perpleksitet ved 64 | ved 128 | ved 256 |
|---|---|---|---|
| slet ingen | 48,79 | 52,63 | 57,52 |
| lærte absolutte embeddings | 38,63 | 108,47 | 181,94 |
| faste sinuskurver | 42,96 | 95,26 | 152,25 |
| RoPE | 44,12 | 50,52 | 84,84 |
| ALiBi | 44,95 | 43,51 | 42,49 |
Lærte absolutte embeddings — én vektor per position, lagt til token — vinder ved den trænede længde og falder så ud over en klippe, fordi position 100 aldrig var i en batch, og dens embedding stadig er den tilfældige vektor, den startede som. Sinuskurver, det oprindelige valg, beregnes snarere end læres, fra sinus og cosinus ved geometrisk fordelte frekvenser; 2017-artiklen håbede, at det ville ekstrapolere, og tabellen siger, at det gør det ikke — funktionen er defineret ved position 200, men modellen lærte aldrig at læse den der. RoPE9 tilføjer intet og roterer i stedet query og key med en vinkel proportional med positionen, i todimensionelle skiver; eftersom det at rotere begge sider af et prikprodukt ens lader det være uændret, ender scoren med kun at afhænge af , så position bliver relativ gratis, og der er ingen tabel, der kan løbe tør. Den degraderer, men den degraderer. ALiBi10 er det simpleste og mærkeligste resultat her: en lineær straf på scoren proportional med afstand, med en forskellig hældning per head. Dens perpleksitet forbedres, når vinduet vokser ud over træningslængden, fra 44,95 til 42,49, fordi straffen er defineret ved enhver afstand, og hvert head bliver ved med at gøre, hvad det blev trænet til.
Læren overlever tabellen: en arkitektur, der ikke kan repræsentere noget, er et andet problem end en, der aldrig lærte det interval, og det andet er det, der bider. Det er også mekanikken bag enhver "we extended the context to 128K"-annoncering — de er næsten altid reskaleringer af en rotary encoding, og de er grunden til, at Kapitel 16 siger, at context-grænsen flytter sig snarere end forsvinder.
Dropout arves på samme måde: det optræder på attention-vægtene efter softmax, på hvert sub-layer-output før residual-additionen og på embedding-summen, og gør præcis det, Kapitel 6 beskrev. I store pretraining-kørsler sættes det ofte til nul, fordi en model, der ser hver token én gang, ikke er i en position til at overfitte.
Hvad det koster
Link til afsnittet: Hvad det kosterTo tensorer i laget har shape , hvor er antallet af tokens: scorerne og vægtene efter softmax. Alt andet — hver projektion, hele MLP'en — er lineært i .
Ét attention-lag, 512 bredt, 8 heads, batch på én, float32, på en laptop-GPU. Læs de to millisekundkolonner kun for deres forhold: de er vægur på et 8 GB laptop-kort, der throttler fra 1.785 MHz til under 300 MHz, når det bliver varmt, så en kold kørsel af samme kode kommer tilbage syv til ti gange hurtigere og en travl endnu langsommere. Megabytekolonnerne er allocator-byteoptællinger og flytter sig ikke.
tokens ms total ms x4 ms projections attn matrix MB peak MB MB x4
128 2.246 - 1.324 0.5 14.6 -
256 2.855 1.27 2.113 2.0 19.2 1.31
512 5.761 2.02 3.105 8.0 34.4 1.79
1024 16.414 2.85 4.008 32.0 89.1 2.59
2048 51.573 3.14 9.989 128.0 296.1 3.32
4096 225.432 4.37 20.176 512.0 1100.1 3.72
8192 832.838 3.69 40.106 2048.0 4300.1 3.91
16384 OUT OF MEMORY 8192.0
fitted exponent (log-log slope, last four rows): time ~ n^1.91 memory ~ n^1.87x4-kolonnerne er forholdet til rækken over, og en fordobling af konvergerer mod præcis 4 for både tid og hukommelse — 3,91 ved sidste trin mod teoretiske 4. Projektionskolonnen er kontrollen: 4,0 ms ved 1024 tokens til 40,1 ms ved 8192, en faktor ti for en faktor otte. Lineær, som annonceret.
Så den sidste række. Ét attention-lag, én sekvens, ingen model omkring det, løber tør for hukommelse på en 8 GB GPU ved 16.384 tokens — scorematricen alene ville være 8 GB, idet den er 8 heads gange 16.384 gange 16.384 gange 4 bytes. Ikke modellen; én mellemliggende tensor i ét lag.
Det er den fysiske kendsgerning under tre senere kapitler. Det er derfor, en context window overhovedet har en grænse, som Kapitel 16 omdanner til en pris. Det er derfor FlashAttention findes, som beregner samme resultat i tiles uden nogensinde at gemme matricen — en hukommelsesoptimering før det er en hastighedsoptimering.11 Og det er aritmetikken bag prisen på en lang prompt, som Kapitel 24 betaler i et agent-loop — en separat sag fra det kapitels andet fund, at en model også bruger en lang context dårligere, hvilket det måler og afviser at give denne formel skylden for.
Vis detaljer
De to cache-krympende varianter, navngivet her og betalt for i Kapitel 13.
Generation cacher keys og values for de tokens, der allerede er processeret — én key og én value per token, per head per lag. Multi-query attention12 beholder query-projektioner, men en enkelt key- og value-projektion delt af alle heads, hvilket dividerer den cache med . Grouped-query attention13 interpolerer: heads grupperes, hver gruppe deler én key og value, så er almindelig attention, og er multi-query. Næsten hver åben model siden 2023 bruger det med 4 eller 8 grupper. Ingen af dem findes for kvalitet; begge findes på grund af størrelsen af den cache, og Kapitel 13 laver aritmetikken, der omdanner det til "hvilken model passer i din GPU".
To former, og størrelsen af én
Link til afsnittet: To former, og størrelsen af én2017-artiklen beskriver en encoder-decoder: én stack, der læser kilden med umaskeret attention, en anden, der genererer målet causalt, og en tredje slags attention i midten, hvor decoderens queries møder encoderens keys. Det er rigtigt for oversættelse, hvor input og output er to sekvenser.
Det, der vandt, var decoder-only-halvdelen — én stack, causal hele vejen, input og output i samme sekvens — og grunden er ikke elegance. "Predict the next token" kører på enhver tekst, så træningssættet er internettet snarere end et parallelt korpus, og alt bliver den ene opgave: en oversættelse er et dokument, der indeholder kilde og derefter mål, et spørgsmål og dets svar er et dokument, en samtale med et tool call i midten er et dokument. Kapitel 11 handler om, hvordan den sidste fremstilles. Encoders forsvandt ikke — en ser hele inputtet på én gang, hvilket er det, du vil have, når opgaven er at repræsentere en tekst snarere end at fortsætte den, og det er derfor Kapitel 19's retrieval embeddings kommer fra encoders og ikke fra modellen, der chatter.
Med blokken defineret er modelstørrelse aritmetik. Per blok, med bredde og en fire-gange udvidelse: for med biases på alle fire, som GPT-2 har dem — tabellen ovenfor udelader bias på tre af dem, derfor 2.304 færre per blok ved ; for MLP'en; for to LayerNorms — , plus en token-tabel på og, for absolutte positioner, . For formen af GPT-2 small — , 12 blokke, et ordforråd på 50.257, en context på 1024, outputlaget deler embedding-vægtene:
token embeddings 50,257 x 768 = 38,597,376
position embeddings 1,024 x 768 = 786,432
one block 7,087,872
12 blocks 85,054,464
final LayerNorm 2 x 768 = 1,536
total (weights tied) 124,439,808Hvilket er den publicerede størrelse af den model. Formlen er ikke en approximation; den er modellen. Bemærk også, at næsten en tredjedel af en lille model er embedding-tabellen, hvilket er grunden til, at ordforrådsstørrelse er en arkitekturbeslutning og ikke en preprocessing-beslutning — trade-off'et Kapitel 7 satte op.
Hvad et head faktisk kigger på
Link til afsnittet: Hvad et head faktisk kigger påPerpleksitet er et tal om et korpus. Hvad et head gør, er et andet spørgsmål, og en model trænet på en megabyte Shakespeare er det forkerte instrument til det: det ærlige at sige om en attention map for en model med 500.000 parametre er, at den for det meste ikke er fortolkelig. Altså: et sprog, hvor spørgsmålet har et rigtigt svar.
Den klassiske illustration er the animal did not cross the street because it was too tired, hvor it er dyret, mod …because it was too wet, hvor ét ord flytter referenten til gaden. Det er Winograd-skemaer14 — sætningspar, der er identiske bortset fra ét ord, hvor det ord afgør, hvad et pronomen refererer til.
De er også løselige ved at snyde, hvilket er den del, tutorials springer over. Hvis de to kandidater er et dyr og et sted, identificerer tired og wet referenten efter kategori, og en model, der kun ved, hvilke ord der er til stede, får det rigtigt uden at vide noget om orden. Målt på den version af opgaven, med holdte dyr/sted-par:
uniform causal average held-out referent accuracy 100.0 %
one transformer block held-out referent accuracy 91.7 %Bag of words slår transformer. Enhver demonstration bygget på den sætning beviser intet om attention.
Luk derfor hullet: træk begge kandidater fra én pulje af seksten substantiver, hvor hver af dem kan optræde i begge slots, og split adjektiverne efter rolle i stedet for kategori — fire der gør it til krydseren (tired, scared, slow, weak), fire der gør det til det krydsede (wet, wide, busy, steep).
the {x} did not cross the {y} because it was too {adj} , so the {ref} waited .Træn som en almindelig next-token predictor, score én position — ordet efter so the — og byg det holdte sæt fra substantivpar, hvis omvendte rækkefølge var i træning, så alt, der ved hvilke to substantiver der er til stede, men ikke hvilket der kom først, må svare baglæns.
| model | parametre | holdt | navngiver det andet substantiv |
|---|---|---|---|
| kun aktuel token | 5.796 | 5,2 % | 5,2 % |
| uniformt causalt gennemsnit | 5.796 | 27,9 % | 50,0 % |
| ét head med lært attention | 18.084 | 35,4 % | 64,6 % |
| fire heads | 22.244 | 75,0 % | 15,6 % |
| én transformer-blok | 55.716 | 92,7 % | 4,2 % |
| to transformer-blokke | 105.508 | 100,0 % | 0,0 % |
Chance blandt de to substantiver, der er til stede, er 50 %. Det uniforme gennemsnit lander på 27,9 % og svarer med det forkerte substantiv i parret præcis halvdelen af tiden — signaturen af noget, der ved, hvilke ord der er der, og intet om deres orden, som shuffle-testen forudsagde tre sektioner tidligere.
Nu kortet: attention ved positionen, der skal navngive referenten, gennemsnitliggjort over de fire heads i hver blok, for de to sætninger der adskiller sig ved ét ord. Et uniformt gennemsnit ville lægge 0,067 på hver af de femten synlige tokens.
the animal did not cross the street because it was too tired , so the animal waited .
blk 1 the:0.00 animal:0.70 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.06
because:0.00 it:0.00 was:0.00 too:0.00 tired:0.00 ,:0.05 so:0.00 the:0.19
blk 2 the:0.00 animal:0.00 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.00
because:0.00 it:0.00 was:0.00 too:0.00 tired:1.00 ,:0.00 so:0.00 the:0.00
the animal did not cross the street because it was too wet , so the street waited .
blk 1 the:0.00 animal:0.70 did:0.00 not:0.00 cross:0.00 the:0.00 street:0.06
because:0.00 it:0.00 was:0.00 too:0.00 wet:0.00 ,:0.05 so:0.00 the:0.19
blk 2 the:0.00 animal:0.00 did:0.00 not:0.00 cross:0.03 the:0.00 street:0.49
because:0.00 it:0.00 was:0.00 too:0.20 wet:0.03 ,:0.00 so:0.00 the:0.25Blok 1 er identisk i begge sætninger — 0,70 på det første substantiv, uanset hvad adjektivet er. Det er ikke en fejl, men et bevis: i det første lag er query ved en position en funktion af positionens egen token og index, og the ved position 14 er den samme token i begge sætninger. Et first-layer head kan ikke conditione på et ord, det endnu ikke har hentet. Så blok 1 gør det eneste nyttige, der er tilgængeligt, og trækker det første substantiv frem.
Blok 2 er dér, sætningerne skilles, og den samme række på tværs af alle otte adjektiver viser reglen, modellen fandt:
| adjektiv | blok 2 på animal | på street | på adjektivet | svar |
|---|---|---|---|---|
| tired, scared, slow, weak | 0,000 | 0,000 | 1,000 | animal |
| wet, wide, busy, steep | 0,000 | 0,491 | 0,00–0,03 | street |
For et krydser-adjektiv bruger den anden blok hele sin vægt på adjektivet, fordi svaret allerede ligger i residual stream — blok 1 lagde det der — og alt, den behøver, er bekræftelse. For et krydset-adjektiv går den ud og henter det andet substantiv i stedet. Det er et to-hop circuit: ét head flytter en kandidat frem, et head i et senere lag læser en token, der afgør, om den skal beholdes. Komposition på tværs af lag er mekanismen, og det er derfor én blok nåede 92,7 %, og to nåede 100 %.
Det er også formen på det bedst dokumenterede circuit i rigtige modeller. Induction heads — et previous-token head, der føder et head i næste lag, som fuldender mønstret [A][B] … [A] → [B] — er, hvad Anthropics fortolkelighedsarbejde identificerer bag en stor del af in-context learning, og de dannes på et identificerbart tidspunkt under pretraining. Dette kapitel forsøger ikke den analyse: den delegeres, med begge artikler i referencerne, fordi at læse circuits ud af en rigtig model er et forskningsfelt og ikke en sektion.
Til sidst implementeringen. De tredive linjer ovenfor, med deres vægte kopieret fra PyTorchs egne:
ours vs nn.MultiheadAttention max |diff| = 1.7881393432617188e-07
ours vs F.scaled_dot_product_attention max |diff| = 1.7881393432617188e-07på outputs, hvis middelmagnitude er 0,159: den samme aritmetik i en anden rækkefølge, ved float32-præcision.
Hvor det går hen næste gang
Link til afsnittet: Hvor det går hen næste gangDu har den arkitektur, hver model i resten af dette kursus er bygget af, og den er mindre end sit ry: et vægtet gennemsnit, hvis vægte læres, en positionsvis MLP, der holder to tredjedele af parametrene, to normaliseringer og to additioner, stablet.
Det, du ikke har, er en model, der ved noget, og stacking fikser det ikke af sig selv. To blokke på dette korpus når en træningsperpleksitet på 14,49 og en valideringsperpleksitet på 40,57, mod én bloks 18,77 og 38,07 — mere kapacitet, bedre på det den har set, værre på det den ikke har, hvilket er Kapitel 6's tabel med en transformer i. Afstanden mellem denne model og dem, Kapitel 14 til 30 taler med, er ikke arkitektonisk. Det er den samme blok, gentaget flere gange, over enormt meget mere tekst.
Hvilket gør det til et regnskabsproblem, og regnskabet er mærkeligere, end det ser ud. Hvor meget tekst, og hvor får nogen det fra? Hvor meget aritmetik, og hvordan estimerer du den før pengene er brugt? Givet et fast budget, er det bedre at gøre modellen større eller vise den mere data — og findes der et korrekt svar, eller kun en mode? Kapitel 10 besvarer alle tre med målinger og sætter en pris på den billigste nyttige form af spørgsmålet: hvad koster det i dag at træne en model som GPT-2 fra ingenting?
Kilder og metode
Link til afsnittet: Kilder og metodeTre forklaringer af dette materiale er bedre end denne til det, de er lavet til, og dette kapitel er skrevet til at blive læst sammen med dem. Jay Alammars The Illustrated Transformer er det bedste billede af dataflowet, der nogensinde er tegnet. Harvard NLP's The Annotated Transformer er 2017-artiklen med kørende kode flettet ind linje for linje. Andrej Karpathys Let's build GPT: from scratch, in code, spelled out bygger den samme model live på to timer, og ablationsstigen ovenfor er den samme rygrad målt på et andet korpus. For fortolkelighedsspørgsmålet, som dette kapitel kun berører, er de primære kilder Elhage et al., A Mathematical Framework for Transformer Circuits (2021) og Olsson et al., In-context Learning and Induction Heads (2022), begge fra Anthropics fortolkelighedsgruppe.
Referencer
Link til afsnittet: Referencer-
Hochreiter, S. og Schmidhuber, J. Long Short-Term Memory. Neural Computation 9(8), s. 1735–1780 (1997). ↩
-
Sutskever, I., Vinyals, O. og Le, Q. V. Sequence to Sequence Learning with Neural Networks. arXiv:1409.3215 (2014). Encoder-decoderen, hvis ene context-vektor er flaskehalsen. ↩
-
Bahdanau, D., Cho, K. og Bengio, Y. Neural Machine Translation by Jointly Learning to Align and Translate. arXiv:1409.0473 (2014). Attention, tre år før transformer. ↩
-
Perpleksitet er eksponentialet af den gennemsnitlige cross-entropy per token, fra Kapitel 8. Hvert tal her bruger samme tokenizer og samme valideringssplit, hvilket er den eneste betingelse, hvorunder to perpleksiteter overhovedet må sammenlignes. ↩
-
Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł. og Polosukhin, I. Attention Is All You Need. arXiv:1706.03762 (2017). Sektion 3.2.1 er den ene sætning om , som dette kapitel bruger en sektion på at måle. ↩
-
Shazeer, N., Mirhoseini, A., Maziarz, K., Davis, A., Le, Q., Hinton, G. og Dean, J. Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer. arXiv:1701.06538 (2017). ↩
-
Ba, J. L., Kiros, J. R. og Hinton, G. E. Layer Normalization. arXiv:1607.06450 (2016). Introduceret og målt i Kapitel 6; brugt her uændret. ↩
-
Xiong, R., Yang, Y., He, D., Zheng, K., Zheng, S., Xing, C., Zhang, H., Lan, Y., Wang, L. og Liu, T.-Y. On Layer Normalization in the Transformer Architecture. arXiv:2002.04745 (2020). Gradientanalysen bag pre-norm og argumentet om, at warmup er et symptom. ↩
-
Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B. og Liu, Y. RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864 (2021). ↩
-
Press, O., Smith, N. A. og Lewis, M. Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation. arXiv:2108.12409 (2021). Ekstrapolationsresultatet gengivet ovenfor. ↩
-
Dao, T., Fu, D. Y., Ermon, S., Rudra, A. og Ré, C. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. arXiv:2205.14135 (2022). ↩
-
Shazeer, N. Fast Transformer Decoding: One Write-Head is All You Need. arXiv:1911.02150 (2019). ↩
-
Ainslie, J., Lee-Thorp, J., de Jong, M., Zemlyanskiy, Y., Lebrón, F. og Sanghai, S. GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. arXiv:2305.13245 (2023). ↩
-
Levesque, H. J., Davis, E. og Morgenstern, L. The Winograd Schema Challenge. KR (2012). Konstruktionen bag animal / street-sætningen, som alle attention-tutorials bruger. ↩