Lewati ke konten
9/30Bab 9 dari 30

Attention dan Blok Transformer, Diturunkan dari Rata-Rata

Mulai dari ringkasan context termurah—rata-rata—ukur kegagalannya, lalu biarkan rumus attention muncul dari perbaikannya.

Di halaman ini

Kamu tiba di sini dengan tokenizer dari Bab 7, tabel embedding dari Bab 8, dan objective yang menyertainya: diberi token sejauh ini, letakkan probabilitas pada token berikutnya.

Yang hilang adalah bagian tengahnya. Untuk memprediksi token tt, model membutuhkan satu vector yang merangkum semua yang mendahuluinya, dan tidak ada yang sudah kamu bangun menghasilkan itu. Embedding token t1t-1 bukan jawabannya — itu model bigram, dan ia tidak bisa tahu bahwa kalimatnya dimulai dengan pertanyaan. Konkatenasi semua embedding sebelumnya juga bukan jawabannya: jumlahnya berubah di setiap langkah, dan matriks bobot tetap tidak bisa menerima input dengan panjang variabel.

Jadi: satu vector berukuran tetap, yang merangkum jumlah vector yang variabel. Itulah seluruh masalahnya, dan attention adalah yang kamu dapatkan dengan menyelesaikannya dengan cara semalas mungkin lalu memperbaiki dua hal yang rusak.

Jawaban yang dulu dimiliki bidang ini, dan mengapa kita tidak membangunnya

Tautan ke bagian: Jawaban yang dulu dimiliki bidang ini, dan mengapa kita tidak membangunnya

Dari 1997 sampai sekitar 2017, ringkasannya adalah recurrent state: simpan vector h\mathbf{h} dan perbarui di setiap token, ht=f(ht1,xt)\mathbf{h}_t = f(\mathbf{h}_{t-1}, \mathbf{x}_t). Ukuran tetap, input variabel, persis bentuk yang benar.

Ia gagal dalam tiga cara, dan arsitektur bab ini menjawab ketiganya. Melakukan backpropagation melalui TT langkah mengalikan TT Jacobian, sehingga gradient menghilang atau meledak — penyakit yang diukur Bab 5 di dalam satu node tanh\tanh. LSTM1 dirancang tepat untuk melawan itu dan mendorong rentang yang bisa dipakai dari puluhan langkah menjadi ratusan, tanpa mengubah fakta bahwa informasi dari token 5 mencapai token 500 hanya dengan bertahan melalui 495 pembaruan berurutan. Seluruh source harus muat dalam satu vector: dalam sequence-to-sequence translation2, encoder memampatkan input ke final state-nya. Bahdanau, Cho, dan Bengio menamai bottleneck itu dan memperbaikinya pada 2014, tiga tahun sebelum transformer, dengan membiarkan decoder mengambil jumlah berbobot dari semua state encoder dengan bobot yang dihitungnya sendiri.3 Semua di bawah ini adalah gagasan itu, diterapkan oleh sequence pada dirinya sendiri, dengan recurrence dihapus. Dan pembaruan bersifat berurutan secara konstruksi: ht\mathbf{h}_t membutuhkan ht1\mathbf{h}_{t-1}, dan GPU dengan sepuluh ribu core tidak bisa berbuat apa-apa dengan itu. Arsitektur yang menang bukan jelas lebih pintar; ia adalah arsitektur yang langkah mahalnya berupa perkalian matriks.

Bias induktif klasik lainnya, convolution — geser satu filter kecil di seluruh input, sehingga fitur yang terdeteksi di mana pun terdeteksi di mana-mana — juga tidak dibangun di sini; ia hampir persis tepat untuk gambar dan diserahkan ke kursus vision. Baik recurrence maupun convolution tidak muncul lagi setelah halaman ini, itulah sebabnya keduanya tidak mendapat bab: Bab 1 berjanji bahwa penghilangan akan dinyatakan, bukan disembunyikan.

Fungsi paling jelas dari jumlah vector yang variabel yang mengembalikan satu vector adalah rata-rata:

ct=1ti=1txi\mathbf{c}_t = \frac{1}{t}\sum_{i=1}^{t} \mathbf{x}_i

Berapa pun jumlah input, ukuran output tetap, differentiable, gratis. Tabel embedding plus rata-rata ini plus layer linear ke vocabulary adalah model bahasa lengkap dalam lima belas baris. Model itu juga buruk sekali, dan bagaimana ia buruk adalah seluruh derivasi.

Corpus di bawah ini adalah satu megabyte Shakespeare, 1.115.394 karakter, melalui tokenizer BPE level-byte seperti yang dibangun di Bab 7 dengan vocabulary 1024: 459.760 token dengan 2,43 karakter masing-masing, dibagi 90/10. Setiap model lebarnya 128, melihat 128 token, dan dilatih selama 3000 langkah AdamW pada 10310^{-3} dengan batch 64. Perplexity diukur pada split held-out.4

modelparametervalidation perplexity
hanya token saat ini, tanpa context sama sekali263.16859,71
plus rata-rata uniform dari semua yang mendahuluinya263.168248,07
plus embedding posisi yang dipelajari279.552245,93
rata-rata uniform ditambahkan ke token alih-alih menggantikannya263.16860,45

