# Causal Language Model တစ်ခုကို အစကနေ လေ့ကျင့်ခြင်း[[training-a-causal-language-model-from-scratch]]

{#if fw === 'pt'}

{:else}

{/if}

အခုအထိတော့ ကျွန်တော်တို့ဟာ pretrained models တွေကို အများအားဖြင့် အသုံးပြုခဲ့ကြပြီး pretraining ကနေရရှိတဲ့ weights တွေကို ပြန်လည်အသုံးပြုခြင်းဖြင့် use cases အသစ်တွေအတွက် fine-tuning လုပ်ခဲ့ကြပါတယ်။ [Chapter 1](/course/chapter1) မှာ ကျွန်တော်တို့ တွေ့ခဲ့ရတဲ့အတိုင်း၊ ဒါကို _transfer learning_ လို့ အများအားဖြင့် ရည်ညွှန်းကြပြီး၊ labeled data ရှားပါးတဲ့ လက်တွေ့ကမ္ဘာသုံး use cases အများစုမှာ Transformer models တွေကို အသုံးချဖို့အတွက် အလွန်အောင်မြင်တဲ့ နည်းဗျူဟာတစ်ခု ဖြစ်ပါတယ်။ ဒီအခန်းမှာ၊ ကျွန်တော်တို့ မတူညီတဲ့ နည်းလမ်းတစ်ခုကို အသုံးပြုပြီး model အသစ်တစ်ခုကို အစကနေ train လုပ်ပါမယ်။ ဒါက သင့်မှာ data အများကြီးရှိပြီး လက်ရှိ models တွေအတွက် အသုံးပြုခဲ့တဲ့ pretraining data တွေနဲ့ အလွန်ကွာခြားတယ်ဆိုရင် ကောင်းမွန်တဲ့ နည်းလမ်းတစ်ခုပါပဲ။ သို့သော်လည်း၊ လက်ရှိ model တစ်ခုကို fine-tune လုပ်တာထက် language model တစ်ခုကို pretrain လုပ်ဖို့အတွက် compute resources တွေ သိသိသာသာ ပိုလိုအပ်ပါတယ်။ model အသစ်တစ်ခုကို train လုပ်တာ အဓိပ္ပာယ်ရှိနိုင်တဲ့ ဥပမာတွေကတော့ musical notes, DNA လို molecular sequences ဒါမှမဟုတ် programming languages တွေ ပါဝင်တဲ့ datasets တွေ ဖြစ်ပါတယ်။ နောက်ဆုံးပြောခဲ့တဲ့အရာတွေက TabNine နဲ့ OpenAI ရဲ့ Codex model က ပံ့ပိုးပေးထားတဲ့ GitHub ရဲ့ Copilot လို tools တွေကြောင့် မကြာသေးခင်က အရှိန်အဟုန် ရရှိလာခဲ့ပါတယ်။ ဒါတွေက code ရဲ့ ရှည်လျားတဲ့ sequences တွေကို generate လုပ်နိုင်ပါတယ်။ text generation ရဲ့ ဒီ task ကို auto-regressive သို့မဟုတ် GPT-2 လို causal language models တွေနဲ့ အကောင်းဆုံး ကိုင်တွယ်ဖြေရှင်းနိုင်ပါတယ်။

ဒီအပိုင်းမှာ ကျွန်တော်တို့ code generation model ရဲ့ scaled-down version တစ်ခုကို တည်ဆောက်ပါမယ်၊ Python code ရဲ့ subset တစ်ခုကို အသုံးပြုပြီး full functions ဒါမှမဟုတ် classes တွေအစား one-line completions တွေအပေါ် အာရုံစိုက်ပါမယ်။ Python မှာ data နဲ့ အလုပ်လုပ်တဲ့အခါ သင်ဟာ `matplotlib`, `seaborn`, `pandas`, နဲ့ `scikit-learn` libraries တွေ ပါဝင်တဲ့ Python data science stack နဲ့ မကြာခဏ ထိတွေ့နေရပါလိမ့်မယ်။ အဲဒီ frameworks တွေကို အသုံးပြုတဲ့အခါ သီးခြား commands တွေကို ရှာဖွေဖို့ လိုအပ်တာက ပုံမှန်ပါပဲ၊ ဒါကြောင့် ကျွန်တော်တို့အတွက် ဒီ calls တွေကို ဖြည့်စွက်ပေးနိုင်တဲ့ model တစ်ခုကို အသုံးပြုနိုင်ရင် ကောင်းပါလိမ့်မယ်။

[Chapter 6](/course/chapter6) မှာ Python source code ကို process လုပ်ဖို့အတွက် ထိရောက်တဲ့ tokenizer တစ်ခုကို ကျွန်တော်တို့ ဖန်တီးခဲ့ပါတယ်၊ ဒါပေမယ့် ကျွန်တော်တို့ လိုအပ်နေသေးတာက model တစ်ခုကို pretrain လုပ်ဖို့အတွက် large-scale dataset တစ်ခုပါပဲ။ ဒီနေရာမှာ၊ ကျွန်တော်တို့ရဲ့ tokenizer ကို GitHub repositories ကနေ ရရှိတဲ့ Python code corpus တစ်ခုပေါ်မှာ အသုံးချပါမယ်။ ပြီးရင် model ကို train လုပ်ဖို့အတွက် `Trainer` API နဲ့ 🤗 Accelerate ကို အသုံးပြုပါမယ်။ စလိုက်ရအောင်!

ဒါက ဒီအပိုင်းမှာ ပြသထားတဲ့ code ကို အသုံးပြုပြီး Hub ကို train လုပ်ပြီး upload လုပ်ထားတဲ့ model ကို လက်တွေ့ပြသနေတာ ဖြစ်ပါတယ်။ သင် [ဒီနေရာမှာ](https://huggingface.co/huggingface-course/codeparrot-ds?text=plt.imshow%28) ရှာတွေ့နိုင်ပါတယ်။ text generation မှာ randomization အချို့ဖြစ်ပေါ်နေတာကြောင့်၊ သင်အနည်းငယ်ကွဲပြားတဲ့ ရလဒ်ကို ရရှိနိုင်မယ်ဆိုတာ မှတ်သားပါ။

## Data များကို စုဆောင်းခြင်း[[gathering-the-data]]

Python code ကို GitHub လို code repositories တွေကနေ အလွယ်တကူ ရရှိနိုင်ပြီး၊ Python repository တိုင်းကို scraping လုပ်ခြင်းဖြင့် dataset တစ်ခု ဖန်တီးဖို့ ကျွန်တော်တို့ အသုံးပြုနိုင်ပါတယ်။ ဒါက [Transformers textbook](https://learning.oreilly.com/library/view/natural-language-processing/9781098136789/) မှာ large GPT-2 model တစ်ခုကို pretrain လုပ်ဖို့ အသုံးပြုခဲ့တဲ့ နည်းလမ်းပါပဲ။ `codeparrot` လို့ခေါ်တဲ့ Python files သန်း ၂၀ ခန့်ပါဝင်တဲ့ 180 GB ခန့်ရှိတဲ့ GitHub dump ကို အသုံးပြုပြီး၊ စာရေးဆရာတွေက dataset တစ်ခုကို တည်ဆောက်ခဲ့ပြီး အဲဒါကို [Hugging Face Hub](https://huggingface.co/datasets/transformersbook/codeparrot) မှာ မျှဝေခဲ့ပါတယ်။

သို့သော်လည်း၊ full corpus ပေါ်မှာ training လုပ်တာက အချိန်နဲ့ compute-consuming ဖြစ်ပြီး၊ ကျွန်တော်တို့က Python data science stack နဲ့ ပတ်သက်တဲ့ dataset ရဲ့ subset ကိုပဲ လိုအပ်ပါတယ်။ ဒါကြောင့်၊ `codeparrot` dataset ကို ဒီ stack ထဲက libraries တွေ ပါဝင်တဲ့ files အားလုံးအတွက် filtering လုပ်ခြင်းဖြင့် စတင်ပါမယ်။ dataset ရဲ့ အရွယ်အစားကြောင့်၊ ကျွန်တော်တို့ ဒါကို download လုပ်တာကို ရှောင်ရှားချင်ပါတယ်၊ အစား streaming feature ကို အသုံးပြုပြီး on the fly မှာ filter လုပ်ပါမယ်။ အစောပိုင်းမှာ ကျွန်တော်တို့ ပြောခဲ့တဲ့ libraries တွေကို အသုံးပြုပြီး code samples တွေကို filter လုပ်ရာမှာ အကူအညီဖြစ်စေဖို့၊ အောက်ပါ function ကို အသုံးပြုပါမယ်။

```py
def any_keyword_in_string(string, keywords):
    for keyword in keywords:
        if keyword in string:
            return True
    return False
```

ဥပမာနှစ်ခုနဲ့ စမ်းသပ်ကြည့်ရအောင်။

```py
filters = ["pandas", "sklearn", "matplotlib", "seaborn"]
example_1 = "import numpy as np"
example_2 = "import pandas as pd"

print(
    any_keyword_in_string(example_1, filters), any_keyword_in_string(example_2, filters)
)
```

```python out
False True
```

ဒါကို အသုံးပြုပြီး dataset ကို stream လုပ်ပြီး ကျွန်တော်တို့ လိုချင်တဲ့ elements တွေကို filter လုပ်မယ့် function တစ်ခု ဖန်တီးနိုင်ပါတယ်။

```py
from collections import defaultdict
from tqdm import tqdm
from datasets import Dataset

def filter_streaming_dataset(dataset, filters):
    filtered_dict = defaultdict(list)
    total = 0
    for sample in tqdm(iter(dataset)):
        total += 1
        if any_keyword_in_string(sample["content"], filters):
            for k, v in sample.items():
                filtered_dict[k].append(v)
    print(f"{len(filtered_dict['content'])/total:.2%} of data after filtering.")
    return Dataset.from_dict(filtered_dict)
```

ပြီးရင် ဒီ function ကို streaming dataset ကို ရိုးရှင်းစွာ အသုံးချနိုင်ပါတယ်။

```py
# This cell will take a very long time to execute, so you should skip it and go to
# the next one!
from datasets import load_dataset

split = "train"  # "valid"
filters = ["pandas", "sklearn", "matplotlib", "seaborn"]

data = load_dataset(f"transformersbook/codeparrot-{split}", split=split, streaming=True)
filtered_data = filter_streaming_dataset(data, filters)
```

```python out
3.26% of data after filtering.
```

ဒါက ကျွန်တော်တို့ကို မူရင်း dataset ရဲ့ ၃% ခန့် ကျန်ရှိစေပါတယ်၊ ဒါကလည်း အတော်လေး ကြီးမားနေဆဲပါပဲ — ရရှိလာတဲ့ dataset က 6 GB ရှိပြီး Python scripts ၆၀၀,၀၀၀ ပါဝင်ပါတယ်။

full dataset ကို filtering လုပ်တာက သင့် machine နဲ့ bandwidth ပေါ်မူတည်ပြီး ၂-၃ နာရီ ကြာနိုင်ပါတယ်။ ဒီလို အချိန်ကုန်တဲ့ လုပ်ငန်းစဉ်ကို သင်ကိုယ်တိုင် မလုပ်ချင်ဘူးဆိုရင်၊ ကျွန်တော်တို့က Hub ပေါ်မှာ filtered dataset ကို download လုပ်ဖို့ ပံ့ပိုးပေးထားပါတယ်။

```py
from datasets import load_dataset, DatasetDict

ds_train = load_dataset("huggingface-course/codeparrot-ds-train", split="train")
ds_valid = load_dataset("huggingface-course/codeparrot-ds-valid", split="validation")

raw_datasets = DatasetDict(
    {
        "train": ds_train,  # .shuffle().select(range(50000)),
        "valid": ds_valid,  # .shuffle().select(range(500))
    }
)

raw_datasets
```

```python out
DatasetDict({
    train: Dataset({
        features: ['repo_name', 'path', 'copies', 'size', 'content', 'license'],
        num_rows: 606720
    })
    valid: Dataset({
        features: ['repo_name', 'path', 'copies', 'size', 'content', 'license'],
        num_rows: 3322
    })
})
```

> [!TIP]
> Pretraining the language model will take a while. We suggest that you first run the training loop on a sample of the data by uncommenting the two partial lines above, and make sure that the training successfully completes and the models are stored. Nothing is more frustrating than a training run failing at the last step because you forgot to create a folder or because there's a typo at the end of the training loop!

dataset ကနေ ဥပမာတစ်ခုကို ကြည့်ရအောင်။ field တစ်ခုစီရဲ့ ပထမဆုံး characters ၂၀၀ ကိုပဲ ပြသပါမယ်။

```py
for key in raw_datasets["train"][0]:
    print(f"{key.upper()}: {raw_datasets['train'][0][key][:200]}")
```

```python out
'REPO_NAME: kmike/scikit-learn'
'PATH: sklearn/utils/__init__.py'
'COPIES: 3'
'SIZE: 10094'
'''CONTENT: """
The :mod:`sklearn.utils` module includes various utilites.
"""

from collections import Sequence

import numpy as np
from scipy.sparse import issparse
import warnings

from .murmurhash import murm
LICENSE: bsd-3-clause'''
```

`content` field က ကျွန်တော်တို့ model train လုပ်ချင်တဲ့ code ကို ပါဝင်နေတာ တွေ့ရပါတယ်။ အခု dataset ရှိပြီဆိုတော့၊ pretraining အတွက် သင့်လျော်တဲ့ format ဖြစ်အောင် texts တွေကို ပြင်ဆင်ဖို့ လိုပါတယ်။

## Dataset ကို ပြင်ဆင်ခြင်း[[preparing-the-dataset]]

ပထမအဆင့်က data ကို tokenize လုပ်မှာ ဖြစ်ပါတယ်၊ ဒါမှ training အတွက် အသုံးပြုနိုင်မှာပါ။ ကျွန်တော်တို့ရဲ့ ပန်းတိုင်က အဓိကအားဖြင့် တိုတောင်းတဲ့ function calls တွေကို autocomplete လုပ်တာဖြစ်တာကြောင့်၊ context size ကို အတော်လေး သေးငယ်အောင် ထားနိုင်ပါတယ်။ ဒါက model ကို အများကြီး ပိုမြန်မြန် train လုပ်နိုင်ပြီး memory အများကြီး သုံးစွဲမှု နည်းပါးစေတဲ့ အကျိုးကျေးဇူး ရှိပါတယ်။ သင့် application အတွက် context ပိုလိုအပ်တယ်ဆိုရင် (ဥပမာ - function definition ပါတဲ့ file တစ်ခုပေါ်မှာ အခြေခံပြီး unit tests တွေ ရေးစေချင်တယ်ဆိုရင်) အဲဒီနံပါတ်ကို သေချာတိုးမြှင့်ပါ၊ ဒါပေမယ့် ဒါက ပိုကြီးမားတဲ့ GPU memory footprint နဲ့ ပါလာနိုင်တယ်ဆိုတာကိုလည်း သတိရပါ။ အခုအတွက်တော့ context size ကို 128 tokens မှာ သတ်မှတ်ထားပါမယ်၊ GPT-2 ဒါမှမဟုတ် GPT-3 မှာ အသုံးပြုတဲ့ 1,024 ဒါမှမဟုတ် 2,048 နဲ့ မတူပါဘူး။

documents အများစုမှာ 128 tokens ထက် အများကြီး ပိုများတဲ့ tokens တွေ ပါဝင်တာကြောင့်၊ inputs တွေကို maximum length အထိ ရိုးရှင်းစွာ truncate လုပ်တာက ကျွန်တော်တို့ dataset ရဲ့ အစိတ်အပိုင်းကြီးတစ်ခုကို ဖယ်ရှားပစ်ပါလိမ့်မယ်။ အစား၊ ကျွန်တော်တို့ `return_overflowing_tokens` option ကို အသုံးပြုပြီး input တစ်ခုလုံးကို tokenize လုပ်ပြီး chunks များစွာအဖြစ် ပိုင်းခြားပါမယ်၊ [Chapter 6](/course/chapter6/4) မှာ လုပ်ခဲ့တဲ့အတိုင်းပါပဲ။ `return_length` option ကိုလည်း အသုံးပြုပြီး ဖန်တီးထားတဲ့ chunk တစ်ခုစီရဲ့ length ကို အလိုအလျောက် ပြန်ပေးပါမယ်။ အများအားဖြင့် နောက်ဆုံး chunk က context size ထက် ပိုသေးငယ်နေမှာဖြစ်ပြီး၊ padding ပြဿနာတွေကို ရှောင်ရှားဖို့အတွက် ဒီအပိုင်းတွေကို ဖယ်ရှားပါမယ်၊ ကျွန်တော်တို့မှာ data အလုံအလောက်ရှိနေတာကြောင့် ဒါတွေ တကယ်မလိုအပ်ပါဘူး။

ဒါက ဘယ်လိုအလုပ်လုပ်လဲဆိုတာကို ပထမဆုံးဥပမာနှစ်ခုကို ကြည့်ပြီး အတိအကျ ကြည့်ရအောင်။

```py
from transformers import AutoTokenizer

context_length = 128
tokenizer = AutoTokenizer.from_pretrained("huggingface-course/code-search-net-tokenizer")

outputs = tokenizer(
    raw_datasets["train"][:2]["content"],
    truncation=True,
    max_length=context_length,
    return_overflowing_tokens=True,
    return_length=True,
)

print(f"Input IDs length: {len(outputs['input_ids'])}")
print(f"Input chunk lengths: {(outputs['length'])}")
print(f"Chunk mapping: {outputs['overflow_to_sample_mapping']}")
```

```python out
Input IDs length: 34
Input chunk lengths: [128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 117, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128, 41]
Chunk mapping: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
```

အဲဒီဥပမာနှစ်ခုကနေ segments ၃၄ ခု ရရှိတာကို တွေ့ရပါတယ်။ chunk lengths တွေကို ကြည့်ရင်၊ documents နှစ်ခုလုံးရဲ့ အဆုံးက chunks တွေမှာ 128 tokens ထက် နည်းပါးတာကို တွေ့ရပါတယ် (အသီးသီး 117 နဲ့ 41)။ ဒါတွေက ကျွန်တော်တို့မှာရှိတဲ့ စုစုပေါင်း chunks တွေရဲ့ အစိတ်အပိုင်းအနည်းငယ်မျှသာ ဖြစ်တာကြောင့်၊ ဒါတွေကို လုံခြုံစွာ ဖယ်ရှားနိုင်ပါတယ်။ `overflow_to_sample_mapping` field နဲ့၊ ဘယ် chunks တွေက ဘယ် input samples တွေနဲ့ သက်ဆိုင်တယ်ဆိုတာကိုလည်း ပြန်လည်တည်ဆောက်နိုင်ပါတယ်။

ဒီ operation နဲ့ ကျွန်တော်တို့ 🤗 Datasets မှာရှိတဲ့ `Dataset.map()` function ရဲ့ အသုံးဝင်တဲ့ feature တစ်ခုကို အသုံးပြုနေပါတယ်။ ဒါက one-to-one maps တွေ မလိုအပ်ပါဘူး၊ [section 3](/course/chapter7/3) မှာ ကျွန်တော်တို့ တွေ့ခဲ့ရတဲ့အတိုင်း၊ input batch ထက် elements ပိုများတာ ဒါမှမဟုတ် နည်းပါးတာနဲ့ batches တွေကို ဖန်တီးနိုင်ပါတယ်။ ဒါက data augmentation ဒါမှမဟုတ် data filtering လို operations တွေ လုပ်တဲ့အခါ elements အရေအတွက်ကို ပြောင်းလဲတဲ့အခါ အသုံးဝင်ပါတယ်။ ကျွန်တော်တို့ရဲ့ ကိစ္စမှာ၊ element တစ်ခုစီကို သတ်မှတ်ထားတဲ့ context size ရှိတဲ့ chunks တွေအဖြစ် tokenize လုပ်တဲ့အခါ၊ document တစ်ခုစီကနေ samples များစွာကို ဖန်တီးပါတယ်။ ကျွန်တော်တို့က လက်ရှိ columns တွေကို ဖျက်ပစ်ဖို့ပဲ လိုအပ်ပါတယ်၊ ဘာလို့လဲဆိုတော့ ၎င်းတို့မှာ conflicting size ရှိနေလို့ပါ။ အကယ်၍ ဒါတွေကို ဆက်ထားချင်တယ်ဆိုရင်၊ ၎င်းတို့ကို သင့်လျော်စွာ ထပ်ခါတလဲလဲ လုပ်ပြီး `Dataset.map()` call ထဲကနေ ပြန်ပေးနိုင်ပါတယ်။

```py
def tokenize(element):
    outputs = tokenizer(
        element["content"],
        truncation=True,
        max_length=context_length,
        return_overflowing_tokens=True,
        return_length=True,
    )
    input_batch = []
    for length, input_ids in zip(outputs["length"], outputs["input_ids"]):
        if length == context_length:
            input_batch.append(input_ids)
    return {"input_ids": input_batch}

tokenized_datasets = raw_datasets.map(
    tokenize, batched=True, remove_columns=raw_datasets["train"].column_names
)
tokenized_datasets
```

```python out
DatasetDict({
    train: Dataset({
        features: ['input_ids'],
        num_rows: 16702061
    })
    valid: Dataset({
        features: ['input_ids'],
        num_rows: 93164
    })
})
```

ကျွန်တော်တို့မှာ အခု 128 tokens စီပါဝင်တဲ့ examples 16.7 သန်း ရှိနေပြီး၊ ဒါက စုစုပေါင်း 2.1 ဘီလီယံ tokens ခန့်နဲ့ ကိုက်ညီပါတယ်။ ဥပမာအနေနဲ့၊ OpenAI ရဲ့ GPT-3 နဲ့ Codex models တွေကို ဘီလီယံ ၃၀၀ နဲ့ ဘီလီယံ ၁၀၀ tokens အသီးသီးပေါ်မှာ train လုပ်ထားပါတယ်၊ Codex models တွေကို GPT-3 checkpoints တွေကနေ initialize လုပ်ထားတာပါ။ ဒီအပိုင်းမှာ ကျွန်တော်တို့ရဲ့ ပန်းတိုင်က ရှည်လျားပြီး သဟဇာတဖြစ်တဲ့ texts တွေကို generate လုပ်နိုင်တဲ့ ဒီ models တွေနဲ့ ယှဉ်ပြိုင်ဖို့ မဟုတ်ပါဘူး၊ ဒါပေမယ့် data scientists တွေအတွက် မြန်ဆန်တဲ့ autocomplete function ကို ပံ့ပိုးပေးမယ့် scaled-down version တစ်ခုကို ဖန်တီးဖို့ပါပဲ။

အခု dataset အဆင်သင့်ဖြစ်ပြီဆိုတော့၊ model ကို တည်ဆောက်ကြရအောင်!

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** context size ထက် သေးငယ်တဲ့ chunks တွေအားလုံးကို ဖယ်ရှားပစ်တာက ဒီနေရာမှာ သိပ်ပြဿနာမရှိခဲ့ပါဘူး၊ ဘာလို့လဲဆိုတော့ ကျွန်တော်တို့က small context windows တွေကို အသုံးပြုနေလို့ပါ။ သင် context size ကို တိုးမြှင့်တာနဲ့အမျှ (သို့မဟုတ် တိုတောင်းတဲ့ documents corpus တစ်ခုရှိတယ်ဆိုရင်) ဖယ်ရှားပစ်တဲ့ chunks တွေရဲ့ အချိုးအစားလည်း တိုးလာပါလိမ့်မယ်။ data ကို ပြင်ဆင်ဖို့ ပိုထိရောက်တဲ့ နည်းလမ်းက batch တစ်ခုထဲက tokenized samples အားလုံးကို `eos_token_id` token တစ်ခုနဲ့ ကြားထဲမှာ ပေါင်းစပ်ပြီး၊ ပြီးရင် concatenated sequences တွေပေါ်မှာ chunking ကို လုပ်ဆောင်တာပါပဲ။ လေ့ကျင့်ခန်းအနေနဲ့၊ အဲဒီနည်းလမ်းကို အသုံးပြုဖို့ `tokenize()` function ကို ပြင်ဆင်ပါ။ `truncation=False` ကို သတ်မှတ်ပြီး tokenizer ကနေ အခြား arguments တွေကို ဖယ်ရှားပြီး token IDs ရဲ့ full sequence ကို ရယူချင်တယ်ဆိုတာ သတိပြုပါ။

## Model အသစ်တစ်ခုကို စတင်ခြင်း[[initializing-a-new-model]]

ကျွန်တော်တို့ရဲ့ ပထမအဆင့်က GPT-2 model တစ်ခုကို လုံးဝအသစ်ကနေ initialize လုပ်ဖို့ပါပဲ။ ကျွန်တော်တို့ရဲ့ model အတွက် small GPT-2 model အတွက် configuration တူတူကို အသုံးပြုပါမယ်၊ ဒါကြောင့် pretrained configuration ကို load လုပ်ပြီး tokenizer size က model vocabulary size နဲ့ ကိုက်ညီကြောင်း သေချာစေကာ `bos` နဲ့ `eos` (beginning and end of sequence) token IDs တွေကို ထည့်ပေးပါမယ်-

{#if fw === 'pt'}

```py
from transformers import AutoTokenizer, GPT2LMHeadModel, AutoConfig

config = AutoConfig.from_pretrained(
    "gpt2",
    vocab_size=len(tokenizer),
    n_ctx=context_length,
    bos_token_id=tokenizer.bos_token_id,
    eos_token_id=tokenizer.eos_token_id,
)
```

အဲဒီ configuration နဲ့ model အသစ်တစ်ခုကို load လုပ်နိုင်ပါတယ်။ ဒါဟာ ကျွန်တော်တို့ `from_pretrained()` function ကို မသုံးဘဲ model ကို ကိုယ်တိုင် initialize လုပ်တာ ပထမဆုံးအကြိမ် ဖြစ်တယ်ဆိုတာ မှတ်သားပါ။

```py
model = GPT2LMHeadModel(config)
model_size = sum(t.numel() for t in model.parameters())
print(f"GPT-2 size: {model_size/1000**2:.1f}M parameters")
```

```python out
GPT-2 size: 124.2M parameters
```

{:else}

```py
from transformers import AutoTokenizer, TFGPT2LMHeadModel, AutoConfig

config = AutoConfig.from_pretrained(
    "gpt2",
    vocab_size=len(tokenizer),
    n_ctx=context_length,
    bos_token_id=tokenizer.bos_token_id,
    eos_token_id=tokenizer.eos_token_id,
)
```

အဲဒီ configuration နဲ့ model အသစ်တစ်ခုကို load လုပ်နိုင်ပါတယ်။ ဒါဟာ ကျွန်တော်တို့ `from_pretrained()` function ကို မသုံးဘဲ model ကို ကိုယ်တိုင် initialize လုပ်တာ ပထမဆုံးအကြိမ် ဖြစ်တယ်ဆိုတာ မှတ်သားပါ။

```py
model = TFGPT2LMHeadModel(config)
model(model.dummy_inputs)  # Builds the model
model.summary()
```

```python out
_________________________________________________________________
Layer (type)                 Output Shape              Param #   
=================================================================
transformer (TFGPT2MainLayer multiple                  124242432 
=================================================================
Total params: 124,242,432
Trainable params: 124,242,432
Non-trainable params: 0
_________________________________________________________________
```

{/if}

ကျွန်တော်တို့ရဲ့ model မှာ parameters 124M ရှိပြီး ဒါတွေကို tune လုပ်ရပါမယ်။ training မစတင်ခင်၊ batches တွေကို ဖန်တီးပေးမယ့် data collator တစ်ခုကို တည်ဆောက်ဖို့ လိုပါတယ်။ `DataCollatorForLanguageModeling` collator ကို အသုံးပြုနိုင်ပါတယ်၊ ဒါက language modeling အတွက် အထူးဒီဇိုင်းထုတ်ထားတာပါ (နာမည်က သိမ်မွေ့စွာ အကြံပြုထားတဲ့အတိုင်း)။ batches တွေကို stacking နဲ့ padding လုပ်ခြင်းအပြင်၊ ဒါက language model labels တွေ ဖန်တီးတာကိုပါ ဂရုစိုက်ပေးပါတယ် — causal language modeling မှာ inputs တွေက labels တွေအဖြစ်လည်း လုပ်ဆောင်ပါတယ် (element တစ်ခုနဲ့ ရွှေ့ထားရုံပါပဲ)၊ ပြီးတော့ ဒီ data collator က training လုပ်နေစဉ် on the fly မှာ ဒါတွေကို ဖန်တီးပေးတာကြောင့် `input_ids` တွေကို ထပ်ပွားဖို့ မလိုအပ်ပါဘူး။

`DataCollatorForLanguageModeling` က masked language modeling (MLM) နဲ့ causal language modeling (CLM) နှစ်ခုလုံးကို ထောက်ပံ့ပေးတယ်ဆိုတာ မှတ်သားပါ။ default အားဖြင့် ဒါက MLM အတွက် data ကို ပြင်ဆင်ပေးပါတယ်၊ ဒါပေမယ့် `mlm=False` argument ကို သတ်မှတ်ခြင်းဖြင့် CLM ကို ပြောင်းနိုင်ပါတယ်။

{#if fw === 'pt'}

```py
from transformers import DataCollatorForLanguageModeling

tokenizer.pad_token = tokenizer.eos_token
data_collator = DataCollatorForLanguageModeling(tokenizer, mlm=False)
```

{:else}

```py
from transformers import DataCollatorForLanguageModeling

tokenizer.pad_token = tokenizer.eos_token
data_collator = DataCollatorForLanguageModeling(tokenizer, mlm=False, return_tensors="tf")
```

{/if}

ဥပမာတစ်ခု ကြည့်ရအောင်...

```py
out = data_collator([tokenized_datasets["train"][i] for i in range(5)])
for key in out:
    print(f"{key} shape: {out[key].shape}")
```

{#if fw === 'pt'}

```python out
input_ids shape: torch.Size([5, 128])
attention_mask shape: torch.Size([5, 128])
labels shape: torch.Size([5, 128])
```

{:else}

```python out
input_ids shape: (5, 128)
attention_mask shape: (5, 128)
labels shape: (5, 128)
```

{/if}

examples တွေကို stacking လုပ်ထားပြီး tensors အားလုံးမှာ shape တူတူရှိတာကို တွေ့ရပါတယ်။

{#if fw === 'tf'}

အခု ကျွန်တော်တို့ ဖန်တီးခဲ့တဲ့ data collator နဲ့ datasets တွေကို TensorFlow datasets တွေအဖြစ် ပြောင်းလဲဖို့ `prepare_tf_dataset()` method ကို အသုံးပြုနိုင်ပါပြီ။

```python
tf_train_dataset = model.prepare_tf_dataset(
    tokenized_datasets["train"],
    collate_fn=data_collator,
    shuffle=True,
    batch_size=32,
)
tf_eval_dataset = model.prepare_tf_dataset(
    tokenized_datasets["valid"],
    collate_fn=data_collator,
    shuffle=False,
    batch_size=32,
)
```

{/if}

> [!WARNING]
> ⚠️ inputs တွေနဲ့ labels တွေကို ချိန်ညှိဖို့ ရွှေ့ပြောင်းတာက model ထဲမှာ ဖြစ်ပေါ်ပါတယ်၊ ဒါကြောင့် data collator က inputs တွေကို labels တွေဖန်တီးဖို့ ကူးယူရုံပါပဲ။

အခု ကျွန်တော်တို့ model ကို train လုပ်ဖို့ အရာအားလုံး အဆင်သင့်ဖြစ်ပါပြီ — ဒီလောက်အလုပ်အများကြီး မဟုတ်ပါလား! training မစတင်ခင် Hugging Face ကို login ဝင်သင့်ပါတယ်။ သင် notebook မှာ အလုပ်လုပ်နေတယ်ဆိုရင်၊ အောက်ပါ utility function နဲ့ လုပ်နိုင်ပါတယ်။

```python
from huggingface_hub import notebook_login

notebook_login()
```

ဒါက သင် Hugging Face login credentials တွေ ထည့်သွင်းနိုင်မယ့် widget တစ်ခုကို ပြသပေးပါလိမ့်မယ်။

သင် notebook မှာ အလုပ်မလုပ်ဘူးဆိုရင်၊ သင့် terminal မှာ အောက်ပါစာကြောင်းကို ရိုက်ထည့်လိုက်ပါ။

```bash
huggingface-cli login
```

{#if fw === 'pt'}

ကျန်ရှိတာက training arguments တွေကို configure လုပ်ပြီး `Trainer` ကို စတင်ဖို့ပါပဲ။ warmup နဲ့ 256 (`per_device_train_batch_size` * `gradient_accumulation_steps`) ရဲ့ effective batch size နဲ့ cosine learning rate schedule ကို ကျွန်တော်တို့ အသုံးပြုပါမယ်။ gradient accumulation က single batch တစ်ခု memory ထဲ မဆံ့တဲ့အခါ အသုံးပြုပြီး၊ forward/backward passes များစွာကနေ gradient ကို တဖြည်းဖြည်း တည်ဆောက်ပါတယ်။ 🤗 Accelerate နဲ့ training loop ကို ဖန်တီးတဲ့အခါ ဒါကို လက်တွေ့ မြင်တွေ့ရပါလိမ့်မယ်။

```py
from transformers import Trainer, TrainingArguments

args = TrainingArguments(
    output_dir="codeparrot-ds",
    per_device_train_batch_size=32,
    per_device_eval_batch_size=32,
    evaluation_strategy="steps",
    eval_steps=5_000,
    logging_steps=5_000,
    gradient_accumulation_steps=8,
    num_train_epochs=1,
    weight_decay=0.1,
    warmup_steps=1_000,
    lr_scheduler_type="cosine",
    learning_rate=5e-4,
    save_steps=5_000,
    fp16=True,
    push_to_hub=True,
)

trainer = Trainer(
    model=model,
    tokenizer=tokenizer,
    args=args,
    data_collator=data_collator,
    train_dataset=tokenized_datasets["train"],
    eval_dataset=tokenized_datasets["valid"],
)
```

အခု ကျွန်တော်တို့ `Trainer` ကို စတင်ပြီး training ပြီးဆုံးဖို့ စောင့်ဆိုင်းနိုင်ပါပြီ။ ဒါကို training set အပြည့်အစုံ ဒါမှမဟုတ် subset တစ်ခုပေါ်မှာ run ခြင်းပေါ်မူတည်ပြီး ၂၀ နာရီ ဒါမှမဟုတ် ၂ နာရီ အသီးသီး ကြာမြင့်ပါလိမ့်မယ်၊ ဒါကြောင့် ကော်ဖီအချို့နဲ့ ဖတ်ဖို့ ကောင်းမွန်တဲ့ စာအုပ်တစ်အုပ် ယူထားပါ။

```py
trainer.train()
```

training ပြီးဆုံးသွားပြီးနောက်၊ model နဲ့ tokenizer ကို Hub သို့ push လုပ်နိုင်ပါတယ်။

```py
trainer.push_to_hub()
```

{:else}

ကျန်ရှိတာက training hyperparameters တွေကို configure လုပ်ပြီး `compile()` နဲ့ `fit()` ကို ခေါ်ဖို့ပါပဲ။ training ရဲ့ stability ကို တိုးတက်စေဖို့အတွက် warmup အချို့နဲ့ learning rate schedule ကို အသုံးပြုပါမယ်။

```py
from transformers import create_optimizer
import tensorflow as tf

num_train_steps = len(tf_train_dataset)
optimizer, schedule = create_optimizer(
    init_lr=5e-5,
    num_warmup_steps=1_000,
    num_train_steps=num_train_steps,
    weight_decay_rate=0.01,
)
model.compile(optimizer=optimizer)

# Train in mixed-precision float16
tf.keras.mixed_precision.set_global_policy("mixed_float16")
```

အခု ကျွန်တော်တို့ `model.fit()` ကို ခေါ်ပြီး training ပြီးဆုံးဖို့ စောင့်ဆိုင်းနိုင်ပါပြီ။ ဒါကို training set အပြည့်အစုံ ဒါမှမဟုတ် subset တစ်ခုပေါ်မှာ run ခြင်းပေါ်မူတည်ပြီး ၂၀ နာရီ ဒါမှမဟုတ် ၂ နာရီ အသီးသီး ကြာမြင့်ပါလိမ့်မယ်၊ ဒါကြောင့် ကော်ဖီအချို့နဲ့ ဖတ်ဖို့ ကောင်းမွန်တဲ့ စာအုပ်တစ်အုပ် ယူထားပါ။ training ပြီးဆုံးသွားပြီးနောက် model နဲ့ tokenizer ကို Hub သို့ push လုပ်နိုင်ပါတယ်။

```py
from transformers.keras_callbacks import PushToHubCallback

callback = PushToHubCallback(output_dir="codeparrot-ds", tokenizer=tokenizer)

model.fit(tf_train_dataset, validation_data=tf_eval_dataset, callbacks=[callback])
```

{/if}

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** GPT-2 ကို raw texts ကနေ train လုပ်ဖို့ `TrainingArguments` အပြင် code လိုင်း ၃၀ ခန့်ပဲ ကျွန်တော်တို့ အသုံးပြုခဲ့ရပါတယ်။ သင့်ကိုယ်ပိုင် dataset နဲ့ စမ်းသပ်ကြည့်ပြီး ကောင်းမွန်တဲ့ ရလဒ်တွေ ရမရ ကြည့်ပါ။

> [!TIP]
> {#if fw === 'pt'}
>
> 💡 သင့်မှာ multiple GPUs ပါတဲ့ machine တစ်ခုရှိရင်၊ အဲဒီမှာ code ကို run ကြည့်ပါ။ `Trainer` က multiple machines တွေကို အလိုအလျောက် စီမံခန့်ခွဲပေးပြီး၊ ဒါက training ကို အလွန်အမင်း မြန်ဆန်စေနိုင်ပါတယ်။
>
> {:else}
>
> 💡 သင့်မှာ multiple GPUs ပါတဲ့ machine တစ်ခုရှိရင်၊ training ကို သိသိသာသာ အရှိန်မြှင့်ဖို့ `MirroredStrategy` context ကို အသုံးပြုကြည့်နိုင်ပါတယ်။ သင်ဟာ `tf.distribute.MirroredStrategy` object တစ်ခုကို ဖန်တီးဖို့ လိုအပ်ပါလိမ့်မယ်၊ ပြီးတော့ `to_tf_dataset()` ဒါမှမဟုတ် `prepare_tf_dataset()` methods တွေအပြင် model creation နဲ့ `fit()` ကို ခေါ်တာတွေ အားလုံးက ၎င်းရဲ့ `scope()` context ထဲမှာ run နေကြောင်း သေချာပါစေ။ ဒီအကြောင်းကို [ဒီနေရာမှာ](https://www.tensorflow.org/guide/distributed_training#use_tfdistributestrategy_with_keras_modelfit) မှတ်တမ်းကို ကြည့်နိုင်ပါတယ်။
>
> {/if}

## Pipeline ဖြင့် Code Generation[[code-generation-with-a-pipeline]]

အခုကတော့ အမှန်တရားရဲ့အချိန်ပါပဲ။ train လုပ်ထားတဲ့ model က ဘယ်လောက်ကောင်းကောင်း အလုပ်လုပ်လဲ ကြည့်ရအောင်။ loss က တသမတ်တည်း ကျဆင်းသွားတာကို logs တွေမှာ ကျွန်တော်တို့ မြင်နိုင်ပါတယ်၊ ဒါပေမယ့် model ကို စမ်းသပ်ဖို့ prompts အချို့မှာ ဘယ်လောက်ကောင်းကောင်း အလုပ်လုပ်လဲ ကြည့်ရအောင်။ ဒါကိုလုပ်ဖို့ model ကို text generation `pipeline` တစ်ခုထဲမှာ ထည့်သွင်းပါမယ်၊ ပြီးတော့ မြန်ဆန်တဲ့ generation တွေအတွက် GPU တစ်ခုရှိရင် GPU ပေါ်မှာ ထားပါမယ်။

{#if fw === 'pt'}

```py
import torch
from transformers import pipeline

device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")
pipe = pipeline(
    "text-generation", model="huggingface-course/codeparrot-ds", device=device
)
```

{:else}

```py
from transformers import pipeline

course_model = TFGPT2LMHeadModel.from_pretrained("huggingface-course/codeparrot-ds")
course_tokenizer = AutoTokenizer.from_pretrained("huggingface-course/codeparrot-ds")
pipe = pipeline(
    "text-generation", model=course_model, tokenizer=course_tokenizer, device=0
)
```

{/if}

scatter plot တစ်ခု ဖန်တီးတဲ့ ရိုးရှင်းတဲ့ task နဲ့ စတင်ကြရအောင်။

```py
txt = """\
# create some data
x = np.random.randn(100)
y = np.random.randn(100)

# create scatter plot with x, y
"""
print(pipe(txt, num_return_sequences=1)[0]["generated_text"])
```

```python out
# create some data
x = np.random.randn(100)
y = np.random.randn(100)

# create scatter plot with x, y
plt.scatter(x, y)

# create scatter
```

ရလဒ်က မှန်ကန်ပုံရပါတယ်။ `pandas` operation တစ်ခုအတွက်လည်း အလုပ်လုပ်သလား။ arrays နှစ်ခုကနေ `DataFrame` တစ်ခု ဖန်တီးနိုင်မလား ကြည့်ရအောင်။

```py
txt = """\
# create some data
x = np.random.randn(100)
y = np.random.randn(100)

# create dataframe from x and y
"""
print(pipe(txt, num_return_sequences=1)[0]["generated_text"])
```

```python out
# create some data
x = np.random.randn(100)
y = np.random.randn(100)

# create dataframe from x and y
df = pd.DataFrame({'x': x, 'y': y})
df.insert(0,'x', x)
for
```

ကောင်းပါပြီ၊ ဒါက မှန်ကန်တဲ့ အဖြေပါ — ဒါပေမယ့် နောက်မှ column `x` ကို ထပ်ထည့်ပြန်ပါတယ်။ generate လုပ်တဲ့ tokens အရေအတွက် ကန့်သတ်ထားတာကြောင့်၊ အောက်ပါ `for` loop က ဖြတ်တောက်ခံထားရပါတယ်။ နည်းနည်းပိုရှုပ်ထွေးတဲ့အရာတစ်ခု လုပ်နိုင်မလား၊ `groupby` operation ကို အသုံးပြုရာမှာ model က ကျွန်တော်တို့ကို ကူညီနိုင်မလား ကြည့်ရအောင်။

```py
txt = """\
# dataframe with profession, income and name
df = pd.DataFrame({'profession': x, 'income':y, 'name': z})

# calculate the mean income per profession
"""
print(pipe(txt, num_return_sequences=1)[0]["generated_text"])
```

```python out
# dataframe with profession, income and name
df = pd.DataFrame({'profession': x, 'income':y, 'name': z})

# calculate the mean income per profession
profession = df.groupby(['profession']).mean()

# compute the
```

မဆိုးပါဘူး၊ ဒါက မှန်ကန်တဲ့နည်းလမ်းပါပဲ။ နောက်ဆုံးအနေနဲ့ `scikit-learn` အတွက်လည်း အသုံးပြုနိုင်မလား၊ Random Forest model တစ်ခုကို တည်ဆောက်နိုင်မလား ကြည့်ရအောင်-

```py
txt = """
# import random forest regressor from scikit-learn
from sklearn.ensemble import RandomForestRegressor

# fit random forest model with 300 estimators on X, y:
"""
print(pipe(txt, num_return_sequences=1)[0]["generated_text"])
```

```python out
# import random forest regressor from scikit-learn
from sklearn.ensemble import RandomForestRegressor

# fit random forest model with 300 estimators on X, y:
rf = RandomForestRegressor(n_estimators=300, random_state=random_state, max_depth=3)
rf.fit(X, y)
rf
```

{#if fw === 'tf'}

ဒီဥပမာအချို့ကို ကြည့်ရတာ၊ model ဟာ Python data science stack ရဲ့ syntax အချို့ကို သင်ယူခဲ့ပုံရပါတယ်။ Oof course, လက်တွေ့ကမ္ဘာမှာ deploy မလုပ်ခင် model ကို ပိုမိုစေ့စပ်သေချာစွာ evaluation လုပ်ဖို့ လိုအပ်ပါလိမ့်မယ်၊ ဒါပေမယ့် ဒါကတော့ အထင်ကြီးစရာ prototype တစ်ခုပါပဲ။

{:else}

ဒီဥပမာအချို့ကို ကြည့်ရတာ၊ model ဟာ Python data science stack ရဲ့ syntax အချို့ကို သင်ယူခဲ့ပုံရပါတယ်။ (Oof course, လက်တွေ့ကမ္ဘာမှာ deploy မလုပ်ခင် model ကို ပိုမိုစေ့စပ်သေချာစွာ evaluation လုပ်ဖို့ လိုအပ်ပါလိမ့်မယ်)။ သို့သော်လည်း၊ ပေးထားတဲ့ use case တစ်ခုအတွက် လိုအပ်တဲ့ performance ကို ရရှိဖို့အတွက် model training ကို ပိုမို customize လုပ်ဖို့ လိုအပ်တာတွေလည်း ရှိပါတယ်။ ဥပမာ၊ batch size ကို dynamically update လုပ်ချင်ရင် ဒါမှမဟုတ် bad examples တွေကို on the fly မှာ ကျော်သွားမယ့် conditional training loop တစ်ခုရှိချင်ရင် ဘယ်လိုလုပ်မလဲ။ နည်းလမ်းတစ်ခုကတော့ `Trainer` ကို subclass လုပ်ပြီး လိုအပ်တဲ့ ပြောင်းလဲမှုတွေကို ထည့်သွင်းတာပါပဲ၊ ဒါပေမယ့် တခါတလေ training loop ကို အစကနေ ရေးတာက ပိုရိုးရှင်းပါတယ်။ အဲဒီနေရာမှာ 🤗 Accelerate က ဝင်လာတာပါ။

{/if}

{#if fw === 'pt'}

## 🤗 Accelerate ဖြင့် Training[[training-with-accelerate]]

`Trainer` နဲ့ model တစ်ခုကို ဘယ်လို train လုပ်ရမယ်ဆိုတာ ကျွန်တော်တို့ မြင်ခဲ့ရပြီးပါပြီ၊ ဒါက customization အချို့ကို ခွင့်ပြုနိုင်ပါတယ်။ သို့သော်လည်း၊ တခါတလေ ကျွန်တော်တို့ training loop အပေါ် အပြည့်အဝ ထိန်းချုပ်ချင်တာ ဒါမှမဟုတ် ထူးခြားဆန်းကြယ်တဲ့ ပြောင်းလဲမှုအချို့ လုပ်ချင်ပါတယ်။ ဒီလိုကိစ္စမှာ 🤗 Accelerate က အကောင်းဆုံးရွေးချယ်မှုဖြစ်ပြီး၊ ဒီအပိုင်းမှာ ကျွန်တော်တို့ရဲ့ model ကို train လုပ်ဖို့အတွက် အသုံးပြုဖို့ အဆင့်တွေကို ကျွန်တော်တို့ ဖော်ပြပေးပါမယ်။ ပိုစိတ်ဝင်စားဖို့ကောင်းအောင်၊ training loop ကို twist တစ်ခုလည်း ထည့်သွင်းပါမယ်။

ကျွန်တော်တို့ဟာ data science libraries တွေအတွက် သဘာဝကျတဲ့ autocompletion ကို အဓိက စိတ်ဝင်စားတာကြောင့်၊ ဒီ libraries တွေကို ပိုအသုံးပြုတဲ့ training samples တွေကို ပိုအလေးထားဖို့ အဓိပ္ပာယ်ရှိပါတယ်။ `plt`, `pd`, `sk`, `fit`, နဲ့ `predict` လို keywords တွေကို အသုံးပြုခြင်းဖြင့် ဒီ examples တွေကို အလွယ်တကူ ဖော်ထုတ်နိုင်ပါတယ်။ ဒါတွေက `matplotlib.pyplot`, `pandas`, နဲ့ `sklearn` အတွက် အသုံးများဆုံး import names တွေအပြင် နောက်ဆုံးနှစ်ခုရဲ့ fit/predict pattern လည်း ဖြစ်ပါတယ်။ ဒါတွေကို token တစ်ခုစီအဖြစ် ကိုယ်စားပြုထားရင်၊ ၎င်းတို့ input sequence မှာ ပါဝင်ခြင်းရှိမရှိ အလွယ်တကူ စစ်ဆေးနိုင်ပါတယ်။ Tokens တွေမှာ whitespace prefix ရှိနိုင်တာကြောင့်၊ tokenizer vocabulary ထဲက အဲဒီ versions တွေကိုလည်း စစ်ဆေးပါမယ်။ ဒါက အလုပ်လုပ်မလုပ် စစ်ဆေးဖို့အတွက်၊ multiple tokens အဖြစ် ခွဲခြားသင့်တဲ့ test token တစ်ခု ထည့်ပါမယ်။

```py
keytoken_ids = []
for keyword in [
    "plt",
    "pd",
    "sk",
    "fit",
    "predict",
    " plt",
    " pd",
    " sk",
    " fit",
    " predict",
    "testtest",
]:
    ids = tokenizer([keyword]).input_ids[0]
    if len(ids) == 1:
        keytoken_ids.append(ids[0])
    else:
        print(f"Keyword has not single token: {keyword}")
```

```python out
'Keyword has not single token: testtest'
```

ကောင်းပါပြီ၊ ဒါက ကောင်းကောင်းအလုပ်လုပ်ပုံရပါတယ်။ အခု input sequence၊ logits နဲ့ ကျွန်တော်တို့ ရွေးချယ်ခဲ့တဲ့ key tokens တွေကို inputs အဖြစ် ယူတဲ့ custom loss function တစ်ခု ရေးနိုင်ပါပြီ။ ပထမဆုံး logits နဲ့ inputs တွေကို ချိန်ညှိဖို့ လိုပါတယ်- input sequence ကို တစ်ခုညာဘက်သို့ ရွှေ့ထားတာက labels တွေ ဖြစ်လာပါတယ်၊ ဘာလို့လဲဆိုတော့ နောက်ဆုံး token က လက်ရှိ token အတွက် label ဖြစ်လို့ပါ။ model က ပထမဆုံး token အတွက် prediction မလုပ်တာကြောင့် input sequence ရဲ့ ဒုတိယ token ကနေ labels တွေကို စတင်ခြင်းဖြင့် ဒါကို ကျွန်တော်တို့ အောင်မြင်နိုင်ပါတယ်။ ပြီးရင် နောက်ဆုံး logit ကို ဖြတ်ပစ်ပါမယ်၊ ဘာလို့လဲဆိုတော့ full input sequence နောက်က လိုက်လာမယ့် token အတွက် label မရှိလို့ပါပဲ။ ဒါတွေနဲ့ sample တစ်ခုစီရဲ့ loss ကို တွက်ချက်နိုင်ပြီး sample တစ်ခုစီမှာရှိတဲ့ keywords တွေရဲ့ ဖြစ်ပေါ်မှုတွေကို ရေတွက်နိုင်ပါတယ်။ နောက်ဆုံးအနေနဲ့၊ ဖြစ်ပေါ်မှုတွေကို weights အဖြစ် အသုံးပြုပြီး samples အားလုံးရဲ့ weighted average ကို တွက်ချက်ပါတယ်။ keywords မရှိတဲ့ samples တွေအားလုံးကို ဖယ်ရှားပစ်ဖို့ မလိုတာကြောင့်၊ weights တွေမှာ ၁ ကို ပေါင်းထည့်ပါတယ်။

```py
from torch.nn import CrossEntropyLoss
import torch

def keytoken_weighted_loss(inputs, logits, keytoken_ids, alpha=1.0):
    # Shift so that tokens  [!TIP]
> 🚨 သင် TPU ပေါ်မှာ train လုပ်နေတယ်ဆိုရင်၊ အပေါ်က cell ကနေ စတင်တဲ့ code အားလုံးကို dedicated training function တစ်ခုထဲကို ရွှေ့ဖို့ လိုအပ်ပါလိမ့်မယ်။ အသေးစိတ်အချက်အလက်တွေအတွက် [Chapter 3](/course/chapter3) ကို ကြည့်ပါ။

ကျွန်တော်တို့ `train_dataloader` ကို `accelerator.prepare()` သို့ ပေးပို့ပြီးတာနဲ့၊ ၎င်းရဲ့ length ကို အသုံးပြုပြီး training steps အရေအတွက်ကို တွက်ချက်နိုင်ပါပြီ။ အဲဒီ method က ၎င်းရဲ့ length ကို ပြောင်းလဲမှာ ဖြစ်တာကြောင့် dataloader ကို ပြင်ဆင်ပြီးနောက် ဒါကို အမြဲလုပ်ဆောင်သင့်တယ်ဆိုတာ မှတ်သားပါ။ learning rate ကနေ ၀ အထိ classic linear schedule ကို ကျွန်တော်တို့ အသုံးပြုပါတယ်။

```py
from transformers import get_scheduler

num_train_epochs = 1
num_update_steps_per_epoch = len(train_dataloader)
num_training_steps = num_train_epochs * num_update_steps_per_epoch

lr_scheduler = get_scheduler(
    name="linear",
    optimizer=optimizer,
    num_warmup_steps=1_000,
    num_training_steps=num_training_steps,
)
```

နောက်ဆုံးအနေနဲ့၊ ကျွန်တော်တို့ model ကို Hub ကို push လုပ်ဖို့အတွက်၊ working folder တစ်ခုထဲမှာ `Repository` object တစ်ခု ဖန်တီးဖို့ လိုအပ်ပါလိမ့်မယ်။ ပထမဆုံး Hugging Face Hub ကို login ဝင်ပါ၊ အကယ်၍ သင် login ဝင်ထားခြင်းမရှိသေးရင်ပေါ့။ ကျွန်တော်တို့ရဲ့ model ကို ပေးချင်တဲ့ model ID ကနေ repository name ကို ကျွန်တော်တို့ ဆုံးဖြတ်ပါမယ် (သင် `repo_name` ကို သင့်ကိုယ်ပိုင် ရွေးချယ်မှုနဲ့ အစားထိုးနိုင်ပါတယ်၊ ဒါက သင့် username ကို ပါဝင်ဖို့ပဲ လိုအပ်ပြီး၊ ဒါက `get_full_repo_name()` function က လုပ်ဆောင်တာပါ)။

```py
from huggingface_hub import Repository, get_full_repo_name

model_name = "codeparrot-ds-accelerate"
repo_name = get_full_repo_name(model_name)
repo_name
```

```python out
'sgugger/codeparrot-ds-accelerate'
```

ပြီးရင် အဲဒီ repository ကို local folder တစ်ခုထဲမှာ clone လုပ်နိုင်ပါတယ်။ အကယ်၍ ဒါက ရှိပြီးသားဆိုရင်၊ ဒီ local folder က ကျွန်တော်တို့ အလုပ်လုပ်နေတဲ့ repository ရဲ့ ရှိပြီးသား clone တစ်ခု ဖြစ်သင့်ပါတယ်။

```py
output_dir = "codeparrot-ds-accelerate"
repo = Repository(output_dir, clone_from=repo_name)
```

အခု ကျွန်တော်တို့ `repo.push_to_hub()` method ကို ခေါ်ခြင်းဖြင့် `output_dir` မှာ သိမ်းဆည်းထားတဲ့ ဘယ်အရာကိုမဆို upload လုပ်နိုင်ပါပြီ။ ဒါက epoch တစ်ခုစီရဲ့ အဆုံးမှာ intermediate models တွေကို upload လုပ်ဖို့ ကူညီပေးပါလိမ့်မယ်။

training မလုပ်ခင်၊ evaluation function မှန်ကန်စွာ အလုပ်လုပ်မလုပ် စစ်ဆေးဖို့ quick test တစ်ခု run ကြရအောင်။

```py
evaluate()
```

```python out
(10.934126853942871, 56057.14453125)
```

ဒါတွေက loss နဲ့ perplexity အတွက် အလွန်မြင့်မားတဲ့ တန်ဖိုးတွေဖြစ်ပေမယ့်၊ model ကို မtrain ရသေးတာကြောင့် အံ့သြစရာ မဟုတ်ပါဘူး။ ဒါတွေနဲ့ training script ရဲ့ core အပိုင်းဖြစ်တဲ့ training loop ကို ရေးဖို့ အရာအားလုံး အဆင်သင့်ဖြစ်ပါပြီ။ training loop ထဲမှာ ကျွန်တော်တို့ dataloader ကို iterate လုပ်ပြီး batches တွေကို model ကို ပေးပို့ပါတယ်။ logits တွေနဲ့၊ ကျွန်တော်တို့ရဲ့ custom loss function ကို evaluate လုပ်နိုင်ပါတယ်။ gradient accumulation steps အရေအတွက်နဲ့ loss ကို scale လုပ်ပါတယ်၊ ဒါမှ steps တွေ ပိုများများ aggregate လုပ်တဲ့အခါ losses တွေ ပိုကြီးလာတာ မဖြစ်အောင်လို့ပါ။ optimize မလုပ်ခင်၊ ပိုမိုကောင်းမွန်တဲ့ convergence အတွက် gradients တွေကို clip လုပ်ပါတယ်။ နောက်ဆုံးအနေနဲ့၊ steps အနည်းငယ်တိုင်းမှာ evaluation set ပေါ်မှာ model ကို ကျွန်တော်တို့ရဲ့ `evaluate()` function အသစ်နဲ့ evaluate လုပ်ပါတယ်။

```py
from tqdm.notebook import tqdm

gradient_accumulation_steps = 8
eval_steps = 5_000

model.train()
completed_steps = 0
for epoch in range(num_train_epochs):
    for step, batch in tqdm(
        enumerate(train_dataloader, start=1), total=num_training_steps
    ):
        logits = model(batch["input_ids"]).logits
        loss = keytoken_weighted_loss(batch["input_ids"], logits, keytoken_ids)
        if step % 100 == 0:
            accelerator.print(
                {
                    "samples": step * samples_per_step,
                    "steps": completed_steps,
                    "loss/train": loss.item() * gradient_accumulation_steps,
                }
            )
        loss = loss / gradient_accumulation_steps
        accelerator.backward(loss)
        if step % gradient_accumulation_steps == 0:
            accelerator.clip_grad_norm_(model.parameters(), 1.0)
            optimizer.step()
            lr_scheduler.step()
            optimizer.zero_grad()
            completed_steps += 1
        if (step % (eval_steps * gradient_accumulation_steps)) == 0:
            eval_loss, perplexity = evaluate()
            accelerator.print({"loss/eval": eval_loss, "perplexity": perplexity})
            model.train()
            accelerator.wait_for_everyone()
            unwrapped_model = accelerator.unwrap_model(model)
            unwrapped_model.save_pretrained(output_dir, save_function=accelerator.save)
            if accelerator.is_main_process:
                tokenizer.save_pretrained(output_dir)
                repo.push_to_hub(
                    commit_message=f"Training in progress step {step}", blocking=False
                )
```

ပြီးပါပြီ။ အခု သင်ကိုယ်ပိုင် causal language models တွေဖြစ်တဲ့ GPT-2 လို models တွေအတွက် custom training loop တစ်ခု ရရှိခဲ့ပါပြီ၊ ဒါကို သင့်လိုအပ်ချက်တွေအတိုင်း ထပ်မံ customize လုပ်နိုင်ပါတယ်။

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** သင့် use case နဲ့ ကိုက်ညီတဲ့ သင့်ကိုယ်ပိုင် custom loss function တစ်ခု ဖန်တီးပါ၊ ဒါမှမဟုတ် training loop ထဲကို အခြား custom step တစ်ခု ထည့်ပါ။

> [!TIP]
> ✏️ **စမ်းသပ်ကြည့်ပါ။** training experiments တွေကို အကြာကြီး run တဲ့အခါ TensorBoard ဒါမှမဟုတ် Weights & Biases လို tools တွေကို အသုံးပြုပြီး အရေးကြီးတဲ့ metrics တွေကို log လုပ်တာက ကောင်းမွန်တဲ့ အကြံဥာဏ်တစ်ခုပါ။ training ဘယ်လိုသွားနေလဲဆိုတာ အမြဲစစ်ဆေးနိုင်ဖို့ training loop ထဲကို သင့်လျော်တဲ့ logging ကို ထည့်ပါ။

{/if}

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

*   **Causal Language Model**: စာသား sequence တစ်ခုရှိ token တစ်ခုစီ၏ နောက်ဆက်တွဲ token ကို ခန့်မှန်းရန် လေ့ကျင့်ထားသော language model အမျိုးအစား။ ၎င်းသည် auto-regressive model တစ်ခုဖြစ်ပြီး GPT-2, GPT-3 ကဲ့သို့ models တွေမှာ အသုံးပြုသည်။
*   **From Scratch**: Model (သို့မဟုတ် tokenizer) တစ်ခုကို မည်သည့် အစောပိုင်းလေ့ကျင့်မှုမျှ မရှိဘဲ လုံးဝအသစ်ကနေ စတင်တည်ဆောက်ခြင်းနှင့် လေ့ကျင့်ခြင်း။
*   **Pretrained Models**: အကြီးစား ဒေတာအမြောက်အမြားဖြင့် ကြိုတင်လေ့ကျင့်ထားပြီးဖြစ်သော AI (Artificial Intelligence) မော်ဒယ်။
*   **Fine-tuning**: ကြိုတင်လေ့ကျင့်ထားပြီးသား (pre-trained) မော်ဒယ်တစ်ခုကို သီးခြားလုပ်ငန်းတစ်ခု (specific task) အတွက် အနည်းငယ်သော ဒေတာနဲ့ ထပ်မံလေ့ကျင့်ပေးခြင်း။
*   **Weights**: Neural network model တစ်ခု၏ layers များကြားရှိ ဆက်သွယ်မှုများ၏ အားသာချက်များကို ကိုယ်စားပြုသော တန်ဖိုးများ။
*   **Pretraining**: Model ကို large-scale datasets များဖြင့် အစောပိုင်းလေ့ကျင့်ခြင်း လုပ်ငန်းစဉ်။
*   **Transfer Learning**: ကြိုတင်လေ့ကျင့်ထားသော model တစ်ခုမှ သင်ယူထားသော ဗဟုသုတများကို အခြားဆက်စပ်လုပ်ငန်းတစ်ခုသို့ လွှဲပြောင်းအသုံးပြုခြင်း။
*   **Transformer Models**: Natural Language Processing (NLP) မှာ အောင်မြင်မှုများစွာရရှိခဲ့တဲ့ deep learning architecture တစ်မျိုးပါ။
*   **Labeled Data**: အဖြေမှန်များ သို့မဟုတ် categories များနှင့် သက်ဆိုင်သော labels များ ပါဝင်သော data။
*   **Sparse (Data)**: အချက်အလက်နည်းပါးသော သို့မဟုတ် ပြည့်စုံမှုမရှိသော ဒေတာ။
*   **Compute Resources**: AI/ML models များကို လေ့ကျင့်ရန်နှင့် အသုံးပြုရန်အတွက် လိုအပ်သော ကွန်ပျူတာစွမ်းအား (ဥပမာ- CPUs, GPUs, TPUs)။
*   **Language Model**: လူသားဘာသာစကား၏ ဖြန့်ဝေမှုကို နားလည်ရန် လေ့ကျင့်ထားသော AI မော်ဒယ်တစ်ခု။
*   **Musical Notes**: ဂီတသံစဉ်များကို ကိုယ်စားပြုသော သင်္ကေတများ။
*   **Molecular Sequences**: DNA သို့မဟုတ် ပရိုတင်းများကဲ့သို့ မော်လီကျူးဖွဲ့စည်းပုံများ၏ အစီအစဉ်များ။
*   **Programming Languages**: ကွန်ပျူတာပရိုဂရမ်များကို ရေးသားရန်အတွက် အသုံးပြုသော ဘာသာစကားများ။
*   **TabNine**: AI-powered code completion tool။
*   **GitHub Copilot**: OpenAI ၏ Codex model က ပံ့ပိုးပေးသော AI-powered code completion tool။
*   **OpenAI Codex Model**: OpenAI မှ code generation အတွက် လေ့ကျင့်ထားသော LLM။
*   **Text Generation**: AI မော်ဒယ်များကို အသုံးပြု၍ လူသားကဲ့သို့သော စာသားအသစ်များ ဖန်တီးခြင်း။
*   **Auto-regressive Models**: input sequence ၏ ယခင် tokens များပေါ်တွင် အခြေခံပြီး နောက်ဆက်တွဲ token များကို တစ်ခုပြီးတစ်ခု ခန့်မှန်းသော model များ။
*   **GPT-2**: OpenAI မှ ထုတ်လုပ်ထားသော Transformer-based causal language model။
*   **Scaled-down Version**: မူရင်းစနစ် သို့မဟုတ် model ၏ အရွယ်အစား သို့မဟုတ် စွမ်းဆောင်ရည်ကို လျှော့ချထားသော version။
*   **One-line Completions**: code ၏ တစ်ကြောင်းတည်းသော အပိုင်းများကို အလိုအလျောက် ဖြည့်စွက်ပေးခြင်း။
*   **Python Code**: Python programming language ဖြင့် ရေးသားထားသော code များ။
*   **Python Data Science Stack**: Python တွင် data science လုပ်ငန်းများအတွက် အသုံးပြုသော libraries များ (ဥပမာ- matplotlib, seaborn, pandas, scikit-learn)။
*   **`matplotlib`**: Python အတွက် plotting library။
*   **`seaborn`**: `matplotlib` ပေါ်တွင် အခြေခံထားသော data visualization library။
*   **`pandas`**: Python အတွက် data analysis library။
*   **`scikit-learn`**: Python အတွက် machine learning library။
*   **Tokenizer**: စာသား (သို့မဟုတ် အခြားဒေတာ) ကို AI မော်ဒယ်များ စီမံဆောင်ရွက်နိုင်ရန် tokens တွေအဖြစ် ပိုင်းခြားပေးသည့် ကိရိယာ သို့မဟုတ် လုပ်ငန်းစဉ်။
*   **Large-scale Dataset**: အရွယ်အစား ကြီးမားသော dataset။
*   **Corpus of Python Code**: Python code များစွာ ပါဝင်သော စာသားအစုအဝေး။
*   **GitHub Repositories**: Git version control system ကို အသုံးပြု၍ code များကို သိမ်းဆည်းထားသော online repository များ။
*   **`Trainer` API**: Hugging Face Transformers library မှ model များကို ထိရောက်စွာ လေ့ကျင့်ရန်အတွက် ဒီဇိုင်းထုတ်ထားသော မြင့်မားသောအဆင့် API။
*   **🤗 Accelerate**: Hugging Face က ထုတ်လုပ်ထားတဲ့ library တစ်ခုဖြစ်ပြီး PyTorch code တွေကို မတူညီတဲ့ training environment (ဥပမာ - GPU အများအပြား၊ distributed training) တွေမှာ အလွယ်တကူ run နိုင်အောင် ကူညီပေးပါတယ်။
*   **Gradio App**: Gradio library ကို အသုံးပြုပြီး တည်ဆောက်ထားသော machine learning model ၏ web demo။
*   **Model Hub**: Hugging Face Hub ကို ရည်ညွှန်းပြီး AI မော်ဒယ်များ ရှာဖွေ၊ မျှဝေ၊ အသုံးပြုနိုင်သော ဗဟို platform။
*   **Scraping**: ဝဘ်ဆိုဒ်များမှ အချက်အလက်များကို အလိုအလျောက် ထုတ်ယူခြင်း။
*   **GitHub Dump**: GitHub repositories များမှ data များကို စုဆောင်းထားသော အစုံလိုက် (bulk) ဒေတာ။
*   **`codeparrot`**: GitHub မှ Python code များဖြင့် ဖွဲ့စည်းထားသော dataset။
*   **Streaming Feature**: Dataset တစ်ခုလုံးကို memory ထဲသို့ load မလုပ်ဘဲ လိုအပ်သလို အပိုင်းလိုက် stream လုပ်ခြင်း။
*   **On the Fly**: လုပ်ငန်းစဉ်တစ်ခု ဖြစ်ပေါ်နေစဉ်အတွင်း ချက်ချင်း လုပ်ဆောင်ခြင်း။
*   **Keywords**: စာသားတစ်ခု၏ အဓိကအချက်အလက်ကို ကိုယ်စားပြုသော စကားလုံးများ။
*   **`defaultdict`**: `collections` module မှ dictionary subclass တစ်ခုဖြစ်ပြီး key တစ်ခု မရှိပါက default value တစ်ခုကို အလိုအလျောက် ဖန်တီးပေးသည်။
*   **`tqdm`**: Python library တစ်ခုဖြစ်ပြီး loops များအတွက် progress bar များကို လှပစွာ ဖော်ပြပေးသည်။
*   **`Dataset` (Hugging Face)**: 🤗 Datasets library တွင် dataset တစ်ခုကို ကိုယ်စားပြုသော class။
*   **`filter_streaming_dataset()` Function**: streaming dataset မှ အချို့သော အခြေအနေများနှင့် ကိုက်ညီသော data များကို filter လုပ်ရန် ဒီဇိုင်းထုတ်ထားသော function။
*   **`raw_datasets`**: preprocessing မလုပ်ရသေးသော dataset။
*   **Python Scripts**: Python programming language ဖြင့် ရေးသားထားသော code file များ။
*   **Pretraining the Language Model**: language model ကို ဒေတာများဖြင့် အစောပိုင်းလေ့ကျင့်ခြင်း။
*   **Training Loop**: model တစ်ခုကို လေ့ကျင့်ရန်အတွက် iterations များစွာဖြင့် လုပ်ဆောင်သော အဓိက code အပိုင်း။
*   **Model Card**: Hugging Face Hub တွင် မော်ဒယ်တစ်ခုစီအတွက် ပါရှိသော အချက်အလက်များပါသည့် စာမျက်နှာ။
*   **`content` Field**: dataset မှ code content ပါဝင်သော field။
*   **Truncating Inputs**: input sequence ၏ အရှည်ကို သတ်မှတ်ထားသော maximum length သို့ လျှော့ချခြင်း။
*   **Context Size**: model တစ်ခုက prediction ပြုလုပ်ရာတွင် ထည့်သွင်းစဉ်းစားသော input sequence ၏ အရှည် (tokens အရေအတွက်)။
*   **GPU Memory Footprint**: GPU memory ပေါ်တွင် model တစ်ခုက သိမ်းပိုက်ထားသော နေရာ။
*   **Tokens**: စာသားကို ပိုင်းခြားထားသော အသေးငယ်ဆုံးယူနစ်များ။
*   **`return_overflowing_tokens` Option**: tokenizer ကို input sequence ကို chunks များစွာအဖြစ် ပိုင်းခြားရန် ညွှန်ကြားသော option။
*   **`return_length` Option**: tokenizer ကို ဖန်တီးထားသော chunk တစ်ခုစီ၏ length ကို ပြန်ပေးရန် ညွှန်ကြားသော option။
*   **Padding Issues**: batch အတွင်းရှိ sequences များကို အရှည်တူညီအောင် ဖြည့်စွက်ရာတွင် ဖြစ်ပေါ်နိုင်သော ပြဿနာများ။
*   **`overflow_to_sample_mapping` Field**: chunk တစ်ခုစီသည် မူရင်း input sample မည်သည့်တစ်ခုနှင့် သက်ဆိုင်သည်ကို ဖော်ပြပေးသော field။
*   **`Dataset.map()` Function**: 🤗 Datasets library မှာ ပါဝင်တဲ့ method တစ်ခုဖြစ်ပြီး dataset ရဲ့ element တစ်ခုစီ ဒါမှမဟုတ် batch တစ်ခုစီပေါ်မှာ function တစ်ခုကို အသုံးပြုနိုင်စေသည်။
*   **One-to-one Maps**: input element တစ်ခုစီအတွက် output element တစ်ခုသာ ထုတ်ပေးသော mapping။
*   **Data Augmentation**: datasets ၏ အရွယ်အစားကို တိုးမြှင့်ရန်အတွက် လက်ရှိ data မှ ပြောင်းလဲထားသော မိတ္တူအသစ်များ ဖန်တီးခြင်း။
*   **Data Filtering**: dataset မှ သတ်မှတ်ထားသော အခြေအနေများနှင့် ကိုက်ညီသော data များကို ရွေးထုတ်ခြင်း။
*   **Conflicting Size**: columns များ၏ အရွယ်အစားများ မကိုက်ညီခြင်း။
*   **`remove_columns` Argument**: `Dataset.map()` method တွင် dataset မှ columns များကို ဖယ်ရှားရန် အသုံးပြုသော argument။
*   **`input_ids`**: Tokenizer မှ ထုတ်ပေးသော tokens တစ်ခုစီ၏ ထူးခြားသော ဂဏန်းဆိုင်ရာ ID များ။
*   **GPT-3**: OpenAI မှ ထုတ်လုပ်ထားသော အလွန်ကြီးမားသည့် Transformer-based causal language model။
*   **Autocomplete Function**: စာရိုက်နေစဉ် စကားလုံးများ သို့မဟုတ် code များကို အလိုအလျောက် ဖြည့်စွက်ပေးသော လုပ်ဆောင်ချက်။
*   **Context Windows**: model က prediction လုပ်ရာတွင် ထည့်သွင်းစဉ်းစားသော input ၏ အပိုင်းအစ။
*   **`eos_token_id` Token**: sequence ၏ အဆုံးကို ကိုယ်စားပြုသော end-of-sequence token ၏ ID။
*   **Concatenated Sequences**: sequences များစွာကို တစ်ခုတည်းအဖြစ် ပေါင်းစပ်ထားခြင်း။
*   **`truncation=False`**: tokenizer ကို input sequence ကို truncate မလုပ်ရန် ညွှန်ကြားခြင်း။
*   **`AutoTokenizer`**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ class တစ်ခုဖြစ်ပြီး မော်ဒယ်အမည်ကို အသုံးပြုပြီး သက်ဆိုင်ရာ tokenizer ကို အလိုအလျောက် load လုပ်ပေးသည်။
*   **`GPT2LMHeadModel`**: GPT-2 model ၏ causal language modeling head ပါဝင်သော class။
*   **`AutoConfig`**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ class တစ်ခုဖြစ်ပြီး model အမည်ကို အသုံးပြုပြီး သက်ဆိုင်ရာ configuration ကို အလိုအလျောက် load လုပ်ပေးသည်။
*   **`vocab_size`**: tokenizer ၏ vocabulary အတွင်းရှိ ထူးခြားသော tokens အရေအတွက်။
*   **`n_ctx`**: context window ၏ အများဆုံး tokens အရေအတွက် (sequence length)။
*   **`bos_token_id`**: beginning-of-sequence token ၏ ID။
*   **`eos_token_id`**: end-of-sequence token ၏ ID။
*   **`from_pretrained()` Function**: pretrained model သို့မဟုတ် tokenizer ကို load လုပ်ရန် အသုံးပြုသော function။
*   **`model.parameters()`**: model ၏ လေ့ကျင့်နိုင်သော parameters (weights နှင့် biases) များကို ပြန်ပေးသော method။
*   **Parameters (Model)**: model ၏ လုပ်ဆောင်ချက်ကို သတ်မှတ်ပေးသော အတွင်းပိုင်းတန်ဖိုးများ (weights, biases)။
*   **`TFGPT2LMHeadModel`**: TensorFlow အတွက် GPT-2 model ၏ causal language modeling head ပါဝင်သော class။
*   **`model.dummy_inputs`**: model ကို build လုပ်ရန်အတွက် အသုံးပြုသော dummy inputs များ။
*   **`model.summary()`**: TensorFlow Keras model ၏ layers များ၊ output shapes များ၊ parameter အရေအတွက်တို့ကို ဖော်ပြပေးသော method။
*   **Data Collator**: Dataloader မှ ရရှိသော samples များကို batch တစ်ခုအဖြစ် စုစည်းပေးသော function သို့မဟုတ် class။
*   **`DataCollatorForLanguageModeling`**: language modeling tasks များအတွက် batch များကို ဖန်တီးပေးရန် Hugging Face Transformers library မှ class။
*   **Stacking**: multiple tensors များကို တန်ဖိုးအသစ်တစ်ခုအဖြစ် ပေါင်းစပ်ခြင်း။
*   **Padding**: batch အတွင်းရှိ sequences များကို အရှည်တူညီအောင် ဖြည့်စွက်ခြင်း။
*   **Language Model Labels**: language model training တွင် input ၏ နောက်ဆက်တွဲ token အဖြစ် အသုံးပြုသော target labels များ။
*   **Masked Language Modeling (MLM)**: စာကြောင်းတစ်ခုထဲမှ စကားလုံးအချို့ကို ဝှက်ထားပြီး ၎င်းတို့ကို ခန့်မှန်းစေခြင်းဖြင့် model ကို လေ့ကျင့်သော task။
*   **Causal Language Modeling (CLM)**: စာကြောင်းတစ်ခု၏ နောက်ဆက်တွဲ token ကို ခန့်မှန်းခြင်းဖြင့် model ကို လေ့ကျင့်သော task။
*   **`mlm=False` Argument**: `DataCollatorForLanguageModeling` ကို causal language modeling အတွက် data ပြင်ဆင်ရန် ညွှန်ကြားသော argument။
*   **`return_tensors="tf"`**: TensorFlow tensors များကို ပြန်ပေးရန် သတ်မှတ်ခြင်း။
*   **Tensor Shapes**: tensor တစ်ခု၏ dimensions များ၏ အရွယ်အစား။
*   **`prepare_tf_dataset()` Method**: Keras model ၏ method တစ်ခုဖြစ်ပြီး 🤗 Datasets dataset ကို TensorFlow dataset သို့ ပြောင်းလဲပေးသည်။
*   **`collate_fn`**: `prepare_tf_dataset()` တွင် data collator ကို သတ်မှတ်ရန် argument။
*   **`shuffle=True`**: dataset ကို shuffle လုပ်ရန် ညွှန်ကြားခြင်း။
*   **`batch_size`**: training သို့မဟုတ် evaluation အတွက် တစ်ပြိုင်နက်တည်း လုပ်ဆောင်မည့် samples အရေအတွက်။
*   **`labels`**: model training အတွက် အဖြေမှန်များ။
*   **`huggingface_hub.notebook_login()`**: Jupyter/Colab Notebooks များတွင် Hugging Face Hub သို့ login ဝင်ရန် အသုံးပြုသော function။
*   **Widget**: Graphical User Interface (GUI) တွင် အသုံးပြုသူနှင့် အပြန်အလှန်တုံ့ပြန်နိုင်သော အစိတ်အပိုင်းများ။
*   **`huggingface-cli login`**: Hugging Face CLI (Command Line Interface) မှ Hugging Face Hub သို့ login ဝင်ရန် အသုံးပြုသော command။
*   **Training Arguments**: `Trainer` API တွင် training process ကို configure လုပ်ရန် အသုံးပြုသော parameters များ။
*   **`Trainer`**: Hugging Face Transformers library မှ model များကို လေ့ကျင့်ရန်အတွက် မြင့်မားသောအဆင့် (high-level) API။
*   **Cosine Learning Rate Schedule**: learning rate ကို cosine function ပုံစံဖြင့် အချိန်ကြာလာသည်နှင့်အမျှ လျှော့ချသော schedule။
*   **Warmup**: training အစပိုင်းတွင် learning rate ကို တဖြည်းဖြည်းတိုးမြှင့်သော နည်းလမ်း။
*   **Effective Batch Size**: `per_device_train_batch_size` ကို `gradient_accumulation_steps` ဖြင့် မြှောက်၍ ရရှိသော စုစုပေါင်း batch size။
*   **`per_device_train_batch_size`**: GPU သို့မဟုတ် TPU တစ်ခုစီတွင် training အတွက် အသုံးပြုသော batch size။
*   **`gradient_accumulation_steps`**: gradient ကို update မလုပ်ခင် gradient များကို စုဆောင်းမည့် step အရေအတွက်။
*   **Gradient Accumulation**: GPU memory ကန့်သတ်ချက်များကြောင့် batch size ကြီးကြီးမားမား အသုံးပြု၍မရသောအခါ gradient များကို batch များစွာမှ စုဆောင်းပြီး တစ်ကြိမ်တည်း update လုပ်သော နည်းလမ်း။
*   **Forward/Backward Passes**: neural network တွင် input data ကို ဖြတ်သန်းစေပြီး output ကို တွက်ချက်ခြင်း (forward pass) နှင့် loss function မှ gradient များကို တွက်ချက်ခြင်း (backward pass)။
*   **`output_dir`**: trained model, logs, checkpoints တို့ကို သိမ်းဆည်းမည့် directory။
*   **`per_device_eval_batch_size`**: GPU သို့မဟုတ် TPU တစ်ခုစီတွင် evaluation အတွက် အသုံးပြုသော batch size။
*   **`evaluation_strategy="steps"`**: သတ်မှတ်ထားသော steps အရေအတွက်အလိုက် evaluation လုပ်ရန် ညွှန်ကြားခြင်း။
*   **`eval_steps`**: evaluation လုပ်မည့် steps အရေအတွက်။
*   **`logging_steps`**: logs များကို မှတ်တမ်းတင်မည့် steps အရေအတွက်။
*   **`num_train_epochs`**: training dataset တစ်ခုလုံးဖြင့် model ကို လေ့ကျင့်မည့် အကြိမ်အရေအတွက် (epochs)။
*   **`weight_decay`**: overfitting ကို လျှော့ချရန်အတွက် model ၏ weights များကို ထိန်းချုပ်သော regularization technique။
*   **`warmup_steps`**: warmup လုပ်မည့် steps အရေအတွက်။
*   **`lr_scheduler_type="cosine"`**: learning rate scheduler အမျိုးအစားကို cosine အဖြစ် သတ်မှတ်ခြင်း။
*   **`learning_rate`**: training လုပ်ငန်းစဉ်အတွင်း model ၏ weights များကို မည်မျှပြောင်းလဲရမည်ကို ထိန်းချုပ်သော parameter။
*   **`save_steps`**: model ကို သိမ်းဆည်းမည့် steps အရေအတွက်။
*   **`fp16=True`**: training ကို float16 (half-precision) ဖြင့် လုပ်ဆောင်ရန် ညွှန်ကြားခြင်း (memory နှင့် speed ကို တိုးတက်စေသည်)။
*   **`push_to_hub=True`**: training ပြီးဆုံးပြီးနောက် model ကို Hugging Face Hub သို့ push လုပ်ရန် ညွှန်ကြားခြင်း။
*   **`eval_dataset`**: evaluation အတွက် အသုံးပြုမည့် dataset။
*   **`trainer.train()`**: `Trainer` ကို အသုံးပြု၍ model ကို train လုပ်ရန်။
*   **`trainer.push_to_hub()`**: `Trainer` ကို အသုံးပြု၍ model နှင့် tokenizer ကို Hub သို့ push လုပ်ရန်။
*   **Training Hyperparameters**: training process ကို ထိန်းချုပ်သော parameters များ (ဥပမာ- learning rate, batch size)။
*   **`compile()` Method**: Keras model ကို training အတွက် ပြင်ဆင်ရန် (optimizer, loss function စသည်)။
*   **`fit()` Method**: Keras model ကို train လုပ်ရန်။
*   **`create_optimizer()`**: Hugging Face Transformers library မှ optimizer နှင့် learning rate schedule ကို ဖန်တီးသော function။
*   **`init_lr`**: စတင် learning rate။
*   **`num_warmup_steps`**: warmup steps အရေအတွက်။
*   **`num_train_steps`**: စုစုပေါင်း training steps အရေအတွက်။
*   **`weight_decay_rate`**: weight decay ၏နှုန်း။
*   **`tf.keras.mixed_precision.set_global_policy("mixed_float16")`**: TensorFlow Keras တွင် mixed-precision (float16) training ကို ဖွင့်ရန်။
*   **`tf_train_dataset`**: TensorFlow format ဖြင့် training dataset။
*   **`tf_eval_dataset`**: TensorFlow format ဖြင့် evaluation dataset။
*   **`PushToHubCallback`**: Keras model ကို training လုပ်နေစဉ် Hugging Face Hub သို့ update လုပ်ရန် Hugging Face Transformers library မှ callback။
*   **`output_dir`**: trained model, logs, checkpoints တို့ကို သိမ်းဆည်းမည့် directory။
*   **`callbacks`**: Keras `fit()` method တွင် training လုပ်နေစဉ် လုပ်ဆောင်ချက်များ (ဥပမာ- logging, saving) ကို ထည့်သွင်းရန် argument။
*   **`model.fit()`**: Keras model ကို train လုပ်ရန်။
*   **Multiple GPUs**: ကွန်ပျူတာစနစ်တစ်ခုတွင် GPUs များစွာ အသုံးပြုခြင်း။
*   **`MirroredStrategy`**: TensorFlow ၏ distributed training strategy တစ်ခုဖြစ်ပြီး multiple GPUs ပေါ်တွင် data-parallel training ကို လုပ်ဆောင်ရန်။
*   **`scope()` Context**: TensorFlow distributed training strategy ၏ context manager တစ်ခုဖြစ်ပြီး၊ ၎င်းအတွင်းရှိ code ကို strategy ၏ စည်းမျဉ်းများအတိုင်း လုပ်ဆောင်စေသည်။
*   **`text-generation` Pipeline**: text generation task အတွက် ဒီဇိုင်းထုတ်ထားသော pipeline။
*   **GPU (Graphics Processing Unit)**: ဂရပ်ဖစ်လုပ်ဆောင်မှုအတွက် အထူးဒီဇိုင်းထုတ်ထားသော processor တစ်မျိုးဖြစ်သော်လည်း AI/ML လုပ်ငန်းများတွင် အရှိန်မြှင့်ရန် အသုံးများသည်။
*   **`torch.device("cuda")`**: PyTorch တွင် CUDA (GPU) device ကို သတ်မှတ်ခြင်း။
*   **`torch.device("cpu")`**: PyTorch တွင် CPU device ကို သတ်မှတ်ခြင်း။
*   **`pipeline()` Function**: Hugging Face Transformers library မှာ ပါဝင်တဲ့ လုပ်ဆောင်ချက်တစ်ခုဖြစ်ပြီး မော်ဒယ်တွေကို သီးခြားလုပ်ငန်းတာဝန်များ (ဥပမာ- စာသားခွဲခြားသတ်မှတ်ခြင်း၊ စာသားထုတ်လုပ်ခြင်း) အတွက် အသုံးပြုရလွယ်ကူအောင် ပြုလုပ်ပေးပါတယ်။
*   **`num_return_sequences`**: generate လုပ်မည့် sequences အရေအတွက်။
*   **`generated_text`**: model မှ generate လုပ်ထားသော စာသား။
*   **Scatter Plot**: data points များကို x-axis နှင့် y-axis ပေါ်တွင် ပြသသော graph အမျိုးအစား။
*   **`np.random.randn()`**: NumPy မှ standard normal distribution မှ ကျပန်းနံပါတ်များ ထုတ်လုပ်သော function။
*   **`plt.scatter(x, y)`**: Matplotlib မှ scatter plot ကို ဖန်တီးသော function။
*   **`pd.DataFrame`**: Pandas မှ DataFrame object ကို ဖန်တီးသော class။
*   **`df.insert()`**: Pandas DataFrame တွင် column အသစ်တစ်ခု ထည့်သွင်းသော method။
*   **`groupby()` Operation**: Pandas DataFrame တွင် columns များကို အုပ်စုဖွဲ့ပြီး aggregate လုပ်ဆောင်ချက်များ လုပ်ဆောင်သော method။
*   **`sklearn.ensemble.RandomForestRegressor`**: scikit-learn မှ Random Forest Regressor model class။
*   **`n_estimators`**: Random Forest model တွင် အသုံးပြုမည့် trees အရေအတွက်။
*   **`random_state`**: ကျပန်းနံပါတ် generator အတွက် seed။
*   **`max_depth`**: tree ၏ အများဆုံး အနက်။
*   **`rf.fit(X, y)`**: Random Forest model ကို data `X` နှင့် `y` ဖြင့် train လုပ်ရန်။
*   **Syntax (Python)**: Python programming language ၏ စည်းမျဉ်းများ။
*   **Prototype**: ထုတ်ကုန်တစ်ခု၏ ကနဦးမူကြမ်း သို့မဟုတ် စမ်းသပ်ဗားရှင်း။
*   **Conditional Training Loop**: သတ်မှတ်ထားသော အခြေအနေများပေါ်မူတည်၍ training steps များကို ကျော်သွားနိုင်သော training loop။
*   **Subclass**: လက်ရှိ class တစ်ခုမှ အင်္ဂါရပ်များကို အမွေခံယူပြီး ပြင်ဆင်နိုင်သော class အသစ်တစ်ခု ဖန်တီးခြင်း။
*   **Exotic Changes**: ပုံမှန်မဟုတ်သော သို့မဟုတ် ထူးခြားသော ပြောင်းလဲမှုများ။
*   **Weighted Loss Function**: data points အချို့ကို အခြား data points များထက် ပိုအလေးထားရန် weights များကို အသုံးပြုသော loss function။
*   **`plt` (matplotlib.pyplot)**: Matplotlib library ၏ commonly imported alias။
*   **`pd` (pandas)**: Pandas library ၏ commonly imported alias။
*   **`sk` (sklearn)**: scikit-learn library ၏ commonly imported alias (တခါတလေ သုံးသည်)။
*   **`fit` / `predict` Pattern**: machine learning model များကို train လုပ်ရန် `fit()` method နှင့် ခန့်မှန်းချက်များ ပြုလုပ်ရန် `predict()` method ကို အသုံးပြုသော ပုံစံ။
*   **Whitespace Prefix**: token ၏ အရှေ့တွင် ပါဝင်သော space character။
*   **Tokenizer Vocabulary**: tokenizer သိရှိသော ထူးခြားသော tokens များစာရင်း။
*   **`tokenizer([keyword]).input_ids[0]`**: keyword ကို tokenize လုပ်ပြီး ၎င်း၏ input IDs များကို ရယူခြင်း။
*   **`CrossEntropyLoss`**: PyTorch တွင် classification tasks အတွက် အသုံးများသော loss function။
*   **`torch`**: PyTorch library။
*   **`inputs[..., 1:].contiguous()`**: input tensor ၏ ဒုတိယ element မှ စတင်၍ slice လုပ်ပြီး memory တွင် ဆက်စပ်နေစေရန်။
*   **`logits[..., :-1, :].contiguous()`**: logits tensor ၏ နောက်ဆုံး element ကို ဖယ်ရှားပြီး memory တွင် ဆက်စပ်နေစေရန်။
*   **`loss_fct = CrossEntropyLoss(reduce=False)`**: per-token loss များကို ပြန်ပေးရန် `reduce=False` ဖြင့် CrossEntropyLoss ကို ဖန်တီးခြင်း။
*   **`loss.view(-1, shift_logits.size(1)).mean(axis=1)`**: per-sample loss များကို တွက်ချက်ခြင်း။
*   **`torch.stack()`**: tensors များစွာကို အတူတကွ stacking လုပ်ခြင်း။
*   **`torch.nn.CrossEntropyLoss`**: PyTorch တွင် classification tasks အတွက် အသုံးများသော loss function။
*   **`torch.optim.AdamW`**: PyTorch မှာ အသုံးပြုတဲ့ AdamW optimizer။
*   **Dataloaders**: batch အလိုက် data ကို load လုပ်ပေးသော PyTorch utility။
*   **Weight Decay Parameters**: model ၏ weights များကို ထိန်းချုပ်ရန် weight decay ကို အသုံးပြုသော parameters များ။
*   **Evaluation Code**: model ၏ စွမ်းဆောင်ရည်ကို တိုင်းတာရန်အတွက် code။
*   **`tokenized_datasets.set_format("torch")`**: dataset ၏ format ကို PyTorch tensors အဖြစ် သတ်မှတ်ခြင်း။
*   **`torch.utils.data.dataloader.DataLoader`**: PyTorch တွင် dataset မှ batch အလိုက် data များကို load လုပ်ပေးသော class။
*   **`get_grouped_params()` Function**: model ၏ parameters များကို weight decay လုပ်ရန် သို့မဟုတ် မလုပ်ရန် ခွဲခြားပေးသော function။
*   **`model.named_parameters()`**: model ၏ parameters များနှင့် ၎င်းတို့၏ နာမည်များကို ပြန်ပေးသော method။
*   **`model.eval()`**: model ကို evaluation mode သို့ ပြောင်းလဲခြင်း။
*   **`torch.no_grad()`**: gradient တွက်ချက်မှုကို ပိတ်ထားရန် PyTorch context manager။
*   **`accelerator.gather()`**: multiple processes မှ tensors များကို စုစည်းရန် 🤗 Accelerate method။
*   **`torch.cat()`**: multiple tensors များကို တစ်ခုတည်းအဖြစ် ပေါင်းစပ်ရန်။
*   **`torch.exp()`**: tensor ၏ element တစ်ခုစီ၏ exponential ကို တွက်ချက်ရန်။
*   **OverflowError**: Python တွင် ဂဏန်းတန်ဖိုးများ အလွန်ကြီးမားသောအခါ ဖြစ်ပေါ်သော error။
*   **Perplexity**: language model တစ်ခု၏ စွမ်းဆောင်ရည်ကို တိုင်းတာသော metric (ပိုနည်းလေ ပိုကောင်းလေ)။
*   **`accelerator.prepare()`**: 🤗 Accelerate တွင် model, optimizer, dataloaders များကို distributed training အတွက် ပြင်ဆင်ရန် method။
*   **TPU (Tensor Processing Unit)**: Google မှ AI/ML workloads များအတွက် အထူးဒီဇိုင်းထုတ်ထားသော processor တစ်မျိုး။
*   **Dedicated Training Function**: training logic အားလုံးပါဝင်သော သီးခြား function။
*   **Linear Schedule**: learning rate ကို linear ပုံစံဖြင့် အချိန်ကြာလာသည်နှင့်အမျှ လျှော့ချသော schedule။
*   **`get_scheduler()`**: Hugging Face Transformers library မှ learning rate scheduler ကို ရယူသော function။
*   **`Repository` Object**: `huggingface_hub` library မှ Git repository များကို ကိုင်တွယ်ရန်အတွက် object။
*   **Working Folder**: project files များကို သိမ်းဆည်းထားသော folder။
*   **`get_full_repo_name()` Function**: Hugging Face Hub ပေါ်တွင် repository ၏ full name (username/repo_name) ကို ရယူသော function။
*   **`clone_from` Argument**: `Repository` object ကို ဖန်တီးသောအခါ remote repository မှ clone လုပ်ရန် ညွှန်ကြားသော argument။
*   **`repo.push_to_hub()` Method**: local repository ၏ ပြောင်းလဲမှုများကို Hugging Face Hub သို့ push လုပ်ရန်။
*   **Intermediate Models**: training လုပ်နေစဉ် သိမ်းဆည်းထားသော model versions များ။
*   **Perplexity**: language model တစ်ခု၏ စွမ်းဆောင်ရည်ကို တိုင်းတာသော metric (ပိုနည်းလေ ပိုကောင်းလေ)။
*   **`model.train()`**: model ကို training mode သို့ ပြောင်းလဲခြင်း။
*   **`tqdm.notebook`**: Jupyter Notebooks အတွက် `tqdm` progress bar။
*   **`enumerate()`**: list သို့မဟုတ် iterable တစ်ခု၏ element တစ်ခုစီကို index နှင့်အတူ ပြန်ပေးသော Python function။
*   **`accelerator.print()`**: distributed training ပတ်ဝန်းကျင်တွင် logs များကို print ထုတ်ရန် 🤗 Accelerate utility။
*   **`loss.item()`**: PyTorch tensor မှ Python float တန်ဖိုးကို ရယူခြင်း။
*   **`accelerator.backward(loss)`**: distributed training တွင် loss မှ gradients များကို တွက်ချက်ရန် 🤗 Accelerate method။
*   **`accelerator.clip_grad_norm_()`**: gradients များကို clip လုပ်ရန် 🤗 Accelerate method။
*   **`optimizer.step()`**: တွက်ချက်ထားသော gradients များကို အသုံးပြုပြီး model ၏ parameters များကို update လုပ်သော optimizer method။
*   **`lr_scheduler.step()`**: learning rate scheduler ကို တစ်ဆင့်ချင်းစီ update လုပ်ရန်။
*   **`optimizer.zero_grad()`**: gradients များကို သုညသို့ ပြန်လည်သတ်မှတ်ရန်။
*   **`accelerator.wait_for_everyone()`**: distributed training တွင် processes အားလုံး အမှတ်တစ်ခုသို့ ရောက်သည်အထိ စောင့်ဆိုင်းရန် 🤗 Accelerate method။
*   **`accelerator.unwrap_model()`**: distributed training အတွက် wrap လုပ်ထားသော model မှ မူရင်း model ကို ပြန်လည်ရယူရန် 🤗 Accelerate method။
*   **`unwrapped_model.save_pretrained()`**: model ကို pretrained format ဖြင့် disk ပေါ်တွင် သိမ်းဆည်းရန်။
*   **`accelerator.save()`**: distributed training တွင် model ကို သိမ်းဆည်းရန် 🤗 Accelerate utility။
*   **`accelerator.is_main_process`**: လက်ရှိ process က main process ဟုတ်မဟုတ် စစ်ဆေးရန် 🤗 Accelerate property။
*   **`tokenizer.save_pretrained()`**: tokenizer ကို disk ပေါ်တွင် သိမ်းဆည်းရန်။
*   **`commit_message`**: Git commit အတွက် ပေးသော မက်ဆေ့ချ်။
*   **`blocking=False`**: `push_to_hub()` ကို asynchronous အဖြစ် run ရန် ညွှန်ကြားခြင်း (main thread ကို မပိတ်မိစေရန်)။
*   **TensorBoard**: Google မှ ဖန်တီးထားသော machine learning experiments များကို visualization လုပ်ရန် ကိရိယာ။
*   **Weights & Biases**: machine learning experiments များကို ခြေရာခံ၊ visualization လုပ်ရန်နှင့် ပူးပေါင်းဆောင်ရွက်ရန် platform။

