2 puan yazan GN⁺ 2024-12-13 | 1 yorum | WhatsApp'ta paylaş
  • Yalnızca yaklaşık 3000 baytlık C koduyla bir GPT-2 çıkarım motoru kuruluyor; ağırlık yüklemeden tokenleştirme, Transformer çalıştırma ve çıktıyı dönüştürmeye kadar tüm akış tek parçada ele alınıyor
  • Küçük kod boyutu korunurken KV cache, hızlı matris çarpımı ve isteğe bağlı OMP paralelleştirmesiyle GPT-2 Small yanıtları modern makinelerde birkaç saniye içinde üretiliyor
  • Çıktı kalitesi “nesnel olarak oldukça kötü” düzeyinde ve UTF-8 işleme ile büyük modelleri çalıştırırken gereken bellek miktarı gibi pratik kısıtlar sürüyor
  • Uygulama; matris işlemleri, sinir ağı katmanları, Transformer, Byte Pair Encoding, G/Ç ve ağırlık/BPE yükleme olarak ayrılıyor ve küçük bir çıkarım motorunun bütün yapısını gösteriyor
  • GPT-2, GPT-4'e kıyasla çok daha zayıf bir 2019 açık kaynak modeli olsa da, modern dil modellerini çalıştırmanın temel bileşenleri küçük bir C koduyla da ifade edilebiliyor

3000 baytlık C ile yapılmış GPT-2 çalıştırıcısı

  • Bu program, bağımlılığı olmayan bir GPT-2 uygulaması ve orijinal TensorFlow dosyalarından ağırlık matrislerini ve BPE dosyasını okuyor
  • Girdi, basit bir Byte Pair Encoding (BPE) kodlayıcısıyla tokenleştiriliyor; çıktı ise BPE çözücüsüyle tekrar metne dönüştürülüyor
  • İç yapı; temel bir lineer cebir paketi, matris işlemleri, Transformer mimarisi ve çıkarım kodu olarak ilerliyor
  • Kod GitHub'da açık olarak paylaşılıyor
  • GPT-2 Small, modern bir makinede tek bir yanıtı birkaç saniyede üretiyor
    • KV cache uygulanıyor
    • Verimli matris çarpımı kullanılıyor
    • İsteğe bağlı olarak OMP paralelleştirmesi açılabiliyor

Çalışma koşulları ve sınırlamalar

  • Bu uygulamayla ChatGPT benzeri etkileşimli bir program yapmak mümkün, ancak çıktı kalitesi iyi değil
  • UTF-8 karakter işleme konusunda bazı tuhaflıklar var
  • XL boyutlu modeli uzun bağlam uzunluğuyla çalıştırmak yaklaşık 100 GB RAM gerektirebilir
  • ASCII girdi ve GPT-2 Small birleşimiyle neredeyse her yerde çalıştırılabiliyor

GPT-2 ve Transformer'ın çalışma biçimi

  • ChatGPT, insan gibi konuşabilen bir uygulama olarak tanımlanıyor; GPT-4 ise ChatGPT'yi çalıştıran güncel model olarak sunuluyor
  • Bu C programı, 2019 modeli GPT-2 ile ChatGPT'ye benzer bir davranış üretiyor
  • GPT-2, Transformer ailesinden bir makine öğrenimi modeli
  • Transformer, sabit boyutlu bir kelime dizisini girdi olarak alıp sonraki kelimeyi tahmin ediyor
  • Aynı süreç tekrarlandığında istenen uzunlukta dizi üretilebiliyor

Matris işlemleri ve makro tabanlı sıkıştırma

  • Sinir ağları matris işlemlerinden oluştuğu için uygulama, en az düzeyde bir Matrix yapısı ile başlıyor
    • float* dat
    • int rows, cols
  • Gerekli işlemler temelde iki türe ayrılıyor
    • Matris-sabit işlemleri
    • Matris-matris işlemleri
  • C makrolarıyla tekrar eden döngü yapıları azaltılıyor ve yalnızca belirli operatörleri değiştirerek birden çok fonksiyon üretiliyor
  • C'deki #define, basit değiştirmeye yakın çalıştığı için yalnızca normal operatörler değil, noktalı virgül içeren ifadeler bile makro argümanı olarak verilip kod boyutu küçültülebiliyor

