IlmHamroh
Data Science va sun'iy intellekt/Katta til modellari2/14-dars39 daqiqa
Mundarija (22)

25.2-dars: Tokenlar, kontekst va xarajat

25-QISM — KATTA TIL MODELLARI · 2-dars


1. Kirish va motivatsiya

25.1-darsda LLM ni "katta GPT" sifatida ko'rdik va uning o'rgatilishi qancha turishini hisobladik. Endi amaliy tomonga o'tamiz: tayyor modelni API orqali ishlatganda har bir so'rov qancha turadi va unga qancha matn sig'adi? Ikkala savolning ham o'lchov birligi bitta — token. LLM matnni so'z yoki belgi bilan emas, 23.3-darsda noldan yozgan BPE ga o'xshash subword tokenlar bilan ko'radi. Narx tokenlar bilan hisoblanadi, kontekst oynasi tokenlar bilan o'lchanadi, kechikish ham chiqarilgan tokenlar soniga bog'liq.

Real vaziyat. O'zbekistondagi startap ingliz tilidagi demo asosida chat-bot byudjetini rejalashtirdi: "o'rtacha so'rov 1500 token, javob 300 token, kuniga 20 ming so'rov". Birinchi oyning hisobi rejadan 2.5 barobar oshdi. Tekshiruv uchta sababni ko'rsatdi. Birinchisi: xuddi shu mazmundagi o'zbekcha matn ishlatilgan tokenizatorda inglizchadan ancha ko'p token oldi. Ikkinchisi: byudjet mediana bo'yicha hisoblangan edi, uzun suhbatlarning "dumi" esa o'rtachani ko'tardi. Uchinchisi: har so'rovga qo'shiladigan 6000 tokenlik tizim ko'rsatmasi va hujjatlar prompt keshlash bilan arzonlashtirilishi mumkin edi, lekin dasturchi prompt boshiga joriy vaqtni yozib qo'ygani uchun kesh bir marta ham ishlamadi. Bu darsning to'rt misoli aynan shu to'rt narsani o'lchaydi.

Bu darsda tokenizator qaysi tilda o'rgatilgani token soniga qanday ta'sir qilishini o'z BPE imizda o'lchaymiz, faraziy narx jadvali bilan xarajat kalkulyatori quramiz, prompt keshlashni virtual vaqtda simulyatsiya qilamiz va uzun suhbatni kontekst oynasiga sig'dirish strategiyalarini solishtiramiz.

Bu darsda:

  • Token nima: BPE qayta ko'rib chiqiladi
  • "Token solig'i": o'zbekcha matn va tokenizator o'quv ma'lumoti
  • Kontekst oynasi: kirish + chiqish
  • Narx: kirish va chiqish tokenlari alohida
  • Byudjet: mediana emas, taqsimot
  • Prompt keshlash: prefiks, TTL, zararsizlik nuqtasi
  • Kontekstga sig'dirish: kesish va xulosa
  • Tuzoqlar

ℹ Misollar real numpy bilan (Python 3.14). Tashqi API va internet ishlatilmaydi. Barcha narxlar — faraziy namuna: haqiqiy narxni provayderning rasmiy sahifasidan oling, ular vaqt o'tishi bilan o'zgaradi.


2. Nazariya — chuqur tushuntirish

2.1. Token nima: BPE qayta

text
23.3-DARSDA:
  BPE - eng ko'p uchraydigan yonma-yon juftlarni ketma-ket birlashtirish
  lug'at = boshlang'ich belgilar + birlashma qoidalari
  tez-tez so'z -> bitta token; kam uchragan so'z -> bir necha bo'lak

ZAMONAVIY LLM TOKENIZATORLARI:
  bayt darajasidagi BPE (yoki shunga o'xshash): boshlang'ich lug'at 256 bayt
    -> OOV umuman yo'q, istalgan UTF-8 matn kodlanadi
  lug'at hajmi o'n minglab - yuz minglab token
  maxsus tokenlar: rollar, xabar chegaralari, "matn oxiri"

TAXMINIY QOIDA (faqat ingliz tili uchun, ingliz-markazli tokenizatorda):
  1 token ~ 4 belgi ~ 0.75 so'z
  BOSHQA TILLARDA BU QOIDA ISHLAMAYDI - o'lchash kerak (1-misol)

TOKENNI QANDAY SANASH:
  provayderning token hisoblash endpointi yoki SDK funksiyasi
  javobdagi usage maydoni: haqiqiy ishlatilgan kirish va chiqish tokenlari
  taxminiy formula - faqat dastlabki reja uchun

Token — narx, kontekst va kechikishning umumiy o'lchov birligi; uni so'z yoki belgi bilan almashtirib bo'lmaydi.

2.2. "Token solig'i": tokenizator qaysi tilda o'rgatilgan

text
MEXANIZM:
  BPE birlashmalari o'quv korpusidagi ENG KO'P juftlardan tanlanadi
  korpus 90% inglizcha -> birlashmalarning ko'pchiligi ingliz so'zlari uchun
  o'zbekcha so'zlar kam birlashtirilgan -> mayda bo'laklarga bo'linadi

AGGLUTINATSIYA:
  "filiallarimizdagi" - bitta so'z, lekin shakllari juda ko'p
  1-misol: 300 jumlada o'zbekcha 657 xil so'z shakli, inglizcha 110
  o'quv korpusida o'zbekcha shakllar 2961 ta (3000 jumlada)

1-MISOL (bir xil mazmunli 300 juft jumla, 200 birlashma):
  o'quv (en/uz)   uz tok/jumla  en tok/jumla  uz/en
   90%/10%            28.2          11.5       2.46   <- "soliq"
   50%/50%            16.0          17.6       0.91
   10%/90%            10.6          30.6       0.35   <- endi inglizcha "soliq" to'laydi

"O'zbek tili qimmat" degan xulosa noto'g'ri. 1-misol ko'rsatadiki, nisbat tilning o'zidan emas, tokenizator o'quv ma'lumotidan keladi: muvozanatli korpusda o'zbekcha matn hatto biroz kam token oldi (agglutinatsiya bitta so'zga ko'p ma'no joylaydi), ingliz-og'ir korpusda esa 2.46 barobar ko'p. Amaliy xulosa: o'z matningizda o'lchang. Turli provayderlarning tokenizatorlari turli til aralashmasida o'rgatilgan, shuning uchun "bir xil mazmun" uchun token soni — va demak narx — modeldan modelga farq qiladi.

text
APOSTROF TUZOG'I (1-misol, 4-bo'lim):
  "o'qituvchi" ASCII apostrof bilan   10 bayt
               U+2019 bilan           12 bayt
               U+02BB bilan           11 bayt
  bayt BPE da noodatiy belgi -> boshqa bo'linish va ko'proq token
  bir xil matnni bir xil normallashtiring (23.1-dars)

Token soni tokenizator o'rgatilgan ma'lumotga bog'liq: o'zbekcha matnning "solig'i" 0.9 dan 2.5 barobargacha o'zgarishi mumkin — faqat o'lchov javob beradi.

2.3. Kontekst oynasi

text
KONTEKST OYNASI = model bir so'rovda "ko'ra oladigan" tokenlar soni
  kirish (tizim + tarix + hujjatlar + savol) + chiqish (javob) <= oyna
  24.9-darsdagi L = 48 ning o'zi, faqat o'n minglab - yuz minglab token

MAX_TOKENS (chiqish chegarasi):
  javob uzunligining yuqori chegarasi; oyna ichida chiqishga joy qoldiradi
  kichik max_tokens -> javob kesiladi (25.3-dars: stop_reason)

UZUN KONTEKST ARZON EMAS:
  narx: har so'rovda BUTUN kirish qayta to'lanadi (suhbat tarixi ham)
  kechikish: birinchi token vaqti kirish uzunligiga bog'liq
  xotira: KV-cache tokenlarga chiziqli (25.1: 7B sinfda 0.52 MB/token)
  sifat: juda uzun kontekstning o'rtasidagi ma'lumot ba'zan
         yomonroq ishlatiladi ("o'rtada yo'qolish" kuzatuvi)

SUHBAT TARIXI:
  API holatsiz: har so'rovda butun tarix qayta yuboriladi
  n-xabardagi kirish ~ n * o'rtacha xabar -> suhbat narxi ~ n^2

Kontekst oynasi — qat'iy chegara, lekin uni to'ldirish ham qimmat: API holatsiz, har so'rovda butun tarix qayta to'lanadi.

2.4. Narx: kirish va chiqish tokenlari alohida

text
FORMULA:
  narx = kirish_tokenlari * kirish_narxi + chiqish_tokenlari * chiqish_narxi
  narxlar odatda "$ / 1 million token"
  chiqish tokeni kirishdan bir necha barobar qimmat (generatsiya ketma-ket)

2-MISOL (NAMUNA narxlar, faraziy: o'rta model 3 $ / 12 $):
  1500 kirish + 300 chiqish = 0.00810 $
  chiqish ulushi 44% - tokenlarning atigi 17% i bo'lsa ham

OYLIK (30 kun, mediana bo'yicha):
  ish yuki          so'rov/kun  kirish  chiqish   kichik   o'rta    katta
  chat-bot            20 000     1500     300      810$    4 860$   16 200$
  hujjat xulosasi      2 000     6000     400      228$    1 368$    4 560$
  maqola yozish          500      300    1500       47$      284$      945$

Uch ish yuki uch xil "og'riq nuqtasi"ni ko'rsatadi: chat-bot — so'rovlar ko'pligi, xulosa — uzun kirish, maqola yozish — uzun chiqish. Tejash usullari ham shunga qarab farq qiladi: chat-botda keshlash va kichik model, xulosada kirishni qisqartirish (kerakli bo'laklarni tanlash — RAG, 25.8), maqolada esa max_tokens va aniq uzunlik ko'rsatmasi.

Narx = kirish x narx + chiqish x narx; chiqish tokenlari kam bo'lsa ham hisobning katta qismini olishi mumkin.

2.5. Byudjet: mediana emas, taqsimot

text
2-MISOL, 3-BO'LIM (log-normal uzunliklar, 600 000 so'rov, o'rta model):
  mediana bo'yicha hisob:   4 860 $
  haqiqiy yig'indi:         6 166 $   (o'rtacha kirish 1798, chiqish 407)
  bitta so'rov: mediana 0.0090 $, 95-persentil 0.0212 $, maks 0.0817 $

