2 puan yazan GN⁺ 2023-09-24 | 1 yorum | WhatsApp'ta paylaş
  • GPT-2'ye benzer bir yalnızca decoder kullanan transformer'ın, eğitim olmadan ağırlıkları doğrudan tasarlanarak (aab)* örüntüsünü tahmin etmesi sağlanan bir deney
  • "aabaabaabaab..." tahmini, bir önceki iki token'a bakmayı gerektirdiği için, basit dönüşümlü örüntülere göre attention'ın nasıl çalıştığını göstermeye daha uygun
  • Model küçük tutuluyor: N_CTX=5, N_VOCAB=2, N_EMBED=8; tokenleştirme a=0, b=1 ve one-hot embedding kullanılıyor
  • Tek bir attention head, son iki token'a 0.5'er attention dağıtıyor ve a=1, b=-1 kodlamasının birbirini götürmesinden yararlanarak bir sonraki token'ı hesaplıyor
  • Belirsiz olmayan bağlamlarda %100.0 (27/27) doğruluk gösterse de, 5 token'lık bağlamla tek tahminde yaklaşık 4.000 FLOP gerekiyor; yani elle yazılmış bir kurala göre çok daha verimsiz

Öğrenme olmadan ağırlıkları elle belirlenmiş mini GPT-2

  • Amaç, transformer ve attention'ın her bileşeninin gerçekte ne yaptığını sezgisel olarak anlamak
  • Model eğitim almıyor, önceden eğitilmiş ağırlıklar da kullanmıyor; tek bir akşamda her ağırlığın elle belirlenmesiyle oluşturuluyor
  • Yapı, GPT-2'ye benzer bir yalnızca decoder kullanan transformer ve uygulama jaymody'nin picoGPT uygulaması temel alınarak sadeleştiriliyor
    • layer norm kaldırılıyor
    • multi-head attention yerine tek head kullanılıyor
    • transformer block içindeki mlp feed-forward katmanı kaldırılıyor

Neden (aab)* dizisi seçildi?

  • Başta "ababababab" gibi bir dizi tahmin edilmek istenmiş, ancak transformer kaydırılmış diziyi tahmin ettiği için bu görev fazla kolay kalmış
    • a ise b, değilse a tahmin etmek yeterli olduğundan konum embedding'ine gerek kalmıyor
  • Son görev "aabaabaabaab...", yani (aab)* dizisini tahmin etmek olarak belirleniyor
    • Önceki iki token ab veya ba ise sonraki token a
    • Önceki iki token aa ise sonraki token b
    • bb ise görev kapsamı dışı bir durum olarak ele alınıyor
  • Tokenleştirme yalnızca iki sembolü kapsayan basit bir yöntem
    • a = 0
    • b = 1

Model boyutları ve hesap akışı

  • Seçilen model parametreleri üç tane
    • N_CTX = 5: modelin bir seferde gördüğü azami bağlam uzunluğu
    • N_VOCAB = 2: a, b olmak üzere iki token
    • N_EMBED = 8: token, konum ve hesaplama alanını taşıyan embedding boyutu
  • Gerçek görevde yalnızca önceki iki token gerekiyor, ancak N_CTX=5 seçilerek ilgisiz token'ların yok sayılması gereken durum da dahil ediliyor
  • gpt fonksiyonu şu sırayla çalışıyor
    • wte[inputs] + wpe[range(len(inputs))] ile token embedding'i ve konum embedding'i toplanıyor
    • tek bir transformer block'tan geçiriliyor
    • sonda x @ wte.T ile kelime dağarcığı uzayında logits üretiliyor

Konum ve token'ları one-hot olarak taşıyan embedding'ler

  • wpe konum embedding'i ve ilk 5 embedding boyutu konum one-hot olarak kullanılıyor
    • position 0 = [1, 0, 0, 0, 0]
    • position 4 = [0, 0, 0, 0, 1]
  • wte token embedding'i ve sonraki 2 boyut token one-hot olarak kullanılıyor
    • token a ilgili token boyutlarında [1, 0]
    • token b ise [0, 1]
    1. embedding konumu başlangıçta kullanılmıyor; transformer block içinde scratch space olarak kullanılıyor
  • Örneğin "aabaa", her satırı konum one-hot ve token one-hot içeren 5 x 8 boyutlu bir embedding matrisi olarak ifade ediliyor

