# Tokenizers[[tokenizers]]

Tokenizers တွေဟာ NLP pipeline ရဲ့ အဓိက အစိတ်အပိုင်းတွေထဲက တစ်ခုပါ။ ၎င်းတို့မှာ ရည်ရွယ်ချက်တစ်ခုတည်းပဲ ရှိပါတယ်၊ text ကို model က လုပ်ဆောင်နိုင်တဲ့ data အဖြစ် ပြောင်းလဲဖို့ပါပဲ။ Model တွေက ဂဏန်းတွေကိုပဲ လုပ်ဆောင်နိုင်တာမို့၊ tokenizers တွေက ကျွန်တော်တို့ရဲ့ text inputs တွေကို numerical data အဖြစ် ပြောင်းလဲပေးဖို့ လိုအပ်ပါတယ်။ ဒီအပိုင်းမှာတော့ tokenization pipeline မှာ ဘာတွေ အတိအကျဖြစ်ပျက်လဲဆိုတာကို လေ့လာသွားပါမယ်။

NLP လုပ်ငန်းတွေမှာ အများအားဖြင့် လုပ်ဆောင်တဲ့ data က raw text ပါ။ ဒီလို text ရဲ့ ဥပမာတစ်ခုကို အောက်မှာ ကြည့်ပါ။

```
Jim Henson was a puppeteer
```

သို့သော်လည်း၊ model တွေက ဂဏန်းတွေကိုပဲ လုပ်ဆောင်နိုင်တာမို့၊ raw text ကို ဂဏန်းတွေအဖြစ် ပြောင်းလဲဖို့ နည်းလမ်းတစ်ခုကို ကျွန်တော်တို့ ရှာဖွေဖို့ လိုအပ်ပါတယ်။ ဒါက tokenizers တွေ လုပ်ဆောင်တဲ့အရာ ဖြစ်ပြီး၊ ဒါကို လုပ်ဆောင်ဖို့ နည်းလမ်းများစွာ ရှိပါတယ်။ ရည်ရွယ်ချက်ကတော့ အဓိပ္ပာယ်အရှိဆုံး ကိုယ်စားပြုမှု (ဆိုလိုသည်မှာ model အတွက် အဓိပ္ပာယ်အရှိဆုံး ကိုယ်စားပြုမှု) နဲ့ ဖြစ်နိုင်ရင် အသေးငယ်ဆုံး ကိုယ်စားပြုမှုကို ရှာဖွေဖို့ပါပဲ။

tokenization algorithm အချို့ရဲ့ ဥပမာတွေကို ကြည့်ပြီး၊ tokenization နဲ့ ပတ်သက်ပြီး သင့်မှာရှိနိုင်တဲ့ မေးခွန်းအချို့ကို ဖြေဆိုဖို့ ကြိုးစားကြရအောင်။

## Word-based[[word-based]]

ပထမဆုံး တွေးမိတဲ့ tokenizer အမျိုးအစားကတော့ *word-based* ပါ။ ဒါကို စည်းမျဉ်းအနည်းငယ်နဲ့ တည်ဆောက်ပြီး အသုံးပြုဖို့ အလွန်လွယ်ကူပြီး၊ အများအားဖြင့် ကောင်းမွန်တဲ့ ရလဒ်တွေ ထွက်ပေါ်လာပါတယ်။ ဥပမာအားဖြင့်၊ အောက်က ပုံမှာ၊ ရည်ရွယ်ချက်က raw text ကို စကားလုံးတွေအဖြစ် ပိုင်းခြားပြီး တစ်ခုချင်းစီအတွက် ဂဏန်းဆိုင်ရာ ကိုယ်စားပြုမှုကို ရှာဖွေဖို့ပါပဲ။

  
  

text ကို ပိုင်းခြားဖို့ နည်းလမ်းအမျိုးမျိုး ရှိပါတယ်။ ဥပမာအားဖြင့်၊ Python ရဲ့ `split()` function ကို အသုံးပြုပြီး whitespace ကို သုံးကာ text ကို စကားလုံးတွေအဖြစ် tokenize လုပ်ဆောင်နိုင်ပါတယ်။

```py
tokenized_text = "Jim Henson was a puppeteer".split()
print(tokenized_text)
```

```python out
['Jim', 'Henson', 'was', 'a', 'puppeteer']
```