Hızlı matris çarpımı

  • Temel matris çarpımı, üç iç içe döngü kullanan basit O(n³) uygulamayla başlıyor
  • Cache ve bellek erişim özellikleri dikkate alınarak, aynı belleğin tekrar tekrar okunup yazılacağı şekilde döngüler değiştiriliyor
  • Hızlı uygulama j ve k değerlerini 4'er artırıyor ve içeride k2, j2 döngülerini kullanıyor
  • Çıkarım aşamasında daha önce hesaplanmış sonuçların bir kısmını yeniden kullanmak için, matris A'nın yalnızca bir kısmının B ile çarpıldığı bir yöntem ekleniyor

Sinir ağı katmanlarının uygulanması

  • Transformer kurmak için birkaç sinir ağı katmanı doğrudan uygulanıyor
  • GELU etkinleştirme fonksiyonu makroyla uygulanıyor
  • causal attention için matrisin alt üçgen kısmını işleyen bir fonksiyon bulunuyor
    • Attention matrisi, gelecekteki token'lara bakmadan yalnızca geçmişi görecek şekilde sınırlandırılıyor
  • LayerNorm, her katmandaki ortalama ve varyansı normalize ediyor
  • Linear fonksiyonu, matris çarpımından sonra bias'ı döşeme yöntemiyle ekliyor

Transformer gövdesi

  • Transformer uygulaması her katmanda şu akışı tekrar ediyor
    • LayerNorm ve Linear üzerinden geçerek query, key, value değerlerini tek seferde hesaplıyor
    • qkv, head bazında ayrılıyor
    • query ile key çarpımı hesaplanıyor ve causal attention uygulanıyor
    • softmax sonucu value matrisiyle çarpılıyor
    • Sonuçlar birleştirilip residual connection uygulanıyor
    • GELU ve Linear'dan geçtikten sonra yeniden residual connection uygulanıyor
  • Sonunda son LayerNorm uygulanıyor, ardından son token konumunun çıktısı embedding ağırlıklarıyla çarpılarak sonraki token adayları hesaplanıyor

KV cache yöntemi

  • Transformer çıkarımında bir token üretildikten sonra bir sonrakini üretmek için tüm fonksiyonun yeniden hesaplanması gerekmiyor
  • N'inci token'a kadar hesaplanan sonuçların büyük kısmı yeniden kullanılırsa, N+1'inci token üretimi için yalnızca ek birkaç işlem gerekiyor
  • Uygulama, tüm bellek tahsislerini aynı bellek bloğu içinde sıralı olarak yapıyor
  • Her matris çarpımının her zaman aynı belleği kullanması sağlanıyor; böylece sonraki yinelemede belleği 0'a sıfırlamak yerine önceki sonuçlar korunuyor
  • Yeni yinelemede yalnızca N+1'inci satır hesaplanıyor

Byte Pair Encoding uygulaması

  • Dil modelleri sabit boyutlu girdi gerektirdiğinden, sonsuz sayıdaki kelimeyi doğrudan kelime düzeyinde işlemek zor
  • Karakter düzeyindeki modeller, her kelimenin anlamını en baştan öğrenmek zorunda kalıyor ve etkili bağlam boyutunu ortalama kelime uzunluğu kadar azaltıyor
  • GPT-2 gibi modeller, kelimeleri parçalara ayıran BPE kullanıyor
    • Sık kullanılan kelimeler tek bir token olabilir
    • Nadir kelimeler daha küçük parçalara bölünür
    • Örneğin nicholas, nich, o, las olarak ayrılabilir
  • Tipik BPE algoritması, bitişik token çiftlerini tekrar tekrar birleştirir
  • Bu C uygulaması, kod boyutunu küçültmek için lineer zamanlı algoritma yerine potansiyel olarak üstel zaman alabilen özyinelemeli bir yaklaşım kullanıyor
    • Mevcut kelimenin prefix'i ile eşleşen vocabulary öğeleri aranıyor
    • Kalan metin özyinelemeli olarak tokenleştiriliyor
    • Uzunluk ve vocabulary indeksi temelinde en iyi tokenleştirme seçiliyor

