2-bo‘lim

Tokenizatsiya va o'zbek tili

Subword tokenizatsiya, maxsus tokenlar, padding va attention_mask, hamda o'zbekcha matn ingliz tilidan necha barobar qimmatga tushishi.

🕑 17 daqiqa o‘qish 📄 1 082 so‘z 👁 2 marta ko‘rilgan
Ushbu bo‘lim mundarijasi
  1. Muhitni tayyorlash
  2. 1. Python
  3. 2. Virtual muhit yaratish
  4. 3. Muhitni faollashtirish
  5. 4. Kutubxonalarni o'rnatish
  6. 5. Tekshirish
  7. Subword - so'z ham emas, harf ham emas
  8. O'zbek tili qancha turadi
  9. Apostrof - alohida muammo
  10. Maxsus tokenlar
  11. Teskari yo'nalish
  12. Paket va attention_mask
  13. Xulosa

Model harf ham, so'z ham ko'rmaydi - u faqat sonlar bilan ishlaydi. Matnni songa aylantiruvchi bo'g'in tokenizator deyiladi va u transformerning eng kam e'tibor beriladigan, lekin eng ko'p muammo keltiradigan qismi.

Muhitni tayyorlash #

Ikki holat bo'lishi mumkin:

HolatNima qilish kerak
PyTorch darsligini o'tgansizMavjud muhitni faollashtirib, bitta kutubxona qo'shasiz
Noldan boshlayapsizQuyidagi to'rt qadamni bajarasiz

1. Python #

Python 3.9 yoki undan yangi versiya kerak. Tekshirish:

Terminal
python --version

O'rnatilmagan bo'lsa, python.org dan yuklab oling.

Windows da «Add Python to PATH» ni belgilang

O'rnatuvchining birinchi ekranida «Add Python to PATH» katagini albatta belgilang. Aks holda terminalda python buyrug'i topilmaydi.

Unutgan bo'lsangiz - o'rnatuvchini qayta ishga tushirib, «Modify» ni tanlang.

Windows da ba'zan python o'rniga py ishlatiladi: py --version.

2. Virtual muhit yaratish #

Papka ochib, unda alohida muhit yaratamiz:

Terminal
mkdir transformer-loyiham
cd transformer-loyiham
python -m venv muhit

3. Muhitni faollashtirish #

Bu qadam operatsion tizimga qarab farq qiladi.

Windows (Command Prompt yoki PowerShell):

CMD
muhit\Scripts\activate

Linux va macOS:

Terminal
source muhit/bin/activate

Faollashgach, buyruq satri oldida muhit nomi paydo bo'ladi:

Natija
(muhit) C:\Users\husanboy\transformer-loyiham>

Chiqish uchun ikkala tizimda ham bir xil: deactivate.

Faollashtirishni unutmang

Har safar yangi terminal ochganingizda muhitni qaytadan faollashtirish kerak.

Unutsangiz, pip install kutubxonani tizim bo'ylab o'rnatadi yoki ModuleNotFoundError: No module named 'transformers' xatosi chiqadi - garchi siz uni o'rnatgan bo'lsangiz ham.

Birinchi tekshiruv: buyruq satri oldida (muhit) turibdimi?

4. Kutubxonalarni o'rnatish #

Faollashtirilgan muhitda buyruq ikkala tizimda bir xil:

Terminal
pip install torch transformers --index-url https://download.pytorch.org/whl/cpu --extra-index-url https://pypi.org/simple
Nima uchun bunday uzun buyruq

--index-url PyTorch ning protsessor uchun mo'ljallangan omboriga ishora qiladi. Oddiy pip install torch ham ishlaydi, lekin u NVIDIA kutubxonalari bilan birga bir necha gigabaytlik paketni tortadi - video karta bo'lmasa, bu behuda.

--extra-index-url esa transformers ni odatiy PyPI dan olish uchun kerak - u PyTorch omborida yo'q.

PyTorch darsligini o'tgan bo'lsangiz, sizda torch allaqachon bor: o'sha muhitni faollashtirib, pip install transformers yozsangiz kifoya.