punctuation အတွက် အပိုစည်းမျဉ်းတွေရှိတဲ့ word tokenizer အမျိုးအစားတွေလည်း ရှိပါသေးတယ်။ ဒီလို tokenizer အမျိုးအစားနဲ့ဆိုရင် ကျွန်တော်တို့ဟာ အတော်လေး ကြီးမားတဲ့ "vocabularies" တွေနဲ့ အဆုံးသတ်နိုင်ပါတယ်။ vocabulary ဆိုတာက ကျွန်တော်တို့ရဲ့ corpus မှာရှိတဲ့ သီးခြား tokens စုစုပေါင်းအရေအတွက်နဲ့ သတ်မှတ်ပါတယ်။

စကားလုံးတစ်ခုစီကို ID တစ်ခုစီ ခွဲပေးပြီး 0 ကနေစပြီး vocabulary အရွယ်အစားအထိ သတ်မှတ်ပေးပါတယ်။ model က ဒီ IDs တွေကို စကားလုံးတစ်ခုစီကို ခွဲခြားသိမြင်ဖို့ အသုံးပြုပါတယ်။

ကျွန်တော်တို့ဟာ word-based tokenizer တစ်ခုနဲ့ ဘာသာစကားတစ်ခုကို အပြည့်အစုံ ကာဗာလုပ်ချင်တယ်ဆိုရင်၊ ဘာသာစကားထဲက စကားလုံးတစ်ခုစီအတွက် identifier တစ်ခုစီ ရှိဖို့ လိုအပ်ပါလိမ့်မယ်။ ဒါက ကြီးမားတဲ့ tokens အရေအတွက်ကို ထုတ်ပေးပါလိမ့်မယ်။ ဥပမာအားဖြင့်၊ English ဘာသာစကားမှာ စကားလုံး ၅၀၀,၀၀၀ ကျော်ရှိတာကြောင့် စကားလုံးတစ်ခုစီကနေ input ID တစ်ခုဆီ map လုပ်ဖို့အတွက် ID အရေအတွက် အများကြီးကို မှတ်ထားဖို့ လိုအပ်ပါလိမ့်မယ်။ ဒါ့အပြင် "dog" လို စကားလုံးတွေကို "dogs" လို စကားလုံးတွေနဲ့ မတူအောင် ကိုယ်စားပြုထားပြီး၊ "dog" နဲ့ "dogs" တို့ဟာ ဆင်တူတယ်ဆိုတာကို model က အစပိုင်းမှာ သိဖို့ နည်းလမ်းမရှိပါဘူး- ၎င်းက စကားလုံးနှစ်ခုကို ဆက်စပ်မှုမရှိဘူးလို့ ခွဲခြားသတ်မှတ်ပါလိမ့်မယ်။ "run" နဲ့ "running" လို အခြားဆင်တူစကားလုံးတွေနဲ့လည်း အတူတူပါပဲ၊ model က အစပိုင်းမှာ ဆင်တူတယ်လို့ မမြင်ပါဘူး။

နောက်ဆုံးအနေနဲ့၊ ကျွန်တော်တို့ရဲ့ vocabulary မှာ မပါဝင်တဲ့ စကားလုံးတွေကို ကိုယ်စားပြုဖို့ custom token တစ်ခု လိုအပ်ပါတယ်။ ဒါကို "unknown" token လို့ ခေါ်ပြီး၊ မကြာခဏဆိုသလို "[UNK]" သို့မဟုတ် "&lt;unk&gt;" နဲ့ ကိုယ်စားပြုပါတယ်။ tokenizer က ဒီ tokens တွေ အများကြီး ထုတ်ပေးနေတာကို သင်တွေ့ရရင် ဒါက မကောင်းတဲ့ လက္ခဏာတစ်ခုပါ။ ဘာလို့လဲဆိုတော့ ၎င်းက စကားလုံးတစ်ခုရဲ့ အဓိပ္ပာယ်ရှိတဲ့ ကိုယ်စားပြုမှုကို ရယူနိုင်ခြင်းမရှိဘဲ၊ သင်ဟာ အချက်အလက်တွေကို ဆုံးရှုံးနေတာကြောင့်ပါပဲ။ vocabulary ကို ဖန်တီးတဲ့အခါ ရည်ရွယ်ချက်ကတော့ tokenizer က unknown token အဖြစ် စကားလုံးအနည်းဆုံးကို tokenized လုပ်နိုင်အောင် ဖန်တီးဖို့ပါပဲ။