Ağırlık yükleme

  • Sinir ağı ağırlıkları diskten okunmalı; dosya biçimi 32 bit float'ların düz bir ikili serileştirme biçimi
  • GPT-2 model boyutlarının hepsi aynı mimariyi kullanıyor ve ağırlıklar da aynı sırayla saklanıyor; bu yüzden doğru şekle sahip matrisleri sırayla okumak yeterli
  • Katmanların kaydedilme sırası beklenenden farklı
    • Katman 0 ve 1'den sonra 10 geliyor
    • Çünkü adlar lexicographic order ile sıralanıyor
    • Metin sıralamasında 10, 2'den önce geliyor
  • Uygulama, bu sırayı gerçek katman sırasına çevirmek için permutation kodu kullanıyor

BPE vocabulary yükleme

  • BPE'yi çalıştırmak için önce vocabulary dosyasının diskten okunması gerekiyor
  • Orijinal dosya, Python'da okunmak üzere tasarlanmış bir biçimde ve küçük bir C koduyla ayrıştırılması kolay değil
  • Dosya, bir kelime listesi değil BPE birleştirme listesi
    • Örneğin Hello token'ı doğrudan saklanmak yerine H ile ello'nun birleştirilmesi gerektiği biçimde tutuluyor
  • Dosya, UTF-8'e benzer ama tam olarak aynı olmayan bir kodlama kullanıyor
    • Yazdırılabilir ASCII karakterleri olduğu gibi saklanıyor
    • 0-31 aralığındaki yazdırılamayan karakterler 188 + karakter değeri olarak kodlanıyor
    • Örneğin boşluk, Ġ token'ı olarak kodlanıyor
  • Diskteki Ġ, UTF-8'de 0xc4 0xa0 olduğundan, bunu yeniden boşluğa çevirmek için ayrı işlem gerekiyor

Küçük kodun gösterdiği şey

  • Onlarca yıllık makine öğrenimi gelişimi birkaç bin baytlık koda sıkıştırılabiliyor
  • Gerçek model ağırlıkları hariç tutulduğunda, modern sinir ağlarını çalıştırmak için gereken unsurların neredeyse hiçbiri eksik kalmıyor
  • Bu uygulama esas olarak eğlence için yapılmış olsa da, sinir ağlarının gerçekte basit bileşenlerle çalıştırılabildiğini gösteren bir örnek

