- Mereplikasi alur inferensi GPT-2 dalam SQL hanya dengan PostgreSQL dan pgvector, mulai dari tokenisasi hingga blok Transformer dan pembuatan token berikutnya
- LLM generatif dapat dipandang mirip fungsi deterministik yang menghasilkan probabilitas kandidat token yang sama untuk input yang sama; titik ketika respons menjadi berbeda adalah tahap pemilihan probabilistik kandidat token
- Implementasi ini mengekspresikan tokenizer BPE GPT-2, 50.257 token, embedding 768 dimensi, konteks 1.024 token, 12 blok, 12 attention head, dan feedforward berbasis GELU sebagai query dan tabel SQL
- Diperlukan solusi workaround realistis yang disesuaikan dengan lingkungan database, seperti tidak adanya dukungan properti Unicode pada regex PostgreSQL dan keterbatasan
EXPdalam menangani nilai yang sangat kecil - Contohnya menghasilkan 10 token dari
"Happy New Year! I wish you"dan mencetak"Happy New Year! I wish you all the best in your new year!"; di lingkungan penulis, proses ini memakan waktu 2 menit 44 detik
Membuat Pipeline Inferensi GPT-2 dengan SQL
- ChatGPT menjawab bahwa SQL tidak cocok untuk mengimplementasikan model bahasa berskala besar, tetapi pipeline inferensi GPT-2 berhasil diimplementasikan dengan SQL PostgreSQL
- Penjelasan implementasi yang dijadikan referensi adalah GPT in 60 Lines of NumPy oleh Jay Mody, dengan komponen yang sama dipindahkan ke tabel dan query database
- LLM generatif dapat dilihat seperti fungsi berbentuk
llm(prompt: str) -> list[tuple[str, float]]- Inputnya adalah prompt teks
- Outputnya adalah kandidat string berikutnya beserta array probabilitas
- Jika matematika internal dan parameternya sama, input yang sama akan mengembalikan hasil yang sama
- Alasan produk seperti ChatGPT dapat memberi jawaban berbeda untuk pertanyaan yang sama lebih terletak pada pemilihan probabilistik di tahap pemilihan token berikutnya daripada pada model itu sendiri
Loop Pembuatan Teks
- Proses pembuatan dimulai dengan mengubah prompt menjadi array token, lalu berulang kali memanggil model untuk memilih token berikutnya dan menambahkannya ke belakang prompt
- Alur dasarnya terdiri dari langkah-langkah berikut
tokenize(prompt)mengubah string menjadi array ID tokengpt2(tokens)menghitung probabilitas untuk 50.257 tokenselect_next_token(candidates)memilih token berikutnya- Menambahkan token yang dipilih ke array
- Berhenti pada kondisi seperti jumlah token yang ditentukan, timeout, atau stopword
detokenize(tokens)mengembalikan array token menjadi string
- Urutan token yang terakumulasi seperti ini dapat menjadi teks bahasa alami yang memiliki karakteristik yang tampak seperti tata bahasa, sintaksis, makna, dan penalaran
Mengimplementasikan Tokenizer BPE dengan SQL
- Sebelum masuk ke jaringan saraf, teks harus diubah menjadi daftar angka, tetapi memakai code point Unicode secara langsung membuat ruang token dan panjangnya tidak efisien
- GPT-2 menggunakan variasi Byte pair encoding
- Kamus token menggunakan 50.257 code point
- Mencakup urutan byte UTF-8 dan token “end of text”
- Awalnya dimulai dari 256 token byte, lalu pasangan token berdekatan yang sering muncul ditambahkan sebagai token baru
- Penggabungan ini diulang 50.000 kali untuk membuat 50.256 token, lalu token end-of-text ditambahkan di akhir
- Tokenizer GPT-2 memiliki lapisan tambahan yang memetakan byte ke karakter string, dan pemetaan ini didefinisikan dalam
encoder.pymilik OpenAI GPT-2 - Dalam implementasi SQL, kamus token yang diunduh dari OpenAI dimasukkan ke tabel
tokenizer, dan pemetaan byte-ke-karakter disimpan di tabelencoder - Contoh
"Mississippilessly"menggunakan recursive CTE untuk memulai dari byte tunggal dan berulang kali menggabungkan pasangan berdekatan terbaik yang dapat digabungkan- Dalam contoh tersebut, jumlah token berkurang dari 17 menjadi 5
- Menggunakan ruang sekitar 50k token GPT-2, bukan sekitar 150k ruang code point Unicode
- Saat memproses beberapa kata, GPT-2 membagi teks dengan regex dan melakukan penggabungan di dalam tiap kata
- PostgreSQL tidak mendukung properti karakter Unicode dalam regex, sehingga regex asli GPT-2 sebagian dimodifikasi
- Modifikasi ini kemungkinan merusak dukungan Unicode yang semestinya
"PostgreSQL is great"diubah oleh tokenizer SQL menjadi[6307, 47701, 318, 1049]- Klaster tokennya adalah
Post,greSQL,Ġis,Ġgreat Ġmenunjukkan spasi
- Klaster tokennya adalah
Embedding dan Context Window
- ID token tidak langsung dipakai dalam perhitungan model, melainkan diubah menjadi vektor embedding
- GPT-2 membuat embedding untuk token dan posisi secara terpisah
WTEadalah word token embedding, berupa matriks 50257×768WPEadalah word position embedding, berupa matriks 1024×768
- Untuk setiap posisi token, vektor
WTEdan vektorWPEdijumlahkan untuk membuat vektor input bagi tahap berikutnya - Karena
WPEhanya memiliki 1.024 posisi, jumlah token maksimum yang dapat digunakan dalam prompt GPT-2 adalah 1.024- Angka ini sesuai dengan context window LLM
- Ini adalah hyperparameter yang ditentukan saat desain model dan tidak berubah melalui pelatihan
- Implementasi SQL menggunakan pgvector
- Operasi vektor dapat didefinisikan langsung pada array sehingga memungkinkan SQL murni, tetapi performanya menurun
- Versi awal berjalan dengan fungsi SQL murni, tetapi lambat
Menguraikan Self-Attention sebagai Query SQL
- Inti Transformer adalah mekanisme self-attention, yang didasarkan pada makalah 2017 Attention is all you need
- Attention membuat vektor token saling memengaruhi, sehingga informasi dari bagian awal prompt dapat diteruskan ke vektor terakhir
- Implementasi GPT-2 menggunakan 12 set matriks
Q,K,V- Setiap set adalah satu attention head
- Setiap head berdimensi 64
c_attnadalah transformasi linear 768×2304, dan hasilnya adalah vektor 2304 dimensi yang berisiQ,K,Vyang ditumpuk secara horizontal- Bobot dan bias disimpan di tabel
c_attn_w,c_attn_b
- Sebelum perhitungan attention, layer normalization diterapkan
- Parameter scale dan shift disimpan di tabel
ln_1_g,ln_1_b
- Parameter scale dan shift disimpan di tabel
- Dalam causal self-attention, causal mask diterapkan agar token di belakang tidak dapat memengaruhi token di depan
- Kandidat token berikutnya dari model pada akhirnya ditentukan dari embedding terakhir
- Aliran informasi harus mengarah ke vektor terakhir, dan nilai antara pada vektor terakhir tidak boleh memengaruhi vektor sebelumnya
- Implementasi SQL menangani input yang lebih kecil dari -745.13 sebagai 0 untuk menghindari masalah PostgreSQL
EXPyang gagal pada angka sangat kecil dalam perhitungan softmax - Berkat causal mask, meskipun token baru ditambahkan ke prompt, hasil perhitungan untuk token sebelumnya tidak berubah
- Implementasi GPT-2 asli memanfaatkan sifat ini
- Implementasi SQL tidak memakai reuse ini demi kesederhanaan
Multi-Head Attention dan Residual Connection
- Hasil attention dari 12 head masing-masing berdimensi 64, lalu ditumpuk secara horizontal untuk kembali menjadi 768 dimensi
- Selanjutnya, output attention diproyeksikan dengan transformasi linear terlatih yang disimpan di
c_proj_w,c_proj_b - Input asli ditambahkan kembali ke hasil multi-headed attention
- Residual connection ini adalah teknik yang disertakan dalam makalah Transformer asli
- Teknik ini diperkenalkan sebagai desain untuk mengurangi masalah vanishing gradient dan exploding gradient selama pelatihan
Tahap Feedforward dan Blok Transformer
- Setelah attention, jaringan saraf feedforward menyusul
- Tahap feedforward GPT-2 terdiri dari multi-layer perceptron 3 lapis
- Dimensinya 768 → 3072 → 768
- Fungsi aktivasinya menggunakan GELU
- Parameter transformasi linear disimpan di tabel berikut
mlp_c_fc_w,mlp_c_fc_bmlp_c_proj_w,mlp_c_proj_b
- Input feedforward juga lebih dulu dinormalisasi dengan parameter
ln_2ln_2_g,ln_2_bmenyimpan scale dan shift
- Residual connection yang menambahkan kembali input juga diterapkan pada output feedforward
- Kombinasi attention + feedforward ini adalah satu blok, dan GPT-2 menghubungkan 12 blok seperti pipeline
- Setiap blok memiliki set parameter terlatihnya sendiri
- Dalam SQL, blok-blok tersebut dihubungkan dengan recursive CTE
- Output blok terakhir dinormalisasi lagi dengan parameter
ln_f
Mengubah Kembali Menjadi Token Berikutnya
- Dari output akhir, vektor 768 dimensi pada posisi terakhir adalah embedding token berikutnya
- Untuk mengubah vektor ini kembali menjadi token, matriks
WTEyang digunakan pada embedding token awal digunakan kembali - Inversi yang tepat biasanya tidak mungkin
- Embedding prediksi mungkin tidak persis sama dengan baris tertentu pada
WTE - Karena itu, dot product dengan setiap embedding token dihitung untuk mencari token yang dekat
- Embedding prediksi mungkin tidak persis sama dengan baris tertentu pada
- Hasil dot product antara
WTEdan embedding prediksi menjadi 50.257 skor, yaitu logit - Skor ini diubah menjadi probabilitas melalui softmax
- Jumlah kandidat teratas adalah
top_n - Nilai yang mengatur distribusi probabilitas adalah temperature
- Semakin tinggi temperature, semakin besar kemungkinan token yang bukan peringkat pertama dipilih, sehingga inferensi menjadi kurang dapat diprediksi
- Jumlah kandidat teratas adalah
- Dalam contoh
"PostgreSQL is great", 5 kandidat token berikutnya teratas adalah sebagai berikutĠfor,.ĠatĠto
- Ketika temperature berubah menjadi 0.5, 1, dan 2, distribusi probabilitas softmax untuk kandidat yang sama ikut berubah
Hasil Inferensi Nyata dan Kode
- SQL final mengulangi proses memilih token berdasarkan probabilitas dan menambahkannya ke prompt
- Model itu sendiri deterministik, dan satu-satunya unsur nondeterministik adalah angka acak yang termasuk dalam pemilihan token
- Pengaturan contohnya adalah sebagai berikut
- Prompt:
"Happy New Year! I wish you" - Jumlah token yang dibuat: 10
- temperature: 2
- top_n: 1
- Menggunakan
SETSEED(0.20231231)
- Prompt:
- Di lingkungan penulis, query berjalan selama 2 menit 44 detik
- Hasil outputnya adalah
"Happy New Year! I wish you all the best in your new year!" - Query dan kode instalasi tersedia di repositori GitHub quassnoi/explain-extended-2024
1 komentar
Opini Hacker News
Indah. Aku juga pernah masuk ke lubang kelinci serupa dengan SQLite, tapi belum sampai tahap membawa jaringan saraf ke dalamnya
Terinspirasi dari seri kuliah makemore[0], dan setelah sekitar 1 jam materinya beralih dari pendekatan counting ke jaringan saraf; kira-kira sampai situ juga aku mencapainya
Memecah ini ke dalam model relasional benar-benar latihan yang bagus
[0] https://www.youtube.com/watch?v=PaCmpygFfXo
Demo yang bagus, tapi penjelasan tentang causal masking di artikelnya tampaknya mencampuradukkan pelatihan dan inferensi
Causal masking bertujuan agar selama pelatihan model tidak bisa “mengintip” token masa depan, dan pada arsitektur bergaya GPT juga bertujuan memaksakan sifat autoregresif saat inferensi
Saat inferensi, bagaimanapun hanya token terakhir yang digunakan, jadi token itu memperhatikan seluruh sekuens input; karena itu token berikutnya tidak ditentukan hanya dari embedding token terakhir
Aku penasaran apakah ini benar-benar merepresentasikan driver loop GPT: tampaknya strukturnya seperti men-tokenize prompt, mendapatkan probabilitas 50.257 token dengan
gpt2(tokens), memilih token berikutnya, menambahkannya ke daftar token, memeriksa kondisi berhenti, lalu melakukan detokenisasi di akhirTapi ini terlihat seperti state machine yang mengimplementasikan algoritma Shlemiel the painter, sehingga membuatku mempertanyakan biaya komputasi inheren dari pekerjaan generasi
Window itu adalah sliding window
gpt2Lebih mirip menunjukkan cara mengumpulkan token yang dihasilkan menjadi kalimat
Materi terkait: A GPT in 60 Lines of NumPy - https://news.ycombinator.com/item?id=34726115 - Februari 2023, 146 komentar
Dalam konteks serupa, aku mengimplementasikan seluruh GPT dengan fungsi spreadsheet, dan juga membuat tutorial video yang bisa ditonton bersamanya
https://spreadsheets-are-all-you-need.ai/
Dari sudut pandang seseorang yang menganggap LLM cukup keren tetapi tidak perlu mempelajari cara kerjanya secara profesional, video 10 menit itu mengajariku lebih banyak daripada bertahun-tahun membaca komentar HN yang sulit dipahami dan artikel media arus utama yang dangkal
Melihat begitu banyak angka floating-point menumpuk menunggu dihitung juga membuat jauh lebih intuitif mengapa teknologi ini memakan GPU sebanyak itu
Kalau menghitung turunan tiap parameter pada setiap contoh pelatihan dan menunjukkan secara eksplisit bagaimana itu dipetakan ke parameter terkait, tampaknya proses pelatihannya juga bisa dijelaskan dengan baik
Bagus. Sesuatu yang bahkan setahun lalu terlihat seperti semacam sihir kini dijelaskan dengan begitu baik, hampir sampai anak kecil pun bisa mengikutinya
Model yang dijelaskan di artikel adalah GPT-2 yang dirilis pada awal 2019
Untuk benar-benar memahami artikel ini, perlu latar belakang ilmu komputer yang kuat, dan judulnya sendiri pun kurang mudah diakses bagi 99% umat manusia
Aku selama ini sepenuhnya menghindari GPT dan LLM, tetapi cara ini tampaknya bisa menghasilkan tingkat kefasihan tertentu pada keluaran teks, namun belum terlihat mampu menafsirkan pertanyaan dan menjawabnya
Aku penasaran apakah ada posting blog sederhana atau kursus yang menjelaskan cara kerjanya secara nyata, atau menunjukkan engine mainan seperti Python
Materi edukasi yang kulihat sejauh ini cenderung berfokus pada cara memakai platform, dan tidak banyak membahas cara kerja internalnya
Khususnya [0], [1], [2] bagus
[0] http://jalammar.github.io/illustrated-transformer/
[1] http://jalammar.github.io/illustrated-gpt2/
[2] https://jalammar.github.io/visualizing-neural-machine-transl...
Menariknya, machine learning modern tidak menuntut Turing-completeness
Namun kita tetap mempertimbangkan kemungkinan AGI, jadi kalau kesimpulannya ternyata Turing-completeness tidak diperlukan, itu akan cukup menarik
Alasannya sederhana: aku bisa mengikuti eksekusi kode yang Turing-complete di dalam kepalaku
Artikelnya luar biasa, dan penjelasan tiap komponennya jelas serta cukup menyeluruh sehingga enak dibaca
Namun setelah tidak sengaja menekan “+ expand source” dan melihat monster menakjubkan itu, aku jadi setuju ketika ChatGPT berkata “SQL tidak cocok untuk implementasi model bahasa besar”
Pernyataan bahwa “Unicode biasa tidak cocok dengan jaringan saraf” tidak benar. Lihat saja ByT5, misalnya
Yang disebut “alfabet” di artikel biasanya disebut vocabulary, dan jika memakai byte UTF-8 sebagai vocabulary, jumlah tokennya menjadi 256, bukan 149.186
ByT5 melakukan persis itu
Fakta bahwa semua model dengan performa terbaik di pasar memakai tokenisasi adalah buktinya
Bukan rahasia bahwa tokenisasi pada dasarnya mirip hack, dan idealnya suatu hari nanti ingin dihilangkan dengan satu atau lain cara (https://twitter.com/karpathy/status/1657949234535211009)
Secara prinsip, kekurangan tokenisasi tingkat byte bisa dikompensasi dengan model yang lebih besar dan konteks yang lebih besar, tetapi dalam praktiknya melatih model dengan tingkat kecerdasan yang sama membutuhkan sumber daya jauh lebih banyak
Tentu saja ada tugas tertentu, seperti menghitung jumlah huruf dalam kata, di mana tokenisasi justru merugikan kecerdasan