Baca baris kedua dua kali. Merata-ratakan context tidak sedikit membantu; ia membuat model empat kali lebih buruk daripada mengabaikan context sepenuhnya. Ada dua alasan, keduanya bisa dibuktikan alih-alih empiris.

Rata-rata tidak bisa melihat urutan. Penjumlahan komutatif, jadi mengacak window membuat ringkasan tidak berubah — bukan hanya kira-kira:

order.pyPYTHON
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())
TEXT
2.9802322387695312e-08

Noise floating-point pada jumlah yang diurutkan ulang: kedua ringkasan adalah vector yang sama. Model yang satu-satunya pandangan terhadap context adalah rata-rata tidak bisa membedakan the dog bit the man dari the man bit the dog. Baris ketiga membuktikan ini tidak bisa diperbaiki dengan menambahkan posisi ke input — embedding posisi yang dipelajari pada setiap token sebelum dirata-ratakan hanya membeli 2,14 poin dari 188. Posisi masuk ke jumlah, dan jumlah melupakannya.

Dan rata-rata menenggelamkan masa kini. Pada posisi 100, token saat ini hanya seperseratus ringkasan. Itu punya perbaikan murah yang sudah kamu miliki: pertahankan token dan tambahkan ringkasan ke dalamnya — residual connection, dari Bab 6, dan baris keempat menunjukkan hasilnya. Setelah pengenceran diperbaiki, rata-rata uniform tidak menyumbang apa pun: 60,45 melawan baseline 59,71. Setiap token ada di sana, diberi bobot sama, dan pembobotan sama adalah sama dengan tanpa informasi.

Masalahnya bukan perataan. Masalahnya adalah bobot.

Rata-rata adalah perkalian matriks, dan mask adalah softmax

Tautan ke bagian: Rata-rata adalah perkalian matriks, dan mask adalah softmax

Merata-ratakan prefix yang tumbuh tampak seperti loop. Ia adalah satu perkalian dengan matriks segitiga bawah yang baris-barisnya berjumlah satu — dan juga, persis, sebuah softmax:

mechanics.pyPYTHON
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 again
TEXT
loop 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.167

Tiga komponen bernama dari transformer kini ada di layar. Segitiga itu adalah causal mask, dipaksa oleh objective: jika posisi tt bisa melihat posisi t+1t{+}1, jawabannya akan ada di input — kebocoran yang Bab 6 suruh kamu audit, kecuali kali ini di dalam arsitektur. Softmax adalah cara mask diimplementasikan: menetapkan entri terlarang ke -\infty mengirimnya tepat ke nol dan menormalkan sisanya, sehingga masking dan normalisasi adalah satu operasi. (Gunakan -\infty, bukan -1e9: itulah nilai yang dimaksud oleh masking, ia bertahan saat cast ke float16 sebagai -\infty, dan ia membebaskanmu dari keputusan apakah konstanta yang kamu pilih cukup besar untuk rentang yang kebetulan kamu masuki — yaitu kotak floating-point Bab 2 yang mengajukan pertanyaan yang tidak perlu kamu jawab.) Dan scores adalah parameter bebasnya. Rata-rata uniform adalah yang kamu dapat saat setiap score yang diizinkan adalah angka yang sama; masukkan angka apa pun di sana dan softmax mengubahnya menjadi bobot valid.

Sisa bab ini adalah satu pertanyaan: dari mana angka-angka itu berasal?

Angka-angka itu tidak bisa berupa parameter polos. Matriks T×TT \times T yang dipelajari akan identik untuk setiap kalimat — ia bisa mengodekan “lihat empat token ke belakang”, tetapi tidak pernah “lihat noun yang dirujuk pronoun ini”. Bobot yang menghubungkan posisi tt ke posisi ii harus bergantung pada apa yang ada di kedua posisi, karena relevansi adalah relasi, bukan properti: kata it tidak relevan secara intrinsik, ia relevan terhadap sesuatu.

Fungsi termurah dari dua vector yang mengembalikan angka adalah dot product dari Bab 1. Beri score posisi ii untuk posisi tt sebagai xtxi\mathbf{x}_t \cdot \mathbf{x}_i dan mekanismenya bekerja — dengan buruk, dalam dua cara yang memaksa semua hal lain. Dot product sebuah vector dengan dirinya sendiri adalah norm kuadratnya, sehingga setiap token akan paling banyak attend ke dirinya sendiri. Dan relasinya akan simetris: jika it attend kuat ke animal, maka animal attend kuat ke it, yang salah tentang bahasa, tempat adjective membutuhkan noun-nya jauh lebih banyak daripada noun membutuhkan adjective.

Jadi beri setiap token dua peran, sebagai dua peta linear yang dipelajari darinya: apa yang posisi ini cari, qt=Wqxt\mathbf{q}_t = W_q\mathbf{x}_t, yaitu query; dan apa yang ia tawarkan agar ditemukan oleh, ki=Wkxi\mathbf{k}_i = W_k\mathbf{x}_i, yaitu key. Score qtki\mathbf{q}_t \cdot \mathbf{k}_i dan simetrinya hilang, karena WqWkW_q \neq W_k: sebuah token bisa mengiklankan satu hal dan mencari hal lain.