unknown tokens အရေအတွက်ကို လျှော့ချဖို့ နည်းလမ်းတစ်ခုကတော့ တစ်ဆင့်နိမ့်ဆင်းပြီး *character-based* tokenizer ကို အသုံးပြုဖို့ပါပဲ။

## Character-based[[character-based]]

Character-based tokenizers တွေက text ကို စကားလုံးတွေအစား characters တွေအဖြစ် ပိုင်းခြားပါတယ်။ ဒါက အဓိက အကျိုးကျေးဇူး နှစ်ခု ရှိပါတယ်-

-   Vocabulary က အများကြီး သေးငယ်ပါတယ်။
-   out-of-vocabulary (unknown) tokens တွေ အများကြီး နည်းပါးသွားပါတယ်။ ဘာလို့လဲဆိုတော့ စကားလုံးတိုင်းကို characters တွေကနေ တည်ဆောက်နိုင်လို့ပါ။

ဒါပေမယ့် ဒီနေရာမှာလည်း နေရာလွတ်တွေ (spaces) နဲ့ punctuation တွေနဲ့ ပတ်သက်ပြီး မေးခွန်းအချို့ ပေါ်ပေါက်လာပါတယ်။

  
  

ဒီနည်းလမ်းကလည်း ပြီးပြည့်စုံတာ မဟုတ်ပါဘူး။ ကိုယ်စားပြုမှုဟာ စကားလုံးတွေအစား characters တွေပေါ် အခြေခံထားတာကြောင့်၊ တစ်ခုတည်းသော character တစ်ခုက သူ့ဘာသာသူ အဓိပ္ပာယ်သိပ်မရှိဘူးလို့ အလိုလိုဆိုနိုင်ပါတယ်။ စကားလုံးတွေနဲ့ဆိုရင်တော့ အဲလို မဟုတ်ပါဘူး။ ဒါပေမယ့် ဒါက ဘာသာစကားပေါ် မူတည်ပြီး ကွဲပြားပါတယ်။ ဥပမာအားဖြင့်၊ တရုတ်ဘာသာစကားမှာ character တစ်ခုစီက Latin ဘာသာစကားက character တစ်ခုထက် အချက်အလက် ပိုသယ်ဆောင်ပါတယ်။

စဉ်းစားရမယ့် နောက်ထပ်အချက်တစ်ခုကတော့ ကျွန်တော်တို့ရဲ့ model က လုပ်ဆောင်ရမယ့် tokens ပမာဏ အများကြီးနဲ့ အဆုံးသတ်ရပါလိမ့်မယ်။ word-based tokenizer တစ်ခုနဲ့ဆိုရင် စကားလုံးတစ်လုံးဟာ token တစ်ခုတည်းသာ ဖြစ်ပေမယ့်၊ characters တွေအဖြစ် ပြောင်းလဲလိုက်တဲ့အခါ token ၁၀ ခု သို့မဟုတ် ပိုများတဲ့အထိ အလွယ်တကူ ဖြစ်သွားနိုင်ပါတယ်။

နှစ်ခုစလုံးရဲ့ အကောင်းဆုံးကို ရယူဖို့အတွက်၊ ချဉ်းကပ်မှုနှစ်ခုကို ပေါင်းစပ်ထားတဲ့ တတိယနည်းပညာဖြစ်တဲ့ *subword tokenization* ကို ကျွန်တော်တို့ အသုံးပြုနိုင်ပါတယ်။

## Subword Tokenization[[subword-tokenization]]

Subword tokenization algorithm တွေဟာ မကြာခဏ အသုံးပြုတဲ့ စကားလုံးတွေကို ပိုသေးငယ်တဲ့ subwords တွေအဖြစ် ပိုင်းခြားသင့်ပါဘူး၊ ဒါပေမယ့် ရှားပါးတဲ့ စကားလုံးတွေကိုတော့ အဓိပ္ပာယ်ရှိတဲ့ subwords တွေအဖြစ် ခွဲခြမ်းသင့်တယ်ဆိုတဲ့ နိယာမပေါ် အခြေခံပါတယ်။