SABAB:
  uzunliklar o'ngga og'ma (uzun suhbatlar, katta hujjatlar)
  yig'indi O'RTACHA ga proporsional, mediana esa o'rtachadan kichik

TIL KOEFFITSIYENTI (1-misol nisbatlari bilan):
  inglizcha                            6 166 $
  o'zbekcha, muvozanatli tokenizator   5 734 $
  o'zbekcha, ingliz-og'ir tokenizator 15 291 $

TEJASH TUGMALARI:
  marshrutlash: 80% oson so'rov kichik modelga -> 2 056 $ (tejam 67%)
  max_tokens=800 -> tejam 5%, 10.9% javob kesiladi
  max_tokens=250 -> tejam 23%, lekin 58.9% javob kesiladi (yomon savdo)

Marshrutlash raqami faqat narx tomonini ko'rsatadi. "Oson so'rov kichik modelga" qarori kichik model shu so'rovlarda yetarlicha sifatli ekanini talab qiladi — buni baho to'plamida juftlashgan taqqoslash bilan tekshirish kerak 25.10-bob. max_tokens bilan tejash esa ko'pincha soxta tejam: kesilgan javobni foydalanuvchi qayta so'raydi.

Byudjetni o'rtacha va dum bilan rejalang; tejash qarorini sifat o'lchovisiz qabul qilmang.

2.6. Prompt keshlash