Masih ada satu hal yang salah. Jumlah berbobot tadi dilakukan atas xi\mathbf{x}_i itu sendiri, yang memaksa hal yang disalin menjadi hal yang dicocokkan. Pencocokan menginginkan fitur yang mengidentifikasi token; penyalinan menginginkan fitur yang berguna downstream. Jadi pelajari peta ketiga, vi=Wvxi\mathbf{v}_i = W_v\mathbf{x}_i, yaitu value, dan jumlahkan itu.

Rumusnya sekarang bookkeeping:

Attention(Q,K,V)=softmax ⁣(QKdk+M)V\mathrm{Attention}(Q, K, V) = \mathrm{softmax}\!\left(\frac{QK^\top}{\sqrt{d_k}} + M\right)V

dengan MM sebagai causal mask, nol pada dan di bawah diagonal serta -\infty di atasnya. Dalam code, ini tiga puluh baris, dua puluh di antaranya adalah shape:

attention.pyPYTHON
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, normalisasi, campur. Yang lain hanyalah projection.

Pembagian dengan akar kuadrat, dan apa yang dilindunginya

Tautan ke bagian: Pembagian dengan akar kuadrat, dan apa yang dilindunginya

Hampir setiap penjelasan tentang dk\sqrt{d_k} mengatakan “agar softmax tidak saturate”, yang benar tetapi tidak menjelaskan apa pun. Argumennya adalah dua baris variance dari Bab 2. Jika entri q\mathbf{q} dan k\mathbf{k} independen dengan mean nol dan variance satu, setiap hasil kali qjkjq_j k_j punya variance satu, dan variance dari hal-hal independen dijumlahkan:

Var(qk)=j=1dkVar(qjkj)=dk\mathrm{Var}(\mathbf{q}\cdot\mathbf{k}) = \sum_{j=1}^{d_k}\mathrm{Var}(q_j k_j) = d_k

Jadi scores punya standard deviation dk\sqrt{d_k}. Diukur atas dua puluh ribu pasangan acak:

TEXT
     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.000

Mengapa itu penting: softmax peka terhadap skala dengan cara yang tidak dimiliki layer linear. Menggandakan input layer linear menggandakan outputnya; mengalikan scores dengan sepuluh sebelum softmax mengubah campuran lembut menjadi pilihan keras. Satu row berisi 64 scores, dengan dan tanpa pembagian:

dkd_kbobot terbesar, tanpa dibagientropytoken efektifbobot terbesar, dibagientropytoken efektif
40,2052,94419,00,0813,75842,9
160,4381,6925,40,0753,84946,9
640,4890,8742,40,0853,67339,4
2560,99990,00071,00,1433,54734,7
10241,00000,00001,00,1323,64438,3

“Token efektif” adalah eksponensial dari entropy: berapa banyak posisi yang benar-benar dirata-ratakan oleh row itu. Tanpa dibagi, pada dk=256d_k = 256, head yang baru diinisialisasi attend tepat ke satu token dari 64, dipilih hanya oleh undian acak.

Itu buruk ke depan dan lebih buruk ke belakang, dalam shape yang sudah diukur Bab 5 pada tanh\tanh. Softmax yang sudah berkomitmen ke satu entri hampir tidak punya derivative: diagonal Jacobian-nya adalah wi(1wi)w_i(1-w_i), nol di kedua ujung. Atas dua ribu row acak:

dkd_kiwi(1wi)\sum_i w_i(1-w_i) tanpa dibagidibagirow tersaturasi (bobot terbesar di atas 0,99)
40,84270,95680,2 % → 0,0 %
640,29400,960917,9 % → 0,0 %
2560,14060,960949,1 % → 0,0 %
10240,06810,961170,4 % → 0,0 %

Pada dk=1024d_k = 1024, tujuh dari sepuluh row sudah beku sebelum training dimulai, dan head yang mulai dalam keadaan beku tidak bisa belajar apa yang harus dilihat. Setelah dibagi, kuantitas itu datar di 0,96 pada setiap width dan tidak ada yang saturate.

Sekarang bagian yang tidak dipublikasikan siapa pun: apakah itu mengubah perplexity akhir? Hapus pembagian dan latih, pada empat head width:

head widthtanpa dibagidibagi dengan dk\sqrt{d_k}dibagi dengan dkd_k
empat head, dk=32d_k = 3237,2938,0737,89
satu head, dk=128d_k = 12848,5146,1045,99
satu head, dk=256d_k = 25665,3747,53
satu head, dk=512d_k = 51267,0649,15
satu head, dk=1024d_k = 102476,6959,17

Dua baris pertama berasal dari budget 3000 langkah di atas; tiga terakhir adalah run yang lebih pendek — 1500 langkah, batch 32, satu head, tanpa normalisasi sebelum projection — dengan kedua varian pada setting identik.

Pada dk=32d_k = 32, pembagian tidak bernilai apa pun dan run tanpanya sedikit unggul. Itu bukan lisensi untuk membuangnya, karena pada 256 nilainya 18 poin perplexity dan pada 1024 nilainya 17. Mekanismenya terlihat pada scores itu sendiri:

dkd_kscore std saat initsetelah 1500 langkah, tanpa dibagisetelah 1500 langkah, dibagirow tersaturasi, tanpa dibagidibagi
25610,49121,672,1391,9 %0,8 %
51215,13836,852,6698,7 %1,3 %
102421,155147,463,4499,9 %16,5 %

