aidoc.uz

1-qism · Matndan til modeligacha·03-bob

Katta til modellari

Miqyos qonuni, kutilmagan qobiliyatlar va MoE. Haqiqiy API bilan ishlash, token va xarajatni hisoblash, LoRA bilan arzon moslash, RLHF va prompt muhandisligi.

Transformer bloklarini bilamiz. Endi savol: agar ularni juda ko'p qilib, juda ko'p matnda o'qitsak nima bo'ladi?

Javob kutilmagan bo'ldi. Ma'lum o'lchamdan keyin modelda hech kim maxsus o'rgatmagan qobiliyatlar paydo bo'la boshladi.

Miqyos qonuni#

OpenAI 2020-yilda kutilmagan darajada aniq bog'liqlik topdi. Model sifati uchta narsaga bog'liq va bog'liqlik darajali funksiya ko'rinishida:

L(N) = (Nc / N)^αN        N — parametrlar soni
L(D) = (Dc / D)^αD        D — o'quv tokenlari
L(C) = (Cc / C)^αC        C — hisoblash quvvati

Buning amaliy ahamiyati juda katta: modelni o'qitmasdan turib uning sifatini hisoblash mumkin.

import numpy as np
import matplotlib.pyplot as plt
 
def yoqotish(N, N_c=8.8e13, alpha=0.076):
    """Miqyos qonuni: parametr soniga qarab kutilayotgan xato."""
    return (N_c / N) ** alpha
 
parametrlar = np.logspace(6, 12, 100)      # 1M dan 1T gacha
plt.loglog(parametrlar, yoqotish(parametrlar))
plt.xlabel("parametrlar soni")
plt.ylabel("xato (loss)")
plt.grid(True, which="both", alpha=0.3)
plt.show()