Attention head'in son iki token'ı seçme yöntemi

  • Transformer block, tek bir attention head ve attention sonucunu yeniden embedding uzayına döndüren c_proj doğrusal katmanından oluşuyor
  • c_attn, boyutu embed_size x (embed_size * 3) olan bir doğrusal katman; giriş embedding'ini qkv matrisine çevirip ardından q, k, v olarak ayırıyor
  • k, konum embedding'lerini ayırarak her token'ın sahip olduğu konum bilgisini temsil ediyor
  • q, her konumun hangi konum aralığını aradığını ifade ediyor ve q @ k.T ile attention score matrisi oluşturuluyor
  • softmax ve causal mask sonrasında attention matrisinin özellikleri şöyle
    • ilk satır yalnızca ilk token'a %100 attention veriyor
    • sonraki satırlar erişilebilir en son iki token'a ayrı ayrı 0.5 attention veriyor
  • Causal mask, gelecekteki token konumlarına çok küçük bir değer ekleyerek, gerçek kodda -1e10 gibi bir değerle, geleceği görmeyi engelliyor
    • Bu elle yapılmış model geleceğe bakacak şekilde tasarlanmamış olsa da, GPT-2 yapısına yakın kalmak için mask korunuyor
  • np.sqrt(q.shape[-1]) ile yapılan ölçekleme, gerçek eğitimde gradyanları iyileştirmeye yardım ediyor ama bu el yapımı modelde bir etkisi olmuyor

v kodlaması ve toplama ile birbirini götürmeye dayalı tahmin

  • v, token one-hot bilgisini a=1, b=-1 kodlamasına dönüştürüyor
  • Attention sonucu son iki token'ın ortalamasını 0.5 ve 0.5 olarak aldığı için, bu kodlama şu kuralı hesaplıyor
    • a, b0.5 * 1 + 0.5 * (-1) = 0
    • b, a0.5 * (-1) + 0.5 * 1 = 0
    • a, a0.5 * 1 + 0.5 * 1 = 1
  • Sonuç olarak satırın 7. konumunda şu değer oluşuyor
    • 0 ise a tahmin edilmesi gereken durum
    • 1 ise b tahmin edilmesi gereken durum
  • "aabaa" girdisinde ilk satırda bilgi yetersizliği nedeniyle b tahmini oluşabilir, ancak sonraki tahminler (aab)* kuralıyla uyumlu oluyor

Tahmin değerlerini yeniden kelime dağarcığı uzayına gönderme

  • c_proj, attention sonucundaki 7. konum değerini token one-hot biçimine geri dönüştürüyor
  • Bunu basitçe [..., 1, 0, ...] veya [..., 0, 1, ...] üreterek değil, 1024 ile ölçeklenmiş bir one-hot oluşturarak yapıyor
    • embedding[row, 5] = 1024 + (-1024) * prediction
    • embedding[row, 6] = 0 + 1024 * prediction
  • Transformer block içinde residual connection bulunduğundan x = x + causal_self_attention(...) ile özgün embedding geri ekleniyor
  • Residual sinyal gereksiz şekilde kaldığı için, 1024 ölçeği bu sinyali bastırmak amacıyla kullanılıyor
  • Son olarak x @ wte.T hesaplanarak logits üretiliyor ve softmax uygulanıyor
    • "aabaa" bağlamında son tahmin satırı b'yi gösteriyor
    • Eğitim sırasında tüm satırların tahmini yararlı olsa da, çıkarımda yalnızca son satır gerekiyor