Head tanpa pembagian tidak pulih. Ia lari tak terkendali: standard deviation scores-nya naik dari 21 saat inisialisasi ke 5147, attention entropy jatuh ke nol, dan 99,9 % row menempatkan lebih dari 0,99 bobotnya pada satu token. Begitu head menjadi selector keras, gradient-nya nyaris nol dan tidak ada yang menariknya kembali, sehingga collapse itu stabil. Head yang dibagi bertahan pada standard deviation score 3,44 setelah training yang sama, sebuah campuran lembut yang masih bisa diubah.

Vaswani et al. mengatakan tepat ini dan tidak lebih — mereka menduga produk itu “tumbuh besar magnitudonya untuk nilai dkd_k yang besar” dan membaginya.5 Kata besar menanggung beban, dan tabel-tabel ini menunjukkan di mana besar mulai: tidak ada apa-apa pada 32, semuanya pada 256.

Lebih dari satu pendapat, dan dua pertiga yang jarang dibicarakan

Tautan ke bagian: Lebih dari satu pendapat, dan dua pertiga yang jarang dibicarakan

Satu head adalah satu row softmax per posisi, sehingga ia memegang satu jawaban untuk “apa yang relevan di sini”. Memprediksi kata setelah the dalam the animal that crossed the wet street membutuhkan slot sintaksis, subject, dan token sebelumnya sekaligus, dan satu distribusi probabilitas tidak bisa terkonsentrasi di tiga tempat. Jadi jalankan beberapa head secara paralel, masing-masing dengan width dmodel/hd_{\text{model}}/h, konkatenasi, dan campur dengan satu matriks lagi WoW_o: kamu mempartisi width, bukan menambahkannya.

Attention juga melakukan tepat satu hal — ia memindahkan informasi antar posisi. Setiap operasi dalam code di atas linear sepanjang feature axis, dan Bab 5 membuktikan apa itu tumpukan peta linear. Jadi setiap block juga membawa MLP kecil yang diterapkan ke setiap posisi secara independen, memperluas width empat kali lalu kembali, dengan GELU di tengah. Pembagian tugas ini layak dihafal: attention mencampur antar posisi, feed-forward network menghitung di dalam satu posisi.

Tangga lengkapnya, setiap row menambahkan satu bagian ke row di atasnya:

modelparametervalidation perplexity
rata-rata uniform, ditambahkan279.55260,45
satu attention head, menggantikan token328.70455,47
satu attention head, ditambahkan328.70446,10
empat head alih-alih satu345.21643,21
plus feed-forward network476.92839,87
plus LayerNorm — block lengkap477.69638,07

Bobot yang dipelajari mengalahkan bobot uniform sebesar 14 poin perplexity, yang merupakan seluruh argumen bab ini dalam satu row. Empat head membeli 3 lagi untuk 16.512 parameter ekstra. Dan head yang sama bernilai 9 poin lebih banyak saat ditambahkan daripada saat menggantikan: attention membawa informasi masuk, ia tidak memutuskan apa itu sebuah posisi.

Sekarang, di mana parameter sebenarnya berada, yang mengejutkan orang yang hanya pernah melihat diagram:

widthheadattentionfeed-forwardtotal per block
128465.664 (33,2 %)131.712 (66,6 %)197.888
768122.360.064 (33,3 %)4.722.432 (66,6 %)7.085.568
40963267.112.960 (33,3 %)134.238.208 (66,7 %)201.367.552

Dua pertiga dari setiap transformer block adalah feed-forward network, pada skala apa pun, karena attention punya empat matriks d×dd \times d dan MLP punya ekuivalen delapan. Apa pun yang diketahui model, sebagian besar parameter yang menyimpannya berada di MLP per-posisi.

Residual dan LayerNorm, diwarisi dari Bab 6

Tautan ke bagian: Residual dan LayerNorm, diwarisi dari Bab 6

LayerNorm dibangun dan diukur di Bab 6, dan bab ini menggunakannya sebagaimana ia ditinggalkan di sana; residual connections dinamai dan di-ablasi di sana, dan dibangun di sini. Row “ditambahkan, bukan menggantikan” di atas adalah residual connections, bernilai 188 poin perplexity untuk rata-rata dan 9 untuk satu head. LayerNorm7 menormalkan setiap example melintasi fitur-fiturnya, dan Bab 6 memberikan alasan mengapa ia, bukan BatchNorm, bertahan di sini — tidak bergantung pada batch, tanpa running statistics, identik dalam training dan inference, tidak peduli panjang sequence — semuanya menjadi requirement saat kamu menghasilkan satu token pada satu waktu untuk satu user, yaitu tempat Bab 13 berakhir. Biayanya 768 parameter dan membeli 1,8 poin perplexity.

block.pyPYTHON
class Block(nn.Module):
    def forward(self, x):
        x = x + self.att(self.ln1(x))     
        x = x + self.ff(self.ln2(x))      
        return x

Lihat di mana normalisasi berada: pada input setiap sub-layer, dengan residual path dari input ke output tidak pernah dinormalisasi. Itu adalah pre-norm. Paper 2017 melakukan kebalikannya, x = LayerNorm(x + Att(x))post-norm, yang menaruh LayerNorm pada residual path itu sendiri.