5. Tekshirish #

tekshir.py faylini yarating:

Python
import torch
import transformers

print("torch:       ", torch.__version__)
print("transformers:", transformers.__version__)
Terminal
python tekshir.py
Natija
torch:        2.14.0+cpu
transformers: 5.17.0

Sizdagi versiya yangiroq bo'lishi mumkin - bu normal. Darslikdagi misollar shu versiyalarda ishga tushirilgan.

Muhit qancha joy oladi

Bo'sh papkadan boshlab o'rnatganda muhit/ papkasi taxminan 1.1 GB joy egalladi. Bu torch ning protsessor versiyasi, transformers va ularning barcha bog'liqliklari (numpy, tokenizers, safetensors va boshqalar).

Modellar esa bunga kirmaydi - ular alohida keshga yuklanadi va yana bir necha gigabayt oladi.

Noutbukda ishlayotgan bo'lsangiz, boshlashdan oldin kamida 5 GB bo'sh joy borligiga ishonch hosil qiling.

Modellar internetdan yuklanadi

from_pretrained(...) birinchi marta chaqirilganda model internetdan yuklab olinadi va ~/.cache/huggingface papkasiga saqlanadi (Windows da C:\Users\<ism>.cache\huggingface).

Shuning uchun birinchi ishga tushirish sekin bo'ladi, keyingilari esa tez. Bu darslikdagi modellar jami bir necha gigabayt joy oladi - 11-bo'limda buni o'lchaymiz.

Endi birinchi tokenizatorni yuklaymiz:

Python
from transformers import AutoTokenizer

tok = AutoTokenizer.from_pretrained("bert-base-multilingual-cased")
print("lug'at hajmi:", tok.vocab_size)
Natija
lug'at hajmi: 119547

Bu model 104 tilda o'qitilgan va lug'atida 119 547 ta token bor.

Subword - so'z ham emas, harf ham emas #

Nega shunchaki so'zlarni raqamlamaymiz? Chunki o'zbek tilida bitta o'zakdan o'nlab shakl yasaladi: kitob, kitobim, kitobingiz, kitoblardan. Har birini alohida token qilsak, lug'at cheksiz o'sadi.

Boshqa chekka - har harfni token qilish. Unda lug'at kichik, lekin matn juda uzun bo'ladi.

Tokenizatorlar o'rtadagi yo'lni tanlaydi: subword (so'z bo'lagi).

Python
matnlar = [
    "Dasturlash qiziqarli",
    "Programming is interesting",
    "Kitob o'qish foydali",
]

for m in matnlar:
    ids = tok(m, add_special_tokens=False)["input_ids"]
    print(f"{m}")
    print(f"  tokenlar ({len(ids)}): {tok.convert_ids_to_tokens(ids)}")
Natija
Dasturlash qiziqarli
  tokenlar (7): ['Das', '##tur', '##lash', 'q', '##izi', '##qa', '##rli']
Programming is interesting
  tokenlar (3): ['Programming', 'is', 'interesting']
Kitob o'qish foydali
  tokenlar (9): ['Kit', '##ob', 'o', "'", 'q', '##ish', 'f', '##oy', '##dali']

## belgisi «bu oldingi tokenning davomi» degani.

Natijaga diqqat qiling. Uch so'zli inglizcha jumla - 3 ta token. Ikki so'zli o'zbekcha jumla - 7 ta token.

O'zbek tili qancha turadi #

Python
print(f"{'matn':32s} {'so\'z':>5s} {'token':>6s} {'nisbat':>7s}")
for m in matnlar:
    n = len(tok(m, add_special_tokens=False)["input_ids"])
    s = len(m.split())
    print(f"{m:32s} {s:5d} {n:6d} {n/s:6.1f}x")
Natija
matn                              so'z  token  nisbat
Dasturlash qiziqarli                 2      7    3.5x
Programming is interesting           3      3    1.0x
Kitob o'qish foydali                 3      9    3.0x

