Transformer Çalışma Prensibi Açıklaması: Arkasındaki Matematiği Anlamak
(osanseviero.github.io)- Transformer çıkarım süreci, Hello World → Hola Mundo çeviri örneğiyle küçültülerek; tokenleştirmeden encoder, decoder ve sonraki token olasılığı hesabına kadar elle takip edilebilir hale getiriliyor
- Orijinal makaledeki büyük ayarlar yerine 4 boyutlu embedding, 2 attention head ve 8 boyutlu feedforward katmanı kullanılarak matris çarpımı ve softmax akışı küçültülüyor
- Encoder, token embedding’lerine konum kodlaması ekledikten sonra multi-head self-attention ve feedforward katmanlarından geçirerek giriş dizisinin bağlamsal temsilini oluşturuyor
- Decoder,
SOSile başlayıp daha önce üretilen token’lar ile encoder çıktısını birlikte kullanıyor; encoder-decoder attention aşamasında query decoder’dan, key/value ise encoder çıktısından hesaplanıyor - Son decoder embedding’i bir lineer katman ve softmax’tan geçirilerek sonraki token olasılığına dönüştürülüyor; ancak örnekte rastgele ağırlıklar kullanıldığı için gerçek çeviri kalitesi beklenmiyor
Amaç ve varsayımlar
- Transformer modelinin içinde çıkarım sırasındaki matematiğin uçtan uca nasıl ilerlediğini bir örnek üzerinden görmek
- Hesapları elle takip etmeyi kolaylaştırmak için model boyutu ciddi biçimde küçültülüyor
- Orijinal makaledeki 512 boyutlu embedding yerine örnekte 4 boyut kullanılıyor
- Orijinal makaledeki 8 attention head yerine 2 adet kullanılıyor
- Orijinal makaledeki 2048 boyutlu feedforward yerine 8 boyut kullanılıyor
- Gerekli ön bilgi temel lineer cebir; hesapların çoğu matris çarpımıyla yapılıyor
- Odak noktası transformer’ın “ne olduğu”ndan çok hesaplamanın nasıl ilerlediği
- Sezgisel açıklama için The Illustrated Transformer ile birlikte okunabilir; orijinal makale ise Attention is all you need
Encoder girdisini oluşturma
-
Tokenleştirme
- Makine öğrenmesi modelleri metni değil sayıları işler; bu yüzden giriş metni token ID’lerine dönüştürülür
- Örnekte sadeleştirme amacıyla
"Hello World","Hello"ve"World"olmak üzere iki kelime token’ına ayrılır - Gerçek tokenleştirme yöntemleri kelime tabanlı, karakter tabanlı ve subword tabanlı olabilir
- Kelime tabanlı yaklaşım büyük bir vocabulary gerektirir ve
"dog"ile"dogs"u farklı token’lar olarak ele alır - Karakter tabanlı yaklaşımın vocabulary’si küçüktür ama anlam bilgisi daha sınırlı olabilir
- Subword tokenleştirme, kelime ve karakter yaklaşımları arasında bir orta noktadır ve tokenizer istatistiksel bir süreçle eğitilir
-
Token embedding’i
- Token ID’lerinin kendisi anlam taşımaz; bu yüzden her token sabit boyutlu bir vektöre, yani embedding’e dönüştürülür
- Örnekte embedding’ler rastgele değerlerle verilir
Hello -> [1, 2, 3, 4]World -> [2, 3, 4, 5]
- Gerçek transformer’larda embedding eşlemesi de öğrenilir ve model göreve uygun token temsillerini öğrenir
- İki embedding tek bir matris içinde birleştirilir ve sonraki matris çarpımlarında kullanılır
-
Konum kodlaması
- Sadece embedding’lerle kelimelerin cümle içindeki konumu bilinemez; bu yüzden konum kodlaması eklenir
- Orijinal makale sabit sine/cosine konum kodlaması kullanır; örnek de aynı yöntemi izler
- Örnekteki konum kodlaması şu şekilde hesaplanır
Hello -> [0, 1, 0, 1]World -> [0.84, 0.99, 0, 1]
- Token embedding’i ile konum kodlaması toplanarak encoder giriş matrisi oluşturulur
Hello -> [1, 3, 3, 5]World -> [2.84, 3.99, 4, 6]
Self-attention hesabı
-
Q, K, V oluşturma
- self-attention, giriş embedding’lerinden query(Q), key(K) ve value(V) hesaplar
- Örnek 2 attention head kullanır ve her head’in ayrı
WQ,WK,WVmatrisleri vardır - Her ağırlık matrisi 4 boyutlu embedding’i 3 boyutlu query/key/value’ye dönüştürür
- İlk head’de giriş matrisi
WK1,WV1,WQ1ile çarpılarakK1,V1,Q1elde edilir
-
Attention formülü
- Attention skoru dört adımda hesaplanır
- query ile her key arasındaki iç çarpım hesaplanır
- sonuç key boyutunun kareköküne bölünür
- softmax ile pozitif ve toplamı 1 olan ağırlıklara dönüştürülür
- bu ağırlıklarla value vektörlerinin ağırlıklı toplamı alınır
- Bu süreç orijinal makalede şu formülle özetlenir
- [
- Attention(Q,K,V) = \text{softmax}\left(\frac{QK^\top}{\sqrt{d}}\right)V
- ]
- Örnekte küçük boyutlar ve rastgele başlangıç değerleri nedeniyle softmax sonucu neredeyse 0 ve 1’e yığılır
- Büyük dot product değerleri softmax içinde daha da güçlenebilir; bu yüzden key boyutunun kareköküne bölerek ölçekleme gerekir
- Anlatım amacıyla geçici olarak
sqrt(3)yerine 30’a bölme gibi bir varyasyon da kullanılır, ancak bu kalıcı bir çözüm değildir
- Attention skoru dört adımda hesaplanır
-
Multi-head attention çıktısı
- Her head’in attention sonucu concatenate edildikten sonra, öğrenilen bir ağırlık matrisiyle çarpılarak yeniden embedding boyutuna döndürülür
- Örnekte iki head’in sonucu birleştirilerek 6 boyutlu bir matris oluşturulur ve bu 4 boyutlu çıktıya dönüştürülür
- Bu çıktı, encoder bloğunun bir sonraki aşaması olan feedforward katmanına aktarılır
Feedforward katman ve encoder bloğu
-
Feedforward katman
- self-attention’ın ardından feedforward sinir ağı (FFN) gelir
- FFN, iki lineer dönüşüm ve aradaki ReLU aktivasyonundan oluşur
- İlk lineer katman boyutu genişletir, ikinci lineer katman ise tekrar orijinal boyuta indirir
- ReLU, negatif değerleri 0 yapar ve pozitifleri olduğu gibi bırakarak doğrusal olmayanlık ekler
- Örnekte 4 boyutlu giriş önce 8 boyuta genişletilir, ardından tekrar 4 boyuta düşürülür
- [
- \text{FFN}(x) = \text{ReLU}(xW_1 + b_1)W_2 + b_2
- ]
-
Encoder bloğu
- Bir encoder bloğu multi-head attention ve FFN’den oluşur
- Orijinal makale 6 encoder yığar; örnek kod da encoder’ı
n=6ile tekrarlar - Birden fazla encoder bloğundan doğrudan geçmek, değerlerin aşırı büyümesine neden olabilir; bu da softmax hesaplarında taşmaya ve
nanüretimine yol açabilir
Residual connection ve layer normalization
-
Değerlerin kontrolden çıkması sorunu
- Örnekte 6 encoder’dan geçildiğinde
overflow encountered in expveinvalid value encountered in divideuyarıları görülür, çıktı dananolur - Değerlerin çok büyüyüp sonraki katmanlarda daha da büyümesi, derin sinir ağlarında yaygın bir sorundur
- Backpropagation sırasında gradient’lerin aşırı büyümesine gradient explosion denir
- Örnekte 6 encoder’dan geçildiğinde
-
Residual connection
- residual connection, katman girişini katman çıkışına ekleme yöntemidir
- [
- \text{Residual}(x) = x + \text{Layer}(x)
- ]
- Örnekte hem attention çıktısına hem de FFN çıktısına residual connection uygulanır
- residual connection, vanishing gradient sorununu hafifletmek için kullanılır
-
Layer normalization
- layer normalization, her embedding boyutunu ortalaması 0 ve standart sapması 1 olacak şekilde normalize eder
- Formül şu şekildedir
- [
- \text{LayerNorm}(x) = \frac{x - \mu}{\sqrt{\sigma^2 + \epsilon}} \times \gamma + \beta
- ]
- (\epsilon), standart sapma 0 olduğunda 0’a bölmeyi önlemek için kullanılan küçük bir değerdir
- (\gamma) ve (\beta), ölçekleme ve kaydırmayı kontrol eden öğrenilebilir parametrelerdir
- residual connection ve layer normalization eklendikten sonra, 6 encoder’dan geçildiğinde bile
nanoluşmadan normal değerler elde edilir
Decoder yapısı
-
Decoder girdisi ve üretim biçimi
- Decoder, encoder çıktısını ve o ana kadar üretilmiş çıktı dizisini giriş olarak alır
- Çıkarım sırasında SOS(start-of-sequence) token’ı ile başlanır
- Decoder, autoregressive biçimde her seferinde bir token üretir
-
- tur:
SOSgirdisiyle"hola"üretilir
- tur:
-
- tur:
SOS + holagirdisiyle"mundo"üretilir
- tur:
-
- tur:
SOS + hola + mundogirdisiyleEOSüretilir
- tur:
-
EOS(end-of-sequence)token’ı üretildiğinde çözümleme durur- Encoder tek bir forward pass ile temsil üretebilirken decoder’ın birden çok forward pass yapması gerekir; bu yüzden daha yavaştır
-
Decoder bloğunun bileşenleri
- Decoder bloğu encoder bloğundan daha karmaşıktır ve şu sırayla oluşur
- masked self-attention
- residual connection ve layer normalization
- encoder-decoder attention
- residual connection ve layer normalization
- feedforward katman
- residual connection ve layer normalization
- Çıkarım örneğinde
SOSembedding’ine konum kodlaması eklenerek[1, 1, 0, 1]kullanılır - Eğitim sırasında gelecekteki token’ların görülmesini engellemek için attention skorları
-infile maskelenen masked self-attention kullanılır
- Decoder bloğu encoder bloğundan daha karmaşıktır ve şu sırayla oluşur
Encoder-decoder attention
- encoder-decoder attention, decoder’ın giriş cümlesinin ilgili bölümlerine odaklanmasını sağlayan aşamadır
- Hesaplama yöntemi self-attention ile aynıdır ancak Q/K/V’yi oluşturan girdiler farklıdır
- query, önceki decoder katmanının çıktısından hesaplanır
- key ve value, encoder çıktısından hesaplanır
- Bu yapı sayesinde decoder’daki her konum, giriş dizisindeki tüm konumlara bakabilir
- Çeviri gibi, çıktı token’larının giriş cümlesindeki ilgili konumlara dayanması gereken görevlerde faydalıdır
Çıkış token’ı üretimi
-
Lineer katman ve softmax
- Decoder çıktısı doğrudan kelime değildir; bu yüzden son embedding bir lineer katmandan geçirilerek vocabulary boyutunda bir logits vektörüne dönüştürülür
- Örnek vocabulary boyutu 10’dur ve sonraki token adayları şunlardır
hello,mundo,world,how,?,EOS,SOS,a,hola,c
- logits, softmax sonrasında her token için bir olasılık dağılımına dönüşür
- Örnek olasılıklarda
"hola"en yüksek olasılığı aldığı için sonraki token olarak seçilir - Her zaman en yüksek olasılıklı token’ı seçmeye greedy decoding denir; bu yöntem her zaman en iyi sonuç olmayabilir
- Üretim teknikleri hakkında daha fazla bilgi için Hugging Face yazısı incelenebilir
-
Tüm üretim döngüsü
- Üretimin genel akışı şöyledir
- giriş dizisi embedding’lere dönüştürülür
- encoder, tüm girişin bağlamsal temsilini üretir
- decoder,
SOSile başlayıp önceki üretilen token’lar ile encoder çıktısını birlikte kullanır - son decoder embedding’ine lineer katman ve softmax uygulanır
- en olası sonraki token seçilip diziye eklenir
EOSgelene ya da maksimum uzunluğa ulaşılana kadar süreç tekrarlanır
- Örnek çalıştırma,
hello worldgirdisi içinSOS hola mundo worldçıktısını üretir - Tüm ağırlıklar ve embedding’ler rastgele kullanıldığı için sonuç iyi bir çeviri değildir; bu beklenen davranıştır
- Üretimin genel akışı şöyledir
Sonuç ve kapsam
- Örnek; embedding, konum kodlaması, self-attention, multi-head attention, FFN, residual connection, layer normalization, encoder-decoder attention ve softmax çıktısı gibi transformer’ın temel bileşenlerini tek bir akışta birleştirir
- Modern transformer mimarileri çeşitli ek teknikler içerir, ancak temel matematik bu örnekte ele alınan yapıya dayanır
- Kullanılan yığın, görevin türüne göre değişebilir
- Sınıflandırma gibi anlama odaklı görevlerde encoder yığınının üstüne bir lineer katman konabilir
- Çeviri gibi üretim odaklı görevlerde encoder ve decoder yığını birlikte kullanılabilir
- ChatGPT veya Mistral gibi serbest üretim görevlerinde yalnızca decoder yığını kullanılabilir
- Eğitim süreci ele alınmaz; odak, mevcut bir modeli kullanırken çıkarım matematiğini anlamaktır
- Daha formel matematiksel materyal için bu PDF incelenebilir
1 yorum
Hacker News görüşleri
Transformer’ın “gizemi”, her katmanda statik ağırlıkları ve değerleri doğrusal sırayla çarpmak yerine, aynı girdiye öğrenilmiş ağırlıkları uygulayarak 3 matris oluşturması ve sonra bu matrisleri birbiriyle çarpmasında yatıyor
Bu, paralelliği artırıp iyi çalışmasını sağlıyor, ancak attention formülünün kendisi sabit olduğu için çok sınırlı
Daha fazla ilerlemek için, hesaplama grafiğinin kendisini öğrenilebilir parametrelere genellemenin bir yoluna ihtiyaç var gibi görünüyor. Küçük değişimlerin performansta büyük değişimlere yol açtığı kaos etkisi yüzünden bunun geleneksel gradyan yöntemleriyle mümkün olup olmadığını bilmiyorum; içeride bir tür genetik algoritma ya da parçacık sürüsü optimizasyonu gerekebilir
RNN’lere kıyasla büyük teorik avantajı, bunu kayıpsız biçimde desteklemesidir. Çünkü her öğe dizideki diğer tüm öğelerin ya da zaman sıralamasında kendisinden önce gelen öğelerin tüm bilgisine erişebilir
Buna karşılık RNN’ler ve “linear Transformer”lar geçmiş değerleri sıkıştırır; bu yüzden uzun dizilerde son öğenin ilk öğenin tüm bilgisine erişmesi, iç durum çok büyük olup hiçbir bilgi atılmadığı durumlar dışında, genellikle zordur ve çoğu zaman imkânsızdır
Sorun şu ki burada kazanılan şey pek fazla değil. Matris çarpımı olmayan işlemler büyük ihtimalle daha yavaş ya da benzer hızda olur
Yalnız akış kontrolü eklerseniz fiilen bir Turing machine olma riski var; o zaman da dediğiniz gibi eğitim sorun haline geliyor. Yine de tamamen başa çıkılamaz bir problem olmayabilir
Daha kuru, biçimsel ve kısa bir açıklama isteyenler için John Thickstun’un “The Transformer Model in Equations” [0] yazısı var
Her şey standart matematik gösterimiyle tek sayfaya sığıyor
[0] https://johnthickstun.com/docs/transformers.pdf
Makine öğrenimi araştırmacıları çoğu zaman sanki matematik hiç çalışmamış gibi görünüyor
“NaN çıkıyor, değer çok büyüyor ve bir sonraki encoder’a geçerken patlıyor, bu da exploding gradients’tir” açıklaması, benim anladığım kadarıyla yanlış
Burada hiçbir noktada gradyan hesaplanmıyor, dolayısıyla bu bir exploding gradients durumu değil
Sorun softmax uygulamasıyla ilgili görünüyor; sayısal olarak kararlı softmax’ın nasıl uygulanacağı burada [0] anlatılıyor
[0]: https://jaykmody.com/blog/stable-softmax/
Yine de sinir ağının tamamı büyük değerlere duyarlı olduğu için, bunu yalnızca sayısal olarak kararlı bir softmax çözmez. Ağın çalışabilmesi için normalization kritik önemde
Transformer eğitimleri yeni Monad eğitimleri haline gelebilir. Anlaması zor bir kavram ama ancak örneklerle uğraşarak kavranabilen türden
Bilgisayar biliminin pek çok alanında olduğu gibi
Daha altı paragraf okudum ama şimdiden bir sorum var
Hello -> [1,2,3,4] World -> [2,3,4,5]örneğinde vektörlerin rastgele olduğu söyleniyor ama ortada bir desen var gibi görünüyor. İki vektörde de bulunan2’nin bir anlamı olup olmadığını, yoksa benzersizliği tüm kümenin mi oluşturduğunu merak ediyorumBurada aralarında yaklaşık 60 derece var ve bir ölçüde aynı yöne bakıyorlar; örneğe negatif sayılar koymamak için vektörler gerçekte olacaklarından daha benzer görünmüş
Sayıların yeniden kullanılmış olmasının kendi başına bir anlamı yok. İlk konumdaki
1, ikinci konumdaki1ile neredeyse hiç ilişkili değil. Zaten bu vektörler üzerinde konvolüsyon da yapılmıyorEğitimden sonra benzer kelimeler bir miktar kosinüs benzerliğine sahip olabilir, ama
[1,2,3,4]ile[2,3,4,5]kadar yüksek kosinüs benzerliği görülmesi neredeyse hiç olmazTam olarak ilgili bir soru değil ama, Transformer yalnızca bir “sonraki token tahmin edicisi” gibi çalışırken yine de aşağıdaki gibi soruları neden işleyebildiğini ele alan yazı veya makaleler arıyorum
"sdsfs_ff","fsdf_value"olan bir tablo oluşturmakMuhtemelen yaygın bir sorudur ama aratmak için anahtar kelimeleri bulamıyorum. Konumsal gömmeler hakkında derinlemesine bağlantılar da iyi olurdu; ayrıca neden sinüs/kosinüs kullanıldığı ve çarpma yerine toplama tercih edildiği konusunda da hâlâ tatmin edici bir cevap bulamadım
Model gerekli olduğuna karar verirse bilinmeyen bir diziyi tek karakterlik token’ları kopyalayarak yeniden üretebilir ya da bağlama uygunsa yeni bir tane oluşturabilir
P(X_1=x_1, X_2=x_2, X_3=x_3) = P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_1=x_1, X_2=x_2)= P(X_3=x_3 | X_1=X_1, X_2=x_2) • P(X_2=x_2 | X_1=x_1) • P(X_1=x_1)Yani önceki token’lar verildiğinde sonraki token için doğru koşullu olasılık dağılımı varsa, tüm token dizisi için de doğru bir olasılık dağılımı elde edilir
“Token dizisi için doğru olasılık dağılımı” ya da bazı koşullar altında verilen bir token dizisi için doğru koşullu olasılık dağılımı, aslında neredeyse her türlü girdi/çıktı davranışını bu terimlerle açıklayabilir
Bu yüzden “sonraki token’ı tahmin ederek çalışır” demek, ilke olarak hangi girdi/çıktı davranışlarını sergileyebileceği üzerinde büyük bir kısıt değildir
Ne kadar etkileyici bir şey yaparsa yapsın, o çıktının
P(X_{n+1}=x_{n+1} | X_1=x_1, ..., X_n=x_n)’den gelmesi, yani “sonraki token tahmini” olmasıyla çelişmezSonraki token tahmini kulağa geldiğinden daha akıllı bir iştir
“Karmaşıklık, adım sayısından ve parametre sayısından gelir” sözüne katılıyorum
Bizim anlayabileceğimiz kadar basit Transformer modelleri ilginç şeyler yapamıyor; ilginç şeyler yapacak kadar karmaşık Transformer’lar da bizim anlayamayacağımız kadar karmaşık görünüyor
Anlaşılabilecek kadar basit ama ilginç şeyler yapabilecek kadar da karmaşık olan orta ölçekli modelleri incelemek isterdim
Kavramları tanımlamadan ya da tanıtmadan kullanınca anlamak zorlaşıyor. Encoder bölümü, bunun ne olduğunu ve tüm sürecin neresine oturduğunu açıklamadan doğrudan başlıyor
Yazarın ne yapmaya çalıştığını anlıyorum ama önce fikri tanıtıp açıklayan, sonra kullanan temel yazı yapısı eksik
Bu konuyu zaten çalışıp yarım yamalak anlamış biri değilseniz, yazının tamamı kafa karıştırıcı geliyor
Sıfırdan ANN yazmış olmama ve TensorFlow kullanmamış olmama rağmen bu açıklama hâlâ kafa karıştırıcı
ChatGPT’den
Matrixya daVectorkelimelerini kullanmadan temel bir ANN’yi self-attention uygulayacak şekilde nasıl değiştireceğini açıklamasını istedim; oldukça basit bir açıklama verdi. Henüz uygulamayı denemedimHer şeyi düğümler, ağırlıklar ve katmanlar açısından düşünmeyi daha faydalı buluyorum. Matrisler ve vektörler, ANN içinde gerçekten olan bitenle bağlantı kurmayı zorlaştırıyor
Alışık olduğum ANN yazım tarzında her giriş düğümü bir skaler, ama ileri besleme algoritması tüm giriş düğümlerini ağırlıklarla çarpıp topladığı için bu vektör-matris çarpımı gibi görünüyor. Bu tür açıklamalara yanlış bir zihniyetle yaklaşıyormuşum gibi geliyor; belki de gerekli arka plan bilgim eksik