Xiong et al. menjelaskan perbedaannya melalui gradient saat inisialisasi, yang dalam network post-norm diskalakan buruk terhadap depth — alasan transformer asli membutuhkan learning-rate warmup agar bisa dilatih sama sekali.8 Dua belas block, 1000 langkah, learning rate 3×1033 \times 10^{-3}:

TEXT
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.88

Post-norm tanpa warmup delapan kali lebih buruk, dan post-norm dengan warmup cocok persis dengan pre-norm. Warmup bukan praktik baik umum di sini; ia adalah patch untuk susunan normalisasi tertentu, dan memindahkan LayerNorm menghilangkan kebutuhannya. Itulah sebabnya hampir setiap model sejak 2019 adalah pre-norm, dan mengapa diagram 2017 sebaiknya dibaca sebagai sejarah, bukan sebagai spesifikasi.

Hapus embedding posisi dan model tetap dilatih; ia hanya tidak bisa tahu di mana apa pun berada, dan itu adalah simetri, bukan kegagalan training. Tidak ada dalam attention score yang menyebut tt atau ii itu sendiri, sehingga mem-permute input mem-permute output: self-attention adalah permutation-equivariant. Ini adalah kebutaan urutan milik rata-rata dalam penyamaran yang lebih baik — causal mask memulihkan sebagian urutan, karena setiap posisi melihat prefix berbeda, tetapi di dalam sebuah prefix semua pengurutan sama saja.

Empat cara menyuntikkan posisi, dilatih pada window 64-token dan dievaluasi pada 64, 128, dan 256 — melewati panjang apa pun yang pernah mereka lihat:

posisiperplexity pada 64pada 128pada 256
tidak ada sama sekali48,7952,6357,52
embedding absolut yang dipelajari38,63108,47181,94
sinusoid tetap42,9695,26152,25
RoPE44,1250,5284,84
ALiBi44,9543,5142,49

Embedding absolut yang dipelajari — satu vector per posisi, ditambahkan ke token — menang pada panjang training lalu jatuh dari tebing, karena posisi 100 tidak pernah ada dalam batch dan embedding-nya masih vector acak seperti saat mulai. Sinusoid, pilihan asli, dihitung alih-alih dipelajari, dari sine dan cosine pada frekuensi berjarak geometris; paper 2017 berharap itu akan mengekstrapolasi, dan tabel mengatakan tidak — fungsi itu terdefinisi pada posisi 200, tetapi model tidak pernah belajar membacanya di sana. RoPE9 tidak menambahkan apa pun dan malah memutar query dan key dengan sudut yang proporsional terhadap posisi, dalam irisan dua dimensi; karena memutar kedua sisi dot product secara sama membuatnya tidak berubah, score akhirnya bergantung hanya pada tit - i, sehingga posisi menjadi relatif secara gratis dan tidak ada tabel yang bisa habis. Ia menurun, tetapi ia menurun dengan wajar. ALiBi10 adalah hasil paling sederhana sekaligus paling aneh di sini: penalti linear pada score yang proporsional terhadap jarak, dengan slope berbeda per head. Perplexity-nya membaik saat window tumbuh melewati panjang training, dari 44,95 ke 42,49, karena penalti itu terdefinisi pada jarak apa pun dan setiap head terus melakukan apa yang dilatih untuk dilakukan.

Pelajarannya bertahan lebih lama daripada tabel: arsitektur yang tidak bisa merepresentasikan sesuatu adalah masalah berbeda dari arsitektur yang tidak pernah mempelajari rentang itu, dan yang kedua itulah yang menggigit. Ini juga mesin di balik setiap pengumuman “kami memperluas context ke 128K” — itu hampir selalu berupa penskalaan ulang rotary encoding, dan itulah sebabnya Bab 16 mengatakan batas context bergerak, bukan menghilang.

Dropout diwarisi dengan cara yang sama: ia muncul pada attention weights setelah softmax, pada output setiap sub-layer sebelum residual addition, dan pada jumlah embedding, melakukan tepat apa yang dijelaskan Bab 6. Dalam run pretraining besar, ia sering disetel ke nol, karena model yang melihat setiap token sekali tidak berada dalam posisi untuk overfit.

Dua tensor dalam layer memiliki shape n×nn \times n, dengan nn sebagai jumlah token: scores dan weights setelah softmax. Semua yang lain — setiap projection, seluruh MLP — linear terhadap nn.

Satu attention layer, width 512, 8 head, batch satu, float32, pada GPU laptop. Baca dua kolom milidetik hanya untuk rasio-nya: itu wall clock pada kartu laptop 8 GB yang throttle dari 1.785 MHz ke bawah 300 MHz saat panas, sehingga cold run dari code yang sama kembali tujuh sampai sepuluh kali lebih cepat dan run yang sibuk lebih lambat lagi. Kolom megabyte adalah hitungan byte allocator dan tidak berubah.

TEXT
  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.87

Kolom x4 adalah rasio terhadap row di atasnya, dan penggandaan nn konvergen tepat ke 4 untuk waktu maupun memory — 3,91 pada langkah terakhir melawan teori 4. Kolom projection adalah kontrol: 4,0 ms pada 1024 token ke 40,1 ms pada 8192, faktor sepuluh untuk faktor delapan. Linear, seperti dijanjikan.

