Attention ve Transformer Bloğu: Ortalamadan Türetilmiş Hâli
Context’in en ucuz özeti olan ortalamadan başlayıp nerede çöktüğünü ölçün; attention formülü onarımdan kendiliğinden çıksın.
Bu sayfada
Bölüm 7’den bir tokenizer, Bölüm 8’den bir embedding tablosu ve bunlarla birlikte gelen hedefle buraya geliyorsun: şimdiye kadarki token’lar verildiğinde bir sonraki token’a olasılık atamak.
Eksik olan orta kısım. Token ’yi tahmin etmek için modelin ondan önceki her şeyi özetleyen tek bir vectore ihtiyacı var ve şimdiye kadar kurduğun hiçbir şey bunu üretmiyor. Token ’ün embedding’i bu değil — bu bir bigram modelidir ve cümlenin bir soruyla başladığını bilemez. Önceki tüm embedding’leri yan yana eklemek de çözüm değil: sayıları her adımda değişir ve sabit bir ağırlık matrisi değişken uzunlukta input alamaz.
Yani: değişken sayıda vector’ü özetleyen, sabit boyutlu tek bir vector. Bütün problem bu; attention, bunu mümkün olan en tembel yoldan çözüp sonra bozulan iki şeyi onardığında elde ettiğin şeydir.
Alanın sahip olduğu cevap ve neden onu kurmuyoruz
Bölüme bağlantı: Alanın sahip olduğu cevap ve neden onu kurmuyoruz1997’den yaklaşık 2017’ye kadar özet, tekrarlayan bir state idi: bir vector tut ve her token’da onu güncelle, . Sabit boyut, değişken input, tam doğru şekil.
Üç şekilde başarısız oldu ve bu bölümün mimarisi üçünü de cevaplıyor. adım boyunca backpropagation yapmak Jacobian’larını çarpar, bu yüzden gradient kaybolur ya da patlar — Bölüm 5’in tek bir node içinde ölçtüğü hastalık. LSTM1 tam buna karşı tasarlandı ve kullanılabilir aralığı onlarca adımdan yüzlerce adıma taşıdı; ama token 5’ten gelen bilginin token 500’e ancak 495 ardışık güncellemeyi sağ çıkarak ulaşması gerçeğini değiştirmedi. Tüm kaynak tek bir vector’e sığmak zorundaydı: sequence-to-sequence çeviride2 bir encoder input’u son state’ine sıkıştırır. Bahdanau, Cho ve Bengio bu darboğazı adlandırdı ve 2014’te, transformer’dan üç yıl önce, decoder’ın kendi hesapladığı ağırlıklarla tüm encoder state’lerinin ağırlıklı toplamını almasına izin vererek düzeltti.3 Aşağıdaki her şey, recurrence silinmiş hâliyle, bu fikrin bir sequence tarafından kendisine uygulanmasıdır. Ve güncelleme yapı gereği ardışıktır: için gerekir; on bin çekirdekli bir GPU bununla hiçbir şey yapamaz. Kazanan mimari bariz biçimde daha zeki olan değil; pahalı adımı bir matris çarpımı olan mimaridir.
Diğer klasik inductive bias, convolution — küçük bir filtreyi tüm input üzerinde kaydırmak, böylece herhangi bir yerde tespit edilen bir özellik her yerde tespit edilir — burada da kurulmayacak; görüntüler için neredeyse tam doğru fikirdir ve bir vision dersine bırakılır. Bu sayfadan sonra ne recurrence ne de convolution yeniden görünür; bu yüzden ikisine de bölüm ayrılmıyor: Bölüm 1 atlamaların sessizce değil, açıkça ilan edileceğine söz vermişti.
Var olan en ucuz özet
Bölüme bağlantı: Var olan en ucuz özetDeğişken sayıda vector alıp tek vector döndüren en bariz function ortalamadır:
Herhangi sayıda input, sabit output boyutu, differentiable, bedava. Embedding tablosu artı bu ortalama artı vocabulary’ye bir linear layer: on beş satırda tam bir language model. Ayrıca berbat; nasıl berbat olduğu da bütün türetmenin kendisi.
Aşağıdaki corpus bir megabyte Shakespeare, 1.115.394 karakter; Bölüm 7’de kurulan türden, vocabulary’si 1024 olan byte-level BPE tokenizer’dan geçirilmiş: token başına 2,43 karakterle 459.760 token, 90/10 bölünmüş. Her model 128 genişliğinde, 128 token görüyor ve 64’lük batch ile ’de 3000 AdamW adımı eğitiliyor. Perplexity held-out split üzerinde.4
| model | parametreler | validation perplexity |
|---|---|---|
| yalnızca mevcut token, hiç context yok | 263,168 | 59.71 |
| artı ondan önceki her şeyin uniform ortalaması | 263,168 | 248.07 |
| artı learned position embeddings | 279,552 | 245.93 |
| token’ın yerine geçmek yerine token’a eklenen uniform ortalama | 263,168 | 60.45 |
İkinci satırı iki kez oku. Context’i ortalamak azıcık yardımcı olmuyor; modeli context’i tamamen yok saymaktan dört kat kötü yapıyor. İki neden var, ikisi de empirik değil kanıtlanabilir.
Ortalama sırayı göremez. Toplama commutative’dir, bu yüzden window’u karıştırmak özeti değiştirmez — yaklaşık olarak değil:
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-08Yeniden sıralanmış toplamda floating-point gürültüsü: iki özet aynı vector. Context’e yalnızca ortalama üzerinden bakan bir model köpek adamı ısırdı ile adam köpeği ısırdı cümlelerini ayırt edemez. Üçüncü satır bunun input’lara position ekleyerek düzeltilemediğini kanıtlıyor — ortalamadan önce her token’a learned position embedding eklemek 188 puanlık farktan yalnızca 2,14 puan kazandırdı. Position’lar toplama girer ve toplam onları unutur.
Ve ortalama şimdiyi boğar. Position 100’de mevcut token özetin yüzde biridir. Bunun elindeki ucuz bir çözümü var: token’ı koru ve özeti ona ekle — Bölüm 6’dan bir residual connection; dördüncü satır da bunun yaptığı şey. Seyrelme onarıldığında uniform ortalama hiçbir şey katmıyor: 59,71 baseline’a karşı 60,45. Her token orada, eşit ağırlıkla; eşit ağırlıklandırma bilgi olmamasıyla aynıdır.
Problem ortalama almak değil. Problem ağırlıklar.
Ortalama bir matris çarpımıdır ve mask bir softmax’tir
Bölüme bağlantı: Ortalama bir matris çarpımıdır ve mask bir softmax’tirBüyüyen prefix üzerinde ortalama almak bir loop gibi görünür. Satırları toplamı bir olan alt üçgensel bir matrisle tek bir çarpımdır — ve aynı zamanda, tam olarak, bir softmax’tir:
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.167Bir transformer’ın üç adlandırılmış bileşeni artık ekranda. Üçgen causal mask’tir, objective tarafından zorunlu kılınır: position position ’ü görebilseydi cevap input’un içinde olurdu — Bölüm 6’nın denetlemeni söylediği sızıntı, sadece mimarinin içinde. Softmax mask’in uygulanma biçimidir: yasak girişleri yapmak onları tam olarak sıfıra gönderir ve geriye kalanı normalize eder; yani mask’leme ve normalize etme tek işlemdir. (-1e9 değil kullan: mask’in anlamı olan değer budur, float16’ya cast edilince olarak kalır ve seçtiğin constant’ın içinde bulunduğun aralık için yeterince büyük olup olmadığına karar verme zahmetinden kurtarır — bu da Bölüm 2’nin floating-point kutusunun, cevaplamak zorunda olmadığın bir soru sormasıdır.) Ve score’lar serbest parametredir. Uniform ortalama, izin verilen her score aynı sayı olduğunda elde ettiğin şeydir; oraya herhangi sayıları koy, softmax onları geçerli ağırlıklara çevirir.
Bu bölümün geri kalanı tek bir soru: bu sayılar nereden geliyor?
Query, key, value
Bölüme bağlantı: Query, key, valueDüz parametreler olamazlar. Learned matrisi her cümle için aynı olurdu — "dört token geriye bak"ı encode edebilir ama asla "bu pronoun’un refer ettiği isme bak" diyemez. Position ile position ’yi bağlayan ağırlık iki position’da ne olduğuna bağlı olmalıdır; çünkü relevance bir ilişkidir, bir özellik değil: it kelimesi kendi başına relevant değildir, bir şeye göre relevant’tır.
İki vector’den sayı döndüren en ucuz function, Bölüm 1’deki dot product’tır. Position ’i position için olarak score’la ve mekanizma çalışır — ama iki şekilde kötü çalışır ve geri kalan her şeyi zorunlu kılar. Bir vector’ün kendisiyle dot product’ı normunun karesidir, bu yüzden her token çoğunlukla kendisine attend ederdi. Ayrıca ilişki simetrik olurdu: it güçlü biçimde animal’a attend ediyorsa, animal da güçlü biçimde it’e attend ederdi; oysa dilde bu yanlıştır, bir adjective kendi noun’una noun’un adjective’e ihtiyaç duyduğundan çok daha fazla ihtiyaç duyar.
O hâlde her token’a, onun iki learned linear map’i olarak iki rol ver: bu position’ın aradığı şey, , yani query; ve kendisinin bulunmak için sunduğu şey, , yani key. score’la ve simetri kaybolur, çünkü : bir token bir şeyi ilan edip başka bir şeyi arayabilir.
Hâlâ yanlış olan bir şey var. Ağırlıklı toplam ’lerin üzerindeydi; bu da kopyalanan şeyin eşleşen şey olmasını zorunlu kılar. Eşleşme bir token’ı tanımlayan özellikleri ister; kopyalama ise downstream’de işe yarayan özellikleri ister. Bu yüzden üçüncü bir map öğren, , yani value, ve onları topla.
Formül artık defter tutma:
burada causal mask’tir; diagonal üzerinde ve altında sıfır, üstünde . Kodda otuz satırdır, bunun yirmisi shape’lerdir:
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’la, mask’le, normalize et, karıştır. Geri kalan her şey projection’dır.
Karekök ile bölme ve neye karşı savunduğu
Bölüme bağlantı: Karekök ile bölme ve neye karşı savunduğuiçin yapılan neredeyse her açıklama "softmax’in saturation’a girmesini önlemek için" der; doğru ama hiçbir şey açıklamıyor. Argüman, Bölüm 2’deki variance’ın iki satırıdır. ve girişleri bağımsız, mean’i sıfır ve variance’ı bir ise, her çarpım variance bir taşır ve bağımsız şeylerin variance’ları toplanır:
Yani score’ların standard deviation’ı olur. Yirmi bin rastgele pair üzerinde ölçülünce:
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.000Bunun önemi: softmax, bir linear layer’ın olmadığı şekilde scale-sensitive’dir. Bir linear layer’ın input’unu ikiye katlamak output’unu ikiye katlar; score’ları softmax’ten önce onla çarpmak yumuşak bir karışımı sert bir seçime dönüştürür. 64 score’luk bir satır, bölmeyle ve bölmesiz:
| en büyük ağırlık, bölmesiz | entropy | effective tokens | en büyük ağırlık, bölünmüş | entropy | effective 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 |
"Effective tokens", entropy’nin üstelidir: satırın gerçekten kaç position üzerinde ortalama aldığı. Bölmesiz durumda, ’de, yeni initialised edilmiş bir head 64 token’dan tam olarak bir tanesine attend eder; seçim sadece random draw ile yapılır.
Bu forward’da kötü, backward’da daha da kötüdür; Bölüm 5’in bir üzerinde zaten ölçtüğü şekildedir. Tek entry’ye bağlanmış bir softmax’in neredeyse derivative’ı yoktur: Jacobian’ının diagonal’i ’dir, iki uçta da sıfırdır. İki bin rastgele satır üzerinde:
| bölmesiz | bölünmüş | saturation’daki satırlar (en büyük ağırlık 0.99 üstünde) | |
|---|---|---|---|
| 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 % |
’de, on satırdan yedisi eğitim başlamadan donmuştur; donmuş başlayan bir head neye bakacağını öğrenemez. Bölünmüş durumda bu nicelik her width’te 0,96’da dümdüz kalır ve hiçbir şey saturation’a girmez.
Şimdi kimsenin yayımlamadığı kısım: final perplexity’yi değiştiriyor mu? Bölmeyi sil ve dört head width’te eğit:
| head width | bölmesiz | ile bölünmüş | ile bölünmüş |
|---|---|---|---|
| dört head, | 37.29 | 38.07 | 37.89 |
| bir head, | 48.51 | 46.10 | 45.99 |
| bir head, | 65.37 | 47.53 | — |
| bir head, | 67.06 | 49.15 | — |
| bir head, | 76.69 | 59.17 | — |
İlk iki satır yukarıdaki 3000 adımlık bütçeden geliyor; son üçü daha kısa bir run — 1500 adım, 32’lik batch, bir head, projection’lardan önce normalization yok — ve iki variant da identical settings altında.
’de bölme hiçbir şey kazandırmıyor ve bölmesiz run çok az önde. Bu, onu atmak için lisans değildir; çünkü 256’da 18 perplexity puanı, 1024’te 17 puan değerindedir. Mekanizma score’ların kendisinde görünür:
| init’te score std | 1500 adım sonra, bölmesiz | 1500 adım sonra, bölünmüş | saturation’daki satırlar, bölmesiz | bölünmüş | |
|---|---|---|---|---|---|
| 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 % |
Bölmesiz head toparlanmaz. Kaçar gider: score’larının standard deviation’ı initialisation’da 21’den 5147’ye çıkar, attention entropy sıfıra düşer ve satırların %99,9’u ağırlığının 0,99’dan fazlasını tek bir token’a koyar. Bir head sert selector hâline geldiğinde gradient’i neredeyse sıfırdır ve hiçbir şey onu geri çekmez; collapse bu yüzden stabildir. Bölünmüş head aynı eğitimden sonra 3,44 score standard deviation’da oturur; bu hâlâ değiştirilebilen yumuşak bir karışımdır.
Vaswani et al. tam olarak bunu söyler, daha fazlasını değil — products’ın büyük değerleri için "büyük magnitude’da büyüdüğünden" şüphelenirler ve bölerler.5 Büyük kelimesi yük taşır; tablolar da büyüğün nerede başladığını söyler: 32’de hiçbir şey, 256’ya gelindiğinde her şey.
Birden fazla görüş ve kimsenin konuşmadığı üçte iki
Bölüme bağlantı: Birden fazla görüş ve kimsenin konuşmadığı üçte ikiBir head, position başına bir softmax satırıdır; yani "burada relevant olan nedir" sorusuna tek bir cevap tutar. the animal that crossed the wet street içindeki the sonrasındaki kelimeyi tahmin etmek, syntactic slot’u, subject’i ve önceki token’ı aynı anda gerektirir; tek bir probability distribution üç yere yoğunlaşamaz. O yüzden birden fazla head’i paralel çalıştır, her biri width’te olsun, concat et ve bir matris daha, , ile karıştır: width’i parçalara böldün, ona ekleme yapmadın.
Attention ayrıca tam olarak tek bir şey yapar — bilgiyi position’lar arasında taşır. Yukarıdaki koddaki her operation feature axis boyunca linear’dır ve Bölüm 5 bir linear map stack’inin ne olduğunu kanıtlamıştı. Bu yüzden her block ayrıca her position’a bağımsız olarak uygulanan küçük bir MLP taşır; width’i dört kat genişletir ve geri döner, ortada bir GELU vardır. İş bölümü ezberlemeye değer: attention position’lar arasında karıştırır, feed-forward network position içinde hesaplar.
Tam merdiven; her satır üstündeki satıra bir parça ekliyor:
| model | parametreler | validation perplexity |
|---|---|---|
| uniform ortalama, eklenmiş | 279,552 | 60.45 |
| tek attention head, token’ın yerine geçiyor | 328,704 | 55.47 |
| tek attention head, eklenmiş | 328,704 | 46.10 |
| bir yerine dört head | 345,216 | 43.21 |
| artı feed-forward network | 476,928 | 39.87 |
| artı LayerNorm — tam block | 477,696 | 38.07 |
Learned ağırlıklar uniform olanları 14 perplexity puanı yener; bu bölümün tüm argümanı tek satırda budur. Dört head, 16.512 ekstra parametre karşılığında 3 puan daha kazandırır. Aynı head ayrıca yerine geçtiğinde değil eklendiğinde 9 puan daha değerlidir: attention bilgi getirir, bir position’ın ne olduğuna karar vermez.
Şimdi parametrelerin gerçekte nerede durduğu; sadece diyagramı görmüş insanları şaşırtır:
| width | heads | attention | feed-forward | block başına toplam |
|---|---|---|---|---|
| 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 |
Her transformer block’un üçte ikisi feed-forward network’tür, her scale’de; çünkü attention’da dört matrisi vardır, MLP’de ise bunun sekizine denk geleni. Bir model ne biliyorsa, onu tutan parametrelerin çoğu per-position MLP’nin içindedir.
Residual’lar ve LayerNorm, Bölüm 6’dan miras
Bölüme bağlantı: Residual’lar ve LayerNorm, Bölüm 6’dan mirasLayerNorm Bölüm 6’da kuruldu ve ölçüldü; bu bölüm onu orada bırakıldığı hâliyle kullanıyor. Residual connection’lar orada adlandırıldı ve ablate edildi; burada kuruluyor. Yukarıdaki "eklendi, yerine geçmedi" satırları residual connection’lardır; ortalama için 188, tek head için 9 perplexity puanı değerindedir. LayerNorm7 her example’ı feature’ları boyunca normalize eder ve Bölüm 6 burada BatchNorm’un değil onun neden hayatta kaldığını vermişti — batch’e bağımlılık yok, running statistics yok, training ve inference’da aynı, sequence length’e kayıtsız — bunların her biri, tek bir kullanıcı için tek seferde bir token generate ettiğinde gereklilik hâline gelir; Bölüm 13 sonunda oraya varır. 768 parametreye mal olur ve 1,8 perplexity puanı kazandırır.
class Block(nn.Module):
def forward(self, x):
x = x + self.att(self.ln1(x))
x = x + self.ff(self.ln2(x))
return xNormalization’ın nerede durduğuna bak: her sub-layer’ın input’unda, input’tan output’a residual path hiç normalize edilmeden. Bu pre-norm’dur. 2017 paper’ı tersini yapar, x = LayerNorm(x + Att(x)) — post-norm, LayerNorm’u residual path’in kendisine koyar.
Xiong et al. farkı initialisation’daki gradient üzerinden açıkladı; post-norm network’te gradient depth ile kötü scale olur — original transformer’ın train edebilmek için learning-rate warmup’a ihtiyaç duymasının nedeni buydu.8 On iki block, 1000 adım, 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.88Warmup’sız post-norm sekiz kat daha kötü; warmup’lı post-norm pre-norm ile tam eşleşiyor. Warmup burada genel iyi pratik değildir; normalization’ın belirli bir düzenlemesi için patch’tir ve LayerNorm’u taşımak ona duyulan ihtiyacı kaldırır. 2019’dan beri neredeyse her modelin pre-norm olmasının ve 2017 diyagramının specification değil tarih olarak okunması gerektiğinin nedeni budur.
Bir token nerede?
Bölüme bağlantı: Bir token nerede?Position embeddings’i sil ve model yine eğitilir; sadece hiçbir şeyin nerede olduğunu söyleyemez, bu da training failure değil bir symmetry’dir. Attention score’da ya da ’nin kendisi geçmez; bu yüzden input’u permute etmek output’u permute eder: self-attention permutation-equivariant’tır. Ortalama almanın order-blindness’ının daha iyi kılık değiştirmiş hâlidir — causal mask bir miktar sıra geri getirir, çünkü her position farklı bir prefix görür; ama bir prefix’in içinde tüm sıralamalar aynıdır.
Position eklemenin dört yolu, 64-token window’larda eğitildi ve gördükleri uzunluğun ötesinde 64, 128 ve 256’da değerlendirildi:
| positions | 64’te perplexity | 128’de | 256’da |
|---|---|---|---|
| hiç yok | 48.79 | 52.63 | 57.52 |
| learned absolute embeddings | 38.63 | 108.47 | 181.94 |
| fixed sinusoids | 42.96 | 95.26 | 152.25 |
| RoPE | 44.12 | 50.52 | 84.84 |
| ALiBi | 44.95 | 43.51 | 42.49 |
Learned absolute embeddings — position başına bir vector, token’a eklenir — eğitim uzunluğunda kazanır ve sonra uçurumdan düşer; çünkü position 100 hiç batch içinde bulunmamıştır ve embedding’i başladığı random vector olarak kalmıştır. Sinusoids, original seçim, learned değil computed’dır; geometrik aralıklı frekanslarda sine ve cosine’lardan gelir. 2017 paper’ı bunun extrapolate edeceğini umdu ve tablo etmeyeceğini söylüyor — function position 200’de tanımlıdır, ama model onu orada okumayı hiç öğrenmedi. RoPE9 hiçbir şey eklemez; bunun yerine query ve key’i position ile orantılı bir angle kadar, iki boyutlu dilimlerde döndürür. Dot product’ın iki tarafını da eşit döndürmek sonucu değiştirmediği için score sonunda yalnızca ’ye bağlı olur; position bedavadan relative hâle gelir ve tükenecek bir tablo yoktur. Bozulur, ama kademeli bozulur. ALiBi10 buradaki en basit ve en tuhaf sonuçtur: distance ile orantılı, head başına farklı slope’a sahip score üzerinde linear penalty. Window training length’i geçtikçe perplexity’si iyileşir, 44,95’ten 42,49’a; çünkü penalty her distance’ta tanımlıdır ve her head eğitildiği şeyi yapmaya devam eder.
Ders tablodan daha uzun ömürlüdür: bir mimarinin bir şeyi represent edememesi, o aralığı hiç learn etmemiş olmasından farklı bir problemdir; ısıran ikinci problemdir. Bu aynı zamanda her "context’i 128K’ya genişlettik" duyurusunun arkasındaki mekaniktir — bunlar neredeyse her zaman rotary encoding’in re-scaling’leridir ve Bölüm 16’nın context limitinin yok olmak yerine yer değiştirdiğini söylemesinin nedeni de budur.
Dropout da aynı şekilde miras alınır: softmax’ten sonra attention weights üzerinde, residual addition’dan önce her sub-layer output’unda ve embedding toplamında görünür; Bölüm 6’nın tarif ettiği şeyi aynen yapar. Büyük pretraining run’larında çoğu zaman sıfıra ayarlanır, çünkü her token’ı bir kez gören bir model overfit edecek konumda değildir.
Maliyeti ne?
Bölüme bağlantı: Maliyeti ne?Layer’daki iki tensor shape’ine sahiptir; burada token sayısıdır: score’lar ve softmax sonrası ağırlıklar. Geri kalan her şey — her projection, tüm MLP — içinde linear’dır.
Bir attention layer, 512 wide, 8 heads, batch of one, float32, laptop GPU üzerinde. İki millisecond sütununu yalnızca oranları için oku: bunlar ısınınca 1.785 MHz’den 300 MHz altına throttling yapan 8 GB laptop kartındaki wall clock değerleri; bu yüzden aynı kodun soğuk bir run’ı yedi ila on kat hızlı, meşgul bir run’ı daha da yavaş döner. Megabyte sütunları allocator byte count’larıdır ve değişmez.
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 sütunları bir üst satıra oranı gösterir ve ’in ikiye katlanması hem time hem memory için tam olarak 4’e yakınsar — son adımda teorik 4’e karşı 3,91. Projections sütunu control’dür: 1024 token’da 4,0 ms’den 8192’de 40,1 ms’ye, sekiz kat için on kat. İlan edildiği gibi linear.
Sonra son satır. Bir attention layer, tek sequence, etrafında model yok, 16.384 token’da 8 GB GPU’da memory’den düşüyor — tek başına score matrisi 8 GB olurdu: 8 head çarpı 16.384 çarpı 16.384 çarpı 4 byte. Model değil; tek bir layer’daki tek bir intermediate tensor.
Bu, sonraki üç bölümün altındaki fiziksel gerçektir. Bir context window’un neden bir limiti olduğunu açıklar; Bölüm 16 bunu fiyata dönüştürür. FlashAttention’ın neden var olduğunu açıklar: matrisi hiç depolamadan, aynı sonucu tile’lar içinde hesaplamak — hız optimizasyonu olmadan önce memory optimizasyonu.11 Ve uzun bir prompt’un fiyatının aritmetiğidir; Bölüm 24 bunu bir agent loop içinde öder — o bölümün diğer bulgusundan ayrı bir mesele: modelin uzun context’i ayrıca daha kötü kullandığı, bunu ölçtüğü ve suçu bu formüle atmayı reddettiği bulgusu.
Ayrıntıları göster
Cache’i küçülten iki variant, burada adlandırıldı ve bedeli Bölüm 13’te ödendi.
Generation, daha önce işlenmiş token’ların key ve value’larını cache’ler — token başına bir key ve bir value, head başına layer başına. Multi-query attention12, query projection’larını korur ama tüm head’ler tarafından paylaşılan tek bir key ve value projection kullanır; bu cache’i ’ye böler. Grouped-query attention13 arayı doldurur: head’ler gruplanır, her grup bir key ve value paylaşır; yani ordinary attention, multi-query’dir. 2023’ten beri neredeyse her open model bunu 4 ya da 8 group ile kullanır. Hiçbiri kalite için yoktur; ikisi de o cache’in boyutu için vardır ve Bölüm 13 bunu "GPU’na hangi model sığar"a dönüştüren aritmetiği yapar.
İki şekil ve birinin boyutu
Bölüme bağlantı: İki şekil ve birinin boyutu2017 paper’ı bir encoder-decoder tarif eder: kaynağı unmasked attention ile okuyan bir stack, hedefi causally generate eden ikinci bir stack ve ortada decoder query’lerinin encoder key’leriyle buluştuğu üçüncü bir attention türü. Input ve output’un iki sequence olduğu çeviri için bu doğrudur.
Kazanan, decoder-only yarısı oldu — tek stack, baştan sona causal, input ve output aynı sequence içinde — ve nedeni elegancy değil. "Bir sonraki token’ı tahmin et" herhangi bir text üzerinde çalışır; bu yüzden training set parallel corpus yerine internettir ve her şey o tek task’e dönüşür: translation, source sonra target içeren bir document’tır; question ve answer bir document’tır; ortasında tool call olan conversation bir document’tır. Bölüm 11 sonuncusunun nasıl üretildiğiyle ilgilidir. Encoder’lar kaybolmadı — biri tüm input’u aynı anda görür; bir text’i devam ettirmek yerine represent etmek istediğinde aradığın şey budur. Bölüm 19’daki retrieval embeddings’in chat yapan modelden değil encoder’lardan gelmesinin nedeni de budur.
Block tanımlandığında model boyutu aritmetiktir. Block başına, width ve dört kat expansion ile: GPT-2’de olduğu gibi dört tanesinde de bias olan için — yukarıdaki tablo bunların üçünde bias’ı bırakır, bu yüzden ’te block başına 2.304 daha azdır; MLP için ; iki LayerNorm için — , artı ’lik token table ve absolute positions için . GPT-2 small şekli için — , 12 block, 50.257 vocabulary, 1024 context, output layer embedding weights’i paylaşıyor:
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,808Bu, o modelin yayımlanan boyutudur. Formül approximation değil; modelin kendisidir. Ayrıca küçük bir modelin neredeyse üçte birinin embedding table olduğunu not et; vocabulary size’ın preprocessing değil architectural decision olmasının nedeni budur — Bölüm 7’nin kurduğu trade-off.
Bir head aslında nereye bakar?
Bölüme bağlantı: Bir head aslında nereye bakar?Perplexity bir corpus hakkında sayıdır. Bir head’in ne yaptığı başka bir sorudur ve bir megabyte Shakespeare üzerinde eğitilmiş bir model bunun için yanlış enstrümandır: 500.000 parametreli bir modelin attention map’i hakkında dürüstçe söylenecek şey, çoğunlukla yorumlanabilir olmadığıdır. O hâlde: sorunun doğru cevabı olan bir dil.
Klasik örnek the animal did not cross the street because it was too tired cümlesidir; burada it animal’dır. Buna karşılık …because it was too wet cümlesinde tek bir kelime referent’i street’e taşır. Bunlar Winograd schemas’tır14 — biri dışında aynı sentence pair’leri; o tek kelime bir pronoun’un neye refer ettiğine karar verir.
Bunlar ayrıca hileyle çözülebilir; tutorial’ların atladığı kısım budur. İki candidate bir animal ve bir place ise, tired ve wet referent’i category ile belirler; yalnızca hangi kelimelerin mevcut olduğunu bilen bir model, order hakkında hiçbir şey bilmeden doğru yapar. Task’in bu version’ında, held-out animal/place pair’leriyle ölçülünce:
uniform causal average held-out referent accuracy 100.0 %
one transformer block held-out referent accuracy 91.7 %Bag of words transformer’ı yener. Bu sentence üzerine kurulan herhangi bir demonstration, attention hakkında hiçbir şey kanıtlamaz.
O yüzden deliği kapat: iki candidate’ı da on altı noun’dan oluşan tek bir pool’dan çek; ikisi de iki slot’un herhangi birinde görünebilsin. Adjective’leri de category yerine role ile böl — dördü it’i crosser yapar (tired, scared, slow, weak), dördü crossed yapar (wet, wide, busy, steep).
the {x} did not cross the {y} because it was too {adj} , so the {ref} waited .Ordinary next-token predictor olarak eğit, tek position’ı score’la — so the sonrasındaki kelime — ve held-out set’i ters sırası training’de bulunan noun pair’lerinden kur; böylece hangi iki noun’un mevcut olduğunu bilen ama hangisinin önce geldiğini bilmeyen her şey geriye doğru cevap vermek zorunda kalır.
| model | parametreler | held-out | diğer noun’u adlandırıyor |
|---|---|---|---|
| yalnızca mevcut token | 5,796 | 5.2 % | 5.2 % |
| uniform causal average | 5,796 | 27.9 % | 50.0 % |
| learned attention’dan bir head | 18,084 | 35.4 % | 64.6 % |
| dört head | 22,244 | 75.0 % | 15.6 % |
| bir transformer block | 55,716 | 92.7 % | 4.2 % |
| iki transformer block | 105,508 | 100.0 % | 0.0 % |
Mevcut iki noun arasında chance %50’dir. Uniform average %27,9’a iner ve pair’in yanlış noun’u ile tam olarak zamanın yarısında cevap verir — üç bölüm önce shuffle test’in predicted ettiği gibi, hangi kelimelerin orada olduğunu bilen ama order hakkında hiçbir şey bilmeyen bir şeyin imzası.
Şimdi map: referent’i adlandırması gereken position’daki attention, her block’un dört head’i üzerinden ortalanmış, tek kelimeyle farklılaşan iki sentence için. Uniform average, görünen on beş token’ın her birine 0,067 koyardı.
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.25Block 1 iki sentence’ta da aynıdır — adjective ne olursa olsun first noun üzerinde 0,70. Bu bir failure değil proof’tur: ilk layer’da bir position’daki query, o position’ın kendi token’ının ve index’inin function’ıdır; position 14’teki the iki sentence’ta da aynı token’dır. First-layer head, henüz fetch etmediği bir kelimeye condition edemez. Bu yüzden block 1 elindeki tek faydalı şeyi yapar ve first noun’u ileri taşır.
Block 2 sentence’ların ayrıldığı yerdir ve sekiz adjective’in tümünde aynı satır modelin bulduğu rule’u gösterir:
| adjective | block 2 animal üzerinde | street üzerinde | adjective üzerinde | answer |
|---|---|---|---|---|
| tired, scared, slow, weak | 0.000 | 0.000 | 1.000 | animal |
| wet, wide, busy, steep | 0.000 | 0.491 | 0.00–0.03 | street |
Crosser-adjective için ikinci block tüm ağırlığını adjective üzerine harcar; çünkü answer residual stream’de zaten vardır — block 1 onu oraya koymuştur — ve tek gereken confirmation’dır. Crossed-adjective için gidip diğer noun’u fetch eder. Bu iki hop’lu bir circuit’tir: bir head candidate’ı ileri taşır, sonraki layer’daki bir head onu tutup tutmamaya karar veren token’ı okur. Layer’lar arası composition mekanizmadır; bir block’un %92,7’ye, ikisinin %100’e ulaşmasının nedeni budur.
Bu aynı zamanda gerçek modellerde en iyi belgelenmiş circuit’in şeklidir. Induction heads — önceki-token head’in, sonraki layer’da [A][B] … [A] → [B] pattern’ini tamamlayan bir head’i beslemesi — Anthropic’in interpretability çalışmasının in-context learning’in büyük bir kısmının arkasında tanımladığı şeydir ve pretraining sırasında belirlenebilir bir anda oluşurlar. Bu bölüm o analize kalkışmıyor: iki paper da references’ta verilerek devrediliyor, çünkü gerçek bir modelden circuit okumak bir araştırma alanıdır, bir section değil.
Son olarak implementation. Yukarıdaki otuz satır, weights’i PyTorch’un kendisinden kopyalanmış hâliyle:
ours vs nn.MultiheadAttention max |diff| = 1.7881393432617188e-07
ours vs F.scaled_dot_product_attention max |diff| = 1.7881393432617188e-07Mean magnitude’ı 0,159 olan output’larda : aynı aritmetik, farklı sırada, float32 precision’da.
Buradan sonra nereye gidiyor?
Bölüme bağlantı: Buradan sonra nereye gidiyor?Kursun geri kalanındaki her modelin üzerine kurulduğu mimariye sahipsin ve ününden daha küçük: ağırlıkları learned olan bir weighted average, parametrelerin üçte ikisini tutan per-position MLP, iki normalization ve iki addition; stack edilmiş.
Elinde olmayan şey herhangi bir şey bilen bir model; stack etmek tek başına bunu düzeltmeyecek. Bu corpus’ta iki block training perplexity 14,49 ve validation perplexity 40,57’ye ulaşır; bir block’un 18,77 ve 38,07 değerlerine karşı — daha fazla capacity, gördüğü şeyde daha iyi, görmediği şeyde daha kötü; bu, Bölüm 6’nın tablosuna transformer konmuş hâlidir. Bu model ile Bölüm 14’ten 30’a kadar konuşulan modeller arasındaki mesafe architectural değildir. Aynı block’tur, daha çok tekrar edilir, çok daha fazla text üzerinde.
Bu da meseleyi bir accounting problemine çevirir ve accounting göründüğünden tuhaftır. Ne kadar text ve insanlar bunu nereden buluyor? Ne kadar arithmetic ve para harcanmadan önce bunu nasıl estimate edersin? Fixed budget varsa modeli büyütmek mi daha iyi, ona daha fazla data göstermek mi — ve doğru cevap var mı, yoksa yalnızca moda mı? Bölüm 10 üçünü de measurement ile cevaplar ve sorunun en ucuz faydalı biçimine fiyat koyar: bugün, GPT-2 gibi bir modeli sıfırdan train etmenin maliyeti nedir?
Kaynaklar ve yöntem
Bölüme bağlantı: Kaynaklar ve yöntemBu materyalin üç açıklaması, kendi amaçları için bundan daha iyidir ve bu bölüm onlarla birlikte okunmak üzere yazıldı. Jay Alammar’ın The Illustrated Transformer’ı, data flow’un şimdiye dek çizilmiş en iyi resmidir. Harvard NLP’nin The Annotated Transformer’ı, 2017 paper’ını satır satır running code ile iç içe verir. Andrej Karpathy’nin Let's build GPT: from scratch, in code, spelled out videosu aynı modeli iki saatte live olarak kurar ve yukarıdaki ablation merdiveni farklı bir corpus üzerinde ölçülen aynı omurgadır. Bu bölümün yalnızca dokunduğu interpretability sorusu için primary sources, Anthropic’in interpretability grubundan Elhage et al., A Mathematical Framework for Transformer Circuits (2021) ve Olsson et al., In-context Learning and Induction Heads (2022)’dir.
Referanslar
Bölüme bağlantı: Referanslar-
Hochreiter, S. and Schmidhuber, J. Long Short-Term Memory. Neural Computation 9(8), pp. 1735–1780 (1997). ↩
-
Sutskever, I., Vinyals, O. and Le, Q. V. Sequence to Sequence Learning with Neural Networks. arXiv:1409.3215 (2014). Tek context vector’ü bottleneck olan encoder-decoder. ↩
-
Bahdanau, D., Cho, K. and Bengio, Y. Neural Machine Translation by Jointly Learning to Align and Translate. arXiv:1409.0473 (2014). Attention, transformer’dan üç yıl önce. ↩
-
Perplexity, Bölüm 8’den, token başına mean cross-entropy’nin üstelidir. Buradaki her sayı aynı tokenizer’ı ve aynı validation split’i kullanır; iki perplexity’nin karşılaştırılabilmesinin tek koşulu budur. ↩
-
Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł. and Polosukhin, I. Attention Is All You Need. arXiv:1706.03762 (2017). Section 3.2.1, bu bölümün bir section boyunca ölçtüğü hakkında tek cümledir. ↩
-
Shazeer, N., Mirhoseini, A., Maziarz, K., Davis, A., Le, Q., Hinton, G. and Dean, J. Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer. arXiv:1701.06538 (2017). ↩
-
Ba, J. L., Kiros, J. R. and Hinton, G. E. Layer Normalization. arXiv:1607.06450 (2016). Bölüm 6’da tanıtıldı ve ölçüldü; burada değiştirilmeden kullanıldı. ↩
-
Xiong, R., Yang, Y., He, D., Zheng, K., Zheng, S., Xing, C., Zhang, H., Lan, Y., Wang, L. and Liu, T.-Y. On Layer Normalization in the Transformer Architecture. arXiv:2002.04745 (2020). Pre-norm’un arkasındaki gradient analysis ve warmup’ın bir symptom olduğu argümanı. ↩
-
Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B. and Liu, Y. RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864 (2021). ↩
-
Press, O., Smith, N. A. and Lewis, M. Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation. arXiv:2108.12409 (2021). Yukarıda reproduced edilen extrapolation result. ↩
-
Dao, T., Fu, D. Y., Ermon, S., Rudra, A. and 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. and Sanghai, S. GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. arXiv:2305.13245 (2023). ↩
-
Levesque, H. J., Davis, E. and Morgenstern, L. The Winograd Schema Challenge. KR (2012). Her attention tutorial’ının kullandığı animal / street sentence’ın arkasındaki construction. ↩