Grafikda to'g'ri chiziq chiqadi (log-log o'qlarda). Ya'ni bog'liqlik shunchalik barqarorki, uni bir necha nuqta bo'yicha chizib, davomini bashorat qilish mumkin.

Chinchilla: hamma noto'g'ri qilayotgan ekan#

2022-yilda DeepMind muhim tuzatish kiritdi. Ular savol berdi: berilgan hisoblash byudjetida model kattaligi va ma'lumot hajmini qanday taqsimlash kerak?

Javob kutilmagan edi: o'sha paytdagi barcha modellar kam ma'lumotda o'qitilgan.

ModelParametrTokenlarNisbat
GPT-3 (2020)175B300B1.7 : 1
Chinchilla (2022)70B1.4T20 : 1

Chinchilla GPT-3 dan 2.5 barobar kichik, lekin deyarli barcha testlarda undan yaxshiroq natija berdi.

Qoida sodda: har bir parametrga taxminan 20 ta token.

def chinchilla_optimal(parametrlar):
    """Berilgan model hajmi uchun kerakli token soni."""
    return parametrlar * 20
 
for p in [1e9, 7e9, 70e9]:
    print(f"{p/1e9:>5.0f}B parametr → {chinchilla_optimal(p)/1e9:>6.0f}B token kerak")
    1B parametr →     20B token kerak
    7B parametr →    140B token kerak
   70B parametr →   1400B token kerak

Kutilmagan qobiliyatlar#

Emergent properties — kichik modelda umuman yo'q, katta modelda birdan paydo bo'ladigan qobiliyatlar.

Diqqat qiling: asta-sekin yaxshilanmaydi. Model ma'lum chegaragacha tasodifiy darajada ishlaydi, keyin qisqa oraliqda deyarli mukammal darajaga chiqadi.

kritik miqyostasodifiy darajamodel hajmi →sifat
Emergent qobiliyat: chegaragacha tasodifiy, keyin keskin sakrash

Taxminiy chegaralar:

MiqyosPaydo bo'lgan qobiliyat
~10 mlrdArifmetik hisob
~100 mlrdMantiqiy xulosa, o'z-o'zini baholash, ko'rsatmaga amal qilish
~500 mlrdSababiy mulohaza, geometrik shakllar

Kontekst oynasi va uning narxi#

Model bir vaqtda ko'ra oladigan maksimal token miqdori. Narxi kvadratik — buni raqamlar bilan ko'ramiz:

def attention_narxi(n_token):
    """E'tibor matritsasi kataklari soni."""
    return n_token ** 2
 
for n in [512, 4096, 32_000, 200_000, 1_000_000]:
    kataklar = attention_narxi(n)
    xotira_gb = kataklar * 2 / 1024**3        # float16 = 2 bayt
    print(f"{n:>9,} token → {kataklar:>18,} katak → {xotira_gb:>8.1f} GB")
      512 token →            262,144 katak →      0.0 GB
    4,096 token →         16,777,216 katak →      0.0 GB
   32,000 token →      1,024,000,000 katak →      1.9 GB
  200,000 token →     40,000,000,000 katak →     74.5 GB
1,000,000 token →  1,000,000,000,000 katak →  1,862.6 GB

Bir million tokenli kontekst uchun sof e'tibor matritsasi 1.8 terabayt xotira talab qiladi — bitta qatlam, bitta head uchun.


Mixture of Experts#

Katta model qimmat, chunki har bir token butun tarmoqdan o'tadi. Lekin bu shartmi?

MoE g'oyasi: modelni mutaxassislarga bo'lish va har bir tokenni faqat 1-2 tasiga yuborish.

token kiradi
masalan «def» — kod so'zi
ROUTER
qaysi mutaxassis kerak? → 3 va 7
mutaxassis 3 · mutaxassis 7
faqat shu ikkisi hisoblanadi
1, 2, 4, 5, 6, 8 — bo'sh
xotirada turadi, lekin ishlamaydi
natijalar birlashtiriladi
MoE: router har bir tokenni kerakli mutaxassislarga yo'naltiradi, qolganlari ishlamaydi

Router qanday ishlashini kodda ko'ramiz:

import numpy as np
 
 
def router(token_vektori, W_router, top_k=2):
    """Tokenni qaysi mutaxassislarga yuborishni hal qiladi."""
    ballar = token_vektori @ W_router              # (n_expert,)
    tanlangan = np.argsort(ballar)[::-1][:top_k]   # eng yuqori k tasi
 
    # Faqat tanlanganlar orasida normallashtiramiz
    ogirliklar = np.exp(ballar[tanlangan])
    ogirliklar = ogirliklar / ogirliklar.sum()
 
    return tanlangan, ogirliklar
 
 
np.random.seed(7)
token = np.random.randn(64)
W_router = np.random.randn(64, 8)          # 8 ta mutaxassis
 
tanlangan, ogirliklar = router(token, W_router)
print("tanlangan mutaxassislar:", tanlangan)
print("ularning ulushi:", np.round(ogirliklar, 3))
tanlangan mutaxassislar: [5 2]
ularning ulushi: [0.731 0.269]
MoE nima beradi
  • Pre-training tezroq — har token butun modeldan o'tmaydi
  • Inferens tezroq — faol parametrlar soni kam
  • Kengaytirish oson — yangi mutaxassis qo'shasiz
  • Har biri o'z sohasiga ixtisoslashadi: kod, matematika, tabiiy til
Nima evaziga
  • BUTUN model xotirada turishi shart — VRAM talabi kamaymaydi
  • O'qitish beqaror, ortiqcha moslashish xavfi yuqori
  • Router 2-3 ta mashhur mutaxassisga qarab qolishi mumkin (load imbalance)
  • Fine-tuning va tushuntirish murakkabroq

Router muvozanatsizligi jiddiy muammo — uni hal qilish uchun o'qitishga maxsus 'load balancing loss' qo'shiladi, u router hamma mutaxassisdan teng foydalanishga undaydi.


Amaliyot: haqiqiy model bilan ishlash#

Nazariya yetarli. Endi haqiqiy API bilan ishlaymiz — bu bobning eng amaliy qismi.

  1. O'rnatish va kalit

    terminal
    pip install anthropic
    Successfully installed anthropic-1.2.0 httpx2-0.29.0 ...

    API kalitini muhit o'zgaruvchisiga yozing, kodga emas:

    terminal
    export ANTHROPIC_API_KEY='sk-ant-...'

    Windows PowerShell'da: $env:ANTHROPIC_API_KEY = "sk-ant-..."

    Doimiy qilish uchun ~/.zshrc yoki ~/.bashrc fayliga qo'shing.

  2. Birinchi so'rov

    import anthropic
     
    # Kalit muhit o'zgaruvchisidan avtomatik olinadi
    client = anthropic.Anthropic()
     
    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        messages=[
            {"role": "user", "content": "Rekursiyani bir jumlada tushuntiring."}
        ],
    )
     
    # response.content — bloklar RO'YXATI, oddiy satr emas
    for block in response.content:
        if block.type == "text":
            print(block.text)
  3. Tizim ko'rsatmasi berish

    response = client.messages.create(
        model="claude-opus-5",
        max_tokens=1024,
        system=(
            "Siz o'zbek tilida javob beradigan dasturlash o'qituvchisiz. "
            "Har bir tushuntirishni ishlaydigan Python kodi bilan yakunlang."
        ),
        messages=[{"role": "user", "content": "Dekorator nima?"}],
    )

    system — bu alohida maydon, messages ichida emas. U modelning umumiy xulq-atvorini belgilaydi va butun suhbat davomida amal qiladi.

  4. Suhbatni davom ettirish

    Model xotirasiz. Har so'rovda butun tarixni yuborishingiz kerak:

    suhbat = []
     
    def sora(matn):
        suhbat.append({"role": "user", "content": matn})
     
        response = client.messages.create(
            model="claude-opus-5",
            max_tokens=1024,
            messages=suhbat,
        )
     
        javob = "".join(b.text for b in response.content if b.type == "text")
        suhbat.append({"role": "assistant", "content": javob})
        return javob
     
     
    print(sora("Python'da ro'yxatni qanday saralayman?"))
    print(sora("Teskari tartibda-chi?"))     # model oldingi savolni "eslaydi"

    Ikkinchi savolda "nimani teskari tartibda" deb aytmadik — chunki tarix yuborildi.

  5. Oqim (streaming)

    Uzun javoblarda foydalanuvchi bo'sh ekranga qarab o'tirmasligi kerak:

    with client.messages.stream(
        model="claude-opus-5",
        max_tokens=4096,
        messages=[{"role": "user", "content": "Transformer arxitekturasini tushuntiring."}],
    ) as stream:
        for matn in stream.text_stream:
            print(matn, end="", flush=True)
     
        # Oxirida to'liq javob va statistika
        xabar = stream.get_final_message()
        print(f"\n\nTokenlar: {xabar.usage.input_tokens}{xabar.usage.output_tokens}")