Lalu row terakhir. Satu attention layer, satu sequence, tanpa model di sekelilingnya, kehabisan memory pada GPU 8 GB di 16.384 token — matriks score saja akan sebesar 8 GB, yaitu 8 head dikali 16.384 dikali 16.384 dikali 4 byte. Bukan modelnya; satu tensor perantara dalam satu layer.

Itulah fakta fisik di bawah tiga bab berikutnya. Itulah mengapa context window punya batas sama sekali, yang Bab 16 ubah menjadi harga. Itulah mengapa FlashAttention ada, menghitung hasil yang sama dalam tile tanpa pernah menyimpan matriks — optimisasi memory sebelum menjadi optimisasi kecepatan.11 Dan itulah aritmetika di balik harga prompt panjang, yang dibayar Bab 24 dalam loop agent — perkara terpisah dari temuan lain bab itu, bahwa model juga menggunakan context panjang dengan lebih buruk, yang diukurnya dan ia menolak menyalahkan rumus ini.

Tampilkan detail

Dua varian pengecil cache, dinamai di sini dan dibayar di Bab 13.

Generation menyimpan cache key dan value dari token yang sudah diproses — satu key dan satu value per token, per head per layer. Multi-query attention12 mempertahankan hh query projection tetapi satu key dan value projection yang dibagi oleh semua head, membagi cache itu dengan hh. Grouped-query attention13 menginterpolasi: head dikelompokkan, setiap group berbagi satu key dan value, sehingga g=hg = h adalah attention biasa dan g=1g = 1 adalah multi-query. Hampir setiap model open sejak 2023 menggunakannya dengan 4 atau 8 group. Keduanya tidak ada demi kualitas; keduanya ada demi ukuran cache itu, dan Bab 13 melakukan aritmetika yang mengubahnya menjadi “model mana yang muat di GPU kamu”.

Paper 2017 mendeskripsikan encoder-decoder: satu stack membaca source dengan attention tanpa mask, stack kedua menghasilkan target secara kausal, dan jenis attention ketiga di tengah tempat query decoder bertemu key encoder. Itu tepat untuk translation, ketika input dan output adalah dua sequence.

Yang menang adalah separuh decoder-only — satu stack, kausal sepenuhnya, input dan output dalam sequence yang sama — dan alasannya bukan elegansi. “Prediksi token berikutnya” berjalan pada teks apa pun, sehingga training set-nya adalah internet alih-alih corpus paralel, dan semuanya menjadi satu tugas itu: translation adalah dokumen yang berisi source lalu target, pertanyaan dan jawabannya adalah dokumen, percakapan dengan tool call di tengah adalah dokumen. Bab 11 membahas bagaimana yang terakhir itu dibuat. Encoder tidak menghilang — encoder melihat seluruh input sekaligus, yang kamu inginkan saat tugasnya adalah merepresentasikan teks alih-alih melanjutkannya, dan itulah mengapa retrieval embeddings Bab 19 berasal dari encoder, bukan dari model yang sedang chatting.

Setelah block didefinisikan, ukuran model adalah aritmetika. Per block, dengan width dd dan ekspansi empat kali: 4d2+4d4d^2 + 4d untuk Wq,Wk,Wv,WoW_q, W_k, W_v, W_o dengan bias pada keempatnya, seperti GPT-2 memilikinya — tabel di atas menghilangkan bias pada tiga di antaranya, karena itu 2.304 lebih sedikit per block pada d=768d = 768; 8d2+5d8d^2 + 5d untuk MLP; 4d4d untuk dua LayerNorm — 12d2+13d12d^2 + 13d, plus tabel token sebesar V×dV \times d dan, untuk posisi absolut, nctx×dn_{\text{ctx}} \times d. Untuk shape GPT-2 small — d=768d = 768, 12 block, vocabulary 50.257, context 1024, output layer berbagi bobot embedding:

TEXT
  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,808

Itulah ukuran model yang dipublikasikan. Rumusnya bukan aproksimasi; rumusnya adalah model. Perhatikan juga bahwa hampir sepertiga model kecil adalah tabel embedding, sehingga ukuran vocabulary adalah keputusan arsitektural, bukan preprocessing — trade-off yang disiapkan Bab 7.

Perplexity adalah angka tentang corpus. Apa yang dilakukan satu head adalah pertanyaan berbeda, dan model yang dilatih pada satu megabyte Shakespeare adalah instrumen yang salah untuk itu: hal jujur yang bisa dikatakan tentang attention map model 500.000-parameter adalah bahwa sebagian besar tidak dapat diinterpretasikan. Jadi: bahasa tempat pertanyaannya punya jawaban benar.

Ilustrasi klasiknya adalah the animal did not cross the street because it was too tired, di mana it adalah animal, melawan …because it was too wet, di mana satu kata memindahkan referent ke street. Ini adalah Winograd schemas14 — pasangan kalimat identik kecuali satu kata, dan kata itu menentukan apa yang dirujuk pronoun.

Keduanya juga bisa diselesaikan dengan curang, bagian yang dilewati tutorial. Jika dua kandidatnya adalah animal dan place, tired dan wet mengidentifikasi referent berdasarkan kategori, dan model yang hanya tahu kata mana yang hadir mendapatkannya benar tanpa mengetahui apa pun tentang urutan. Diukur pada versi tugas itu, dengan pasangan animal/place held-out:

