Klon ChatGPT berbasis GPT-2 yang Diimplementasikan dalam C 3000 Byte (2023)
(nicholas.carlini.com)- Membangun inferencer GPT-2 hanya dengan kode C sekitar 3000 byte, menangani semuanya dalam satu alur mulai dari pemuatan bobot, tokenisasi, eksekusi Transformer, hingga konversi keluaran
- Meski ukuran kodenya kecil, ia menghasilkan jawaban GPT-2 Small dalam hitungan detik di mesin modern berkat KV caching, perkalian matriks cepat, dan paralelisasi OMP opsional
- Kualitas keluarannya berada pada level “secara objektif cukup buruk”, dan masih ada batasan praktis seperti penanganan UTF-8 serta kebutuhan memori saat menjalankan model besar
- Implementasinya dibagi menjadi operasi matriks, layer jaringan saraf, Transformer, Byte Pair Encoding, I/O, serta pemuatan bobot dan BPE, memperlihatkan struktur lengkap inferencer kecil
- GPT-2 adalah model open source tahun 2019 yang jauh lebih lemah daripada GPT-4, tetapi komponen inti untuk menjalankan model bahasa modern tetap dapat diekspresikan bahkan dengan kode C kecil
Eksekutor GPT-2 yang Dibuat dengan C 3000 Byte
- Program ini adalah implementasi GPT-2 tanpa dependensi, yang membaca matriks bobot dan file BPE dari file TensorFlow asli
- Masukan ditokenisasi dengan encoder Byte Pair Encoding(BPE) sederhana, dan keluaran dikonversi kembali menjadi string dengan decoder BPE
- Struktur internalnya berurutan dari paket aljabar linear dasar, operasi matriks, arsitektur Transformer, hingga kode inferensi
- Kodenya tersedia di GitHub
- GPT-2 Small menghasilkan satu jawaban dalam sekitar beberapa detik di mesin modern
- Mengimplementasikan KV caching
- Menggunakan perkalian matriks yang efisien
- Paralelisasi OMP dapat diaktifkan secara opsional
Kondisi Eksekusi dan Batasan
- Dengan implementasi ini, program percakapan seperti ChatGPT bisa dibuat, tetapi kualitas keluarannya tidak bagus
- Ada beberapa keanehan dalam penanganan karakter UTF-8
- Menjalankan model ukuran XL dengan panjang konteks besar dapat membutuhkan sekitar 100GB RAM
- Kombinasi masukan ASCII dan GPT-2 Small dapat dijalankan hampir di mana saja
Cara Kerja GPT-2 dan Transformer
- ChatGPT adalah aplikasi yang memungkinkan percakapan seperti dengan manusia menggunakan model bahasa, dan GPT-4 diperkenalkan sebagai model terbaru yang menggerakkan ChatGPT
- Program C ini mengimplementasikan perilaku mirip ChatGPT dengan GPT-2, model tahun 2019
- GPT-2 adalah model machine learning keluarga Transformer
- Transformer menerima urutan kata berukuran tetap sebagai input dan memprediksi kata berikutnya
- Dengan mengulang prosedur yang sama, urutan dengan panjang sembarang dapat dihasilkan
Operasi Matriks dan Kompresi Berbasis Makro
- Karena jaringan saraf tersusun dari operasi matriks, implementasinya dimulai dari struct Matrix minimal
float* datint rows, cols
- Operasi yang diperlukan secara garis besar ada dua jenis
- Operasi matriks-konstanta
- Operasi matriks-matriks
- Makro C digunakan untuk mengurangi struktur loop yang berulang, lalu beberapa fungsi dibuat hanya dengan mengganti operator tertentu
#definedi C hampir seperti substitusi sederhana, sehingga bukan hanya operator umum, tetapi juga ekspresi yang menyertakan titik koma dapat dimasukkan sebagai argumen makro untuk mengurangi ukuran kode
Perkalian Matriks Cepat
- Perkalian matriks dasar berawal dari implementasi O(n³) sederhana dengan tiga loop bertingkat
- Dengan mempertimbangkan karakteristik cache dan akses memori, loop diubah agar membaca dan menulis memori yang sama secara berulang
- Implementasi cepat menaikkan
jdankmasing-masing sebesar 4, dan menggunakan loopk2sertaj2di dalamnya - Pada tahap inferensi, untuk menggunakan kembali sebagian hasil yang sudah dihitung, ditambahkan cara mengalikan hanya sebagian matriks A dengan B
Implementasi Layer Jaringan Saraf
- Untuk membuat Transformer, beberapa layer jaringan saraf diimplementasikan langsung
- Fungsi aktivasi GELU diimplementasikan dengan makro
- Ada fungsi yang memproses bagian segitiga bawah matriks untuk causal attention
- Matriks attention dibatasi agar hanya melihat masa lalu, bukan token masa depan
- LayerNorm menormalisasi rata-rata dan varians tiap layer
- Fungsi Linear menambahkan bias dengan cara tiling setelah perkalian matriks
Inti Transformer
- Implementasi Transformer mengulangi alur berikut pada setiap layer
- Melalui LayerNorm dan Linear, query, key, value dihitung sekaligus
- qkv dibagi per head
- Perkalian query dan key dihitung, lalu pemrosesan causal attention diterapkan
- Hasil softmax dikalikan dengan matriks value
- Hasilnya digabungkan dan residual connection diterapkan
- Melalui GELU dan Linear, residual connection diterapkan lagi
- Pada akhirnya, setelah LayerNorm final, keluaran di posisi token terakhir dikalikan dengan bobot embedding untuk menghitung kandidat token berikutnya
Metode KV Caching
- Dalam inferensi Transformer, setelah menghasilkan satu token, tidak perlu menghitung ulang seluruh fungsi saat membuat token berikutnya
- Jika sebagian besar hasil perhitungan hingga token ke-N digunakan kembali, pembuatan token ke-N+1 hanya memerlukan sedikit pekerjaan tambahan
- Implementasi melakukan semua alokasi secara berurutan di dalam blok memori yang sama
- Setiap perkalian matriks dibuat agar selalu menggunakan memori yang sama, sehingga pada iterasi berikutnya memori tidak diinisialisasi ke 0 dan hasil sebelumnya dipertahankan
- Pada iterasi baru, hanya baris ke-N+1 yang dihitung
Implementasi Byte Pair Encoding
- Karena model bahasa memerlukan input berukuran tetap, sulit memperlakukan kata yang jumlahnya tak terbatas apa adanya pada tingkat kata
- Model berbasis karakter harus mempelajari makna semua kata dari awal, dan memiliki masalah mengurangi ukuran konteks efektif sebesar rata-rata panjang kata
- Model seperti GPT-2 menggunakan BPE yang membuat token dari potongan kata
- Kata yang umum dapat menjadi satu token
- Kata yang langka dipecah menjadi potongan yang lebih kecil
- Sebagai contoh,
nicholasdapat dibagi menjadinich,o,las
- Algoritme BPE umum berulang kali menggabungkan pasangan token yang berdekatan
- Implementasi C ini, demi mengurangi ukuran kode, menggunakan metode rekursif yang berpotensi memakan waktu eksponensial alih-alih algoritme waktu linear
- Mencari entri vocabulary yang cocok dengan prefix kata saat ini
- Mentokenisasi sisa string secara rekursif
- Memilih tokenisasi terbaik berdasarkan panjang dan indeks vocabulary
Pemuatan Bobot
- Bobot jaringan saraf harus dibaca dari disk, dan filenya berupa format serialisasi biner datar dari float 32-bit
- Ukuran model GPT-2 menggunakan arsitektur yang sama, dan bobot juga disimpan dalam urutan yang sama, sehingga cukup membaca matriks dengan bentuk yang benar secara berurutan
- Urutan penyimpanan layer berbeda dari dugaan
- Setelah layer 0 dan 1, muncul 10
- Ini karena nama diurutkan dalam lexicographic order
- Dalam pengurutan string,
10muncul sebelum2
- Implementasi menggunakan kode permutasi untuk mengubah urutan ini menjadi urutan layer sebenarnya
Pemuatan Vocabulary BPE
- Untuk menjalankan BPE, file vocabulary harus terlebih dahulu dibaca dari disk
- File asli adalah format untuk dibaca dari Python, bukan format yang mudah diparsing dengan kode C kecil
- File tersebut bukan daftar kata, melainkan daftar merge BPE
- Misalnya, alih-alih token
Hellodisimpan langsung, ia disimpan sebagai instruksi untuk menggabungkanHdanello
- Misalnya, alih-alih token
- File menggunakan encoding yang mirip UTF-8 tetapi tidak persis sama
- Karakter ASCII yang dapat dicetak disimpan apa adanya
- Karakter yang tidak dapat dicetak dalam rentang 0~31 dienkode sebagai
188 + nilai karakter - Misalnya, spasi dienkode sebagai token
Ġ
Ġdi disk adalah0xc4 0xa0dalam UTF-8, sehingga diperlukan pemrosesan terpisah untuk mengubahnya kembali menjadi spasi
Hal yang Ditunjukkan oleh Kode Kecil Ini
- Perkembangan machine learning selama puluhan tahun dapat dipadatkan menjadi kode beberapa ribu byte
- Jika bobot model aktual dikecualikan, hampir tidak ada elemen yang hilang untuk menjalankan jaringan saraf modern
- Implementasi ini terutama dibuat untuk bersenang-senang, tetapi menjadi contoh bahwa jaringan saraf sebenarnya dapat dijalankan dengan komponen-komponen sederhana
1 komentar
Komentar Hacker News
Saya belum benar-benar menjalankan kodenya, tetapi ukurannya yang kecil cukup mengesankan
Mengingat program-program ELIZA awal bahkan lebih besar, terasa luar biasa bahwa dalam 4 tahun terakhir hal seperti ini bisa dipadatkan hingga level byte
Saya ingin ada yang menjelaskan di mana letak sihirnya. Apakah di fungsi GELU, atau pada model yang diunduh lewat skrip Bash?
Untuk
Who are you?ia menjawabI am Alice., dan kalau ditanya tentang komputer atau fungsinya ia terus mengulangI am a computer model trained by OpenAI. How can I help you?Saat diminta menjelaskan penjumlahan, ia malah menjelaskan perkalian, dan untuk
2+2atauSum 2+2ia cuma mengulanginya begitu sajaSaya masih ingat saat pertama kali GPT-2 keluar dan saya memainkannya
Saya pernah mengekspor log chat dengan seorang teman, lalu melakukan fine-tuning GPT-2 agar meniru percakapan kami berdua, dan hasilnya sangat lucu sekaligus kadang-kadang menyeramkan karena akurat
Saya penasaran apa yang menyebabkan lonjakan besar dari GPT-2 ke GPT-3. Apakah model yang lebih besar, data yang lebih banyak, atau keduanya
Saya tahu RLHF membuat perbedaan besar, tetapi model dasar GPT-3 pun sudah cukup berguna hanya dengan text completion jika diberi cukup contoh
Saya tidak terlalu paham, tetapi ada dongeng favorit saya yang ditulis GPT-2
https://deepdreams.stavros.io/episodes/the-princess-the-fair...
Saya penasaran apakah yang di halaman ini juga dibuat dengan GPT-2
Kalimat “Sebagian besar dibuat untuk bersenang-senang, tetapi ini contoh bagus untuk menunjukkan betapa sederhananya jaringan saraf sebenarnya” itu lucu
Ssst, jangan bilang siapa-siapa. AI itu ilmu hitam untuk menghasilkan uang
Apakah GPT-2 ini di-instruction-tune sehingga benar-benar bisa dipakai untuk chat?
Kalau tidak, menurut saya agak berlebihan menyebutnya klon ChatGPT
Praktis tidak bisa dipakai, dan selain menumpang nama, nyaris tidak ada hubungannya. Meski begitu, ini tetap program yang bisa dikompilasi dan dijalankan
Melihat reaksi yang menilai tinggi performa proyek yang pembuatnya sendiri akui tidak benar-benar bekerja, rasanya inti utamanya adalah menarik perhatian dengan kata kunci populer
Kalimat “Apakah kalian para bahasa dengan macro yang layak sedang memperhatikan. Lisp tidak selalu lebih baik daripada C!” kali ini bisa diterima. Soalnya ini lelucon yang menyerang ke atas
Kalau Anda belum melihat tautan kodenya, itu tersembunyi di dalam artikel: https://github.com/carlini/c-chat-gpt-2
Saya pernah melihat chatbot AI klasik yang lebih baik
https://www.cs.cmu.edu/afs/cs/project/ai-repository/ai/areas...
Splotch bisa dikompilasi dengan baik di sistem Unix modern dengan sedikit perbaikan
Saya penasaran apakah ada yang menjalankannya secara lokal untuk melihat keluaran seperti apa yang dihasilkan GPT-2 ini
Meski begitu, tetap cukup menarik dan saya ingin membongkar lalu menyesuaikannya sendiri. Sudah lama saya ingin mengutak-atik GPT-2 secara lokal
Saya sendiri belum sempat memastikan temperature dan seed di kodenya, karena saya lebih sedang mencoba memahami kenapa kodenya diobfuscate
Bahkan setelah deobfuscation pun, sepertinya kodenya tidak akan menjadi terlalu panjang, dan kalau sekitar 10 ribu karakter, menurut saya melihatnya di layar saja sudah cukup mengesankan
Sekarang kalau memakai gptscript, Anda bisa dengan cepat membuat ChatGPT versi sendiri
https://github.com/gptscript-ai/gptscript
GELU memang terasa seperti sihir:
UNARY(GELU, b / 2 * (1 + tanh(.7978845 * (b + .044715 * b * b * b))))Definisinya adalah
GELU(x) := x * Φ(x), dengan Φ(x) sebagai fungsi distribusi kumulatif dari distribusi Gaussian