Tokenni oldindan sanash#

So'rov yuborishdan oldin uning necha token ekanini bilish mumkin:

natija = client.messages.count_tokens(
    model="claude-opus-5",
    messages=[{"role": "user", "content": open("hujjat.txt").read()}],
)
print("kirish tokenlari:", natija.input_tokens)

Xarajatni hisoblash#

Bu — loyihaning yashashi yoki o'lishini hal qiladigan hisob.

# 2026-yil holatiga ko'ra, 1M token uchun narx (dollarda)
NARXLAR = {
    "claude-opus-5":   {"kirish": 5.00, "chiqish": 25.00},
    "claude-sonnet-5": {"kirish": 2.00, "chiqish": 10.00},
    "claude-haiku-4-5": {"kirish": 1.00, "chiqish":  5.00},
}
 
 
def xarajat(model, kirish_tokenlar, chiqish_tokenlar):
    n = NARXLAR[model]
    return (kirish_tokenlar * n["kirish"] + chiqish_tokenlar * n["chiqish"]) / 1_000_000
 
 
# Misol: kuniga 10 000 ta so'rov, har birida 2000 kirish + 500 chiqish
kunlik = 10_000
for model in NARXLAR:
    bir_sorov = xarajat(model, 2000, 500)
    print(f"{model:<18} 1 so'rov: ${bir_sorov:.5f}   oyiga: ${bir_sorov * kunlik * 30:>9,.0f}")
claude-opus-5      1 so'rov: $0.02250   oyiga: $    6,750
claude-sonnet-5    1 so'rov: $0.00900   oyiga: $    2,700
claude-haiku-4-5   1 so'rov: $0.00600   oyiga: $    1,800

Prompt keshlash — eng katta tejash#

