តើ LLM ជាអ្វី?
មាតិកា
- Autocomplete ដែលអ្នកប្រើរួចហើយ
- គំនិតទាំងមូលក្នុង Loop មួយ
- អត្ថន័យនៃពាក្យ Large Language Model
- អ្វីដែល LLM មិនមែន
- ពី Autocomplete ទៅ Chatbot
- ហេតុអ្វី Loop សាមញ្ញមួយអាចមើលទៅឆ្លាត
- របៀបរៀបចំស៊េរីនេះ
- រៀបចំ Folder llmlab
- Corpus រួម
- តារាង Autocomplete សរសេរដោយដៃ
- រូបមន្ត៖ Module Autocomplete
- កន្លែងដែល Toy ខុស
- សាកល្បងដោយខ្លួនឯង
- សំណួរដែលអ្នកនឹងត្រូវគេសួរ
1. Autocomplete ដែលអ្នកប្រើរួចហើយ
បើកកម្មវិធីសារលើទូរសព្ទរបស់អ្នក ហើយវាយ៖
I am going to the
ពីលើក្ដារចុច អ្នកនឹងឃើញសំណូមពរបី ប្រហែលជា market, shop និង office។ អ្នកមិនបាន
បង្រៀនទូរសព្ទនូវពាក្យទាំងនោះទេ។ វាទាយពាក្យទាំងនោះពីទម្រង់ដែលវាឃើញ៖ បន្ទាប់ពី "going to the"
មនុស្សច្រើនតែវាយពាក្យមួយក្នុងចំណោមនោះ។ ចុចមួយ ហើយទូរសព្ទបង្ហាញការទាយថ្មីបីសម្រាប់ពាក្យបន្ទាប់។
ធ្វើដូច្នេះម្តងហើយម្តងទៀត អ្នកអាចសរសេរប្រយោគទាំងមូលដោយគ្រាន់តែចុចសំណូមពរ។
នោះគឺជាគ្រាប់ពូជនៃអ្វីៗទាំងអស់ក្នុងស៊េរីនេះ។ large language model (LLM) គឺជាកំណែដែលខ្លាំង ជាងឆ្ងាយនៃល្បិចដូចគ្នានោះ។ អ្នកផ្តល់អត្ថបទមួយចំនួនឲ្យវា។ វាទាយថាអត្ថបទអ្វីគួរមកបន្ទាប់។ អ្នកបន្ថែមបំណែកនោះទៅក្នុងអត្ថបទ ហើយវាទាយម្តងទៀត។
សំណួរបីដែលមនុស្សសួរភ្លាមៗ៖
- តើ chatbot គ្រាន់តែជា autocomplete មែនទេ? loop ស្នូលដូចគ្នា ប៉ុន្តែខ្នាត និងការ train បង្កើតភាពខុសគ្នាដ៏ធំ។ ផ្នែកទី 6 និងជំពូកក្រោយៗពន្យល់ពីរបៀប។
- ចុះម្តេចវាឆ្លើយសំណួរដែលវាមិនដែលឃើញ? វាមិនស្វែងរកចម្លើយទេ។ វាបន្តអត្ថបទតាមរបៀបដែល ត្រូវនឹងទម្រង់ដែលវារៀនពីការសរសេរក្នុងបរិមាណដ៏ច្រើនសន្ធឹកសន្ធាប់។
- តើវាគិតទេ? ចម្លើយស្មោះត្រង់៖ អ្នកវិទ្យាសាស្ត្រ និងវិស្វករមិនយល់ស្របគ្នាអំពីពាក្យត្រឹមត្រូវ។ យើងនឹងត្រឡប់មកវិញក្នុងជំពូកចុងក្រោយ។ សម្រាប់ពេលនេះ សូមមើលអ្វីដែលវា ធ្វើ មុនពេលជជែកអំពី អ្វីដែលវា ជា។
2. គំនិតទាំងមូលក្នុង Loop មួយ
នេះជាគំនិតក្នុងបួនជំហាន។ សូមអានយឺតៗ ព្រោះរាល់ជំពូកគឺជាការមើលជិតជាងលើជំហានមួយ។
- អាន អត្ថបទដែលមានរហូតដល់ពេលនេះ (prompt)។
- ទាយ ថាតើបំណែកអត្ថបទបន្ទាប់នីមួយៗមានលទ្ធភាពប៉ុនណា។
- ជ្រើស បំណែកមួយ ជាធម្មតាបំណែកដែលទំនង ហើយ បន្ថែម វាទៅក្នុងអត្ថបទ។
- ធ្វើម្តងទៀត ពីជំហានទី 1 រហូតដល់អ្នកមានអត្ថបទគ្រប់គ្រាន់ ឬ model និយាយថាបានចប់។
ជាដ្យាក្រាម៖
"The coffee" ---> [ model ] ---> "shop" is likely
^ |
| v
+---------- "The coffee shop" <----+
(append, then repeat)
ក្នុង JavaScript loop មានតែប៉ុន្មានបន្ទាត់ប៉ុណ្ណោះ។ នេះជា pseudo-code៖ រូបរាងគឺពិត ប៉ុន្តែ
predictNext មិនទាន់ត្រូវបានកំណត់ទេ។
let text = "The coffee";
for (let step = 0; step < 5; step++) {
const next = predictNext(text); // the hard part: the model
text = text + " " + next; // append
}
អ្វីៗដែលពិបាកអំពី LLM ត្រូវបានលាក់នៅក្នុង predictNext។ loop ជុំវិញវាស្ទើរតែគ្មានអ្វីទេ។
ក្នុងជំពូកនេះ យើងសរសេរ predictNext ដោយដៃ ដោយប្រើតារាង lookup។ ក្នុងជំពូកទី 3
កុំព្យូទ័របង្កើតតារាងនោះដោយរាប់។ ក្នុងជំពូកទី 5 វារៀនវាដោយការកែតម្រូវបន្តិចម្តងៗ។
ក្នុង LLM ពិត predictNext គឺជា neural network ដ៏ធំ ប៉ុន្តែ loop ជុំវិញវាមើលទៅដូចគ្នាបេះបិទ
នឹង loop ខាងលើ។
3. អត្ថន័យនៃពាក្យ Large Language Model
សូមពិនិត្យពាក្យទាំងបីម្តងមួយៗ។
Language (ភាសា)។ model ធ្វើការលើអត្ថបទ៖ ពាក្យ កូដ លេខ emoji អ្វីក៏ដោយដែលអ្នកអាចសរសេរ។ model ខ្លះក៏ទទួលរូបភាព ឬសំឡេងដែរ ប៉ុន្តែផ្នែកភាសាគឺជាបេះដូង។
Model។ model គឺជាច្បាប់ចម្លងសាមញ្ញនៃអ្វីមួយដែលពិត ដែលបង្កើតឡើងដើម្បីឲ្យអ្នកអាចធ្វើ ការទស្សន៍ទាយ។ model អាកាសធាតុទស្សន៍ទាយភ្លៀងថ្ងៃស្អែក។ language model ទស្សន៍ទាយបំណែក អត្ថបទបន្ទាប់។ ក្នុងកូដ model ជាធម្មតាគឺ លេខ បូករួមនឹងរូបមន្ត សម្រាប់ផ្សំវា។ លេខទាំងនោះ ហៅថា parameter (ឬ weight)។ ការ train មានន័យថាកែតម្រូវលេខទាំងនោះរហូតដល់ការទស្សន៍ទាយ ក្លាយជាល្អ។
Large (ធំ)។ មានពីរយ៉ាងដែលធំ៖ model និងអត្ថបទសម្រាប់ train។
- model មានចំនួន parameter ច្រើនណាស់ ជារឿយៗរាប់ពាន់លាន។ នីមួយៗគ្រាន់តែជាលេខមួយ ប៉ុន្តែ រួមគ្នា ពួកវាផ្ទុកទម្រង់នៃភាសា។
- វាត្រូវបាន train លើអត្ថបទក្នុងបរិមាណដ៏ច្រើន ដូចជាសៀវភៅ គេហទំព័រ និងកូដ ច្រើនជាង អ្វីដែលមនុស្សម្នាក់អាចអានអស់ក្នុងជីវិតជាច្រើន។
តើ "ធំ" ប៉ុនណា? វាប្រែប្រួលជានិច្ច ហើយយើងនឹងមិនដកស្រង់លេខដែលនឹងហួសសម័យនៅឆ្នាំក្រោយទេ។ ច្បាប់ទូទៅ៖ model តូចដែលយើងសាងសង់ក្នុងស៊េរីនេះមានលេខប៉ុន្មានសិប ឯ LLM ពិតមានរាប់ពាន់លាន ដូច្នេះ model ពិតធំជាង រាប់លានដង។ toy របស់យើងបង្ហាញគំនិត មិនមែនកម្លាំងទេ។
| Autocomplete លើទូរសព្ទ | llmlab toy របស់យើង | LLM ពិត | |
|---|---|---|---|
| ទាយ | ពាក្យបន្ទាប់ | ពាក្យបន្ទាប់ | token បន្ទាប់ (បំណែកនៃពាក្យ) |
| រៀនពី | ការវាយរបស់អ្នក | អត្ថបទតូចមួយ | អត្ថបទក្នុងបរិមាណដ៏ច្រើន |
| អង្គចងចាំនៃអត្ថបទដែលមានរហូតដល់ពេលនេះ | 1-2 ពាក្យ | 1 ពាក្យ | token រាប់ពាន់ ឬច្រើនជាងនេះ |
| ទំហំ | តូច | លេខប៉ុន្មានសិប | លេខរាប់ពាន់លាន |
4. អ្វីដែល LLM មិនមែន
ដោយសារ LLM សរសេរអត្ថបទបានរលូន មនុស្សសន្មត់រឿងដែលមិនពិតអំពីវា។ ការកែតម្រូវបួនដែលមានប្រយោជន៍៖
វាមិនមែនជា database ទេ។ database រក្សាទុកការពិត ហើយឲ្យអ្វីដែលអ្នកបានរក្សាទុកមកវិញយ៉ាងពិតប្រាកដ។ LLM មិនរក្សាបញ្ជីការពិតទេ។ វារក្សាលេខដែលកំណត់រូបរាងការទស្សន៍ទាយរបស់វា។ នៅពេលវានិយាយថា "Phnom Penh is the capital of Cambodia" នោះគឺដោយសារអត្ថបទដែលបន្ត "The capital of Cambodia is" ស្ទើរតែតែងតែបន្តបែបនោះក្នុងអត្ថបទ train របស់វា មិនមែនដោយសារវាបានរកមើលកំណត់ត្រាទេ។ នេះជាហេតុដែលវាក៏អាចនិយាយរឿងខុសបានយ៉ាងរលូនដែរ។ ជំពូកទី 9 ស្វែងយល់រឿងនេះ។
វាមិនមែនជា search engine ទេ។ search engine រកទំព័រដែលមានស្រាប់ ហើយបង្ហាញដល់អ្នក។ LLM បង្កើតអត្ថបទថ្មី។ ផលិតផលខ្លះផ្សំទាំងពីរ (ស្វែងរកមុន បន្ទាប់មកឲ្យ model សង្ខេបលទ្ធផល) ប៉ុន្តែវាជាពីរផ្នែកដាច់ពីគ្នា។
វាមិនទាន់សម័យដោយស្វ័យប្រវត្តិទេ។ model រៀនពីអត្ថបទរហូតដល់កាលបរិច្ឆេទមួយ បន្ទាប់មកការ train ឈប់។ វាមិនអានព័ត៌មានដោយខ្លួនឯងទេ។ ប្រសិនបើផលិតផលបង្ហាញព័ត៌មានថ្មីៗ នោះគឺជាផលិតផល ដែលបានទៅយកវា ហើយដាក់វាក្នុង prompt សម្រាប់ model។
វាមិនមែនជាមនុស្សទេ។ វាគ្មានរាងកាយ កុមារភាព ឬគោលដៅដូចអ្នកទេ។ ថាតើវាមានអ្វីដូចជាការយល់ដឹង ឬអត់ គឺជាការជជែកដែលនៅបើកចំហពិតប្រាកដ ដែលយើងនឹងដោះស្រាយដោយយុត្តិធម៌ក្នុងជំពូកចុងក្រោយ។ ចូរប្រយ័ត្នជាមួយពាក្យដូចជា "វាចង់" ឬ "វាដឹង"។ ពួកវាជាផ្លូវកាត់ងាយស្រួល ប៉ុន្តែអាចធ្វើឲ្យអ្នក យល់ខុសអំពីអ្វីដែលវាអាច និងមិនអាចទុកចិត្តបាន។
5. ពី Autocomplete ទៅ Chatbot
autocomplete ធម្មតាបន្តអត្ថបទណាមួយ។ chatbot ឆ្លើយ អ្នក។ តើធ្វើដូចម្តេចពីមួយទៅមួយទៀត?
ល្បិចគឺ ធ្វើទ្រង់ទ្រាយការសន្ទនាជាអត្ថបទវែងមួយ ហើយឲ្យ model បន្តវា។ ស្រមៃអត្ថបទនេះ៖
The following is a conversation between a helpful assistant and a user.
User: What is the capital of Cambodia?
Assistant:
model ដែលបានរៀនថាការសន្ទនាមើលទៅយ៉ាងណា នឹងទាយថាអត្ថបទបន្ទាប់ពី Assistant: គឺជាចម្លើយ
ដូច្នេះវាបន្តជាមួយអ្វីមួយដូចជា "The capital of Cambodia is Phnom Penh." នោះគឺជាការឆ្លើយតប
របស់ chat។
model chat ពិតត្រូវបាន train បន្ថែមទៀត ដើម្បីឲ្យវាធ្វើតាមការណែនាំ និងនៅតែមានប្រយោជន៍ (ជំពូកទី 5 ពន្យល់គំនិតនៃ fine-tuning) ហើយកម្មវិធីរុំសាររបស់អ្នកដោយសញ្ញាពិសេសសម្រាប់ role system, user និង assistant (ជំពូកទី 8)។ ប៉ុន្តែនៅខាងក្រោម ម៉ាស៊ីនគឺនៅតែដដែល៖ ទាយបំណែកបន្ទាប់ បន្ថែម ធ្វើម្តងទៀត។
នេះពន្យល់រឿងពីរដែលអ្នកនឹងសង្កេតឃើញជាញឹកញាប់៖
- model "ឃើញ" តែអ្វីដែលមាននៅក្នុងអត្ថបទដែលអ្នកផ្ញើទៅវាប៉ុណ្ណោះ។ ប្រសិនបើអ្នកមិនបានផ្ញើវា វាមិនដឹងទេ។ (ជំពូកទី 7។)
- ចម្លើយត្រូវបានបង្កើតម្តងមួយបំណែក ដែលជាហេតុដែលចម្លើយ chat ហាក់ដូចជា "វាយ" ខ្លួនឯងនៅលើអេក្រង់។
6. ហេតុអ្វី Loop សាមញ្ញមួយអាចមើលទៅឆ្លាត
ប្រសិនបើ loop សាមញ្ញខ្លាំងម្ល៉េះ ហេតុអ្វី LLM អាចសរសេរកូដ បកប្រែ ឬពន្យល់រឿងកំប្លែង? នេះជាកំណែខ្លី និងស្មោះត្រង់។
ដើម្បីទាយពាក្យបន្ទាប់នៃប្រយោគឲ្យបានល្អ អ្នកត្រូវធ្វើ model រឿងជាច្រើនក្នុងពេលតែមួយ។ សូមយកប្រយោគនេះ៖
Sokha put the keys on the table, then went to the market. Later, she
could not find her
ដើម្បីទាយ "keys" អ្នកត្រូវតាមដានថា "she" ជានរណា ចងចាំអ្វីដែលបានលើកឡើងពីមុន ហើយដឹងបន្តិចអំពីរបៀបដែលមនុស្សបាត់អ្វីៗ។ model ដែលទាយបានល្អ ឆ្លងកាត់ឧទាហរណ៍រាប់ពាន់លាន ដូចនេះ ចុងក្រោយចាប់បានវេយ្យាករណ៍ ការពិតដែលលេចឡើងញឹកញាប់ ទម្រង់នៃការវែកញែកទូទៅ និងរចនាប័ទ្មនៃការសរសេរប្រភេទផ្សេងៗ។ គ្មាននរណាសរសេរកម្មវិធីជំនាញទាំងនោះចូលម្តងមួយៗទេ។ ពួកវាលេចឡើងដោយសារពួកវាជួយដល់កិច្ចការទស្សន៍ទាយ។
ការប្រុងប្រយ័ត្នពីរដើម្បីរក្សាភាពស្មោះត្រង់៖
- ការទាយបានល្អមិនដូចគ្នានឹងការត្រឹមត្រូវទេ។ model ជ្រើសអ្វីដែល ទំនង មិនមែនអ្វីដែល ពិត ទេ។ នោះគឺជាឫសគល់នៃ hallucination។
- យើងមិនយល់ទាំងស្រុងអំពីអ្វីដែលកើតឡើងនៅខាងក្នុងទេ។ យើងដឹងគណិតវិទ្យាដែលដំណើរការ និង របៀបដែលវាត្រូវបាន train។ ការពន្យល់យ៉ាងពិតប្រាកដថា ហេតុអ្វី ចម្លើយជាក់លាក់មួយចេញមក នៅតែជាវិស័យស្រាវជ្រាវសកម្ម។
7. របៀបរៀបចំស៊េរីនេះ
មាន 10 ជំពូក។ នីមួយៗពន្យល់គំនិតមួយដោយកម្មវិធីតូចមួយ ហើយបន្ថែម module មួយទៅ llmlab។
- តើ LLM ជាអ្វី? (ជំពូកនេះ)៖ loop និងការរៀបចំ។
- Token និង Tokenizer៖ របៀបដែលអត្ថបទក្លាយជាបំណែក និងហេតុអ្វីបំណែកកំណត់វិក្កយបត្ររបស់អ្នក។
- សាងសង់ Language Model តូចមួយ៖ រាប់គូពាក្យ ហើយបង្កើតអត្ថបទ។
- ប្រូបាប Temperature និង Sampling៖ របៀបដែលការជ្រើសរើសត្រូវបានធ្វើ និងអ្វីដែល "temperature" ធ្វើ។
- របៀបដែល Model ត្រូវបាន Train៖ ការរៀនដោយកែតម្រូវលេខ។
- Embedding និង Attention៖ របៀបដែលពាក្យក្លាយជាលេខដែលចាប់បានអត្ថន័យ។
- Context Window និងអង្គចងចាំ៖ ហេតុអ្វី model ភ្លេច និងអ្វីដែលវាធ្វើឲ្យអស់ប៉ុន្មាន។
- Prompt, Role និង Structured Output៖ ការណែនាំ model និងការទទួលបាន JSON មកវិញ។
- ហេតុអ្វី Model Hallucinate៖ មូលហេតុ និងអ្វីដែលត្រូវធ្វើ។
- ដែនកំណត់ តម្លៃ និងសំណួរដែលអ្នកនឹងត្រូវគេសួរ៖ ទិដ្ឋភាពទូទៅ និង Q&A ដែលរួចរាល់សម្រាប់ ការនិយាយ។
អ្នកអាចអានជំពូកតាមលំដាប់ ហើយនោះជាអ្វីដែលយើងណែនាំ។ នីមួយៗបន្តពី toy នៃជំពូកមុន។
8. រៀបចំ Folder llmlab
អ្វីៗដំណើរការក្នុង Node.js ដោយគ្មាន package ត្រូវដំឡើង គ្មាន API key ហើយមិនត្រូវការ អ៊ីនធឺណិតបន្ទាប់ពីដំឡើង Node រួច។ ពិនិត្យថាអ្នកមានវា៖
node --version
អ្នកគួរតែឃើញលេខកំណែដូចជា v22.22.2។ កំណែ LTS បច្ចុប្បន្នណាក៏បានដែរ។ ប្រសិនបើអ្នកឃើញ
"command not found" សូមទាញយកកម្មវិធីដំឡើង LTS ពី nodejs.org
ដំណើរការវា បើក terminal ថ្មី ហើយសាកល្បងម្តងទៀត។ ប្រសិនបើ cd និង mkdir មិនធ្លាប់ស្គាល់
សូមអាន មូលដ្ឋានគ្រឹះ Command Line សិន។
បង្កើតគម្រោង៖
mkdir llmlab
cd llmlab
npm init -y
mkdir src
npm init -y បង្កើត package.json ជាមួយចម្លើយលំនាំដើម។ វាបោះពុម្ពឯកសារដែលវាបានសរសេរ
ដែលមើលទៅដូចនេះ (name គឺជាឈ្មោះ folder របស់អ្នក)៖
{
"name": "llmlab",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"keywords": [],
"author": "",
"license": "ISC"
}
ឥឡូវបើក package.json ក្នុង editor របស់អ្នក ហើយបន្ថែមមួយបន្ទាត់ "type": "module"
ដើម្បីឲ្យ Node យល់ import និង export៖
{
"name": "llmlab",
"version": "1.0.0",
"description": "",
"type": "module",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"license": "ISC"
}
(យើងក៏បានលុបប៉ុន្មានបន្ទាត់ដែលយើងមិនត្រូវការដែរ។ មានតែ "type": "module" ប៉ុណ្ណោះដែលសំខាន់។)
បើគ្មានវា Node នឹងបដិសេធឯកសាររបស់យើងដោយមានកំហុស Cannot use import statement outside a module។
នៅពេលស៊េរីចប់ folder នឹងមើលទៅដូចនេះ។ កុំទាន់បង្កើតឯកសារទាំងនេះឥឡូវ។ ជំពូកនីមួយៗប្រាប់អ្នកពេលណាត្រូវបន្ថែមមួយ។
llmlab/
package.json
demo.js <- we run this to try things
src/
corpus.js <- chapter 1: shared sample text
autocomplete.js <- chapter 1: hand-written next-word table
tokenizer.js <- chapter 2
rng.js <- chapter 3
bigram.js <- chapter 3
sampling.js <- chapter 4
train.js <- chapter 5
embeddings.js <- chapter 6
attention.js <- chapter 6
context.js <- chapter 7
prompt.js <- chapter 8
grounding.js <- chapter 9
report.js <- chapter 10
index.js <- chapter 10
ជាមួយ ES module អ្នកត្រូវសរសេរ ./ និងផ្នែកបន្ថែម .js ក្នុងគ្រប់ path នៃ import។
កំហុសទូទៅបំផុតរបស់អ្នកចាប់ផ្តើមគឺភ្លេចសរសេរ .js។
9. Corpus រួម
corpus គឺជាបណ្តុំអត្ថបទដែល model រៀនពី។ model ពិតអាន corpus ដ៏ធំ។ របស់យើងតូច៖ ដប់ប្រាំបន្ទាត់ខ្លីអំពីហាងកាហ្វេតូចមួយក្នុងភ្នំពេញ ដែលសរសេរសម្រាប់ស៊េរីនេះ។ ការប្រើ corpus ដូចគ្នា ក្នុងគ្រប់ជំពូក អនុញ្ញាតឲ្យអ្នកប្រៀបធៀបលទ្ធផលពីជំពូកមួយទៅជំពូកមួយ។
បង្កើត src/corpus.js ជាមួយមាតិកាពិតប្រាកដនេះ៖
// Shared sample text for every llmlab chapter. Original text, written for this series.
export const corpus = `
Sokha opens the small coffee shop near the river every morning.
The coffee shop is quiet in the morning and busy at lunch.
Sokha makes iced coffee with milk and iced tea with lime.
The students come to the coffee shop after school.
The students order iced coffee and the students share a table.
Dara is a student and Dara writes code at the table by the window.
Dara writes code for a small app and Dara drinks iced tea.
The app helps the coffee shop take orders on a phone.
Sokha likes the app because the app saves time every morning.
The river is calm in the morning and the coffee shop smells like fresh coffee.
Sokha says that a good coffee shop needs good coffee and a good table.
Dara says that a good app needs good code and a good idea.
The students laugh and the students order more iced coffee.
After lunch the coffee shop is quiet and Sokha cleans the table by the window.
Dara walks home by the river and Dara thinks about the next app.
`;
// Lowercase, strip punctuation, split on whitespace.
export function words(text) {
return text
.toLowerCase()
.replace(/[^a-z\s]/g, " ")
.split(/\s+/)
.filter(Boolean);
}
មាន export ពីរ។ corpus គឺជា template string ដែលផ្ទុកអត្ថបទ។ words បំប្លែងអត្ថបទណាមួយ
ទៅជាបញ្ជីពាក្យអក្សរតូច ដោយដកវណ្ណយុត្តិចេញ។ regular expression /[^a-z\s]/g មានន័យថា
"តួអក្សរណាដែលមិនមែនជាអក្សរតូច ឬចន្លោះ" ហើយយើងជំនួសនីមួយៗដោយចន្លោះ។
សាកល្បងវា។ បង្កើត demo.js នៅ root នៃ llmlab៖
import { corpus, words } from "./src/corpus.js";
const w = words(corpus);
console.log("word count:", w.length);
console.log("first 8 words:", w.slice(0, 8).join(" "));
console.log("unique words:", new Set(w).size);
ដំណើរការវាដោយ node demo.js៖
word count: 182
first 8 words: sokha opens the small coffee shop near the
unique words: 67
បន្ទាត់ទាំងបីមានស្ថិរភាព ព្រោះ corpus មិនដែលប្រែប្រួល។ model ដែលយើងសាងសង់នឹងឃើញ 182 ពាក្យ ប៉ុន្តែមានតែ 67 ពាក្យ ខុសគ្នា។ យើងហៅបញ្ជីពាក្យខុសគ្នាថា vocabulary។ model ពិតមាន vocabulary ពី token រាប់ម៉ឺន (ជំពូកទី 2)។
10. តារាង Autocomplete សរសេរដោយដៃ
ឥឡូវយើងសរសេរ predictNext តូចបំផុតដែលអាចធ្វើបាន៖ តារាង lookup។
សម្រាប់ពាក្យនីមួយៗ យើងរាយពាក្យដែលអាចមកបន្ទាប់ ពាក្យដែលទំនងបំផុតមុន។ យើងវាយវាដោយដៃ។
const table = {
the: ["coffee", "students", "app", "river"],
coffee: ["shop", "with", "and"],
iced: ["coffee", "tea"],
// ...more words
};
ដើម្បីទាយបន្ទាប់ពី coffee រកមើល table["coffee"] ហើយអ្នកទទួលបាន
["shop", "with", "and"]។ ដើម្បីបំពេញប្រយោគ ធ្វើម្តងទៀត៖
- រកមើលពាក្យចុងក្រោយ។
- ជ្រើសជម្រើសមួយរបស់វា។
- បន្ថែមវា។
- ឈប់នៅពេលតារាងគ្មានធាតុ ឬអ្នកមានពាក្យគ្រប់គ្រាន់។
តើយើងជ្រើសក្នុងចំណោមជម្រើសយ៉ាងដូចម្តេច? ពាក្យដែលទំនងបំផុតគឺនៅមុន ប៉ុន្តែការយកពាក្យទីមួយ ជានិច្ចអាចជាប់ក្នុង loop ដូចជា "the coffee shop is quiet in the coffee shop is quiet..."។ ដូច្នេះក្នុងជំពូកនេះ យើងវិលតាមជម្រើសដោយលេខជំហាន។ ក្នុងជំពូកទី 3 និង 4 យើងនឹងជំនួសនេះ ដោយប្រូបាបពិត និងការជ្រើសចៃដន្យ។
តើតារាងល្អមកពីណា? ជំនួសឲ្យការវាយ យើងអាច រាប់ អ្វីដែលមកតាមពាក្យនីមួយៗក្នុង corpus។
នេះជាការមើលជាមុនរហ័សសម្រាប់ពាក្យ the។ រក្សាទុកនេះជា count.js ហើយដំណើរការ node count.js។
import { corpus, words } from "./src/corpus.js";
const w = words(corpus);
const counts = new Map();
for (let i = 0; i < w.length - 1; i++) {
if (w[i] !== "the") continue;
counts.set(w[i + 1], (counts.get(w[i + 1]) ?? 0) + 1);
}
console.log([...counts].sort((a, b) => b[1] - a[1]));
[
[ 'coffee', 5 ],
[ 'students', 5 ],
[ 'river', 3 ],
[ 'app', 3 ],
[ 'morning', 2 ],
[ 'table', 2 ],
[ 'window', 2 ],
[ 'small', 1 ],
[ 'next', 1 ]
]
អានវាដូចនេះ៖ ក្នុង corpus របស់យើង ពាក្យបន្ទាប់ពី the គឺ coffee ប្រាំដង students ប្រាំដង
river បីដង ហើយបន្តបន្ទាប់ទៀត។ នេះគឺជាស្នូលនៃ language model ដែលធ្វើពីការរាប់។ លទ្ធផលមាន
ស្ថិរភាព ព្រោះ corpus ថេរ។ ជំពូកទី 3 បំប្លែងវាទៅជា module ពិតសម្រាប់ពាក្យ ទាំងអស់។
11. រូបមន្ត៖ Module Autocomplete
រូបមន្តនេះបន្ថែម module ដំបូងនៃ toolkit។ បង្កើត src/autocomplete.js៖
// A hard-coded "autocomplete": for some words, a list of likely next words.
// The first word in each list is the most likely one.
export const table = {
the: ["coffee", "students", "app", "river"],
coffee: ["shop", "with", "and"],
shop: ["is", "near", "needs"],
is: ["quiet", "busy", "calm"],
quiet: ["in", "and"],
in: ["the"],
students: ["order", "come", "laugh"],
order: ["iced", "more"],
iced: ["coffee", "tea"],
and: ["the", "dara"],
dara: ["writes", "drinks", "says"],
writes: ["code"],
code: ["for", "at"],
with: ["milk", "lime"],
milk: ["and"],
tea: ["with", "at"],
lime: ["and"],
for: ["a"],
a: ["small", "good"],
small: ["app", "coffee"],
good: ["coffee", "code"],
at: ["the"],
app: ["helps", "saves"],
};
// Predict: return the possible next words, or an empty list if unknown.
export function predict(word) {
return table[word] ?? [];
}
// Predict, append, repeat. `step` rotates through the options so the
// output does not get stuck repeating the same pair of words.
export function complete(start, length) {
const out = [start];
for (let step = 0; step < length; step++) {
const options = predict(out[out.length - 1]);
if (options.length === 0) break; // the table has no idea, so stop
out.push(options[step % options.length]);
}
return out.join(" ");
}
សូមកត់សម្គាល់បីចំណុច។
tableគឺជា "model" ទាំងមូល៖ 23 ពាក្យ និងការទាយរបស់ពួកវា។ អ្វីៗដែលកម្មវិធី "ដឹង" គឺនៅក្នុង object នោះ។table[word] ?? []មានន័យថា "ប្រើធាតុក្នុងតារាង ឬបញ្ជីទទេប្រសិនបើគ្មាន"។ operator??ត្រឡប់ទៅតម្លៃបម្រុងតែចំពោះundefinedឬnullប៉ុណ្ណោះ។step % options.lengthគឺជា remainder operator ដែលប្រើដើម្បីវិលតាមជម្រើសដោយមិនចេញក្រៅ ដែនកំណត់។ (ប្រសិនបើនេះមិនធ្លាប់ស្គាល់ សូមមើល នព្វន្ត Modular។)
ប្រើវាពី demo.js។ បន្ថែមបន្ទាត់ទាំងនេះនៅចុង៖
import { predict, complete } from "./src/autocomplete.js";
console.log(predict("coffee"));
console.log(predict("banana"));
console.log(complete("the", 6));
console.log(complete("dara", 10));
console.log(complete("students", 12));
console.log(complete("banana", 5));
(ដាក់បន្ទាត់ import ថ្មីនៅខាងលើឯកសារជាមួយបន្ទាត់មួយទៀត។)
ដំណើរការ node demo.js។ ប្រាំមួយបន្ទាត់ចុងក្រោយនៃលទ្ធផលគឺ៖
[ 'shop', 'with', 'and' ]
[]
the coffee with milk and the students
dara writes code for a small coffee shop near
students order more
banana
បន្ទាត់ទាំងនេះទាំងអស់មានស្ថិរភាព។ គ្មានអ្វីចៃដន្យទេ ដូច្នេះអ្នកគួរទទួលបានលទ្ធផលដូចគ្នា លើកុំព្យូទ័រណាក៏ដោយ។ អានវាជាការពិសោធន៍តូចៗ៖
predict("banana")ត្រឡប់[]ព្រោះតារាងមិនដែលឃើញbanana។complete("the", 6)ចាប់ផ្តើមជាមួយtheទាយcoffeeបន្ទាប់មកwithហើយបន្តបន្ទាប់ទៀត។ ប្រយោគមិនសូវល្អទេ ព្រោះយើងវាយតារាងដោយដៃ ហើយជ្រើសក្នុងចំណោមជម្រើសតាមលំដាប់វិលថេរ។complete("students", 12)ឈប់បន្ទាប់ពីmoreព្រោះmoreគ្មានធាតុ។ យើងសុំដប់ពីរពាក្យ ហើយបានបី។ loop បានបញ្ចប់ភ្លាមៗដែលតារាងគ្មានអ្វីនិយាយ។complete("banana", 5)ត្រឡប់តែbanana។ model ដែលមិនដែលឃើញពាក្យមួយ មិនអាចបន្តវាបានទេ។
ចំណុចចុងក្រោយនោះគឺជាបញ្ហា out-of-vocabulary។ ជំពូកទី 2 បង្ហាញពីរបៀបដែល model ពិតជៀសវាង វាដោយកាត់ពាក្យទៅជាបំណែកតូចជាង។
12. កន្លែងដែល Toy ខុស
toy នេះមានប្រយោជន៍ ដោយសារ វាបរាជ័យតាមរបៀបច្បាស់ៗ។ ការបរាជ័យនីមួយៗចង្អុលទៅជំពូកក្រោយ។
| ចំណុចខ្សោយរបស់ toy | ដំណោះស្រាយពិត | ជំពូក |
|---|---|---|
| យើងវាយតារាងដោយដៃ | រៀនវាពីទិន្នន័យដោយរាប់ ឬ train | 3, 5 |
| វាឈប់នៅពាក្យមិនស្គាល់ | កាត់អត្ថបទទៅជា token តូចជាង | 2 |
| វាចងចាំតែមួយពាក្យ | មើល token មុនៗជាច្រើនក្នុងពេលតែមួយ | 3, 6 |
| វាជ្រើសតាមលំដាប់ថេរជានិច្ច | ជ្រើសដោយចៃដន្យតាមប្រូបាប | 4 |
| វាមិនដឹងថាពាក្យមានន័យអ្វី | បំប្លែងពាក្យទៅជា number vector | 6 |
| វាភ្លេចអ្វីៗទាំងអស់បន្ទាប់ពីការហៅនីមួយៗ | ផ្ញើប្រវត្តិម្តងទៀតជា context | 7 |
ចងចាំតារាងនេះ។ នៅជំពូកទី 10 អ្នកនឹងបានសាងសង់កំណែគ្រោងនៃដំណោះស្រាយនីមួយៗ ហើយអ្នកនឹង អាចពន្យល់ថា model ពិតធ្វើអ្វីសម្រាប់ជួរនីមួយៗ។
13. សាកល្បងដោយខ្លួនឯង
- ពង្រីកតារាង។ បន្ថែមធាតុសម្រាប់
sokha,river,morningនិងtable។ ត្រូវប្រាកដថាបញ្ជីនីមួយៗមានពាក្យដែលមកតាមពិតប្រាកដក្នុង corpus។ បន្ទាប់មកដំណើរការcomplete("sokha", 10)។ តើប្រយោគវែងប៉ុនណាមុនពេលវាឈប់? - រក loop។ រកមើលវដ្តក្នុងតារាង ដូចជា
the -> coffee -> shop -> is -> quiet -> in -> the។ ផ្លាស់ប្តូរcompleteឲ្យប្រើoptions[0]ជានិច្ច ហើយដំណើរការcomplete("the", 14)។ តើមានអ្វីកើតឡើង? (នេះជាហេតុដែល model ពិតមិនយកពាក្យដែលទំនងបំផុតតែមួយជានិច្ចទេ។) - រាប់ពាក្យផ្សេងទៀត។ ចម្លង
count.jsប្តូរ"the"ទៅ"coffee"ហើយដំណើរការវា។ តើពាក្យអ្វីមកតាមcoffeeញឹកញាប់បំផុតក្នុង corpus? តើចម្លើយត្រូវនឹងជម្រើសទីមួយក្នុងtable.coffeeទេ? - សាកល្បងលើទូរសព្ទរបស់អ្នក។ បើកក្ដារចុចទូរសព្ទរបស់អ្នក វាយ "I am going to the" ហើយចុចសំណូមពរកណ្តាលដប់ដង។ សរសេរប្រយោគដែលអ្នកទទួលបាន។ តើវាត្រឹមត្រូវតាមវេយ្យាករណ៍ទេ? តើវាសមហេតុផលទេ? តើវាដូចគ្នាទេប្រសិនបើអ្នកចាប់ផ្តើមឡើងវិញ?
- Prompt បន្ទាប់មកទាយ។ សរសេរដោយដៃនូវបីពាក្យដែលអ្នកគិតថា chatbot នឹងបន្ថែមបន្ទាប់ពី
អត្ថបទ
The capital of Cambodia is។ បន្ទាប់មកសុំ chatbot ពិតឲ្យបន្តអត្ថបទដូចគ្នា។ តើអ្នកជិតត្រឹមត្រូវប៉ុនណា? - ធ្វើឲ្យ import ខូច។ ដក
.jsចេញពី path នៃ import ក្នុងdemo.jsហើយដំណើរការវា។ អានកំហុស បន្ទាប់មកកែវា។ អ្នកនឹងជួបកំហុសនេះញឹកញាប់។
14. សំណួរដែលអ្នកនឹងត្រូវគេសួរ
តើ LLM គ្រាន់តែជា autocomplete មែនទេ? ត្រង់ស្នូល បាទ/ចាស៖ វាទាយ token បន្ទាប់ ហើយធ្វើម្តងទៀត។ ប៉ុន្តែអ្នកទាយគឺជា neural network ដែលមាន parameter រាប់ពាន់លាន ដែលត្រូវបាន train លើអត្ថបទក្នុងបរិមាណដ៏ច្រើន ដែលជាហេតុដែល វាអាចធ្វើបានច្រើនជាងក្ដារចុចទូរសព្ទរបស់អ្នកឆ្ងាយ។ ការនិយាយថា "គ្រាន់តែជា autocomplete" គឺពិតអំពី loop ហើយនាំឲ្យយល់ខុសអំពីសមត្ថភាព។
តើវាយល់ពីអ្វីដែលវាសរសេរទេ? អ្នកជំនាញមិនយល់ស្របគ្នា ហើយអ្នកណាដែលឲ្យចម្លើយបាទ/ចាស ឬទេ ដោយទំនុកចិត្ត គឺកំពុងហួសភស្តុតាង។ អ្វីដែលច្បាស់គឺថាវា model ទម្រង់នៃភាសាបានល្អគ្រប់គ្រាន់ដើម្បីមានប្រយោជន៍ខ្លាំង ហើយថាវាក៏អាចខុសដោយទំនុកចិត្តបានដែរ។ ចាត់ទុកលទ្ធផលរបស់វាជាសេចក្តីព្រាងដែលត្រូវពិនិត្យ មិនមែនជាសាក្សីដែលនិយាយការពិតទេ។
តើវាទទួលបានចម្លើយមកពីណា? តើវាស្វែងរកក្នុងអ៊ីនធឺណិតទេ? តាមលំនាំដើម ទេ។ វាបង្កើតចម្លើយពីទម្រង់ដែលបានរក្សាទុកក្នុង parameter របស់វាអំឡុងពេល train។ កម្មវិធីខ្លះភ្ជាប់ model ទៅនឹងការស្វែងរក ឬឯកសាររបស់អ្នក ហើយនៅពេលនោះ កម្មវិធី មិនមែន model តែឯងទេ ដែលនាំយកព័ត៌មានថ្មី។
ហេតុអ្វីវាធ្វើខុស ប្រសិនបើវារៀនពីអត្ថបទច្រើនម្ល៉េះ? ព្រោះវាត្រូវបាន train ដើម្បីបង្កើតអត្ថបទដែល ទំនង មិនមែនអត្ថបទដែល ពិត។ ប្រសិនបើអត្ថបទ train មានកំហុស ការពិតកម្រ ឬចន្លោះប្រហោង model នៅតែអាចផលិតចម្លើយដែលរលូនប៉ុន្តែខុស។ ជំពូកទី 9 គ្របដណ្តប់រឿងនេះលម្អិត។
តើវាជា database នៃអ្វីៗទាំងអស់នៅលើអ៊ីនធឺណិតទេ? ទេ។ វាមិនរក្សាទុកទំព័រទេ។ វារក្សាលេខដែលត្រូវបានកែតម្រូវអំឡុងពេល train។ ពេលខ្លះវាអាចផលិត អត្ថបទដែលវាបានឃើញច្រើនដងឡើងវិញ ប៉ុន្តែវាមិនមែនជាបណ្ណសារដែលអាចស្វែងរកបានទេ ហើយអ្នកមិនអាច សួរវាដោយទុកចិត្តបានថាការពិតមួយមកពីណា។
ហេតុអ្វីហៅថា "large"? ដោយសារទំហំពីរ៖ ចំនួន parameter (រាប់ពាន់លានក្នុង model ដែលល្បីសព្វថ្ងៃ) និងបរិមាណអត្ថបទ ដែលប្រើសម្រាប់ train។ មិនមានចំណុចកាត់ផ្លូវការថា model ណាមួយរាប់ជា "large" ទេ ហើយអត្ថន័យនៃពាក្យនេះបន្តផ្លាស់ប្តូរនៅពេល model ធំឡើង។
តើខ្ញុំអាចដំណើរការមួយលើកុំព្យូទ័ររបស់ខ្ញុំបានទេ? បាទ/ចាស model តូចជាងអាចដំណើរការលើកុំព្យូទ័រយួរដៃ ហើយខ្លះត្រូវបានបោះពុម្ពផ្សាយឲ្យអ្នកណាក៏ទាញយកបាន។ ជាធម្មតាពួកវាមានសមត្ថភាពតិចជាង model ធំបំផុតដែលបង្ហោះនៅលើ server ប៉ុន្តែវាឯកជន ហើយមិនគិតលុយក្នុងការប្រើនីមួយៗទេ។ យើងនឹងត្រឡប់ទៅរក model ចំហ និង model ដែលបង្ហោះនៅលើ server ក្នុងជំពូកទី 10។
តើខ្ញុំត្រូវដឹងគណិតវិទ្យាដើម្បីសាងសង់ជាមួយ LLM ទេ? សម្រាប់ការប្រើ LLM ក្នុងកម្មវិធី ទេ៖ អ្នកត្រូវដឹងរបៀបហៅវា រៀបចំ prompt និងពិនិត្យលទ្ធផល។ ការយល់គំនិតក្នុងស៊េរីនេះជួយអ្នកសម្រេចថាពេលណាត្រូវទុកចិត្តលទ្ធផល។ កូដនៅទីនេះប្រើតែនព្វន្ត នៅសាលាប៉ុណ្ណោះ។
ទៅបន្តទៀត។ ឥឡូវអ្នកដឹងគំនិតទាំងមូលហើយ៖ អានអត្ថបទ ទាយបំណែកបន្ទាប់ បន្ថែម ធ្វើម្តងទៀត។ ប៉ុន្តែរឿងដំបូងដែល model ពិតធ្វើជាមួយអត្ថបទរបស់អ្នក មិនមែនអានវាជាពាក្យទាល់តែសោះ។ វាកាត់វា ទៅជា token ហើយ token កំណត់អ្វីដែល model អាចមើលឃើញ និងអ្វីដែលអ្នកត្រូវបង់។ បន្តជាមួយ Token និង Tokenizer។
ទិញកាហ្វេជូនខ្ញុំ
ចូលចិត្តមេរៀននេះមែនទេ? សូមពិចារណាទិញកាហ្វេជូនខ្ញុំមួយកែវ ដើម្បីគាំទ្រការបង្កើតមាតិកាឥតគិតថ្លៃបន្ថែមទៀត!