TEXT
uniform causal average           held-out referent accuracy 100.0 %
one transformer block            held-out referent accuracy  91.7 %

Bag of words mengalahkan transformer. Demonstrasi apa pun yang dibangun di atas kalimat itu tidak membuktikan apa pun tentang attention.

Jadi tutup celahnya: ambil kedua kandidat dari satu pool berisi enam belas noun, salah satunya bisa muncul di slot mana pun, dan bagi adjective berdasarkan peran alih-alih kategori — empat yang membuat it menjadi crosser (tired, scared, slow, weak), empat yang membuatnya menjadi crossed (wet, wide, busy, steep).

TEXT
the {x} did not cross the {y} because it was too {adj} , so the {ref} waited .

Latih sebagai next-token predictor biasa, beri score satu posisi — kata setelah so the — dan bangun held-out set dari pasangan noun yang urutan terbaliknya ada dalam training, sehingga apa pun yang tahu dua noun mana yang hadir tetapi tidak tahu mana yang duluan harus menjawab terbalik.

modelparameterheld-outmenamai noun lain
hanya token saat ini5.7965,2 %5,2 %
rata-rata kausal uniform5.79627,9 %50,0 %
satu head learned attention18.08435,4 %64,6 %
empat head22.24475,0 %15,6 %
satu transformer block55.71692,7 %4,2 %
dua transformer block105.508100,0 %0,0 %

Chance di antara dua noun yang hadir adalah 50 %. Rata-rata uniform mendarat di 27,9 % dan menjawab dengan noun yang salah dari pasangan itu tepat separuh waktu — signature dari sesuatu yang tahu kata mana yang ada dan tidak tahu apa pun tentang urutannya, seperti diprediksi shuffle test tiga bagian lalu.

Sekarang map-nya: attention pada posisi yang harus menamai referent, dirata-ratakan atas empat head dari setiap block, untuk dua kalimat yang berbeda satu kata. Rata-rata uniform akan menaruh 0,067 pada masing-masing dari lima belas token yang terlihat.

TEXT
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.25

Block 1 identik di kedua kalimat — 0,70 pada noun pertama, apa pun adjective-nya. Itu bukan kegagalan, melainkan bukti: di layer pertama, query pada sebuah posisi adalah fungsi dari token dan indeks posisi itu sendiri, dan the pada posisi 14 adalah token yang sama di kedua kalimat. Head layer pertama tidak bisa condition pada kata yang belum ia fetch. Jadi block 1 melakukan satu-satunya hal berguna yang tersedia baginya dan menarik noun pertama ke depan.

Block 2 adalah tempat kalimat-kalimat itu berpisah, dan row yang sama di semua delapan adjective menunjukkan aturan yang ditemukan model:

adjectiveblock 2 pada animalpada streetpada adjectivejawaban
tired, scared, slow, weak0,0000,0001,000animal
wet, wide, busy, steep0,0000,4910,00–0,03street

Untuk crosser-adjective, block kedua menghabiskan seluruh bobotnya pada adjective, karena jawabannya sudah ada di residual stream — block 1 menaruhnya di sana — dan yang ia butuhkan hanyalah konfirmasi. Untuk crossed-adjective, ia pergi mengambil noun lain. Itu adalah circuit dua-hop: satu head memindahkan kandidat ke depan, head di layer berikutnya membaca token yang memutuskan apakah kandidat itu dipertahankan. Komposisi antar layer adalah mekanismenya, dan itulah mengapa satu block mencapai 92,7 % dan dua mencapai 100 %.

Itu juga bentuk circuit paling terdokumentasi di model nyata. Induction heads — previous-token head yang memberi makan head di layer berikutnya yang melengkapi pola [A][B] … [A] → [B] — adalah yang diidentifikasi kerja interpretability Anthropic di balik sebagian besar in-context learning, dan mereka terbentuk pada momen yang dapat dikenali selama pretraining. Bab ini tidak mencoba analisis itu: ia diserahkan, dengan kedua paper di referensi, karena membaca circuit dari model nyata adalah bidang riset, bukan satu bagian.

Terakhir, implementasinya. Tiga puluh baris di atas, dengan bobotnya disalin dari milik PyTorch sendiri:

TEXT
ours vs nn.MultiheadAttention           max |diff| = 1.7881393432617188e-07
ours vs F.scaled_dot_product_attention  max |diff| = 1.7881393432617188e-07

1.8×1071.8 \times 10^{-7} pada output yang mean magnitude-nya 0,159: aritmetika yang sama dalam urutan berbeda, pada presisi float32.

Kamu memiliki arsitektur yang menjadi dasar setiap model di sisa kursus ini, dan ia lebih kecil daripada reputasinya: rata-rata berbobot yang bobotnya dipelajari, MLP per-posisi yang memegang dua pertiga parameter, dua normalisasi dan dua penjumlahan, ditumpuk.

Yang belum kamu miliki adalah model yang tahu apa pun, dan stacking tidak akan memperbaikinya sendirian. Dua block pada corpus ini mencapai training perplexity 14,49 dan validation perplexity 40,57, melawan satu block 18,77 dan 38,07 — kapasitas lebih besar, lebih baik pada apa yang sudah dilihat, lebih buruk pada apa yang belum, yaitu tabel Bab 6 dengan transformer di dalamnya. Jarak antara model ini dan model yang diajak bicara Bab 14 sampai 30 bukan arsitektural. Itu adalah block yang sama, diulang lebih banyak kali, di atas teks yang jauh lebih banyak.