Agar so'rovlaringizning boshi bir xil bo'lsa (uzun tizim ko'rsatmasi, hujjat, misollar), uni keshlash mumkin:

response = client.messages.create(
    model="claude-opus-5",
    max_tokens=1024,
    system=[
        {
            "type": "text",
            "text": uzun_hujjat,                          # masalan 50 000 token
            "cache_control": {"type": "ephemeral"},       # SHU YERGACHA keshlanadi
        }
    ],
    messages=[{"role": "user", "content": savol}],        # bu har safar o'zgaradi
)
 
print("keshdan o'qildi:", response.usage.cache_read_input_tokens)

Xatolarni to'g'ri boshqarish#

import time
import random
import anthropic
 
logger = logging.getLogger(__name__)
 
 
def sora_ishonchli(prompt, urinishlar=4):
    """Qayta urinish bilan xavfsiz chaqiruv."""
    for i in range(urinishlar):
        try:
            return client.messages.create(
                model="claude-opus-5",
                max_tokens=4096,
                messages=[{"role": "user", "content": prompt}],
            )
 
        except anthropic.NotFoundError:
            logger.error("Model topilmadi — model nomini tekshiring")
            raise                                   # qayta urinish foydasiz
 
        except anthropic.AuthenticationError:
            logger.error("Kalit noto'g'ri yoki muddati o'tgan")
            raise                                   # qayta urinish foydasiz
 
        except anthropic.RateLimitError:
            kutish = 2**i + random.random()         # 1s, 2s, 4s, 8s + tasodif
            logger.warning("Chegara oshdi, %.1f s kutamiz", kutish)
            time.sleep(kutish)
 
        except anthropic.APIStatusError as e:
            if e.status_code >= 500:                # server tomonda — qayta urinamiz
                time.sleep(2**i + random.random())
            else:
                logger.error("So'rov xatosi: %s", e)
                raise
 
        except anthropic.APIConnectionError:
            time.sleep(2**i + random.random())      # tarmoq — qayta urinamiz
 
    raise RuntimeError("Bir necha urinishdan keyin ham muvaffaqiyatsiz")
Amaliy topshiriq

Xarajat kuzatuvchisi bilan chatbot yozing

Terminalda ishlaydigan chatbot yozing. Talablar:

  1. Suhbat tarixini saqlaydi va davom ettiradi
  2. Har javobdan keyin shu so'rovning narxini va jami sarfni ko'rsatadi
  3. Xatolarni yuqoridagi qoidaga ko'ra boshqaradi
  4. Tarix 20 xabardan oshsa — eski qismini xulosalab qisqartiradi
  5. /narx buyrug'i to'liq hisobotni chiqaradi

Qo'shimcha: uzun tizim ko'rsatmasini keshlang va cache_read_input_tokens ni kuzating — tejash qanchalik ekanini o'lchang.

Maslahatni ko'rsatish

Tuzilma: class Chatbot: def __init__(self, model="claude-opus-5"): self.client = anthropic.Anthropic() self.model = model self.suhbat = [] self.jami_kirish = 0 self.jami_chiqish = 0 def sora(self, matn): ... def hisobot(self): ... Kontekstni qisqartirish uchun eng sodda usul: if len(self.suhbat) > 20: # birinchi 10 tasini xulosaga almashtiring xulosa = self.client.messages.create(... 'quyidagi suhbatni xulosala' ...) self.suhbat = [{'role':'user','content':f'Oldingi suhbat xulosasi: {xulosa}'}] + self.suhbat[-10:] Jitter'ni unutmang va har chaqiruvda usage'ni yig'ib boring.


LoRA: katta modelni arzon moslash#

100 milliard parametrli modelni fine-tuning qilish uchun ulkan infratuzilma kerak. Lekin hiyla bor va u juda nafis.

Asosiy kuzatuv#

Fine-tuning paytida og'irliklar o'zgarishi ΔW — bu ortiqcha ma'lumotga to'la matritsa. Uni ancha kichikroq shaklda ifodalash mumkin.

odatdagi: W' = W + ΔW
ΔW ham W kabi ulkan — 1000×1000 = 1M parametr
LoRA: W' = W + B·A
A: 1000×8, B: 8×1000 = 16K parametr
LoRA: katta ΔW matritsasi ikkita kichik matritsaning ko'paytmasi bilan almashtiriladi

Raqamlar bilan:

d = 1000          # matritsa o'lchami
r = 8             # LoRA rangi
 
toliq = d * d
lora = d * r + r * d
 
print(f"To'liq fine-tuning: {toliq:>10,} parametr")
print(f"LoRA (r={r}):        {lora:>10,} parametr")
print(f"Tejash:              {toliq / lora:>10.0f} barobar")
To'liq fine-tuning:  1,000,000 parametr
LoRA (r=8):             16,000 parametr
Tejash:                     62 barobar

GPT-3 miqyosida: 175 milliard o'rniga 17.5 million parametr o'qitiladi — 0.01%.

LoRA'ni noldan yozamiz#

import torch
import torch.nn as nn
 
 
class LoRALinear(nn.Module):
    """Muzlatilgan chiziqli qatlam + o'qitiladigan past rangli qo'shimcha."""
 
    def __init__(self, asl_qatlam: nn.Linear, r=8, alpha=16):
        super().__init__()
        self.asl = asl_qatlam
        self.asl.weight.requires_grad = False        # ASL OG'IRLIKLAR MUZLATILADI
        if self.asl.bias is not None:
            self.asl.bias.requires_grad = False
 
        kirish = asl_qatlam.in_features
        chiqish = asl_qatlam.out_features
 
        # A tasodifiy, B NOL — boshida qo'shimcha ta'siri nol bo'lsin
        self.A = nn.Parameter(torch.randn(r, kirish) * 0.01)
        self.B = nn.Parameter(torch.zeros(chiqish, r))
        self.masshtab = alpha / r
 
    def forward(self, x):
        return self.asl(x) + (x @ self.A.T @ self.B.T) * self.masshtab
 
 
# Sinab ko'ramiz
asl = nn.Linear(512, 512)
lora = LoRALinear(asl, r=8)
 
jami = sum(p.numel() for p in lora.parameters())
oqitiladigan = sum(p.numel() for p in lora.parameters() if p.requires_grad)
 
print(f"Jami parametr:        {jami:>8,}")
print(f"O'qitiladigan:        {oqitiladigan:>8,}")
print(f"Ulush:                {oqitiladigan / jami:>8.2%}")
Jami parametr:         271,872
O'qitiladigan:           8,192
Ulush:                    3.01%

Amaliyotda: PEFT kutubxonasi#

from peft import LoraConfig, get_peft_model, TaskType
from transformers import AutoModelForCausalLM
 
model = AutoModelForCausalLM.from_pretrained("mistralai/Mistral-7B-v0.3")
 
config = LoraConfig(
    task_type=TaskType.CAUSAL_LM,
    r=16,                                   # rang — katta bo'lsa ko'proq sig'im
    lora_alpha=32,                          # odatda 2 × r
    lora_dropout=0.05,
    target_modules=["q_proj", "v_proj"],    # odatda attention matritsalari
)
 
model = get_peft_model(model, config)
model.print_trainable_parameters()
trainable params: 3,407,872 || all params: 7,251,431,424 || trainable%: 0.047

7 milliard parametrli model, 3.4 million o'qitiladigan. Bu oddiy bitta GPU'da bajariladi.

ParametrTa'siriTavsiya
rSig'im. Katta = ko'proq o'rganadi, qimmatroq8–32
lora_alphaQo'shimchaning kuchiodatda 2 × r
target_modulesQaysi qatlamlarga qo'llashq_proj, v_proj dan boshlang
lora_dropoutOrtiqcha moslashishdan himoya0.05

LoRA'ning yana bir katta afzalligi: bitta asosiy model, o'nlab moslama. Har vazifa uchun alohida 10 MB'lik LoRA fayli saqlanadi va kerak bo'lganda almashtiriladi.


Alignment: modelni odamga moslash#

Pre-training'dan keyin model — bu juda aqlli avtoto'ldirgich. U bilim to'plagan, lekin uning maqsadi "foydali javob berish" emas, "matnni davom ettirish".

1. SFT — nazorat ostida moslash
odamlar 10-100 ming so'rovga ideal javob yozadi; model ularni taqlid qiladi
2. Mukofot modeli
odamlar javoblarni yaxshidan yomonga tartiblaydi; shu asosda BALL QO'YUVCHI model o'qitiladi
3. PPO bilan optimallashtirish
model javob beradi → mukofot modeli ball qo'yadi → model yangilanadi
RLHF — uch bosqichli jarayon

DPO — soddaroq muqobil#

RLHF qimmat va beqaror: annotatorlar yollash kerak, RL o'qitish nozik.

DPO mukofot modelini butunlay olib tashlaydi:

Ma'lumot:  <so'rov, yomonroq javob, yaxshiroq javob>
Vazifa:    yaxshiroq javob ehtimolligini oshir, yomonini kamaytir

Oddiy backpropagation — RL kerak emas. Bugun ko'p jamoalar shuni tanlaydi.

DPO
  • Mukofot modeli kerak emas — bitta model kamroq
  • Oddiy backpropagation, RL beqarorligi yo'q
  • Kamroq hisoblash resursi
  • Amalga oshirish ancha sodda
RLHF (PPO)
  • Mukofot modeli kerak — qo'shimcha o'qitish
  • RL beqaror, sozlash nozik
  • Qimmatroq
  • Lekin murakkab holatlarda hamon aniqroq nazorat beradi

Boshlash uchun DPO. Agar sizga afzalliklar ustidan nozik nazorat kerak bo'lsa yoki DPO natijasi yetarli bo'lmasa — RLHF'ga o'ting.


Kichik va tez modellar#

Har doim ham 100 milliard parametr kerak emas.

Kvantlash#

Og'irliklar yuqori aniqlikdagi turdan pastroqqa o'tkaziladi:

def model_hajmi(parametrlar, bit):
    """Model xotirada necha GB joy egallaydi."""
    return parametrlar * bit / 8 / 1024**3
 
 
p = 7e9      # 7 milliard parametr
 
for nom, bit in [("float32", 32), ("float16", 16), ("int8", 8), ("int4", 4)]:
    print(f"{nom:<9} {bit:>2} bit → {model_hajmi(p, bit):>6.1f} GB")
float32   32 bit →   26.1 GB
float16   16 bit →   13.0 GB
int8       8 bit →    6.5 GB
int4       4 bit →    3.3 GB

int4 da 7B model oddiy noutbukka sig'adi.

from transformers import AutoModelForCausalLM, BitsAndBytesConfig
import torch
 
konfig = BitsAndBytesConfig(
    load_in_4bit=True,
    bnb_4bit_compute_dtype=torch.bfloat16,     # hisoblash aniqroq turda
    bnb_4bit_quant_type="nf4",                 # normal float 4 — eng yaxshi variant
    bnb_4bit_use_double_quant=True,            # kvantlash konstantalarini ham siqadi
)
 
model = AutoModelForCausalLM.from_pretrained(
    "mistralai/Mistral-7B-v0.3",
    quantization_config=konfig,
    device_map="auto",
)

Pruning — keraksiz og'irliklarni kesish#

import torch.nn.utils.prune as prune
 
# Eng kichik 30% og'irlikni nolga tenglaymiz
for nom, modul in model.named_modules():
    if isinstance(modul, nn.Linear):
        prune.l1_unstructured(modul, name="weight", amount=0.3)
        prune.remove(modul, "weight")          # o'zgarishni doimiy qilamiz

Multimodal modellar#

Til modeli faqat matn bilan ishlaydi. Lekin agar biror ma'lumot turini vektorga aylantira olsak — uni transformer blokiga bera olamiz. Butun multimodallik shu bitta g'oyaga tayanadi.

ViT: rasm ham ketma-ketlik#

Vision Transformer rasmni 16×16 kvadratchalarga bo'ladi. Har bir kvadratcha — token.

import numpy as np
 
 
def rasmni_boklarga_bol(rasm, p=16):
    """
    rasm — (H, W, C) massiv
    Natija — (N, p*p*C), ya'ni tokenlar ketma-ketligi
    """
    H, W, C = rasm.shape
    assert H % p == 0 and W % p == 0, "o'lcham kvadratchaga bo'linishi kerak"
 
    bloklar = rasm.reshape(H // p, p, W // p, p, C)
    bloklar = bloklar.transpose(0, 2, 1, 3, 4)         # (H/p, W/p, p, p, C)
    return bloklar.reshape(-1, p * p * C)
 
 
rasm = np.random.rand(224, 224, 3)
tokenlar = rasmni_boklarga_bol(rasm, p=16)
 
print("tokenlar:", tokenlar.shape)                     # (196, 768)
print("N =", (224 * 224) // (16 * 16))                 # 196

Formula: N = (H × W) / P²

Nega alohida piksel emas? Chunki bitta piksel deyarli hech qanday ma'lumot tashimaydi va 224 × 224 = 50176 token e'tibor uchun juda ko'p (kvadratik narxni eslang).

CLIP: matn va rasmni bitta fazoga#

CLIP ikkita encoder o'qitadi va to'g'ri juftlik vektorlarini yaqinlashtiradi.

Yaqinlik qanday o'lchanadi? Kosinus o'xshashligi — birinchi bobdagi o'sha formula.

from sentence_transformers import SentenceTransformer, util
from PIL import Image
 
model = SentenceTransformer("clip-ViT-B-32")
 
rasmlar = [Image.open(f) for f in ["mushuk.jpg", "it.jpg", "mashina.jpg"]]
izohlar = ["mushuk divanda", "it bog'da yuguryapti", "ko'chada mashina"]
 
r_vek = model.encode(rasmlar, convert_to_tensor=True)
m_vek = model.encode(izohlar, convert_to_tensor=True)
 
oxshashlik = util.cos_sim(r_vek, m_vek)
print(oxshashlik.round(decimals=2))

Diagonal qiymatlar eng yuqori bo'lishi kerak — ya'ni har bir rasm o'z izohiga eng yaqin.

Bu zero-shot tasniflash imkonini beradi: modelga yorliqlar ro'yxatini berasiz, u rasmni maxsus o'qitilmasdan tasniflaydi.


Gallyutsinatsiya va qarash#

Gallyutsinatsiya#

Model ishonch bilan noto'g'ri javob beradi. Ikki turi bor:

TuriNimaMisol
FaktualTekshiriladigan faktga zidMavjud bo'lmagan maqolaga havola
SodiqlikBerilgan kontekstga zidHujjatda yo'q narsani hujjatdan deb aytish

Qarashni o'lchash#

Model o'quv ma'lumotidagi qarashlarni o'zlashtiradi va ba'zan kuchaytiradi. Buni o'lchash mumkin:

import evaluate
 
toxicity = evaluate.load("toxicity")
natija = toxicity.compute(predictions=model_javoblari, aggregation="ratio")
print("zararli javoblar ulushi:", natija)
 
# Ikki guruh uchun javoblarni solishtirish
regard = evaluate.load("regard", "compare")
natija = regard.compute(data=guruh1_javoblari, references=guruh2_javoblari)

Bir tajribada model "direktor" haqidagi promptlarni "yuk mashinasi haydovchisi" haqidagilardan ancha ijobiyroq to'ldirgan.


Prompt muhandisligi#

In-context learning#

LLM'ning eng g'aroyib xususiyati: promptga bir nechta misol qo'ysangiz, model yangi vazifani bajara boshlaydi — hech qanday qayta o'qitishsiz.

To'rt uslub — solishtirib ko'ramiz#

SAVOL = """Do'konda 23 ta olma bor edi. 20 tasini sotishdi,
keyin 6 ta olib kelishdi. Hozir nechta olma bor?"""
 
uslublar = {
    "zero-shot": SAVOL,
 
    "zero-shot CoT": SAVOL + "\n\nQadam-baqadam o'ylab ko'ring.",
 
    "few-shot": """Savol: 5 ta qalam bor edi, 2 tasi sindi, 3 ta sotib olindi. Nechta?
Javob: 5 - 2 = 3, keyin 3 + 3 = 6. Javob: 6.
 
Savol: """ + SAVOL + "\nJavob:",
 
    "CoT few-shot": """Savol: 5 ta qalam bor edi, 2 tasi sindi, 3 ta sotib olindi. Nechta?
Javob: Boshida 5 ta bor edi.
       2 tasi sindi: 5 - 2 = 3 ta qoldi.
       3 ta qo'shildi: 3 + 3 = 6 ta.
       Javob: 6.
 
Savol: """ + SAVOL + "\nJavob:",
}
 
for nom, prompt in uslublar.items():
    javob = client.messages.create(
        model="claude-opus-5",
        max_tokens=512,
        messages=[{"role": "user", "content": prompt}],
    )
    matn = "".join(b.text for b in javob.content if b.type == "text")
    print(f"\n=== {nom} ===\n{matn.strip()[:200]}")

Ilg'or usullar#

Self-consistency — bitta savolga bir necha javob generatsiya qilib, ko'pchilik ovozini olish:

from collections import Counter
 
javoblar = []
for _ in range(5):
    j = client.messages.create(
        model="claude-opus-5",
        max_tokens=512,
        messages=[{"role": "user", "content": SAVOL + "\n\nQadam-baqadam o'ylang."}],
    )
    matn = "".join(b.text for b in j.content if b.type == "text")
    javoblar.append(matn.strip().split()[-1])       # oxirgi so'z — javob
 
print("eng ko'p uchragan javob:", Counter(javoblar).most_common(1))

Narxi 5 barobar, lekin qiyin masalalarda aniqlik sezilarli oshadi.

Tree of Thoughts — model bir nechta fikr yo'lini quradi, ularni o'zi baholaydi va eng yaxshisini tanlaydi. Yanada qimmatroq, lekin eng murakkab masalalarda ishlaydi.

Amaliy topshiriq

Prompt uslublarini o'lchang

20 ta matematik masaladan iborat test to'plami tuzing va to'rt uslubni solishtiring.

Har biri uchun o'lchang:

  1. Aniqlik — nechta masala to'g'ri yechildi
  2. Narx — jami qancha token sarflandi
  3. Samaradorlik — 1% aniqlik oshishi qanchaga tushdi

Savol: qaysi uslub eng yaxshi narx-sifat nisbatini beradi? Javob sizni hayron qoldirishi mumkin.

Maslahatni ko'rsatish

Test to'plami uchun g'oyalar: - GSM8K datasetidan 20 ta masala (huggingface.co/datasets/gsm8k) - O'zingiz 20 ta oddiy matematik masala yozing - Mantiqiy jumboqlar O'lchash: natijalar = {} for uslub, shablon in uslublar.items(): togri = 0 jami_narx = 0 for masala, javob in test_toplami: r = sora(shablon.format(masala=masala)) if javobni_ajrat(r) == javob: togri += 1 jami_narx += xarajat(...) natijalar[uslub] = (togri/len(test), jami_narx) Javobni ajratish uchun regex ishlating: re.search(r'Javob:\s*(-?\d+)', matn) Natijani jadval qilib chiqaring: uslub | aniqlik | narx | 1% aniqlik narxi


Xulosa#

miqyos qonuni
sifatni oldindan hisoblash mumkin
N, D, C
Chinchilla
har parametrga ~20 token
ma'lumot muhimroq
emergent qobiliyatlar
chegaradan keyin keskin sakrash
bahsli
MoE
faqat kerakli mutaxassis ishlaydi
tezroq inferens
LoRA + kvantlash
arzon moslash
0.01% parametr
RLHF / DPO
odam afzalliklariga moslash
alignment
Transformer'dan LLM'gacha
Yodda saqlang
  • 01Miqyos qonuni sifatni oldindan hisoblash imkonini beradi — lekin Chinchilla ko'rsatdiki, sifatli ma'lumot parametr sonidan muhimroq.
  • 02Kontekst narxi kvadratik. 1M token uchun e'tibor matritsasi terabaytlar egallaydi — shuning uchun FlashAttention kabi optimizatsiyalar zarur.
  • 03LoRA — amaliyotda eng ko'p kerak bo'ladigan texnika. 7B modelni oddiy GPU'da moslash mumkin. B matritsasi nol bilan boshlanadi — bu barqarorlik uchun.
  • 04Har chaqiruvda usage'ni loglang va tokenni count_tokens bilan sanang. tiktoken Claude uchun noto'g'ri natija beradi.
  • 05Xatolarni ikkiga ajrating: qayta urinish foydali (429, 5xx, tarmoq) va foydasiz (401, 404, 400). Jitter'ni unutmang.
  • 06Gallyutsinatsiya — arxitektura oqibati, xato emas. Modelda tekshirish mexanizmi yo'q. Buni prompt bilan to'liq hal qilib bo'lmaydi — tashqi ma'lumot manbasi kerak.

Oxirgi fikr bizni keyingi qismga olib boradi. Model matn yozadi — lekin nega unga kod ishga tushirish, internetdan qidirish, bazaga murojaat qilish imkonini bermaymiz?

Mana shu agent tushunchasining boshlanishi.