Üretim sonuçları ve doğruluk

  • complete fonksiyonu son en fazla 5 token'ı modele veriyor ve softmax sonucunun son satırındaki argmax ile sonraki token'ı seçiyor
  • Örnek üretim sonuçları şöyle
    • complete("a")a :: baabaabaab
    • complete("ba")ba :: abaabaabaa
    • complete("abaab")abaab :: aabaabaaba
  • Kapsam dışı girdilerde bile tekrar eden örüntüye geri döndüğü durumlar var
    • complete("ababa")ababa :: abaabaabaa
    • complete("bbbbb")bbbbb :: aabaabaaba
  • "aab" * 10 testinde yalnızca belirsiz olmayan bağlamlar değerlendirildiğinde doğruluk %100.0 (27/27) oluyor

4.000 FLOP ile 8 komut arasındaki fark

  • 5 token'lık tam bağlam kullanıldığında, bu model tek bir token tahmini için yaklaşık 4.000 floating point operation gerektiriyor
    • bunun büyük kısmı attention hesabında kullanılıyor
    • context window küçültme, fused multiply-add, kv caching gibi yöntemlerle azaltılabilir
    • yine de tek token tahmini için yüzlerce makine komutu gerekiyor
  • Aynı (aab)* kuralını doğrudan yazan x64 assembly ise sonraki token'ı 8 komutta hesaplıyor
  • Buradan, doğal dil üretiminde mevcut modellere göre 1000 kat daha verimli bir dil modeli eğitmenin mümkün olup olmadığı sorusu ortaya çıkıyor