ဥပမာအားဖြင့်၊ "annoyingly" ကို ရှားပါးတဲ့ စကားလုံးအဖြစ် မှတ်ယူနိုင်ပြီး "annoying" နဲ့ "ly" အဖြစ် ခွဲခြားနိုင်ပါတယ်။ ဒါတွေဟာ တစ်ဦးချင်းစီ subwords တွေအဖြစ် ပိုမိုမကြာခဏ ပေါ်လာနိုင်ဖွယ်ရှိပြီး၊ တစ်ချိန်တည်းမှာ "annoyingly" ရဲ့ အဓိပ္ပာယ်ကို "annoying" နဲ့ "ly" ရဲ့ ပေါင်းစပ်အဓိပ္ပာယ်ကနေ ထိန်းသိမ်းထားပါတယ်။

ဒီနေရာမှာ subword tokenization algorithm က "Let's do tokenization!" ဆိုတဲ့ sequence ကို ဘယ်လို tokenize လုပ်မယ်ဆိုတာကို ပြသထားတဲ့ ဥပမာတစ်ခု ဖြစ်နိုင်ပါတယ်။

  
  

ဒီ subwords တွေဟာ အဓိပ္ပာယ်ဆိုင်ရာ အချက်အလက်များစွာကို ပေးစွမ်းပါတယ်။ ဥပမာအားဖြင့်၊ အထက်ပါ ဥပမာမှာ "tokenization" ကို "token" နဲ့ "ization" အဖြစ် ပိုင်းခြားခဲ့ပါတယ်။ ဒါတွေဟာ အဓိပ္ပာယ်ရှိတဲ့ tokens နှစ်ခုဖြစ်ပြီး နေရာလည်းသက်သာပါတယ် (ရှည်လျားတဲ့ စကားလုံးတစ်လုံးကို ကိုယ်စားပြုဖို့ tokens နှစ်ခုပဲ လိုအပ်ပါတယ်)။ ဒါက ကျွန်တော်တို့ကို သေးငယ်တဲ့ vocabularies တွေနဲ့ ကောင်းမွန်တဲ့ coverage ကို ပေးနိုင်ပြီး unknown tokens တွေလည်း မရှိသလောက်ပါပဲ။

ဒီနည်းလမ်းက Turkish လိုမျိုး agglutinative languages တွေမှာ အထူးအသုံးဝင်ပါတယ်။ ဘာလို့လဲဆိုတော့ subwords တွေကို ဆက်စပ်ပြီး (နီးပါး) ပမာဏအကန့်အသတ်မရှိ ရှည်လျားတဲ့ ရှုပ်ထွေးတဲ့ စကားလုံးတွေကို ဖွဲ့စည်းနိုင်လို့ပါ။

### အခြားနည်းလမ်းများ![[and-more]]

အံ့သြစရာမလိုဘဲ၊ အခြားနည်းပညာများစွာ ရှိပါသေးတယ်။ အချို့ကို ဖော်ပြရရင်-

-   Byte-level BPE, GPT-2 မှာ အသုံးပြုထားပါတယ်။
-   WordPiece, BERT မှာ အသုံးပြုထားပါတယ်။
-   SentencePiece သို့မဟုတ် Unigram, multilingual models အများအပြားမှာ အသုံးပြုထားပါတယ်။

Tokenizer တွေ ဘယ်လိုအလုပ်လုပ်တယ်ဆိုတဲ့ အသိပညာဟာ API နဲ့ စတင်ဖို့ လုံလောက်သင့်ပါပြီ။

## Loading နှင့် Saving[[loading-and-saving]]

Tokenizers တွေကို load လုပ်တာနဲ့ save လုပ်တာက model တွေနဲ့ လုပ်တာလိုပဲ ရိုးရှင်းပါတယ်။ တကယ်တော့၊ ၎င်းဟာ `from_pretrained()` နဲ့ `save_pretrained()` ဆိုတဲ့ methods နှစ်ခုတည်းပေါ် အခြေခံထားတာပါ။ ဒီ methods တွေက tokenizer အသုံးပြုတဲ့ algorithm (model ရဲ့ architecture နဲ့ ဆင်တူပါတယ်) နဲ့ ၎င်းရဲ့ vocabulary (model ရဲ့ weights နဲ့ ဆင်တူပါတယ်) နှစ်ခုလုံးကို load သို့မဟုတ် save လုပ်ပေးပါလိမ့်မယ်။

BERT နဲ့ တူညီတဲ့ checkpoint နဲ့ train လုပ်ထားတဲ့ BERT tokenizer ကို load လုပ်တာက model ကို load လုပ်တာနဲ့ နည်းလမ်းတူတူပါပဲ၊ ဒါပေမယ့် ကျွန်တော်တို့က `BertTokenizer` class ကို အသုံးပြုရုံပါပဲ။