1 yorum

 
GN⁺ 2024-12-13
Hacker News yorumları
  • Kodu bizzat çalıştırmadım ama küçük boyutlu olması etkileyici
    İlk ELIZA programlarının daha büyük olduğunu düşününce, son 4 yılda bunun bayt düzeyinde bu kadar sıkıştırılabilir hale gelmiş olması dikkat çekici
    Sihirin nerede saklı olduğunu bilen biri varsa açıklamasını isterdim. Bunun GELU fonksiyonu mu, yoksa Bash betiğiyle indirilen model mi olduğunu merak ediyorum

    • Sihirin büyük kısmı Bash betiğiyle indirilen 475MB model dosyasında
    • Denedim, pek etkileyici değildi
      Who are you? sorusuna I am Alice. diye yanıt veriyor; bilgisayarı ya da işlevlerini sorunca da I am a computer model trained by OpenAI. How can I help you? cümlesini tekrarlıyor
      Toplamayı açıklamasını isteyince çarpmayı anlatıyor, 2+2 ya da Sum 2+2 içinse sadece aynısını tekrar ediyor
  • GPT-2 ilk çıktığında onunla uğraştığımı hatırlıyorum
    Bir arkadaşımla sohbet kayıtlarını dışa aktarıp GPT-2'yi ince ayar yaparak ikimizin konuşmalarını taklit ettirmiştik; hem çok komikti hem de bazen ürkütücü derecede isabetliydi
    GPT-2'den GPT-3'e geçişteki sıçramanın nedenini merak ediyorum. Daha büyük model mi, daha fazla veri mi, yoksa ikisi birden mi bilmiyorum
    RLHF'nin büyük fark yarattığını biliyorum ama temel GPT-3 modeli de yeterince örnek verildiğinde yalnızca metin tamamlama ile epey kullanışlıydı

  • Çok bilgim yok ama GPT-2'nin yazdığı sevdiğim masallar var
    https://deepdreams.stavros.io/episodes/the-princess-the-fair...

    • Gerçekten güzel, gerçekten eğlenceli ve dinlerken uykuya dalmak için de iyi bir hikâye
      Bunun bu sayfadaki GPT-2 ile yapılıp yapılmadığını merak ediyorum
    • Etkileyici, tuhaf ve yaklaşık %90 oranında tutarlı, bu da kendine özgü garip bir hava yaratıyor
  • “Çoğunlukla eğlence için yapılmış olsa da, sinir ağlarının aslında ne kadar basit olduğunu göstermeye yarayan iyi bir örnek” kısmı hoşuma gitti
    Şşşt, kimseye söylemeyelim. Yapay zeka para kazanmak için kullanılan kara büyü

  • GPT-2 komut ayarlı olduğu için mi bunu gerçekten sohbet için kullanabiliyoruz?
    Değilse buna ChatGPT klonu demek bana biraz zorlama geliyor

    • Yazıda zaten şöyle deniyor: çıktı kalitesini önemsemiyorsanız ChatGPT benzeri bir şey yapılabiliyor; nesnel olarak çıktı oldukça korkunç ama çalışıyor
      Pratikte kullanılamaz ve ismi çağrıştırması dışında pek alakası yok. Yine de derlenip çalışan bir program
      Bunu yapan kişinin de düzgün çalışmadığını kabul ettiği bir projenin performansını öven tepkilere bakınca, asıl meselenin moda sözcükle ilgi çekmek olduğu anlaşılıyor
  • “Düzgün makroları olan dillere bakın. Lisp her zaman C'den üstün değildir!” cümlesi bu kez kabul edilebilir. Sonuçta yukarıya doğru bir şaka
    Kod bağlantısını görmediyseniz metnin içine gömülü: https://github.com/carlini/c-chat-gpt-2

  • Bundan daha iyi klasik yapay zeka sohbet botları gördüm
    https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/areas...
    Splotch biraz düzeltmeyle modern Unix türevlerinde de rahatça derleniyor

  • Bunu yerelde çalıştırıp bu GPT-2'nin nasıl çıktılar verdiğini gören biri var mı diye merak ediyorum

    • Neredeyse her zaman aynı çıktıyı tekrar tekrar üretiyor gibi
      Yine de oldukça ilginç ve içine bakıp kurcalamak isterdim. Bir süredir yerelde GPT-2 ile uğraşmak istiyordum
    • Okuduklarıma göre aynı sıcaklık ve seed kullanılırsa, normal şekilde yüklenen GPT-2 modeli ile bu programın yüklediği modelin tam olarak aynı çıktıyı vermesi gerekir gibi görünüyor
      Kodda sıcaklığı ve seed'i bizzat teyit edemedim; daha çok neden obfuscation yapıldığını anlamaya çalışıyordum
      Obfuscation kaldırıldığında kodun aşırı uzamayacağını tahmin ediyorum; kabaca 10 bin karakter civarında olsa bile yalnızca ekranda görmek bile yeterince etkileyici olurdu
  • Bugünlerde gptscript ile kendi ChatGPT'nizi çok hızlı biçimde kurabilirsiniz
    https://github.com/gptscript-ai/gptscript

  • GELU gerçekten büyü gibi:
    UNARY(GELU, b / 2 * (1 + tanh(.7978845 * (b + .044715 * b * b * b))))

    • Bu sadece GELU'nun gerçek matematiksel tanımına yönelik pratik bir yaklaşım
      Tanım GELU(x) := x * Φ(x) şeklinde ve burada Φ(x), Gauss dağılımının kümülatif dağılım fonksiyonu
    • Hızlı ters karekökü hatırlatan bir biçimi var