1 yorum

 
GN⁺ 2023-09-24
Hacker News yorumları
  • İlgili bir çalışma olarak "Thinking Like Transformers" var.
    RASP adlı ilkel bir programlama dili tanıtıyor; Transformer bileşenleriyle modellenebilen işlemlerden oluşuyor ve histogram ya da sıralama gibi programların yazılabildiğini gösteriyor.
    Sasha Rush ve Gail Weiss’in harika bir blog yazısı da var; sonraki araştırmalar ise RASP türü programların eğitim olmadan gerçek model ağırlıklarına derlenebildiğini gösterdi.
    [1] https://arxiv.org/abs/2106.06981
    [2] https://srush.github.io/raspy/
    [3] https://arxiv.org/abs/2301.05062

    • RASP ailesini gerçekten seviyorum.
      Bu alan ilginizi çekiyorsa, Transformer modelinin ağırlıklarını doğrudan seçerek insanın ilkokulda öğrendiği yönteme benzer şekilde uzun toplama yapmasını sağlayan HandCrafted Transformers çalışmama da göz atmaya değer.
      [1] https://colab.research.google.com/github/newhouseb/handcraft...
    • Bu tür işler için Haskell gibi fonksiyonel dillerin uygun olacağını düşünüyorum.
      Sinir ağlarından koda giden yön de açıklanabilirlik açısından çok ilginç olabilir.
  • Transformer’ları iyi anladığımı sanıyordum ama hiç kendim uygulamamıştım.
    Bir gün kendim uyguladığımda, standart PyTorch Transformer kadar iyi çalışmadığını ya da öğrenmediğini gördüm; sonunda nedenin dropout’u göz ardı etmem olduğunu fark ettim.
    Sayı toplamayı öğrenmesini sağlamıştım ve aynı çifti iki kez göstermediğim için aşırı uyumun imkânsız olduğunu düşünüyordum; meğer dropout’un rolü sandığımdan çok daha büyükmüş.
    Özetle, Transformer’ı doğrudan kendiniz uygulamanız iyi olur; ne kadar temelden başlarsanız o kadar iyi.
    Bunu yapan herkes beklemediği bir şey öğrendi; token düzeyinde eğitim paralelleştirmesinden geri yayılımın gerçekte nasıl işlediğine kadar, herkesin fark ettiği nokta farklıydı.

    • Bu işe yaklaşmak için yardımcı olabilecek kaynaklar var mı, merak ediyorum.
  • Karpathy’nin materyalleri de iyi ama Transformer’ı sonunda anlamamı sağlayan şu video oldu: https://youtu.be/kWLed8o5M2Y?si=SJT5_lCJ0hSR7Z_k

  • Bir süredir benzer bir fikir üzerine düşünüyorum.
    Alan uzmanlarının elle ayarlayarak eğitimi hızlandırabileceği, model ağırlıkları için sezgisel bir arayüz yapılamaz mı?
    Örneğin bir görsel modelde trafik konisini algılarken "turunculuk"a karşılık gelen bir ağırlık grubunu artırmak gibi.
    Böylece "turunculuk"u düzgün kalibre etmek için binlerce, milyonlarca ek örnek istemek yerine, insan bunu hızlandırabilir.
    Elbette zor olan nokta, bu arayüzün farklı anlamlar taşıyan ağırlık gruplarına eşlenmesi gerekliliği; bunun teknik olarak imkânsız olmasının bir nedeni var mı, merak ediyorum.

    • "Alan uzmanının modelin ağırlıklarını elle ayarlaması" fikri, derin öğrenme öncesi görüntü tanıma yöntemlerine benziyor.
      [1] https://www.youtube.com/watch?v=8SF_h3xF3cE&t=1358s
    • Aradığınız gerekçeye The Bitter Lesson deniyor.
      Kısaca, yapay zekaya insanın yardım ettiği yöntemler, onu daha fazla hesaplama gücüyle çalıştırmaktan neredeyse her zaman daha az maliyet-etkindir.
      Siz turuncu trafik konisini algılasın diye bir ağırlık katmanını kalibre ederken, GPU kümesi yapay zekaya trafik konilerini, trafik ışıklarını, ağaçları, diğer arabaları ve biraz farklı turuncu tonundaki trafik konilerini bile algılamayı öğretmiş olur.
    • Katman ve ağırlık sayısı, insanın elle güncelleyebileceği ölçekte değil; mümkün olsa bile ağırlıkları değiştirmenin aşağı akış etkilerini yönetmek çok zor.
      Turuncuyu daha iyi görmesi için resmi ayarlasanız bile, aynı anda diğer tüm renklerdeki doğruluğu izleyemiyorsanız, farkında olmadan başka renklerde sorun yaratma ihtimaliniz yüksek.
    • Bunun teknik olarak imkânsız ya da çok zor olmasının nedeni, ağırlıkların genellikle yorumlanmasının çok zor olmasıdır.
      Belirli bir nöron kümesinin belirli bir kavrama karşılık gelmesi gibi değil; genel olarak her şey, her işten biraz yapar.
    • Transformer’ın attention mekanizması insanın anlayabileceği semantiklere kolayca eşlenmiyor gibi görünüyor.
      İşin içinde çok fazla parametre var.
  • Transformer makalesi çok teknik olduğu için hep yüzeysel de olsa anlamak istemiştim ama zor gelmişti.
    Bu yazı çalışma biçimini anlamama gerçekten yardımcı oldu; en azından örnek çok açıktı.
    Bu sayede üniversitede öğrendiğim matrisleri de yeniden hatırlayabildim.

  • Turing makinesi ya da düzenli ifadeleri ayrıştıran bir makine gibi bir tür soyut makine değil mi?

    • Biraz basitleştirirsek, giriş kümesini bir sonraki çıktının olasılık kümesine eşleyen bir “makine”
      Önce token listesini tanımlarız; örneğin kolaylık olsun diye 24 karakter diyelim
      Bu makine bir token giriş dizisi alır, deterministik matris işlemleri yapar ve ardından tüm token’ların olasılık listesini çıktı olarak verir
      “Öğrenme”, sadece bu işlemlerde kullanılan matrislerin içindeki sayıların bir kısmını ayarlama sürecidir
      Nihai kodda yalnızca bir if ifadesi olması, onun da sonucun doğruluğunu değerlendirmek için kullanılması dikkat çekici
      Tüm “mantık” matris işlemlerinin sonucundan gelir
    • Bunları genelde akla gelen anlamıyla otomata olarak yorumlamak oldukça zor
      Sinir ağlarında her şey çoğunlukla biraz bulanıktır ve if/else gibi şeyler neredeyse hiç yoktur; ama Transformer örneğinde olduğu gibi değerleri 0 ya da -∞ ile “maskeleme” durumları vardır
      Çıktı da neredeyse her zaman skorlar ya da olasılıklar kümesidir; kedi ve köpek fotoğraflarını ayıran bir model dog:0.95 cat:0.05 gibi bir sonuç verdiğinde, köpek skoru daha yüksek olduğu için köpek tahmin ettiğini söyleriz
      Transformer’ın merkezindeki attention mekanizması bir tür yumuşak lookup işlemine dayanır
      Bulanık olmayan bir sistem olsaydı, dizideki her token üzerinden geçip mevcut token’la ilişkili olup olmadığını kontrol eder, ilişkiliyse bir eylem yapardı; Transformer’da ise ilişkililik ikili bir karar değildir
      Bunun yerine dizideki tüm token çiftleri arasında sürekli ilişkililik skorları hesaplar ve sonraki eylemi bu skorları kullanarak yapar
      Ancak bazı şeyleri ikili karar tabanlı sistemlerden doğrudan genellemek kolay değildir
      Örneğin bu ilişkililik skorları, sözlük token’ları üzerinde ağırlıklı ortalama hesaplamak için ağırlık olarak kullanılır ve mevcut konum için bir “ortalama token” elde edilir
      Bunu dallanma mantığına dayalı bir sürecin uzantısı olarak kolayca yorumlamanın bir yolu yok gibi görünüyor
    • Sanki lineer cebir yığınına AllSpark değmiş gibi değil mi?
    • Doğru
      Linear Transformers’ın aslında Fast Weight Programmers olduğunu açıklayan şu makaleye bakmak iyi olur: https://arxiv.org/abs/2102.11174
    • Sinir ağları Turing makinesidir
      Ağırlıkları dikkatle ayarlarsanız herhangi bir hesaplamayı yaptırabilirsiniz
      Yine de yaklaşıma dayanmayan bir derleyici olsa iyi olurdu
  • “Kendi modelinizi yapmak isteyebilirsiniz” sözünün, merakı gidermeye yönelik bir öğrenme egzersizi dışında nerede kullanılacağını merak ediyorum
    Karmaşık makine öğrenimi modellerinin, evde blog okuyan birinin uğraşması için gerçekçi olmadığı hissine kapılmaya başlıyorum

    • nanoGPT’de modeli Shakespeare ile önceden eğitince, 3 dakika içinde özgün veriye Lewis Carroll’ın Jabberwocky’si düzeyinde bir sadakate ulaşıyor
      İnandırıcı görünen pek çok eski İngilizce kelime üretiyor; İngilizce dilbilgisinin temellerini, tiyatro oyunu biçimini vb. öğreniyor
      Bu kadar kısa sürede o seviyeye gelmesi oldukça şaşırtıcıydı
      Yerelde birkaç modeli Shakespeare-from-Wish.com düzeyinde sadakatle eğitmek, iyi bir mimari bulup bulmadığınızı ve ölçeklemeyi deneme zamanının gelip gelmediğini anlamaya yardımcı olabilir gibi görünüyor
    • Yazının ilk paragrafında amaç belirtilmiş
      Transformer’ı ve attention’ı daha iyi anlamak istediğini, The Illustrated Transformer’ı okuduğunu ama attention’ın çeşitli parçalarının gerçekte ne yaptığına dair sezgisel bir kavrayış oluşmadığını söylüyor
      q ile k arasındaki fark, v ise zaten ayrı bir meseleymiş gibi
    • Harika bir öğrenme egzersizi
      Sadece merakı gidermenin ötesinde, anlayış oluşturmaya ve derinleştirmeye yardımcı olur
    • Belki de insan böyle projeleri kurcalamaktan gerçekten keyif alıyordur? Garip ama olabilir
  • Başlığa neural network gibi bir ifade konabilse iyi olurdu
    Bu, iki devreyi elektromanyetik olarak bağlayan bobin demetiyle değil, makine öğrenimindeki “Transformer” mimarisiyle ilgili bir içerik