```py
from transformers import BertTokenizer

tokenizer = BertTokenizer.from_pretrained("bert-base-cased")
```

`AutoModel` နဲ့ ဆင်တူစွာ၊ `AutoTokenizer` class က checkpoint name ကို အခြေခံပြီး library ထဲက မှန်ကန်တဲ့ tokenizer class ကို ရယူပါလိမ့်မယ်၊ ပြီးတော့ မည်သည့် checkpoint နဲ့မဆို တိုက်ရိုက် အသုံးပြုနိုင်စေပါတယ်။

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")
```

အခု ကျွန်တော်တို့ tokenizer ကို ယခင်အပိုင်းမှာ ပြသခဲ့သလို အသုံးပြုနိုင်ပါပြီ။

```python
tokenizer("Using a Transformer network is simple")
```

```python out
{'input_ids': [101, 7993, 170, 11303, 1200, 2443, 1110, 3014, 102],
 'token_type_ids': [0, 0, 0, 0, 0, 0, 0, 0, 0],
 'attention_mask': [1, 1, 1, 1, 1, 1, 1, 1, 1]}
```

tokenizer ကို save လုပ်တာက model ကို save လုပ်တာနဲ့ အတူတူပါပဲ။

```py
tokenizer.save_pretrained("directory_on_my_computer")
```

`token_type_ids` အကြောင်းကို [Chapter 3](/course/chapter3) မှာ ပိုပြီး အသေးစိတ် ဆွေးနွေးပါမယ်။ `attention_mask` key ကိုတော့ နောက်မှ အနည်းငယ် ရှင်းပြပါမယ်။ ပထမဆုံးအနေနဲ့ `input_ids` တွေ ဘယ်လို ထုတ်လုပ်ခဲ့လဲဆိုတာ ကြည့်ရအောင်။ ဒါကို လုပ်ဖို့ tokenizer ရဲ့ ကြားခံ methods တွေကို ကြည့်ဖို့ လိုအပ်ပါလိမ့်မယ်။

## Encoding[[encoding]]

Text ကို ဂဏန်းတွေအဖြစ် ပြောင်းလဲတာကို *encoding* လို့ ခေါ်ပါတယ်။ Encoding ကို အဆင့်နှစ်ဆင့်နဲ့ လုပ်ဆောင်ပါတယ်- tokenization လုပ်ခြင်း၊ ပြီးရင် input IDs တွေအဖြစ် ပြောင်းလဲခြင်းတို့ ဖြစ်ပါတယ်။

ကျွန်တော်တို့ တွေ့ခဲ့ရသလိုပဲ၊ ပထမအဆင့်က text ကို စကားလုံးတွေအဖြစ် (သို့မဟုတ် စကားလုံးအစိတ်အပိုင်းများ၊ punctuation symbols စသည်တို့) ပိုင်းခြားတာဖြစ်ပြီး၊ ဒါကို အများအားဖြင့် *tokens* လို့ ခေါ်ပါတယ်။ ဒီလုပ်ငန်းစဉ်ကို ထိန်းချုပ်နိုင်တဲ့ စည်းမျဉ်းများစွာ ရှိတာကြောင့် model ကို pretrained လုပ်ခဲ့တုန်းက အသုံးပြုခဲ့တဲ့ စည်းမျဉ်းတွေ အတူတူကို သေချာအသုံးပြုနိုင်ဖို့ model ရဲ့ နာမည်ကို အသုံးပြုပြီး tokenizer ကို instantiate လုပ်ဖို့ လိုအပ်ပါတယ်။

ဒုတိယအဆင့်ကတော့ အဲဒီ tokens တွေကို ဂဏန်းတွေအဖြစ် ပြောင်းလဲတာပါ၊ ဒါမှ ၎င်းတို့ကနေ tensor တစ်ခုကို တည်ဆောက်ပြီး model ကို ထည့်သွင်းပေးနိုင်မှာပါ။ ဒါကို လုပ်ဖို့အတွက် tokenizer မှာ *vocabulary* တစ်ခုရှိပြီး၊ ဒါက `from_pretrained()` method နဲ့ instantiate လုပ်တဲ့အခါ ကျွန်တော်တို့ download လုပ်တဲ့ အစိတ်အပိုင်းပါပဲ။ ထပ်မံပြီး၊ model ကို pretrained လုပ်ခဲ့တုန်းက အသုံးပြုခဲ့တဲ့ vocabulary အတူတူကို ကျွန်တော်တို့ အသုံးပြုဖို့ လိုအပ်ပါတယ်။

အဆင့်နှစ်ဆင့်ကို ပိုမိုနားလည်နိုင်ဖို့အတွက် ၎င်းတို့ကို သီးခြားစီ လေ့လာသွားပါမယ်။ tokenization pipeline ရဲ့ အစိတ်အပိုင်းအချို့ကို သီးခြားစီ လုပ်ဆောင်တဲ့ methods အချို့ကို ကျွန်တော်တို့ အသုံးပြုသွားမှာပါ။ ဒါက အဲဒီအဆင့်တွေရဲ့ ကြားခံရလဒ်တွေကို သင့်ကို ပြသဖို့ပါပဲ။ ဒါပေမယ့် လက်တွေ့မှာတော့ သင်ဟာ သင်ရဲ့ inputs တွေပေါ်မှာ tokenizer ကို တိုက်ရိုက် ခေါ်ဆိုသင့်ပါတယ် (အပိုင်း ၂ မှာ ပြထားသလို)။

### Tokenization[[tokenization]]

Tokenization လုပ်ငန်းစဉ်ကို tokenizer ရဲ့ `tokenize()` method က လုပ်ဆောင်ပါတယ်။ 

```py
from transformers import AutoTokenizer