Ingliz tilida bir so'z - taxminan bir token. O'zbek tilida bir so'z uch-to'rt token.

Bir so'zga to'g'ri keladigan token soni 4x 3x 2x 1x 0 1.0x Ingliz tili 3 so'z = 3 token 3.0x O'zbek tili 3 so'z = 9 token 3.5x O'zbek (apostrofli) 2 so'z = 7 token Bir xil ma'noli matn uchun 3 barobar ko'p token = 3 barobar qimmat
Ko'p tilli tokenizator ingliz tiliga moslashgan - qolgan tillar buning hisobini to'laydi
Bu uch joyda pul va sifat yo'qotadi
  1. Narx. API xizmatlari token bo'yicha hisoblaydi. Bir xil matn o'zbek tilida uch barobar qimmatroq tushadi.
  2. Kontekst oynasi. Model bir vaqtda cheklangan token qabul qiladi. 4096 tokenlik oyna inglizcha ~3000 so'z, o'zbekcha ~1200 so'z demak.
  3. Sifat. So'z mayda bo'laklarga sochilgach, modelga uning ma'nosini ushlash qiyinroq bo'ladi.

Bu kamsitish emas - tokenizator qaysi matnda ko'p o'qitilgan bo'lsa, o'shanga moslashadi. Internetdagi matnning katta qismi esa ingliz tilida.

Apostrof - alohida muammo #

O'zbek lotin yozuvida o' va g' harflari bor. Ular tokenizatorga qanday ta'sir qiladi?

Python
for m in ["o'rganish", "oʻrganish", "organish"]:
    ids = tok(m, add_special_tokens=False)["input_ids"]
    print(f"  {m:12s} -> {len(ids)} token: {tok.convert_ids_to_tokens(ids)}")
Natija
  o'rganish    -> 5 token: ['o', "'", 'r', '##gani', '##sh']
  oʻrganish    -> 4 token: ['o', '##ʻ', '##rgan', '##ish']
  organish     -> 2 token: ['organi', '##sh']

Bitta so'z, uch xil yozuv, uch xil narx: 5, 4 va 2 token.

To'g'ri apostrof (') ishlatilganda so'z beshta bo'lakka sochilib ketdi - hatto o va ' alohida token bo'ldi.

Amaliy xulosa

Matnni tayyorlashda apostrof shaklini bir xil qiling. Loyihangizda ' (U+2018) va ' (to'g'ri tirnoq) aralash bo'lsa, model bir xil so'zni ikki xil ko'radi.

Apostrofni butunlay olib tashlash ham variant - lekin unda tosh va to'sh farqi yo'qoladi. Qaysi biri muhimroq ekanini masalangiz hal qiladi.

Maxsus tokenlar #

Python
enc = tok("Salom dunyo")
print("id lar:", enc["input_ids"])
print("tokenlar:", tok.convert_ids_to_tokens(enc["input_ids"]))
print("CLS:", tok.cls_token, "| SEP:", tok.sep_token,
      "| PAD:", tok.pad_token, "| UNK:", tok.unk_token)
Natija
id lar: [101, 64831, 10692, 23145, 15594, 102]
tokenlar: ['[CLS]', 'Sal', '##om', 'dun', '##yo', '[SEP]']
CLS: [CLS] | SEP: [SEP] | PAD: [PAD] | UNK: [UNK]

Tokenizator o'zi ikkita token qo'shdi: boshiga [CLS], oxiriga [SEP].

TokenVazifasi
[CLS]Butun jumlani ifodalovchi token - tasniflashda ishlatiladi
[SEP]Jumlalar chegarasi
[PAD]Qisqa jumlalarni to'ldirish (PyTorch 17-bo'lim)
[UNK]Lug'atda umuman yo'q belgi

Teskari yo'nalish #

Python
print("decode:", tok.decode(enc["input_ids"]))
print("decode (maxsus tokensiz):", tok.decode(enc["input_ids"], skip_special_tokens=True))
Natija
decode: [CLS] Salom dunyo [SEP]
decode (maxsus tokensiz): Salom dunyo