Yang membuatnya menjadi masalah akuntansi, dan akuntansinya lebih aneh daripada kelihatannya. Berapa banyak teks, dan dari mana orang mendapatkannya? Berapa banyak aritmetika, dan bagaimana kamu memperkirakannya sebelum uang dibelanjakan? Dengan budget tetap, lebih baik membuat model lebih besar atau menunjukkan lebih banyak data — dan apakah ada jawaban yang benar, atau hanya tren? Bab 10 menjawab ketiganya lewat pengukuran, dan memberi harga pada bentuk pertanyaan berguna termurah: berapa biayanya, hari ini, untuk melatih model seperti GPT-2 dari nol?


Tiga penjelasan materi ini lebih baik daripada penjelasan ini untuk tujuan masing-masing, dan bab ini ditulis agar dibaca berdampingan dengan mereka. The Illustrated Transformer karya Jay Alammar adalah gambar terbaik tentang aliran data yang pernah dibuat. The Annotated Transformer dari Harvard NLP adalah paper 2017 dengan code berjalan yang disisipkan baris demi baris. Let's build GPT: from scratch, in code, spelled out karya Andrej Karpathy membangun model yang sama secara live dalam dua jam, dan tangga ablation di atas adalah tulang punggung yang sama yang diukur pada corpus berbeda. Untuk pertanyaan interpretability yang hanya disentuh bab ini, sumber primernya adalah Elhage et al., A Mathematical Framework for Transformer Circuits (2021) dan Olsson et al., In-context Learning and Induction Heads (2022), keduanya dari grup interpretability Anthropic.

  1. Hochreiter, S. dan Schmidhuber, J. Long Short-Term Memory. Neural Computation 9(8), hlm. 1735–1780 (1997).

  2. Sutskever, I., Vinyals, O. dan Le, Q. V. Sequence to Sequence Learning with Neural Networks. arXiv:1409.3215 (2014). Encoder-decoder yang satu context vector-nya menjadi bottleneck.

  3. Bahdanau, D., Cho, K. dan Bengio, Y. Neural Machine Translation by Jointly Learning to Align and Translate. arXiv:1409.0473 (2014). Attention, tiga tahun sebelum transformer.

  4. Perplexity adalah eksponensial dari mean cross-entropy per token, dari Bab 8. Setiap angka di sini memakai tokenizer yang sama dan validation split yang sama, satu-satunya kondisi yang membuat dua perplexity boleh dibandingkan sama sekali.

  5. Vaswani, A., Shazeer, N., Parmar, N., Uszkoreit, J., Jones, L., Gomez, A. N., Kaiser, Ł. dan Polosukhin, I. Attention Is All You Need. arXiv:1706.03762 (2017). Bagian 3.2.1 adalah satu kalimat tentang dk\sqrt{d_k} yang diukur satu bagian penuh oleh bab ini.

  6. Shazeer, N., Mirhoseini, A., Maziarz, K., Davis, A., Le, Q., Hinton, G. dan Dean, J. Outrageously Large Neural Networks: The Sparsely-Gated Mixture-of-Experts Layer. arXiv:1701.06538 (2017).

  7. Ba, J. L., Kiros, J. R. dan Hinton, G. E. Layer Normalization. arXiv:1607.06450 (2016). Diperkenalkan dan diukur di Bab 6; digunakan di sini tanpa perubahan.

  8. Xiong, R., Yang, Y., He, D., Zheng, K., Zheng, S., Xing, C., Zhang, H., Lan, Y., Wang, L. dan Liu, T.-Y. On Layer Normalization in the Transformer Architecture. arXiv:2002.04745 (2020). Analisis gradient di balik pre-norm, dan argumen bahwa warmup adalah gejala.

  9. Su, J., Lu, Y., Pan, S., Murtadha, A., Wen, B. dan Liu, Y. RoFormer: Enhanced Transformer with Rotary Position Embedding. arXiv:2104.09864 (2021).

  10. Press, O., Smith, N. A. dan Lewis, M. Train Short, Test Long: Attention with Linear Biases Enables Input Length Extrapolation. arXiv:2108.12409 (2021). Hasil ekstrapolasi yang direproduksi di atas.

  11. Dao, T., Fu, D. Y., Ermon, S., Rudra, A. dan Ré, C. FlashAttention: Fast and Memory-Efficient Exact Attention with IO-Awareness. arXiv:2205.14135 (2022).

  12. Shazeer, N. Fast Transformer Decoding: One Write-Head is All You Need. arXiv:1911.02150 (2019).

  13. Ainslie, J., Lee-Thorp, J., de Jong, M., Zemlyanskiy, Y., Lebrón, F. dan Sanghai, S. GQA: Training Generalized Multi-Query Transformer Models from Multi-Head Checkpoints. arXiv:2305.13245 (2023).

  14. Levesque, H. J., Davis, E. dan Morgenstern, L. The Winograd Schema Challenge. KR (2012). Konstruksi di balik kalimat animal / street yang dipakai setiap tutorial attention.

Siap membiarkan LIA yang memilih?

Berkarya dengan semua model AI dalam satu tempat — mulai gratis hari ini.