tokenizer = AutoTokenizer.from_pretrained("bert-base-cased")

sequence = "Using a Transformer network is simple"
tokens = tokenizer.tokenize(sequence)

print(tokens)
```

ဒီ method ရဲ့ output ကတော့ strings ဒါမှမဟုတ် tokens တွေရဲ့ list တစ်ခုပါ။ 

```python out
['Using', 'a', 'transform', '##er', 'network', 'is', 'simple']
```

ဒီ tokenizer က subword tokenizer တစ်ခုပါ- ဒါက စကားလုံးတွေကို သူ့ရဲ့ vocabulary က ကိုယ်စားပြုနိုင်တဲ့ tokens တွေ ရရှိတဲ့အထိ ပိုင်းခြားပေးပါတယ်။ ဒီဥပမာမှာ `transformer` ကို `transform` နဲ့ `##er` ဆိုတဲ့ tokens နှစ်ခုအဖြစ် ပိုင်းခြားထားတာကို တွေ့ရပါတယ်။

### Tokens တွေကနေ Input IDs တွေဆီသို့[[from-tokens-to-input-ids]]

Input IDs တွေအဖြစ် ပြောင်းလဲခြင်းကို `convert_tokens_to_ids()` tokenizer method က ကိုင်တွယ်ပါတယ်။ 

```py
ids = tokenizer.convert_tokens_to_ids(tokens)

print(ids)
```

```python out
[7993, 170, 11303, 1200, 2443, 1110, 3014]
```

ဒီ outputs တွေကို သင့်လျော်တဲ့ framework tensor အဖြစ် ပြောင်းလဲပြီးတာနဲ့၊ ဒီအခန်းရဲ့ အစောပိုင်းမှာ တွေ့ခဲ့ရသလို model ရဲ့ inputs တွေအဖြစ် အသုံးပြုနိုင်ပါတယ်။

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** အပိုင်း ၂ မှာ အသုံးပြုခဲ့တဲ့ input sentences တွေ ("I've been waiting for a HuggingFace course my whole life." နဲ့ "I hate this so much!") ပေါ်မှာ နောက်ဆုံးအဆင့်နှစ်ခု (tokenization နဲ့ input IDs အဖြစ် ပြောင်းလဲခြင်း) ကို ပြန်လည်လုပ်ဆောင်ပါ။ ကျွန်တော်တို့ အစောပိုင်းက ရရှိခဲ့တဲ့ input IDs တွေ အတူတူ ရရှိမရရှိ စစ်ဆေးပါ။

## Decoding[[decoding]]

*Decoding* ဆိုတာကတော့ ပြောင်းပြန်လုပ်တာပါ၊ vocabulary indices တွေကနေ string တစ်ခုကို ပြန်ရချင်တာပါ။ ဒါကို `decode()` method နဲ့ အောက်ပါအတိုင်း လုပ်ဆောင်နိုင်ပါတယ်။