## bo'laklar qaytadan birlashtirildi va asl matn tiklandi.

Paket va attention_mask #

PyTorch darsligining 17-bo'limida padding niqobini qo'lda yozgan edik. Bu yerda tokenizator uni o'zi beradi:

Python
paket = tok(["Salom", "Dasturlash juda qiziqarli ish"],
            padding=True, return_tensors="pt")
print("input_ids shakli:", tuple(paket["input_ids"].shape))
print("attention_mask:")
print(paket["attention_mask"])
print("1-qator tokenlari:", tok.convert_ids_to_tokens(paket["input_ids"][0]))
Natija
input_ids shakli: (2, 12)
attention_mask:
tensor([[1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0],
        [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]])
1-qator tokenlari: ['[CLS]', 'Sal', '##om', '[SEP]', '[PAD]', '[PAD]', '[PAD]', '[PAD]', '[PAD]', '[PAD]', '[PAD]', '[PAD]']

Ikkala jumla 12 tokenga tenglashtirildi. attention_mask esa qaysi o'rinlar haqiqiy ekanini aytadi: birinchi qatorda 4 ta 1 va 8 ta 0.

attention_mask ni modelga berishni unutmang

tok(...) natijasini butunligicha modelga uzating:

Python
chiqish = model(**paket)

Agar faqat input_ids bersangiz, model [PAD] tokenlarni ham haqiqiy so'z deb hisoblaydi. Xato chiqmaydi - natija shunchaki yomonlashadi, ayniqsa jumlalar uzunligi juda har xil bo'lganda.

Amaliy topshiriq
  1. bert-base-multilingual-cased tokenizatorini yuklab, lug'at hajmini chop eting.
  2. O'zbekcha uchta jumlani tokenlarga ajrating.
  3. ## belgisi nimani anglatishini tushuntiring.
  4. Xuddi shu ma'nodagi inglizcha jumla bilan token sonini solishtiring.
  5. Bir so'zga to'g'ri keladigan token sonini ikkala tilda hisoblang.
  6. o'rganish, oʻrganish va organish ni tokenlarga ajratib, farqni yozing.
  7. Uzun o'zbekcha matn oling va 4096 tokenlik oynaga necha so'z sig'ishini hisoblang.
  8. [CLS], [SEP], [PAD] va [UNK] tokenlarining vazifasini yozing.
  9. decode bilan id larni matnga qaytaring.
  10. Ikki xil uzunlikdagi jumlani padding=True bilan kodlab, attention_mask ni tushuntiring.

Xulosa #

  • Model matn emas, son qabul qiladi; uni tokenizator tayyorlaydi.
  • Subword tokenizatsiya so'z va harf o'rtasidagi yo'l - lug'at cheklangan qoladi.
  • ## prefiksi tokenning oldingisining davomi ekanini bildiradi.
  • O'zbekcha matn inglizchaga qaraganda 3-3.5 barobar ko'p token oladi.
  • Bu uch narsaga ta'sir qiladi: narx, kontekst oynasi va sifat.
  • Sabab kamsitish emas - tokenizator ko'proq ingliz tilida o'qitilgan.
  • Apostrof narxni yana oshiradi: o'rganish 5 token, organish 2 token.
  • Loyihada apostrof shaklini bir xil qiling, aks holda model bir so'zni ikki xil ko'radi.
  • Tokenizator [CLS] va [SEP] ni o'zi qo'shadi.
  • padding=True bilan attention_mask avtomatik chiqadi - uni modelga berish shart.

Keyingi bo'limda token id laridan vektor yasaymiz va e'tibor mexanizmining birinchi qismiga - so'rov, kalit va qiymatga o'tamiz.

Xatolik topdingizmi?

Imlo xatosi, ishlamaydigan kod yoki noto‘g‘ri ma‘lumotni ko‘rsangiz - bizga xabar bering. Har bir xabar administrator tomonidan ko‘rib chiqiladi.