text
G'OYA:
  ko'p so'rovlarda prompt BOSHI bir xil (tizim ko'rsatmasi, hujjatlar, misollar)
  provayder shu prefiksning hisobini (KV-cache, 24.11) saqlab qo'yadi
  keyingi so'rovda prefiks aynan mos kelsa - arzonroq va tezroq

QOIDALAR (umumiy tamoyil; aniq shartlar provayder hujjatida):
  moslik PREFIKS bo'yicha: birinchi farq qiluvchi tokendan keyingi hammasi yangi
  keshning yashash muddati (TTL) bor; ishlatilganda yangilanadi
  kesh yozish odatda oddiy kirishdan QIMMATROQ, o'qish esa ancha arzon

3-MISOL SHARTLARI (faraziy): yozish x1.25, o'qish x0.10, TTL 300 s
  zararsizlik nuqtasi: har yozishga 0.25 / 0.90 = 0.28 ta o'qish

TRAFIK (6000 tokenli statik prefiks, 1000 so'rov narxi):
  so'rov/min   keshsiz   keshli   topilish   tejam
     0.05       22.12    22.21     21.3%     -0.4%   <- kesh eskiradi
     0.2        22.12    13.81     61.9%     37.6%
     1.0        22.12     6.08     99.2%     72.5%
    10.0        22.12     5.93    100.0%     73.2%

TARTIB (1 so'rov/min):
  statik qism boshida, vaqt oxirida   topilish 99.2%   6.08 $
  sana boshida (kuniga 1 marta)       topilish 99.2%   6.06 $
  soat boshida (har so'rovda boshqa)  topilish  1.1%  26.39 $  <- keshsizdan qimmat

Anthropic API da keshlash nuqtasi cache_control bilan belgilanadi (ma'lumotnomada ko'rinishi bor), javobdagi usage esa keshga yozilgan va keshdan o'qilgan tokenlarni alohida ko'rsatadi — tejamni taxmin emas, shu maydonlar bilan o'lchang.

Keshlash — statik qism boshida, o'zgaruvchan qism oxirida; trafik TTL dan siyrak bo'lsa, kesh zarar keltiradi.

2.7. Kontekstga sig'dirish strategiyalari

text
MUAMMO: suhbat yoki hujjat oynadan (yoki byudjetdan) uzun

STRATEGIYALAR:
  boshidan saqlash    - eski qism qoladi, yangi xabarlar yo'qoladi (yomon)
  oxiridan saqlash    - "sirpanuvchi oyna"; tizim ko'rsatmasi ham tushib qolishi mumkin!
  tizim + oxir        - tizim ko'rsatmasi DOIM, qolgan joy - oxirgi xabarlar
  tizim + xulosa + oxir - eski qism qisqa xulosaga aylanadi
  qidiruv (RAG)       - eski qismdan savolga tegishli bo'laklarni topish 25.8-bob

4-MISOL (400 suhbat, 832 so'z, byudjet 150 so'z ~18%):
  usul                   fakt   bosh  o'rta  oxir  raqamli raqamsiz tizim
  boshidan              14.0%  39.2%   0.0%  0.0%   14.5%   13.6%   100%
  oxiridan              15.8%   0.0%   0.0% 53.4%   15.1%   16.4%     0%
  tizim + oxir          13.5%   0.0%   0.0% 45.8%   13.4%   13.6%   100%
  tizim + xulosa + oxir 52.0%  45.5%  48.2% 64.4%  100.0%   10.3%   100%

Xulosa strategiyasi faktlarni to'rt barobar ko'p saqladi — lekin faqat raqamli faktlarni: bizning sodda ekstraktiv xulosamiz raqam bor bo'laklarni oladi, "ko'k rangdagisi yoqadi" kabi raqamsiz faktni esa yo'qotadi (10.3%). Bu xulosaning umumiy xususiyati: u nimani saqlashi kerakligini oldindan "bilishi" kerak. LLM bilan yozilgan xulosa ancha moslashuvchan, lekin u ham tafsilotlarni tashlab yuboradi va qo'shimcha so'rov narxini talab qiladi.

Tizim ko'rsatmasini hech qachon kesmang; eski qism uchun xulosa yoki qidiruvdan foydalaning va nima yo'qolayotganini o'lchang.

2.8. Tuzoqlar

Asosiy tuzoqlar: tokenni "4 belgi" yoki "0.75 so'z" deb boshqa tillarga ham qo'llash; o'zbekcha matn narxini ingliz demosi bo'yicha rejalash; narxlarni kodga "haqiqiy" deb yozib qo'yish va yangilamaslik; kirish va chiqish narxini bitta narx deb hisoblash; byudjetni mediana bo'yicha hisoblash; suhbat tarixi har so'rovda qayta to'lanishini unutish; prompt boshiga vaqt, so'rov ID si yoki foydalanuvchi ismini yozib keshni buzish; siyrak trafikda keshlashni yoqib, yozish ustamasini to'lash; tejamni usage maydonlari o'rniga taxmin bilan baholash; "oxiridan kesish" da tizim ko'rsatmasini tashlab yuborish; max_tokens ni juda kichik qilib, kesilgan javoblarni "tejam" deb hisoblash; marshrutlashni sifat o'lchovisiz joriy qilish; apostrof va boshqa belgilarni normallashtirmaslik.


3. Tez ma'lumotnoma

python
# narx (NARX - faraziy jadval, rasmiy sahifadan yangilang)
narx = (kirish * NARX[m]["kirish"] + chiqish * NARX[m]["chiqish"]) / 1e6
oylik = kunlik_sorovlar * 30 * narx_ortacha         # mediana emas!

# keshlash zararsizlik nuqtasi
kerakli_oqish = (yozish_koef - 1) / (1 - oqish_koef)

# token solig'i - o'z matningizda
nisbat = tokenlar(uz_matn) / tokenlar(en_matn)

# kontekstga sig'dirish: tizim + oxir
qolgan = byudjet - len(tizim)
oxirgi = []
for x in reversed(xabarlar):
    if tokenlar_soni(oxirgi) + len(x) > qolgan:
        break
    oxirgi.insert(0, x)

# Anthropic API: tokenlarni sanash, usage va keshlash (faqat ko'rinish)
import anthropic

client = anthropic.Anthropic()                      # ANTHROPIC_API_KEY muhitdan
soni = client.messages.count_tokens(
    model="claude-haiku-4-5-20251001",
    messages=[{"role": "user", "content": "Buyurtmam qachon yetkaziladi?"}],
)
print(soni.input_tokens)

javob = client.messages.create(
    model="claude-haiku-4-5-20251001",
    max_tokens=400,
    system=[{"type": "text", "text": KATTA_TIZIM_VA_HUJJATLAR,
             "cache_control": {"type": "ephemeral"}}],        # statik prefiks keshga
    messages=[{"role": "user", "content": savol}],             # o'zgaruvchan qism oxirida
)
u = javob.usage
print(u.input_tokens, u.output_tokens,
      u.cache_creation_input_tokens, u.cache_read_input_tokens)

Tokenlar va xarajat xulosasi

token - narx, kontekst va kechikish birligi; tokenizatorga bog'liq
o'zbekcha "soliq" 0.9x - 2.5x: tokenizator o'quv ma'lumotiga bog'liq, o'lchang
narx = kirish x narx_k + chiqish x narx_ch; chiqish qimmat
byudjet: o'rtacha va 95-persentil, til koeffitsiyenti bilan
kesh: statik boshida, trafik TTL dan zich; usage bilan o'lchang
sig'dirish: tizim doim + oxirgi xabarlar + xulosa/qidiruv

4. Batafsil misollar

Misollar real numpy bilan (Python 3.14). Narxlar — faraziy namuna, API chaqiruvi yo'q.

Misol 1 — Token solig'i: tokenizator qaysi tilda o'rgatilgan

python
"""O'zbekcha va inglizcha matnning token soni: tokenizator qaysi tilda o'rgatilgani ta'siri."""

import math
import re
from collections import Counter, defaultdict

import numpy as np

OTLAR = [("bank", "bank"), ("mijoz", "customer"), ("xodim", "employee"),
         ("filial", "branch"), ("hisob", "account"), ("to'lov", "payment"),
         ("karta", "card"), ("kredit", "loan"), ("ariza", "application"),
         ("hujjat", "document"), ("xizmat", "service"), ("narx", "price"),
         ("shartnoma", "contract"), ("talaba", "student"), ("o'qituvchi", "teacher"),
         ("dars", "lesson"), ("imtihon", "exam"), ("kitob", "book"),
         ("bemor", "patient"), ("shifokor", "doctor"), ("dori", "medicine"),
         ("buyurtma", "order"), ("mahsulot", "product"), ("ombor", "warehouse"),
         ("yetkazma", "delivery"), ("haydovchi", "driver"), ("mashina", "car"),
         ("uy", "house"), ("ijara", "rent"), ("soliq", "tax")]
FELLAR = [("och", "open", "opened", "opening"), ("yop", "close", "closed", "closing"),
          ("tekshir", "check", "checked", "checking"), ("yubor", "send", "sent", "sending"),
          ("qabul qil", "accept", "accepted", "accepting"), ("to'la", "pay", "paid", "paying"),
          ("yangila", "update", "updated", "updating"),
          ("tasdiqla", "confirm", "confirmed", "confirming"),
          ("bekor qil", "cancel", "cancelled", "cancelling"),
          ("ko'rib chiq", "review", "reviewed", "reviewing")]
EGALIK = [("", ""), ("imiz", "our"), ("ingiz", "your"), ("i", "its")]
KELISHIK = [("", ""), ("ga", "to"), ("ning", "of"), ("da", "in"), ("dan", "from"),
            ("ni", ""), ("dagi", "in"), ("gacha", "until")]
YASOVCHI = [("", ""), ("chi", "worker"), ("lik", "related"), ("siz", "without")]
ZAMON = [("di", "{o}"), ("adi", "will {v}"), ("moqda", "is {i}"), ("ishimiz kerak", "we must {v}"),
         ("ilgan", "was {o}"), ("masin", "must not {v}"), ("ib bo'ldi", "has {o}"),
         ("ayotgan", "that is {i}")]
SOZ_RE = re.compile(r"[a-z]+(?:'[a-z]+)*")
OXIR = "</w>"


def unli(soz):
    return soz[-1] in "aeiou"


def kop(en):
    if en.endswith(("x", "s", "ch")):
        return en + "es"
    if en.endswith("y") and en[-2] not in "aeiou":
        return en[:-1] + "ies"
    return en + "s"


def ot_iborasi(rng, ega=False):
    uz, en = OTLAR[rng.integers(len(OTLAR))]
    ya_uz, ya_en = YASOVCHI[rng.integers(len(YASOVCHI))] if rng.random() < 0.3 else ("", "")
    uz, en = uz + ya_uz, (f"{ya_en} {en}" if ya_en else en)
    koplik = rng.random() < 0.4
    eg_uz, eg_en = EGALIK[rng.integers(len(EGALIK))]
    ke_uz, ke_en = ("", "") if ega else KELISHIK[rng.integers(len(KELISHIK))]
    asos = uz + ("lar" if koplik else "")
    if eg_uz and unli(asos):
        eg_uz = {"imiz": "miz", "ingiz": "ngiz", "i": "si"}[eg_uz]
    elif eg_uz and asos[-1] in "kq":                   # mijozlik + i -> mijozligi
        asos = asos[:-1] + ("g" if asos[-1] == "k" else "g'")
    soz_uz = asos + eg_uz + ke_uz
    en_ot = kop(en) if koplik else en
    soz_en = " ".join(w for w in (ke_en, eg_en or "the", en_ot) if w)
    return soz_uz, soz_en


def fel(f, z):
    """Unli bilan tugagan o'zakda qo'shimcha o'zgaradi: to'la + adi -> to'laydi."""
    if unli(f):
        z = {"adi": "ydi", "ishimiz kerak": "shimiz kerak", "ilgan": "ngan",
             "ib bo'ldi": "b bo'ldi", "ayotgan": "yotgan"}.get(z, z)
    return f + z


def jumla(rng):
    """Bir xil mazmun ikki tilda: o'zbekcha SOV + qo'shimchalar, inglizcha SVO + so'zlar."""
    iboralar = [ot_iborasi(rng, k == 0) for k in range(rng.integers(2, 4))]
    f_uz, v, o, i = FELLAR[rng.integers(len(FELLAR))]
    z_uz, z_en = ZAMON[rng.integers(len(ZAMON))]
    uz = " ".join(b[0] for b in iboralar) + " " + fel(f_uz, z_uz)
    en_fel = z_en.format(v=v, o=o, i=i)
    en = iboralar[0][1] + " " + en_fel + " " + " ".join(b[1] for b in iboralar[1:])
    return uz, en


def bolakla(soz):
    return tuple(soz[:-1]) + (soz[-1] + OXIR,)


def juftlar(b):
    return list(zip(b, b[1:]))


def birlashtir(b, juft):
    a, c = juft
    yangi, i = [], 0
    while i < len(b):
        if i < len(b) - 1 and b[i] == a and b[i + 1] == c:
            yangi.append(a + c)
            i += 2
        else:
            yangi.append(b[i])
            i += 1
    return tuple(yangi)


def bpe_orgat(chastota, n_birlashma):
    """23.3-darsdagi BPE: faqat o'zgargan so'zlarning juftlari qayta sanaladi."""
    bolaklar = {s: bolakla(s) for s in sorted(chastota)}
    sanoq, joy = Counter(), defaultdict(set)
    for s, b in bolaklar.items():
        for j in juftlar(b):
            sanoq[j] += chastota[s]
            joy[j].add(s)
    qoidalar = []
    for _ in range(n_birlashma):
        if not sanoq:
            break
        eng = max(sanoq, key=lambda j: (sanoq[j], j))
        qoidalar.append(eng)
        for s in sorted(joy.pop(eng)):
            eski = bolaklar[s]
            for j in juftlar(eski):
                sanoq[j] -= chastota[s]
                if sanoq[j] <= 0:
                    del sanoq[j]
            yangi = birlashtir(eski, eng)
            bolaklar[s] = yangi
            for j in juftlar(yangi):
                sanoq[j] += chastota[s]
                joy[j].add(s)
    return {j: r for r, j in enumerate(qoidalar)}


def tokenlar_soni(matn, rang, kesh):
    n = 0
    for soz in SOZ_RE.findall(matn):
        if soz not in kesh:
            b = bolakla(soz)
            while len(b) > 1:
                nomzod = [(rang[j], j) for j in juftlar(b) if j in rang]
                if not nomzod:
                    break
                b = birlashtir(b, min(nomzod)[1])
            kesh[soz] = len(b)
        n += kesh[soz]
    return n


def main() -> None:
    rng = np.random.default_rng(0)
    uz_oquv = [jumla(rng)[0] for _ in range(3000)]
    en_oquv = [jumla(rng)[1] for _ in range(3000)]
    test = [jumla(rng) for _ in range(300)]
    oquv_shakl = len({w for j in uz_oquv for w in SOZ_RE.findall(j)})

    print("=== 1. Parallel test jumlalari (300 ta) ===")
    for uz, en in test[:2]:
        print(f"  uz: {uz}\n  en: {en}")
    for til, k in (("uz", 0), ("en", 1)):
        sozlar = [w for j in test for w in SOZ_RE.findall(j[k])]
        print(f"  {til}: {len(sozlar) / len(test):.1f} so'z/jumla, "
              f"{np.mean([len(j[k]) for j in test]):.1f} belgi/jumla, "
              f"{len(set(sozlar))} xil so'z shakli")
    print(f"  o'quv korpusidagi o'zbekcha so'z shakllari: {oquv_shakl} (3000 jumlada)")

    print("\n=== 2. Tokenizator o'quv aralashmasi -> token soni ===")
    print("  o'quv (en/uz)  birlashma  uz tok/jumla  en tok/jumla  uz/en  uz belgi/tok")
    nisbat = {}
    for en_ulush in (0.9, 0.5, 0.1):
        n_en = int(3000 * en_ulush)
        korpus = en_oquv[:n_en] + uz_oquv[:3000 - n_en]
        chastota = Counter(w for j in korpus for w in SOZ_RE.findall(j))
        for n_b in (200, 800):
            rang = bpe_orgat(chastota, n_b)
            kesh = {}
            uz_t = np.array([tokenlar_soni(u, rang, kesh) for u, _ in test])
            en_t = np.array([tokenlar_soni(e, rang, kesh) for _, e in test])
            belgi = np.mean([len(u.replace(" ", "")) for u, _ in test])
            nisbat[(en_ulush, n_b)] = uz_t / en_t
            print(f"  {en_ulush:>4.0%}/{1 - en_ulush:<4.0%} {n_b:>10} {uz_t.mean():>13.1f} "
                  f"{en_t.mean():>13.1f} {uz_t.sum() / en_t.sum():>6.2f} {belgi / uz_t.mean():>13.2f}")

    print("\n=== 3. 'Token solig'i': uz/en nisbati, jumla bo'yicha o'rtacha va SE ===")
    for kalit, r in nisbat.items():
        se = r.std(ddof=1) / math.sqrt(len(r))
        print(f"  en {kalit[0]:.0%}, {kalit[1]:>4} birlashma: {r.mean():.2f} (SE {se:.3f})")
    d = nisbat[(0.9, 200)] - nisbat[(0.5, 200)]
    se = d.std(ddof=1) / math.sqrt(len(d))
    print(f"  ingliz-og'ir - muvozanatli (200): {d.mean():+.2f}, SE {se:.3f} -> "
          f"{'sezilarli' if abs(d.mean()) > 2 * se else 'sezilarli emas'}")

    print("\n=== 4. Apostrof varianti ham baytni o'zgartiradi (UTF-8) ===")
    for nom, belgi in (("ASCII '", "'"), ("U+2019", "\u2019"), ("U+02BB", "\u02bb")):
        soz = f"o{belgi}qituvchi"
        print(f"  {nom:<8}: 'o?qituvchi' = {len(soz)} belgi, {len(soz.encode('utf-8'))} bayt")
    print("  bayt darajasidagi BPE da noodatiy apostrof -> ko'proq token va boshqa bo'linish")
    print("  ⭐ Token soni tilga emas, tokenizator o'rgatilgan ma'lumotga bog'liq")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Parallel test jumlalari (300 ta) ===
  uz: mahsulotlaringiz kartangizdan uyda bekor qiladi
  en: your products will cancel from your card in the house
  uz: narx soliqchilarimizning mijozligi tasdiqlangan
  en: the price was confirmed of our worker taxes its related customer
  uz: 4.0 so'z/jumla, 43.6 belgi/jumla, 657 xil so'z shakli
  en: 8.8 so'z/jumla, 49.1 belgi/jumla, 110 xil so'z shakli
  o'quv korpusidagi o'zbekcha so'z shakllari: 2961 (3000 jumlada)

=== 2. Tokenizator o'quv aralashmasi -> token soni ===
  o'quv (en/uz)  birlashma  uz tok/jumla  en tok/jumla  uz/en  uz belgi/tok
   90%/10%         200          28.2          11.5   2.46          1.44
   90%/10%         800           6.5           8.8   0.74          6.20
   50%/50%         200          16.0          17.6   0.91          2.53
   50%/50%         800           6.2           8.8   0.70          6.53
   10%/90%         200          10.6          30.6   0.35          3.83
   10%/90%         800           6.1           9.8   0.62          6.68

=== 3. 'Token solig'i': uz/en nisbati, jumla bo'yicha o'rtacha va SE ===
  en 90%,  200 birlashma: 2.48 (SE 0.023)
  en 90%,  800 birlashma: 0.75 (SE 0.008)
  en 50%,  200 birlashma: 0.93 (SE 0.010)
  en 50%,  800 birlashma: 0.71 (SE 0.007)
  en 10%,  200 birlashma: 0.35 (SE 0.004)
  en 10%,  800 birlashma: 0.63 (SE 0.007)
  ingliz-og'ir - muvozanatli (200): +1.55, SE 0.022 -> sezilarli

=== 4. Apostrof varianti ham baytni o'zgartiradi (UTF-8) ===
  ASCII ' : 'o?qituvchi' = 10 belgi, 10 bayt
  U+2019  : 'o?qituvchi' = 10 belgi, 12 bayt
  U+02BB  : 'o?qituvchi' = 10 belgi, 11 bayt
  bayt darajasidagi BPE da noodatiy apostrof -> ko'proq token va boshqa bo'linish
  ⭐ Token soni tilga emas, tokenizator o'rgatilgan ma'lumotga bog'liq

Nima ko'rsatdi: generator bir xil mazmunni ikki tilda yozadi: o'zbekcha — qo'shimchalar bilan (mahsulotlaringiz kartangizdan uyda bekor qiladi), inglizcha — alohida so'zlar bilan (your products will cancel from your card in the house). Sintetik jumlalar grammatik jihatdan mukammal emas, lekin asosiy xususiyatni saqlaydi: o'zbekcha jumlada so'z kam (4.0 va 8.8), so'z shakllari esa ko'p (300 jumlada 657 va 110). Tokenizatorni uch xil aralashmada o'rgatdik. 200 birlashmada (real holatga yaqin rejim: birlashmalar so'z shakllaridan ancha kam) ingliz-og'ir tokenizator o'zbekcha jumlaga 28.2 token, inglizchaga 11.5 sarfladi — nisbat 2.46 (jumla bo'yicha o'rtacha 2.48, SE 0.023). Muvozanatli korpusda nisbat 0.93, o'zbek-og'ir korpusda esa teskari: 0.35 — endi inglizcha "soliq" to'laydi. Ingliz-og'ir va muvozanatli tokenizator farqi +1.55 (SE 0.022) — sezilarli. 800 birlashma qatorlarida nisbat 0.62-0.75 ga tushdi, lekin bu bizning kichik sintetik lug'atimizning artefakti: inglizcha 110 ta shakl tezda to'liq birlashadi va qolgan birlashmalar o'zbekchaga ketadi. Real tillarda so'z shakllari lug'atdan ko'p, shuning uchun 200 birlashma qatorlari realistikroq. 4-bo'lim: bir xil o'qituvchi so'zi apostrof turiga qarab 10, 11 yoki 12 bayt. Bog'liq bo'limlar: 2.1, 2.2.

Misol 2 — Xarajat kalkulyatori

python
"""Xarajat kalkulyatori: kirish va chiqish tokenlari, taqsimot, til koeffitsiyenti, marshrutlash."""

import math

import numpy as np

# NAMUNA NARX JADVALI (FARAZIY!) - dollar / 1 million token.
# Haqiqiy narxni provayderning rasmiy sahifasidan oling: narxlar o'zgaradi.
NARX = {
    "kichik": {"kirish": 0.50, "chiqish": 2.00},
    "o'rta": {"kirish": 3.00, "chiqish": 12.00},
    "katta": {"kirish": 10.00, "chiqish": 40.00},
}
# Ish yuklari: kuniga so'rovlar, kirish va chiqish tokenlarining medianasi (inglizcha matn)
YUKLAR = {
    "chat-bot": (20000, 1500, 300),
    "hujjat xulosasi": (2000, 6000, 400),
    "maqola yozish": (500, 300, 1500),
}
KUN = 30


def narx(kirish, chiqish, model):
    n = NARX[model]
    return (kirish * n["kirish"] + chiqish * n["chiqish"]) / 1e6


def main() -> None:
    print("=== 1. Bitta so'rov narxi (NAMUNA narxlar, faraziy) ===")
    print("  model     kirish $/1M  chiqish $/1M  1500 kirish + 300 chiqish   chiqish ulushi")
    for m, n in NARX.items():
        jami = narx(1500, 300, m)
        ulush = narx(0, 300, m) / jami
        print(f"  {m:<9} {n['kirish']:>11.2f} {n['chiqish']:>13.2f} {jami:>18.5f} $ {ulush:>15.0%}")
    n = NARX["o'rta"]
    print(f"  chiqish tokeni kirishdan {n['chiqish'] / n['kirish']:.0f} barobar qimmat: 300 chiqish "
          f"narxi 1500 kirishning {300 * n['chiqish'] / (1500 * n['kirish']):.0%} iga teng")

    print("\n=== 2. Oylik xarajat: medianadan hisoblash (30 kun) ===")
    print("  ish yuki          so'rov/kun  kirish  chiqish     kichik       o'rta       katta")
    for yuk, (n, k, c) in YUKLAR.items():
        qator = " ".join(f"{n * KUN * narx(k, c, m):>10,.0f}$" for m in NARX)
        print(f"  {yuk:<17} {n:>10,} {k:>7} {c:>8} {qator}")

    print("\n=== 3. Taqsimot: medianadan hisoblash byudjetni kam ko'rsatadi ===")
    rng = np.random.default_rng(0)
    n, k_med, c_med = YUKLAR["chat-bot"]
    kirish = rng.lognormal(math.log(k_med), 0.6, n * KUN).round()
    chiqish = np.minimum(rng.lognormal(math.log(c_med), 0.8, n * KUN).round(), 2000)
    orta = "o'rta"
    oylik = narx(kirish, chiqish, orta)
    print(f"  chat-bot, o'rta model, {n * KUN:,} so'rov (log-normal uzunliklar):")
    print(f"    mediana bo'yicha hisob:  {n * KUN * narx(k_med, c_med, orta):>9,.0f} $")
    print(f"    haqiqiy yig'indi:        {oylik.sum():>9,.0f} $  "
          f"(o'rtacha kirish {kirish.mean():.0f}, chiqish {chiqish.mean():.0f})")
    print(f"    bitta so'rov: mediana {np.median(oylik):.4f} $, 95-persentil "
          f"{np.percentile(oylik, 95):.4f} $, maks {oylik.max():.4f} $")
    kunlik = oylik.reshape(KUN, n).sum(1)
    print(f"    kunlik xarajat: o'rtacha {kunlik.mean():,.0f} $, SE {kunlik.std(ddof=1) / math.sqrt(KUN):.1f}")

    print("\n=== 4. Til koeffitsiyenti: bir xil mazmun, ko'proq token ===")
    for til, koef in (("inglizcha", 1.0), ("o'zbekcha, muvozanatli tokenizator", 0.93),
                      ("o'zbekcha, ingliz-og'ir tokenizator", 2.48)):
        s = (kirish * koef).round(), (chiqish * koef).round()
        print(f"  {til:<36} x{koef:<5} oylik {narx(s[0], s[1], orta).sum():>9,.0f} $")
    print("  (koeffitsiyentlar - 1-misoldagi uz/en nisbatlari, 200 birlashma; o'z matningizda o'lchang)")

    print("\n=== 5. Marshrutlash: oson so'rovlar kichik modelga ===")
    oson = rng.random(n * KUN) < 0.8
    hammasi_orta = narx(kirish, chiqish, orta).sum()
    aralash = (narx(kirish[oson], chiqish[oson], "kichik").sum()
               + narx(kirish[~oson], chiqish[~oson], "o'rta").sum())
    print(f"  hammasi o'rta:              {hammasi_orta:>9,.0f} $")
    print(f"  80% kichik + 20% o'rta:     {aralash:>9,.0f} $  (tejam {1 - aralash / hammasi_orta:.0%})")
    for chegara in (800, 250):
        qisqa = narx(kirish, np.minimum(chiqish, chegara), orta).sum()
        print(f"  hammasi o'rta, max_tokens={chegara:<5}{qisqa:>9,.0f} $  (tejam "
              f"{1 - qisqa / hammasi_orta:.0%}, kesilgan javoblar {np.mean(chiqish > chegara):.1%})")
    print("  ⭐ Byudjet: taqsimot (o'rtacha va dum), chiqish tokenlari va til koeffitsiyenti bilan")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bitta so'rov narxi (NAMUNA narxlar, faraziy) ===
  model     kirish $/1M  chiqish $/1M  1500 kirish + 300 chiqish   chiqish ulushi
  kichik           0.50          2.00            0.00135 $             44%
  o'rta            3.00         12.00            0.00810 $             44%
  katta           10.00         40.00            0.02700 $             44%
  chiqish tokeni kirishdan 4 barobar qimmat: 300 chiqish narxi 1500 kirishning 80% iga teng

=== 2. Oylik xarajat: medianadan hisoblash (30 kun) ===
  ish yuki          so'rov/kun  kirish  chiqish     kichik       o'rta       katta
  chat-bot              20,000    1500      300        810$      4,860$     16,200$
  hujjat xulosasi        2,000    6000      400        228$      1,368$      4,560$
  maqola yozish            500     300     1500         47$        284$        945$

=== 3. Taqsimot: medianadan hisoblash byudjetni kam ko'rsatadi ===
  chat-bot, o'rta model, 600,000 so'rov (log-normal uzunliklar):
    mediana bo'yicha hisob:      4,860 $
    haqiqiy yig'indi:            6,166 $  (o'rtacha kirish 1798, chiqish 407)
    bitta so'rov: mediana 0.0090 $, 95-persentil 0.0212 $, maks 0.0817 $
    kunlik xarajat: o'rtacha 206 $, SE 0.1

=== 4. Til koeffitsiyenti: bir xil mazmun, ko'proq token ===
  inglizcha                            x1.0   oylik     6,166 $
  o'zbekcha, muvozanatli tokenizator   x0.93  oylik     5,734 $
  o'zbekcha, ingliz-og'ir tokenizator  x2.48  oylik    15,291 $
  (koeffitsiyentlar - 1-misoldagi uz/en nisbatlari, 200 birlashma; o'z matningizda o'lchang)

=== 5. Marshrutlash: oson so'rovlar kichik modelga ===
  hammasi o'rta:                  6,166 $
  80% kichik + 20% o'rta:         2,056 $  (tejam 67%)
  hammasi o'rta, max_tokens=800      5,848 $  (tejam 5%, kesilgan javoblar 10.9%)
  hammasi o'rta, max_tokens=250      4,751 $  (tejam 23%, kesilgan javoblar 58.9%)
  ⭐ Byudjet: taqsimot (o'rtacha va dum), chiqish tokenlari va til koeffitsiyenti bilan

Nima ko'rsatdi: faraziy narx jadvalida chiqish tokeni kirishdan 4 barobar qimmat, shuning uchun 1500 kirish va 300 chiqishli so'rovda chiqish tokenlarning atigi 17% i bo'lsa ham narxning 44% ini oldi. Mediana bo'yicha oylik hisob chat-bot uchun o'rta modelda 4,860 $. 3-bo'limda so'rov uzunliklari log-normal taqsimotdan olindi (mediana o'sha 1500 va 300): haqiqiy yig'indi 6,166 $ — mediana hisobidan 27% ko'p, chunki o'rtacha kirish 1798, chiqish 407. Bitta so'rovning 95-persentili medianadan 2.4 barobar qimmat (0.0212 va 0.0090 $). Kunlik xarajat juda barqaror (206 $, SE 0.1) — ko'p so'rovda tasodifiy tebranish o'rtachalanadi, lekin o'rtachaning o'zi medianadan yuqori. 4-bo'lim 1-misoldagi nisbatlarni qo'lladi: ingliz-og'ir tokenizatorda o'zbekcha chat-bot 15,291 $ — inglizchadan 2.5 barobar qimmat, muvozanatli tokenizatorda esa 5,734 $. 5-bo'lim: 80% so'rovni kichik modelga yo'naltirish narxni 67% kamaytirdi (sifatini alohida tekshirish sharti bilan); max_tokens=250 23% tejadi, lekin javoblarning 58.9% ini kesdi — max_tokens=800 esa atigi 5% tejab, 10.9% ini kesdi. Bog'liq bo'limlar: 2.4, 2.5.

Misol 3 — Prompt keshlash simulyatsiyasi

python
"""Prompt keshlash simulyatsiyasi: prefiks mosligi, TTL, trafik va tejam (virtual vaqt)."""

import hashlib
import math

import numpy as np

# NAMUNA narxlar va kesh shartlari (FARAZIY) - rasmiy hujjatdan tekshiring
KIRISH, CHIQISH = 3.00, 12.00           # $ / 1M token
YOZISH_KOEF, OQISH_KOEF = 1.25, 0.10    # kesh yozish va o'qish: kirish narxiga ko'paytuvchi
TTL = 300                               # sekund; har o'qishda yangilanadi

TIZIM = 2000                            # tizim ko'rsatmasi (token)
HUJJATLAR = 4000                        # har so'rovda beriladigan bilim bazasi
CHIQ = 300


class Kesh:
    """Prefiks keshi: kalit = prefiks matnining xeshi, qiymat = amal qilish muddati."""

    def __init__(self):
        self.muddat = {}

    def sorov(self, prefiks, t):
        kalit = hashlib.sha256(prefiks.encode()).hexdigest()
        if self.muddat.get(kalit, -1) >= t:
            self.muddat[kalit] = t + TTL
            return True
        self.muddat[kalit] = t + TTL
        return False


def prompt(t, sxema, rng):
    """(prefiks matni, prefiks tokenlari, o'zgaruvchan tokenlar) qaytaradi."""
    savol = int(rng.integers(80, 250))
    if sxema == "vaqt boshida":                # har so'rovda boshqacha -> prefiks buziladi
        return f"soat {t:.0f}|tizim v3|hujjatlar v7", TIZIM + HUJJATLAR + 10, savol
    if sxema == "sana boshida":                # kuniga bir marta o'zgaradi
        return f"kun {int(t // 86400)}|tizim v3|hujjatlar v7", TIZIM + HUJJATLAR + 10, savol
    return "tizim v3|hujjatlar v7", TIZIM + HUJJATLAR, savol + 10  # vaqt oxirida


def simulyatsiya(sxema, stavka_min, keshli, n=2000, urug=0):
    """n ta so'rov, Puasson oqimi (virtual vaqt, time.sleep yo'q)."""
    rng = np.random.default_rng(urug)
    kesh, t = Kesh(), 0.0
    narxlar, topildi = [], []
    for _ in range(n):
        t += rng.exponential(60.0 / stavka_min)
        prefiks, p_tok, o_tok = prompt(t, sxema, rng)
        if not keshli:
            kirish = (p_tok + o_tok) * KIRISH
            hit = False
        else:
            hit = kesh.sorov(prefiks, t)
            koef = OQISH_KOEF if hit else YOZISH_KOEF
            kirish = p_tok * KIRISH * koef + o_tok * KIRISH
        narxlar.append((kirish + CHIQ * CHIQISH) / 1e6)
        topildi.append(hit)
    return np.array(narxlar), np.array(topildi)


def main() -> None:
    print("=== 1. Bitta so'rov tarkibi (NAMUNA narxlar, faraziy) ===")
    print(f"  tizim {TIZIM} + hujjatlar {HUJJATLAR} + savol ~165 token; javob {CHIQ} token")
    print(f"  kesh: yozish x{YOZISH_KOEF}, o'qish x{OQISH_KOEF} kirish narxidan, TTL {TTL} s")
    oqim = (TIZIM + HUJJATLAR) * KIRISH / 1e6
    print(f"  prefiks narxi: keshsiz {oqim:.4f} $, yozish {oqim * YOZISH_KOEF:.4f} $, "
          f"o'qish {oqim * OQISH_KOEF:.4f} $")
    zarar = YOZISH_KOEF - 1
    tejam = 1 - OQISH_KOEF
    print(f"  zararsizlik nuqtasi: har yozishga {zarar / tejam:.2f} ta o'qish "
          f"({zarar:.2f} ortiqcha / {tejam:.2f} tejam)")

    print("\n=== 2. Trafik va TTL: 1000 so'rov narxi, $ (2000 so'rov simulyatsiyasi) ===")
    print("  so'rov/min   keshsiz   kesh (vaqt oxirida)  topilish   tejam")
    tejamlar = {}
    for stavka in (0.05, 0.2, 1.0, 10.0):
        a, _ = simulyatsiya("vaqt oxirida", stavka, False)
        b, h = simulyatsiya("vaqt oxirida", stavka, True)
        tejamlar[stavka] = (a - b) / a.mean()
        print(f"  {stavka:>10} {a.mean() * 1000:>9.2f} {b.mean() * 1000:>20.2f} "
              f"{h.mean():>9.1%} {1 - b.sum() / a.sum():>7.1%}")
    for stavka, d in tejamlar.items():
        if d.mean() < 0:
            print(f"  {stavka}/min: kesh har safar eskiradi -> faqat yozish, keshsizdan QIMMAT")

    print("\n=== 3. Prefiks tartibi: o'zgaruvchan qism qayerda (1 so'rov/min) ===")
    a, _ = simulyatsiya("vaqt oxirida", 1.0, False)
    for sxema in ("vaqt oxirida", "sana boshida", "vaqt boshida"):
        b, h = simulyatsiya(sxema, 1.0, True)
        print(f"  {sxema:<14}: topilish {h.mean():>6.1%}, 1000 so'rov {b.mean() * 1000:>7.2f} $ "
              f"(keshsiz {a.mean() * 1000:.2f} $)")
    print("  vaqt tamg'asi prompt boshida bo'lsa, har prefiks yangi -> kesh deyarli topilmaydi")

    print("\n=== 4. Tejamning barqarorligi: 5 urug' (1 so'rov/min) ===")
    t = []
    for urug in range(5):
        a, _ = simulyatsiya("vaqt oxirida", 1.0, False, urug=urug)
        b, _ = simulyatsiya("vaqt oxirida", 1.0, True, urug=urug)
        t.append(1 - b.sum() / a.sum())
    t = np.array(t)
    print(f"  tejam: {', '.join(f'{x:.1%}' for x in t)} -> o'rtacha {t.mean():.1%}, "
          f"SE {t.std(ddof=1) / math.sqrt(len(t)):.2%}")
    print("  ⭐ Kesh: statik qism boshida, o'zgaruvchan qism oxirida; trafik TTL dan zich bo'lsin")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Bitta so'rov tarkibi (NAMUNA narxlar, faraziy) ===
  tizim 2000 + hujjatlar 4000 + savol ~165 token; javob 300 token
  kesh: yozish x1.25, o'qish x0.1 kirish narxidan, TTL 300 s
  prefiks narxi: keshsiz 0.0180 $, yozish 0.0225 $, o'qish 0.0018 $
  zararsizlik nuqtasi: har yozishga 0.28 ta o'qish (0.25 ortiqcha / 0.90 tejam)

=== 2. Trafik va TTL: 1000 so'rov narxi, $ (2000 so'rov simulyatsiyasi) ===
  so'rov/min   keshsiz   kesh (vaqt oxirida)  topilish   tejam
        0.05     22.12                22.21     21.3%   -0.4%
         0.2     22.12                13.81     61.9%   37.6%
         1.0     22.12                 6.08     99.2%   72.5%
        10.0     22.12                 5.93    100.0%   73.2%
  0.05/min: kesh har safar eskiradi -> faqat yozish, keshsizdan QIMMAT

=== 3. Prefiks tartibi: o'zgaruvchan qism qayerda (1 so'rov/min) ===
  vaqt oxirida  : topilish  99.2%, 1000 so'rov    6.08 $ (keshsiz 22.12 $)
  sana boshida  : topilish  99.2%, 1000 so'rov    6.06 $ (keshsiz 22.12 $)
  vaqt boshida  : topilish   1.1%, 1000 so'rov   26.39 $ (keshsiz 22.12 $)
  vaqt tamg'asi prompt boshida bo'lsa, har prefiks yangi -> kesh deyarli topilmaydi