```py
decoded_string = tokenizer.decode([7993, 170, 11303, 1200, 2443, 1110, 3014])
print(decoded_string)
```

```python out
'Using a Transformer network is simple'
```

`decode` method က indices တွေကို tokens တွေအဖြစ် ပြန်ပြောင်းပေးရုံသာမကဘဲ၊ တူညီတဲ့ စကားလုံးရဲ့ အစိတ်အပိုင်းဖြစ်တဲ့ tokens တွေကို စုစည်းပြီး ဖတ်လို့ရတဲ့ စာကြောင်းတစ်ခုကို ထုတ်လုပ်ပေးတာကို သတိပြုပါ။ ဒီ behavior က text အသစ်တွေကို ခန့်မှန်းတဲ့ model တွေကို အသုံးပြုတဲ့အခါ (prompt တစ်ခုကနေ ထုတ်လုပ်တဲ့ text ဖြစ်စေ၊ ဒါမှမဟုတ် translation သို့မဟုတ် summarization လို sequence-to-sequence ပြဿနာတွေအတွက် ဖြစ်စေ) အလွန်အသုံးဝင်ပါလိမ့်မယ်။

အခုဆိုရင် tokenizer တစ်ခုက ကိုင်တွယ်နိုင်တဲ့ atomic operations တွေကို သင်နားလည်သင့်ပါပြီ- tokenization လုပ်ခြင်း၊ IDs တွေအဖြစ် ပြောင်းလဲခြင်း၊ နဲ့ IDs တွေကို string အဖြစ် ပြန်ပြောင်းလဲခြင်းတို့ ဖြစ်ပါတယ်။ သို့သော်လည်း၊ ကျွန်တော်တို့ဟာ ရေခဲတောင်ရဲ့ ထိပ်ဖျားလေးကိုပဲ ကုတ်ဖဲ့မိပါသေးတယ်။ နောက်အပိုင်းမှာတော့ ကျွန်တော်တို့ရဲ့ နည်းလမ်းကို သူ့ရဲ့ အကန့်အသတ်တွေဆီ ယူဆောင်သွားပြီး ၎င်းတို့ကို ဘယ်လိုကျော်လွှားရမလဲဆိုတာ ကြည့်ရပါလိမ့်မယ်။

## ဝေါဟာရ ရှင်းလင်းချက် (Glossary)

