Siri Belajar AI : Mari Belajar tentang Penanaman Posisi (Positional Embedding)
Pembaca kenal tak gambar di atas ni gambar apa? Inilah dia gambar transformer, gambar model AI yang terkini dan yang paling sofistikated ketika ini. Model transformer inilah yang bertanggungjawab membentuk ChatGPT (T di hujung itu membawa maksud transformer). Ia dibentuk dan dicadangkan oleh 8 orang saintis dari Google pada tahun 2017, melalui kertas penyelidikan mereka yang popular, “Attention is All You Need”.
Dan bermula hari ini, kita akan cuba belajar, sedikit demi sedikit apa yang tertulis dalam model transformer. Kita sudah tahu bagaimana model LLM memahami perkataan melalui tokenization. Hari ini kita akan tengok pula bagaimana AI memahami setiap posisi perkataan yang dimasukkan.
Kenapa AI Perlu Tahu Posisi Perkataan?
Ia merupakan satu soalan yang baik. Untuk manusia, membaca sahaja satu-satu teks, kita sudahpun boleh memahami dan mengetahui di manakah posisi setiap perkataan dalam teks tersebut. Sebagai contoh, kalau kita menulis teks seperti di bawah:
“Anjing dan kucing itu sentiasa berkelahi untuk merebut makanan”
Kita akan tahu yang perkataan kucing itu datang selepas anjing dengan hanya membaca sekali lalu. Tapi tidak untuk AI. Ini kerana bentuk model transformer itu sendiri. Ia tak mampu untuk mengetahui posisi setiap perkataan yang ada dalam teks yang ‘dibaca’ oleh transformer. Ini bukanlah satu bentuk kelemahan. Ia sebenarnya adalah satu kekuatan. Kekuatan yang memungkinkan anjakan paradigma dalam penyelidikan AI.
Seperti yang kita tahu, sebelum tibanya model transformer, dunia AI dikuasai oleh model RNN (Recurrent Neural Network) dan juga model LSTM (Long short term memory). Kedua-dua model walaupun mampu melakukan tugasnya, tapi ia mempunyai banyak limitasi, terutama dari segi keperluan memori dan juga kuasa komputasi yang tinggi. Ini kerana natijah model RNN dan LSTM ini yang memproses teks mengikut urutan. Sama seperti manusia yang membaca dari kiri ke kanan (atau kanan ke kiri, bergantung pada bahasa), model RNN dan LSTM juga memproses teks mengikut urutan. Namun begitu, cara ini ternyata membawa masalah kerana ini bermakna setiap perkataan yang diproses itu perlulah diingati oleh model AI dan ini ternyata memerlukan ruang memori yang besar. Oleh kerana itulah ketika latihan, model-model seperti RNN dan LSTM mengalami kehilangan konteks disebabkan oleh pecahan ayat yang perlu dilakukan ketika latihan.
Masalah ini diselesaikan oleh model transformer dengan membawa satu anjakan paradigma. Bagi memastikan konteks dalam teks yang diproses tidak hilang, keseluruhan teks perlulah dimasukkan ke dalam transformer sekaligus, tanpa mengikut urutan. . Dari sinilah datangnya persoalan pokok tadi, jika keseluruhan teks dimasukkan ke dalam transformer tanpa mengikut urutan, bagaimana transformer itu dapat mengenalpasti kedudukan perkataan tersebut?
Kedudukan perkataan dalam teks ditentukan melalui proses penanaman posisi (positional embedding) yang memberi nilai vektor bagi setiap input token yang kita masukkan. Dan nilai vektor dari penanaman posisi ini akan ditambah dengan vektor yang terhasil dari proses penokenisasi sebelum ia dimasukkan ke dalam transformer.
Bagi menukarkan posisi perkataan kepada nilai vektor perlulah melalui proses penanaman posisi melalui persamaan yang mudah di bawah:
Praktikal: Mari kita cuba buat penanaman posisi yang mudah
Para pembaca masih ingat lagi dengan matriks yang dipelajari ketika zaman sekolah? Harap para pembaca masih ingat lagi sedikit sebanyak pada asas matriks kerana proses penanaman posisi ini hanyalah operasi matriks darab dan matriks tambah. Berikut adalah apa yang kita perlu lakukan.
Katakanlah kita ada 10 perkataan yang ingin kita proses dalam transformer. Untuk praktikal ini kita sebenarnya tak perlulah tahu apa perkataan itu (yang penting hanyalah posisi perkataan tersebut). Tapi untuk senang membayangkan, kita boleh anggap 10 perkataan tersebut seperti di bawah:
“Saya pergi ke perpustakaan di waktu petang untuk membaca buku”
Di sini kita memang ada 10 perkataan yang perlu diproses. Dan kita mempunyai 10 dimensi penanaman (embedding dimension) yang perlu dibuat. Embedding dimension ini melambangkan berapa panjang vektor yang perlu kita ada. Kebiasaannya transformer mengambil sehingga 512 dimensi, tapi untuk meringkaskan praktikal kita, seeloknya kita bayangkan hanya ada 10 sahaja dimensi penanaman yang perlu kita lakukan.
Untuk praktikal ini kita hanya perlu menggunakan library torch, jadi pastikan kita sudah memuat library ini dalam sistem komputer
!pip install torchKita anggap ada 10 perkataan maksimum yang perlu dimasukkan dan 10 merupakan saiz dimensi penanaman
import torch
import torch.nn as nn
panjang_perkataan = 10
d_tanam = 10Mari kita lihat penyebut (denominator) untuk nombor genap
Katakan dimensi penanaman kita ada 10, jadi kita buat satu matriks yang melambangkan semua nombor genap
Fungsi di bawah ini kita membentuk satu matriks yang bermula dari 0 ke 10, dan akan melangkaui setiap 2 nombor (nombor genap)
index_genap = torch.arange(0, d_tanam, 2).float()
index_genapIa akan membentuk tensor/matriks seperti di bawah
Kalau kita buat untuk nombor ganjil pula
Fungsi bawah ini kita membentuk satu matriks yang bermula dari 1 ke 10, dan akan melangkaui setiap 2 nombor (nombor ganjil)
index_ganjil = torch.arange(1, d_tanam, 2).float()
index_ganjilJika kita masukkan kedua-dua index ganjil dan index genap ke dalam penyebut, kita akan mendapat satu nilai yang sama
penyebut_genap = torch.pow(10000, index_genap/d_tanam)
penyebut_ganjil = torch.pow(10000, (index_ganjil-1)/d_tanam)
print(penyebut_genap)
print(penyebut_ganjil)Jadi seeloknya, untuk meringkaskan lagi persamaan, kita boleh menggunakan hanya satu sahaja penyebut.
#selarikan penyebut ganjil dan genap
penyebut = penyebut_genap
penyebutMari kita beri pula nilai vektor bagi 10 perkataan yang ingin kita masukkan tadi. Kita mulakan dengan mewujudkan matriks dari 1 ke 10 dengan 2 dimensi.
posisi = torch.arange(panjang_perkataan, dtype=torch.float).reshape(panjang_perkataan, 1)
posisiTensor/matriks yang terhasil seperti di bawah:
Mari kita buat penanaman posisi bagi setiap posisi perkataan yang ada tadi, menggunakan persamaan di atas
penanaman_genap = torch.sin(posisi / penyebut)
penanaman_ganjil = torch.cos(posisi / penyebut)
print(penanaman_genap)
print(penanaman_ganjil)Ia akan membentuk tensor/matriks seperti di bawah:
Mari kita periksa bentuk matriks/tensor kita
#mari kita periksa bentuk matriks kita
bentuk_ganjil = penanaman_ganjil.shape
bentuk_genap = penanaman_genap.shape
print(f"Bentuk matriks dimensi genap adalah {bentuk_genap}")
print(f"Bentuk marriks dimensi ganjil adalah {bentuk_ganjil}")Kita boleh lihat di sini, di mana setiap posisi perkataan kita diwakili 5 dimensi genap, dan 5 dimensi ganjil. Sebelum kita masukkan nilai matriks ini ke dalam transformer, sebaiknya kita gabungkan dahulu dan ratakan bagi memudahkan proses transformer kelak.
#sekarang kita perlu gabungkan kedua-kedua matriks ini dan susun di atas satu sama lain
susun = torch.stack([penanaman_genap,penanaman_ganjil],dim =2)
susun.shape#dan kita ratakan matriks yang diganungkan tadi, agar lebih senang dimasukkan dalam transformer
tanam_posisi = torch.flatten(susun, start_dim = 1, end_dim = 2)
tanam_posisiDan ia membentuk matriks (10,10) (posisi,dimensi) seperti di bawah:
Akhirnya, kita sudah berjaya membentuk penanaman posisi bagi 10 perkataan yang kita masukkan. Tapi perlu diingatkan, yang apa yang kita buat ni, hanyalah untuk 10 perkataan dan 10 dimensi. Kalau untuk transformer yang sebenar, kita ada berjuta perkataan dan juga beratus dimensi (kebiasannya 512), disebabkan itulah proses melatih transformer ini memerlukan kuasa komputer yang kuat.