=== 4. Tejamning barqarorligi: 5 urug' (1 so'rov/min) ===
  tejam: 72.5%, 72.4%, 72.6%, 72.4%, 72.6% -> o'rtacha 72.5%, SE 0.03%
  ⭐ Kesh: statik qism boshida, o'zgaruvchan qism oxirida; trafik TTL dan zich bo'lsin

Nima ko'rsatdi: simulyatsiya soat o'rniga virtual vaqtda ishlaydi (so'rovlar Puasson oqimi, time.sleep yo'q) va kesh kalitini prefiks matnining haqiqiy sha256 xeshidan oladi. 6000 tokenli statik prefiksni o'qish keshsiz narxning o'ndan biri (0.0018 va 0.0180 $), yozish esa chorak qimmat (0.0225 $); zararsizlik uchun har yozishga 0.28 ta o'qish kerak. 2-bo'lim TTL ning ahamiyatini ko'rsatdi: daqiqasiga 0.05 so'rovda (o'rtacha 20 daqiqada bir) kesh deyarli har doim eskirgan — topilish 21.3%, narx keshsizdan biroz yuqori (-0.4% tejam). Daqiqasiga 1 so'rovda topilish 99.2%, tejam 72.5%; 10 so'rovda 73.2% — undan yuqori tejam bo'lmaydi, chunki savol va javob tokenlari keshlanmaydi. 3-bo'lim — eng qimmat xato: vaqt tamg'asini prompt boshiga qo'yish topilishni 1.1% ga tushirdi va 1000 so'rov narxini 26.39 $ ga — keshsizdan (22.12 $) ham qimmat — chiqardi. Kunlik o'zgaradigan sana boshida bo'lsa, zarar yo'q (99.2%). 4-bo'lim: 5 urug'da tejam 72.4-72.6%, SE 0.03% — natija urug'ga deyarli bog'liq emas. Bog'liq bo'lim: 2.6.

Misol 4 — Kontekst oynasiga sig'dirish strategiyalari

python
"""Kontekst oynasiga sig'dirish: boshidan, oxiridan, tizim + oxir va xulosa bilan kesish."""

import math

import numpy as np

TOLDIRUVCHI = [
    "rahmat tushundim", "yana bir savolim bor edi", "bu haqda batafsil aytib bera olasizmi",
    "albatta hozir tekshirib ko'raman", "sizga yana qanday yordam bera olaman",
    "iltimos biroz kuting", "ha shunday qilsak bo'ladi", "bu variant menga ham to'g'ri keladi",
    "narxlar haqida ham ma'lumot kerak edi", "yetkazib berish qancha vaqt oladi",
    "odatda bir necha kun ichida yetkaziladi", "to'lovni qanday usulda qilsam bo'ladi",
    "karta yoki naqd pul bilan to'lash mumkin", "yaxshi unda shu bilan davom etamiz",
]
TIZIM = ("tizim : sen do'kon yordamchisisan faqat o'zbek tilida javob ber "
         "shaxsiy ma'lumotni boshqalarga aytma xushmuomala bo'l").split()


def fakt(tur, rng):
    """Raqamli va raqamsiz faktlar; savol - shu faktning qiymati."""
    if tur == "raqamli":
        k = str(rng.integers(10000, 99999))
        return f"buyurtma raqamim {k} edi", k
    rang = str(rng.choice(["ko'k", "yashil", "qizil", "sariq", "qora", "oq"]))
    return f"menga faqat {rang} rangdagisi yoqadi", rang


def suhbat(rng, n_xabar=40):
    """Xabarlar ro'yxati (so'zlar), fakt joyi va turi."""
    xabarlar = []
    for _ in range(n_xabar):
        k = rng.integers(3, 6)
        xabarlar.append(" ".join(rng.choice(TOLDIRUVCHI, k)).split())
    tur = "raqamli" if rng.random() < 0.5 else "raqamsiz"
    joy = int(rng.integers(0, n_xabar))
    gap, qiymat = fakt(tur, rng)
    xabarlar[joy] = xabarlar[joy][:6] + gap.split() + xabarlar[joy][6:]
    return xabarlar, joy, tur, qiymat


def sigdir(xabarlar, byudjet, usul):
    """Kontekstga kiradigan so'zlar ro'yxati; tizim ko'rsatmasi alohida hisoblanadi."""
    if usul == "boshidan":
        hammasi, qism = [TIZIM] + xabarlar, []
        for x in hammasi:
            if sum(map(len, qism)) + len(x) > byudjet:
                break
            qism.append(x)
        return qism
    if usul == "oxiridan":
        hammasi, qism = [TIZIM] + xabarlar, []
        for x in reversed(hammasi):
            if sum(map(len, qism)) + len(x) > byudjet:
                break
            qism.insert(0, x)
        return qism
    qolgan = byudjet - len(TIZIM)
    oxirgi = []
    xulosa_byudjet = qolgan // 4 if usul == "tizim + xulosa + oxir" else 0
    for x in reversed(xabarlar):
        if sum(map(len, oxirgi)) + len(x) > qolgan - xulosa_byudjet:
            break
        oxirgi.insert(0, x)
    eski = xabarlar[:len(xabarlar) - len(oxirgi)]
    xulosa = []
    if xulosa_byudjet:
        # sodda ekstraktiv xulosa: raqam bor xabarlardan 8 so'zlik bo'lak
        for x in eski:
            for i, w in enumerate(x):
                if w.isdigit() and len(xulosa) + 8 <= xulosa_byudjet:
                    xulosa += ["xulosa", ":"] + x[max(0, i - 3):i + 3]
    return [TIZIM] + ([xulosa] if xulosa else []) + oxirgi


def main() -> None:
    rng = np.random.default_rng(0)
    suhbatlar = [suhbat(rng) for _ in range(400)]
    uzunlik = np.array([len(TIZIM) + sum(map(len, s[0])) for s in suhbatlar])
    print("=== 1. Ma'lumot ===")
    print("  400 suhbat, har birida 40 xabar va bitta fakt (50% raqamli, 50% raqamsiz)")
    print(f"  suhbat uzunligi: o'rtacha {uzunlik.mean():.0f} so'z (tokenni so'z deb olamiz)")
    byudjet = 150
    print(f"  kontekst byudjeti: {byudjet} so'z (suhbatning ~{byudjet / uzunlik.mean():.0%} i)")

    usullar = ["boshidan", "oxiridan", "tizim + oxir", "tizim + xulosa + oxir"]
    natija = {u: [] for u in usullar}
    for xabarlar, joy, tur, qiymat in suhbatlar:
        for u in usullar:
            kontekst = sigdir(xabarlar, byudjet, u)
            sozlar = [w for x in kontekst for w in x]
            natija[u].append((qiymat in sozlar, kontekst[0] is TIZIM, len(sozlar),
                              joy // 14, tur == "raqamli"))

    print("\n=== 2. Fakt va tizim ko'rsatmasi saqlandimi ===")
    print("  usul                    fakt   bosh  o'rta   oxir  raqamli  raqamsiz  tizim  so'z")
    arr = {u: np.array(v, dtype=float) for u, v in natija.items()}
    for u in usullar:
        a = arr[u]
        joylar = " ".join(f"{a[a[:, 3] == k, 0].mean():>6.1%}" for k in range(3))
        print(f"  {u:<22} {a[:, 0].mean():>6.1%} {joylar} {a[a[:, 4] == 1, 0].mean():>8.1%} "
              f"{a[a[:, 4] == 0, 0].mean():>9.1%} {a[:, 1].mean():>6.0%} {a[:, 2].mean():>5.0f}")

    print("\n=== 3. Juftlashgan farq: fakt saqlanishi (400 suhbat) ===")
    asos = arr["tizim + oxir"][:, 0]
    for u in ("boshidan", "oxiridan", "tizim + xulosa + oxir"):
        d = arr[u][:, 0] - asos
        se = d.std(ddof=1) / math.sqrt(len(d))
        print(f"  {u:<22} - (tizim + oxir): {d.mean():+.3f}, SE {se:.3f} -> "
              f"{'sezilarli' if abs(d.mean()) > 2 * se else 'sezilarli emas'}")

    print("\n=== 4. Xulosa (natijadan) ===")
    x = arr["tizim + xulosa + oxir"]
    if x[x[:, 4] == 1, 0].mean() > x[x[:, 4] == 0, 0].mean() + 0.2:
        print("  xulosa raqamli faktlarni saqladi, raqamsizlarini yo'qotdi -")
        print("  xulosa qoidasi nimani saqlashi kerakligini oldindan bilishi kerak")
    if arr["oxiridan"][:, 1].mean() < 0.5:
        print("  'oxiridan' kesish tizim ko'rsatmasini tashlab yubordi - bu xavfsizlik xatosi")
    print("  ⭐ Tizim ko'rsatmasi doim saqlanadi; eski qism - xulosa yoki qidiruv (RAG) bilan")


if __name__ == "__main__":
    main()

Natijaning muhim qismi:

text
=== 1. Ma'lumot ===
  400 suhbat, har birida 40 xabar va bitta fakt (50% raqamli, 50% raqamsiz)
  suhbat uzunligi: o'rtacha 832 so'z (tokenni so'z deb olamiz)
  kontekst byudjeti: 150 so'z (suhbatning ~18% i)

=== 2. Fakt va tizim ko'rsatmasi saqlandimi ===
  usul                    fakt   bosh  o'rta   oxir  raqamli  raqamsiz  tizim  so'z
  boshidan                14.0%  39.2%   0.0%   0.0%    14.5%     13.6%   100%   140
  oxiridan                15.8%   0.0%   0.0%  53.4%    15.1%     16.4%     0%   140
  tizim + oxir            13.5%   0.0%   0.0%  45.8%    13.4%     13.6%   100%   140
  tizim + xulosa + oxir   52.0%  45.5%  48.2%  64.4%   100.0%     10.3%   100%   111

=== 3. Juftlashgan farq: fakt saqlanishi (400 suhbat) ===
  boshidan               - (tizim + oxir): +0.005, SE 0.026 -> sezilarli emas
  oxiridan               - (tizim + oxir): +0.022, SE 0.007 -> sezilarli
  tizim + xulosa + oxir  - (tizim + oxir): +0.385, SE 0.026 -> sezilarli

=== 4. Xulosa (natijadan) ===
  xulosa raqamli faktlarni saqladi, raqamsizlarini yo'qotdi -
  xulosa qoidasi nimani saqlashi kerakligini oldindan bilishi kerak
  'oxiridan' kesish tizim ko'rsatmasini tashlab yubordi - bu xavfsizlik xatosi
  ⭐ Tizim ko'rsatmasi doim saqlanadi; eski qism - xulosa yoki qidiruv (RAG) bilan

Nima ko'rsatdi: 400 suhbatning har birida 40 xabar (o'rtacha 832 so'z) va bitta fakt bor; byudjet 150 so'z — suhbatning ~18% i, shuning uchun biror narsa albatta yo'qoladi. "Boshidan" saqlash faqat suhbat boshidagi faktlarni ushladi (39.2%), o'rtadagi va oxirdagilarni — hech birini. "Oxiridan" saqlash oxirgi xabarlardagi faktni 53.4% holatda saqladi, lekin tizim ko'rsatmasini 400 suhbatning birortasida ham saqlamadi (0%) — model "faqat o'zbek tilida javob ber" va "shaxsiy ma'lumotni aytma" qoidalarini "unutadi". "Tizim + oxir" buni tuzatdi (100%), fakt saqlanishi esa biroz tushdi (13.5% va 15.8%, farq +0.022, SE 0.007 — sezilarli): 14 so'zlik tizim ko'rsatmasi joy egallaydi. Xulosali strategiya faktlarning 52.0% ini saqladi (+0.385, SE 0.026) va hamma joylashuvda ishladi (45.5-64.4%) — lekin faqat raqamli faktlarda (100.0%); raqamsiz faktlarni sodda xulosamiz deyarli ushlamadi (10.3%). Bundan tashqari u byudjetni to'liq ishlatmadi (111 so'z). Bog'liq bo'limlar: 2.3, 2.7.


5. To'g'ri va noto'g'ri tushunishlar

Noto'g'ri fikr To'g'risi
"1 token = 4 belgi, hamma tilda" Faqat ingliz tilida, ingliz-markazli tokenizatorda taxminan; o'lchang
"O'zbek tili LLM uchun doim qimmat" 1-misolda nisbat 0.35 dan 2.46 gacha — tokenizator o'quv ma'lumotiga bog'liq
"Narx = tokenlar x bitta narx" Kirish va chiqish alohida; chiqish 44% ni oldi
"Byudjet = mediana x so'rovlar" Haqiqiy yig'indi 6,166 $, mediana hisobi 4,860 $
"Keshlash doim tejaydi" Siyrak trafikda (0.05/min) keshsizdan qimmat
"Prompt boshidagi vaqt belgisi zararsiz" Topilish 1.1%, narx keshsizdan 19% yuqori
"Kichik max_tokens — yaxshi tejam" 250 da 58.9% javob kesildi
"Oxirgi xabarlarni saqlash yetarli" Tizim ko'rsatmasi 0% holatda saqlandi
"Xulosa hamma narsani saqlaydi" Raqamli faktlar 100.0%, raqamsizlar 10.3%
"API suhbatni eslab qoladi" API holatsiz: tarix har so'rovda qayta yuboriladi va to'lanadi

6. Keng tarqalgan xatolar va yechimlari

1. Tokenni belgilardan taxmin qilish

python
tokenlar = len(matn) / 4                                            # ⚠️ o'zbekcha uchun
tokenlar = client.messages.count_tokens(model=m, messages=xabarlar).input_tokens  # ✅

2. Narxni kodga qotirib yozish

python
NARX = 3.0                                                          # ⚠️ qayerdan? qachon?
NARX = konfig["narxlar"][model]      # ✅ manba va sana bilan konfigda, muntazam yangilanadi

3. Kirish va chiqishni bitta narx bilan

python
narx = (kirish + chiqish) * n_kirish / 1e6                          # ⚠️
narx = (kirish * n_kirish + chiqish * n_chiqish) / 1e6              # ✅

4. Byudjet mediana bo'yicha

python
oylik = sorovlar * narx(np.median(k), np.median(c))                 # ⚠️
oylik = narx(k_namuna, c_namuna).mean() * sorovlar                  # ✅ + 95-persentil

5. Prompt boshida o'zgaruvchan qism

python
system = f"Hozirgi vaqt: {vaqt}\n{KATTA_TIZIM}"                     # ⚠️ kesh buziladi
system = KATTA_TIZIM                                                # ✅
savol = f"{savol}\n(hozirgi vaqt: {vaqt})"                          # o'zgaruvchan - oxirida

6. Oxiridan kesishda tizim ko'rsatmasi yo'qoladi

python
kontekst = hammasi[-n:]                                             # ⚠️
kontekst = [tizim] + oxirgi_xabarlar(byudjet - len(tizim))          # ✅

7. Tejamni taxmin bilan baholash

python
tejam = 0.9 * prefiks_tokenlar * narx                               # ⚠️ taxmin
tejam = sum(u.cache_read_input_tokens for u in usagelar) * narx * (1 - oqish_koef)  # ✅

7. Integratsiya — bu bilim qayerda kerak bo'ladi

  • 23.3-dars (o'tilgan): BPE algoritmi — bu darsdagi tokenizator
  • 24.11-dars (o'tilgan): KV-cache — prompt keshlash aynan shu hisobni qayta ishlatadi
  • 25.1-dars (o'tilgan): masshtab va xotira hisob-kitobi
  • 18-qism (o'tilgan): juftlashgan farq va SE — strategiyalarni taqqoslash
  • Keyingi darslar: max_tokens va stop_reason 25.3-bob, prompt tuzilishi va shablonlar 25.4-bob, API xarajatini kuzatish 25.6-bob, RAG — kontekstga faqat keraklisini qo'yish 25.8-bob, marshrutlash sifatini baholash (25.10)

8. Eng yaxshi amaliyotlar

  1. Token sonini o'z matningizda va aynan ishlatiladigan model tokenizatorida o'lchang.

  2. Narxlarni konfigda manba va sana bilan saqlang; kodga qotirmang.

  3. Kirish va chiqish tokenlarini alohida hisoblang va kuzating (usage).

  4. Byudjetni taqsimot bo'yicha rejalang: o'rtacha, 95-persentil va til koeffitsiyenti.

  5. Promptni "statik boshda, o'zgaruvchan oxirda" tartibida tuzing.

  6. Keshlashni trafik zichligi TTL ga mos bo'lganda yoqing va tejamni usage bilan o'lchang.

  7. Tizim ko'rsatmasini hech qachon kesmang; eski tarixni xulosa yoki qidiruv bilan qisqartiring.

  8. Har bir tejash qarorini (kichik model, qisqa max_tokens) sifat o'lchovi bilan tasdiqlang.


9. Amaliy topshiriq

Vazifa 1: Bashorat qiling

python
1.  # BPE birlashmalari qaysi juftlardan tanlanadi?
2.  # ingliz-og'ir korpusda o'rgatilgan tokenizator o'zbekcha matnni qanday bo'ladi?
3.  # 1-misolda muvozanatli tokenizatorda uz/en nisbati?
4.  # 2000 kirish, 500 chiqish, narxlar 3 $ va 12 $ / 1M - so'rov narxi?
5.  # nega mediana bo'yicha byudjet kam chiqadi?
6.  # kesh yozish x1.25, o'qish x0.10 - zararsizlik uchun har yozishga necha o'qish?
7.  # TTL 5 daqiqa, trafik soatiga 2 so'rov - kesh foydalimi?
8.  # prompt boshida so'rov ID si bor - keshga ta'siri?
9.  # 40 xabarli suhbatda n-xabar narxi qanday o'sadi?
10. # "oxiridan kesish" da nima yo'qolishi mumkin?
11. # 4-misolda sodda xulosa qaysi faktlarni yo'qotdi?
12. # "U+02BB" apostrofli so'z ASCII apostroflidan necha bayt uzun?
Javoblar
  1. O'quv korpusida eng ko'p uchraydigan yonma-yon juftlardan
  2. Mayda bo'laklarga — ko'p token (1-misol: 2.46 barobar)
  3. 0.93 (jumla bo'yicha o'rtacha), yig'indi bo'yicha 0.91
  4. (2000 * 3 + 500 * 12) / 1e6 = 0.012 $
  5. Uzunliklar o'ngga og'ma: yig'indi o'rtachaga bog'liq, o'rtacha esa medianadan katta
  6. 0.25 / 0.90 ≈ 0.28
  7. Yo'q — o'rtacha 30 daqiqada bir so'rov, kesh eskiradi, faqat yozish ustamasi to'lanadi
  8. Har prefiks yangi — kesh deyarli topilmaydi va yozish ustamasi to'lanadi
  9. Har so'rovda butun tarix — n-xabar kirishi ~n, butun suhbat ~n^2
  10. Tizim ko'rsatmasi (4-misol: 0% saqlandi)
  11. Raqamsiz faktlar (10.3%)
  12. 1 bayt (11 va 10)

Vazifa 2: Xatolarni tuzating

python
1.  oylik = 20000 * 30 * (1500 + 300) * 3.0 / 1e6

2.  system = f"Foydalanuvchi: {ism}. Sana: {bugun}.\n" + QOIDALAR_20_SAHIFA

3.  kontekst = xabarlar[-20:]

4.  tokenlar = len(uz_matn.split()) / 0.75

5.  if kesh_yoqilgan:
        tejam = prefiks_tokenlar * sorovlar * narx * 0.9
Javoblar
python
1.  k, c = namuna_kirish, namuna_chiqish                 # taqsimotdan
    oylik = 30 * 20000 * ((k * n_kirish + c * n_chiqish) / 1e6).mean()

2.  system = QOIDALAR_20_SAHIFA                          # statik - keshlanadi
    xabar = f"(foydalanuvchi: {ism}, sana: {bugun})\n{savol}"   # o'zgaruvchan - oxirida

3.  kontekst = [tizim] + oxirgi_xabarlar(xabarlar, byudjet - tokenlar(tizim))

4.  tokenlar = client.messages.count_tokens(model=m, messages=xabarlar).input_tokens

5.  tejam = sum(u.cache_read_input_tokens for u in usagelar) * n_kirish * (1 - 0.10) / 1e6
    ortiqcha = sum(u.cache_creation_input_tokens for u in usagelar) * n_kirish * 0.25 / 1e6
    sof_tejam = tejam - ortiqcha

Vazifa 3: Token solig'i

Modellang:

  1. Parallel o'zbekcha va inglizcha jumlalar generatori
  2. Uch xil aralashmada BPE
  3. uz/en nisbati, jumla bo'yicha SE
  4. O'z matningizdan 50 jumla bilan qayta o'lchang

Vazifa 4: Xarajat kalkulyatori

Modellang:

  1. Faraziy narx jadvali (konfigdan)
  2. Log-normal uzunliklar, o'rtacha va 95-persentil
  3. Til koeffitsiyenti
  4. Marshrutlash va max_tokens — kesilgan javoblar ulushi bilan

Vazifa 5: Keshlash

Modellang:

  1. Prefiks xeshi va TTL bilan kesh
  2. Trafik zichligi bo'yicha tejam
  3. O'zgaruvchan qism joyi
  4. Zararsizlik nuqtasi formulasi va simulyatsiya mosligi

Vazifa 6: Kontekstga sig'dirish

Modellang:

  1. Faktli suhbatlar generatori
  2. To'rt strategiya
  3. Fakt joyi va turi bo'yicha saqlanish
  4. Raqamsiz faktlarni ham saqlaydigan xulosa qoidasi (masalan, "yoqadi", "kerak" kabi kalit so'zlar) — va uning narxi

Vazifa 7: O'ylash

Moliya bo'limi aytdi: "Chat-bot oyiga 15 ming dollar bo'lyapti. Eng arzon modelga o'tamiz va max_tokens ni 150 ga tushiramiz — xarajat 10 barobar kamayadi." Siz nima deysiz?

Javob

Qisqa javob: ikkala tugma ham narxni tushiradi, lekin ular birinchi galda qo'llanadigan tugmalar emas va sifat o'lchovisiz xavfli. Avval xarajat qayerdan kelayotganini o'lchash kerak.

1. Xarajat tarkibi. 2-misolda o'zbekcha chat-bot ingliz-og'ir tokenizatorda 15,291 $, inglizchada esa 6,166 $ edi — hisobning katta qismi "token solig'i"dan. Boshqa model (boshqa tokenizator) bir xil matnga ancha kam token sarflashi mumkin. Buni count_tokens bilan 200 ta real so'rovda o'lchang.

2. Keshlash. Agar har so'rovda katta tizim ko'rsatmasi va hujjatlar bo'lsa, 3-misoldagi kabi keshlash kirish xarajatini ~70% kamaytirishi mumkin — sifatga umuman ta'sir qilmasdan. Faqat prompt boshida o'zgaruvchan qism yo'qligini tekshiring.

3. max_tokens. 2-misolda max_tokens=250 23% tejadi, lekin javoblarning 58.9% ini kesdi. 150 da bu yanada yomon: foydalanuvchi chala javob oladi va qayta so'raydi — tejam soxta.

4. Eng arzon model. Marshrutlash (oson so'rovlar kichik modelga) 2-misolda 67% tejadi — lekin faqat kichik model shu so'rovlarda yetarli sifatli bo'lsa. Buni baho to'plamida juftlashgan taqqoslash bilan tekshirish kerak 25.10-bob.

Tavsiya:

python
# 1. usage loglaridan: kirish/chiqish/kesh tokenlari taqsimoti, eng qimmat 5% so'rovlar
# 2. Keshlash: statik prefiks, TTL va trafikka mos
# 3. Muqobil modellarda o'zbekcha token soni (count_tokens)
# 4. Marshrutlash: 200 savollik baho to'plami, juftlashgan farq, keyin bosqichma-bosqich
# 5. max_tokens - javob uzunligi taqsimotining 99-persentili atrofida

Moliya bo'limiga javob: "Xarajatni kamaytirish mumkin, lekin kesilgan javoblar hisobiga emas. Avval keshlash va token sonini tekshiramiz — bu sifatga ta'sir qilmaydi. Arzon modelga o'tishni esa real savollar to'plamida sinab, sifat pasaymagan qismida bosqichma-bosqich qilamiz."

Nimani mustahkamlaydi: 2.2, 2.4, 2.5, 2.6, 2.7-bo'limlar.


Xulosa

Bu darsda token — LLM dunyosining asosiy o'lchov birligi — bilan ishlashni o'rgandik: tokenizator o'quv ma'lumotining ta'sirini o'lchadik, xarajat kalkulyatori qurdik, prompt keshlashni simulyatsiya qildik va uzun suhbatni kontekstga sig'dirish strategiyalarini solishtirdik.

Eng muhim uch fikr:

  1. Token soni tokenizatorga bog'liq — o'lchang. 1-misolda bir xil mazmunli o'zbekcha jumla ingliz-og'ir tokenizatorda 2.46 barobar ko'p token oldi, muvozanatli tokenizatorda 0.93, o'zbek-og'ir tokenizatorda esa 0.35. Agglutinatsiya so'z shakllarini ko'paytiradi (300 jumlada 657 va 110), va tokenizator ularni ko'rmagan bo'lsa, mayda bo'laklarga bo'ladi.

  2. Xarajat = kirish va chiqish, taqsimot bilan. 2-misolda chiqish tokenlari tokenlarning 17% i bo'lib, narxning 44% ini oldi; log-normal uzunliklarda haqiqiy oylik xarajat 6,166 $, mediana hisobi esa 4,860 $. Til koeffitsiyenti bir xil ishni 15,291 $ ga chiqarishi mumkin. Tejash tugmalari (marshrutlash 67%, max_tokens) sifat o'lchovi bilan birga ishlatiladi: max_tokens=250 javoblarning 58.9% ini kesdi.

  3. Kesh va kontekst — tartib masalasi. 3-misolda statik prefiks boshida bo'lganda kesh 72.5% tejadi, prompt boshidagi vaqt belgisi esa topilishni 1.1% ga tushirib, narxni keshsizdan ham qimmat qildi; siyrak trafikda ham kesh foyda bermadi. 4-misolda "oxiridan kesish" tizim ko'rsatmasini 100% holatda tashlab yubordi; xulosa strategiyasi faktlarni 52.0% saqladi, lekin faqat o'zi "bilgan" turdagilarini.

Keyingi darsda generatsiya parametrlari: temperature, top_p, top_k, max_tokens, stop ketma-ketliklari va takror jarimalarini API nuqtai nazaridan kichik modelimizda o'lchaymiz, stop_reason bilan kesilgan javoblarni aniqlaymiz va temperature=0 nega har doim aynan bir xil javob bermasligini ko'ramiz.

Ulashish:Telegram'da

Izohlar (0)

Izoh yozish uchun kiring.

  • Hozircha izoh yo'q. Birinchi bo'ling!
25.2-dars: Tokenlar, kontekst va xarajat — IlmHamroh