*   **Tokenizers**: စာသား (သို့မဟုတ် အခြားဒေတာ) ကို AI မော်ဒယ်များ စီမံဆောင်ရွက်နိုင်ရန် tokens တွေအဖြစ် ပိုင်းခြားပေးသည့် ကိရိယာ သို့မဟုတ် လုပ်ငန်းစဉ်။
*   **NLP Pipeline**: Natural Language Processing (NLP) လုပ်ငန်းတာဝန်တစ်ခုကို ပြီးမြောက်အောင် လုပ်ဆောင်ရန် အဆင့်ဆင့် လုပ်ဆောင်ရမည့် လုပ်ငန်းစဉ်များ။
*   **Raw Text**: မည်သည့်လုပ်ဆောင်မှုမျှ မပြုလုပ်ရသေးသော သို့မဟုတ် ပုံစံမချရသေးသော မူရင်းစာသား။
*   **Numerical Data**: ဂဏန်းပုံစံဖြင့် ဖော်ပြထားသော အချက်အလက်များ။
*   **Tokenization**: စာသားကို tokens များအဖြစ် ပိုင်းခြားသော လုပ်ငန်းစဉ်။
*   **Tokens**: စာသားကို ခွဲခြမ်းစိတ်ဖြာရာတွင် အသုံးပြုသော အသေးငယ်ဆုံးယူနစ်များ (ဥပမာ- စကားလုံးများ၊ subwords များ သို့မဟုတ် ပုဒ်ဖြတ်သံများ)။
*   **Word-based Tokenizer**: စာသားကို စကားလုံးများအဖြစ် ပိုင်းခြားသော tokenizer အမျိုးအစား။
*   **Whitespace**: စာသားထဲရှိ နေရာလွတ်များ (space, tab, newline)။
*   **`split()` Function**: Python တွင် string တစ်ခုကို သတ်မှတ်ထားသော delimiter ဖြင့် ပိုင်းခြားရန် အသုံးပြုသော function။
*   **Vocabulary**: tokenizer သို့မဟုတ် model တစ်ခုက သိရှိနားလည်ပြီး ကိုင်တွယ်နိုင်သော ထူးခြားသည့် tokens များ စုစုပေါင်း။
*   **Corpus**: Machine Learning တွင် အသုံးပြုသော စာသားဒေတာအစုအဝေးကြီး။
*   **ID**: token တစ်ခုစီကို ကိုယ်စားပြုသော ထူးခြားသည့် ဂဏန်း။
*   **Unknown Token (`[UNK]`, ``)**: tokenizer ၏ vocabulary တွင် မပါဝင်သော စကားလုံးများကို ကိုယ်စားပြုရန် အသုံးပြုသော special token။
*   **Character-based Tokenizer**: စာသားကို characters များအဖြစ် ပိုင်းခြားသော tokenizer အမျိုးအစား။
*   **Out-of-vocabulary (OOV) Tokens**: tokenizer ၏ vocabulary တွင် မပါဝင်သော tokens များ။
*   **Subword Tokenization**: မကြာခဏ အသုံးပြုသော စကားလုံးများကို မခွဲဘဲ၊ ရှားပါးသော စကားလုံးများကို အဓိပ္ပာယ်ရှိသော subwords များအဖြစ် ခွဲခြားသော tokenization နည်းလမ်း။
*   **Agglutinative Languages**: စကားလုံးများကို အစိတ်အပိုင်းငယ်လေးများ ပေါင်းစပ်ခြင်းဖြင့် ဖွဲ့စည်းထားသော ဘာသာစကားများ (ဥပမာ- တူရကီဘာသာ)။
*   **Byte-level BPE**: Byte Pair Encoding (BPE) ၏ ပြောင်းလဲထားသော ပုံစံတစ်ခုဖြစ်ပြီး characters များအစား bytes များကို အသုံးပြုသည်။ GPT-2 တွင် အသုံးပြုသည်။
*   **WordPiece**: Google မှ ဖန်တီးထားသော subword tokenization algorithm တစ်ခုဖြစ်ပြီး BERT တွင် အသုံးပြုသည်။
*   **SentencePiece / Unigram**: Google မှ ဖန်တီးထားသော subword tokenization algorithm များဖြစ်ပြီး multilingual models များတွင် အသုံးပြုသည်။
*   **`AutoTokenizer` Class**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ class တစ်ခုဖြစ်ပြီး မော်ဒယ်အမည်ကို အသုံးပြုပြီး သက်ဆိုင်ရာ tokenizer ကို အလိုအလျောက် load လုပ်ပေးသည်။
*   **`BertTokenizer` Class**: BERT model အတွက် သီးသန့်ဒီဇိုင်းထုတ်ထားသော tokenizer class။
*   **`from_pretrained()` Method**: Pre-trained model သို့မဟုတ် tokenizer ကို load လုပ်ရန် အသုံးပြုသော method။
*   **`save_pretrained()` Method**: Model သို့မဟုတ် tokenizer ၏ weights များနှင့် architecture configuration ကို save လုပ်ရန် အသုံးပြုသော method။
*   **Encoding**: Text ကို ဂဏန်းဆိုင်ရာ ကိုယ်စားပြုမှုအဖြစ် ပြောင်းလဲသော လုပ်ငန်းစဉ်။
*   **`tokenize()` Method**: tokenizer ၏ text ကို tokens များအဖြစ် ပိုင်းခြားပေးသော method။
*   **`convert_tokens_to_ids()` Method**: tokens list ကို input IDs list အဖြစ် ပြောင်းလဲပေးသော tokenizer method။
*   **Decoding**: ဂဏန်းဆိုင်ရာ ကိုယ်စားပြုမှု (vocabulary indices) များမှ မူရင်းစာသားသို့ ပြန်ပြောင်းလဲသော လုပ်ငန်းစဉ်။
*   **`decode()` Method**: input IDs များကို မူရင်းစာသားသို့ ပြန်ပြောင်းလဲပေးသော method။
*   **Sequence-to-sequence Problems**: input sequence တစ်ခုမှ output sequence တစ်ခုသို့ ပြောင်းလဲခြင်း လုပ်ငန်းများ (ဥပမာ- ဘာသာပြန်ခြင်း၊ အနှစ်ချုပ်ခြင်း)။
*   **Prompt**: မော်ဒယ်ကို text ထုတ်လုပ်ရန်အတွက် ပေးသော အစစာသား။

