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.
| Model | Parametr | Tokenlar | Nisbat |
|---|---|---|---|
| GPT-3 (2020) | 175B | 300B | 1.7 : 1 |
| Chinchilla (2022) | 70B | 1.4T | 20 : 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.
Taxminiy chegaralar:
| Miqyos | Paydo bo'lgan qobiliyat |
|---|---|
| ~10 mlrd | Arifmetik hisob |
| ~100 mlrd | Mantiqiy xulosa, o'z-o'zini baholash, ko'rsatmaga amal qilish |
| ~500 mlrd | Sababiy 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.
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]
- 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
- 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.
O'rnatish va kalit
terminalpip install anthropicSuccessfully installed anthropic-1.2.0 httpx2-0.29.0 ...API kalitini muhit o'zgaruvchisiga yozing, kodga emas:
terminalexport ANTHROPIC_API_KEY='sk-ant-...'Windows PowerShell'da:
$env:ANTHROPIC_API_KEY = "sk-ant-..."Doimiy qilish uchun
~/.zshrcyoki~/.bashrcfayliga qo'shing.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)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,messagesichida emas. U modelning umumiy xulq-atvorini belgilaydi va butun suhbat davomida amal qiladi.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.
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")Xarajat kuzatuvchisi bilan chatbot yozing
Terminalda ishlaydigan chatbot yozing. Talablar:
- Suhbat tarixini saqlaydi va davom ettiradi
- Har javobdan keyin shu so'rovning narxini va jami sarfni ko'rsatadi
- Xatolarni yuqoridagi qoidaga ko'ra boshqaradi
- Tarix 20 xabardan oshsa — eski qismini xulosalab qisqartiradi
/narxbuyrug'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.
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.
| Parametr | Ta'siri | Tavsiya |
|---|---|---|
r | Sig'im. Katta = ko'proq o'rganadi, qimmatroq | 8–32 |
lora_alpha | Qo'shimchaning kuchi | odatda 2 × r |
target_modules | Qaysi qatlamlarga qo'llash | q_proj, v_proj dan boshlang |
lora_dropout | Ortiqcha moslashishdan himoya | 0.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".
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.
- Mukofot modeli kerak emas — bitta model kamroq
- Oddiy backpropagation, RL beqarorligi yo'q
- Kamroq hisoblash resursi
- Amalga oshirish ancha sodda
- 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 qilamizMultimodal 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)) # 196Formula: 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:
| Turi | Nima | Misol |
|---|---|---|
| Faktual | Tekshiriladigan faktga zid | Mavjud bo'lmagan maqolaga havola |
| Sodiqlik | Berilgan kontekstga zid | Hujjatda 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.
Prompt uslublarini o'lchang
20 ta matematik masaladan iborat test to'plami tuzing va to'rt uslubni solishtiring.
Har biri uchun o'lchang:
- Aniqlik — nechta masala to'g'ri yechildi
- Narx — jami qancha token sarflandi
- 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#
- 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.