Asosiy qismga o'tish

tez9: yetti soatlik muvaffaqiyatsizlik

21-bob 5 kod bloki 2049 so'z

Katta qadam

tez8 dan keyin Tez real hayotga yaqinlashtirildi. Birinchi marta haqiqiy, ommaga ochiq jadvallar ustida test to'plamlari yasaldi (6-qism), va ularda tez8 ning zaif joylari ko'rindi: "qila olmayman" deya olmaydi, butun jadval bo'yicha bitta jami yo'q, Excel faylning sarlavha ustidagi nomini bilmaydi. Bu kamchiliklarning hammasi bitta keyingi modelda tuzatilishi rejalashtirildi — tez9.

tez9 ning ma'lumoti va engine iga kiritilgan o'zgarishlar:

  • 858 ta "qila olmayman" qatori (17-bob);
  • butun jadval bo'yicha jami va count_distinct (yangi tool shakllari, va shu uchun schema o'zgarishi);
  • to'rtta yangi sintetik jadval;
  • Excel loaderi va promptda jadval nomi (11-bob);
  • "eng yaqin yozilish" qoidasi (10-bob);
  • yangi partiyalar: shartlar, oraliqlar, jamilar, qisqa so'rovlar.

Sozlama — tez8 niki bilan aynan bir xil. Saqlangan fayllardan:

python18 qator
import json
import re
from datetime import datetime

def jadvallar(model):
    nom = re.compile(r'Table "([^"]+)" \(')
    return {nom.search(json.loads(q)["messages"][0]["content"]).group(1)
            for q in open(Path.home() / f"tez_runs/{model}/data/train.jsonl", encoding="utf-8")}

for model in ("tez8", "tez9"):
    qatorlar = sum(1 for _ in open(Path.home() / f"tez_runs/{model}/data/train.jsonl", encoding="utf-8"))
    print(f"{model}: {qatorlar:,} qator, {len(jadvallar(model))} ta jadval")
print("sozlamalar bir xilmi:",
      (Path.home() / "tez_runs/tez8/soup.yaml").read_text() == (Path.home() / "tez_runs/tez9/soup.yaml").read_text())

boshlanish = datetime.strptime(json.load(open(Path.home() / "tez_runs/tez9/output/soup_run.json"))["run_id"][4:19], "%Y%m%d_%H%M%S")
oxirgi = datetime.fromtimestamp((Path.home() / "tez_runs/tez9/output/checkpoint-1465/trainer_state.json").stat().st_mtime)
print(f"o'qitish: {boshlanish:%H:%M} dan {oxirgi:%H:%M} gacha, {(oxirgi - boshlanish).seconds / 3600:.1f} soat")
Chiqish
tez8: 19,886 qator, 14 ta jadval
tez9: 24,666 qator, 18 ta jadval
sozlamalar bir xilmi: True
o'qitish: 11:27 dan 18:17 gacha, 6.8 soat

Olti yarim soatdan ko'p training. Keyin — birinchi test.

Birinchi zarba va noto'g'ri xulosa

Birinchi natija yomon edi: o'n bitta to'plamda tez8 ning 472 to'g'ri javobiga qarshi tez9 — 446. Birinchi xulosa: "tez9 yomon o'qitilgan".

9-bobda bu xulosaning nega noto'g'ri ekanini ko'rdik. tez9 ning schema o'zgarishi (group_by ixtiyoriy) grammar da kalitlar tartibini buzgan edi: model group_by ni birinchi yozishni o'rgangan, grammar esa unga ruxsat bermagan. Va tez9 ning yangi grammar dagi natijasi tez8 ning eski grammar dagi natijasi bilan solishtirilgan edi — ikki narsa bir vaqtda o'zgargan.

Grammar tuzatildi (har bir kalit o'z variantida majburiy), va ikkala model qaytadan, bir xil grammar bilan, bir xil 745 savolda sinaldi. Bu — adolatli benchmark.

Adolatli natija

python19 qator
import glob

TOZA = ["loans", "deposits", "cash_desk", "transactions", "realistic_loans", "realistic_deposits", "realistic_cash"]
GURUHLAR = {
    "toza": TOZA,
    "shovqinli": [f"noisy_{t}" for t in TOZA],
    "real": sorted(Path(f).parent.name for f in glob.glob(str(TEZ / "accuracy/suites/real_*/questions.json"))),
}

def hukmlar(prefiks, toplamlar):
    return {(t, j["id"]): j for t in toplamlar for j in map(json.loads, open(TEZ / f"results/{prefiks}_cpu_{t}.jsonl", encoding="utf-8"))}

jami8 = jami9 = 0
for guruh, toplamlar in GURUHLAR.items():
    t8, t9 = hukmlar("tez8g", toplamlar), hukmlar("tez9g", toplamlar)
    b8, b9 = sum(j["correct"] for j in t8.values()), sum(j["correct"] for j in t9.values())
    jami8, jami9 = jami8 + b8, jami9 + b9
    print(f"{guruh:10s} {len(t8):4d} savol:  tez8 {b8},  tez9 {b9}")
print(f"{'jami':10s}  745 savol:  tez8 {jami8},  tez9 {jami9}")
Chiqish
toza        320 savol:  tez8 315,  tez9 308
shovqinli   320 savol:  tez8 311,  tez9 310
real        105 savol:  tez8 81,  tez9 80
jami        745 savol:  tez8 707,  tez9 698

Grammar tuzatilgandan keyin ham tez9 yutqazdi. Har uchala guruhda ham tez8 dan ozgina past. Yetti soatga yaqin training — va eski model yaxshiroq.

Lekin "ozgina" qanchalik ishonchli? 19-bobda ko'rdik: modellar orasida tasodifiy farq bor. Buni o'lchashning oddiy usuli — bootstrap: savollarni qaytarib-qaytarib tasodifiy tanlab, farqni o'n ming marta qayta hisoblash. Farqning 95 foiz oralig'i nolni o'z ichiga olsa — farq tasodif bo'lishi mumkin:

python12 qator
import random

def oraliq(prefiks_a, prefiks_b, toplamlar, marta=10000):
    a, b = hukmlar(prefiks_a, toplamlar), hukmlar(prefiks_b, toplamlar)
    farqlar = [int(b[k]["correct"]) - int(a[k]["correct"]) for k in sorted(a)]
    tasodif = random.Random(1)
    yigindilar = sorted(sum(tasodif.choice(farqlar) for _ in farqlar) for _ in range(marta))
    return sum(farqlar), yigindilar[int(0.025 * marta)], yigindilar[int(0.975 * marta)]

for nom, toplamlar in (("real (105)", GURUHLAR["real"]), ("hammasi (745)", sum(GURUHLAR.values(), []))):
    farq, past, yuqori = oraliq("tez8g", "tez9g", toplamlar)
    print(f"{nom:14s} tez9 - tez8 = {farq:+d}, 95% oraliq [{past:+d}, {yuqori:+d}]")
Chiqish
real (105)     tez9 - tez8 = -1, 95% oraliq [-7, +5]
hammasi (745)  tez9 - tez8 = -9, 95% oraliq [-19, +1]

Real jadvallarda: farq bitta savol, oraliq esa ikki tomonga bir necha savol — tez9 va tez8 ni ajratib bo'lmaydi. Hamma savollar bo'yicha: tez9 to'qqiz savolga past, oraliq deyarli nolgacha yetadi — chegarada. Ya'ni tez9 yaxshiroq emas, va ehtimol biroz yomonroq.

Ship qoidalari (tez9 dan oldin yozilgan) bo'yicha tez9 o'tmadi: toza to'plamlarda 97 foiz talabi ham bajarilmadi (320 dan 308 — 96.3 foiz), real jadvallarda "aniq yuqori" talabi — yo'q, va bir nechta tuzoq turi yomonlashdi. tez8 mahsulot modeli bo'lib qoldi.

Nima yaxshilandi, nima buzildi

Real jadvallardagi tuzoq turlari bo'yicha:

python12 qator
tuzoqlar = {}
for t in GURUHLAR["real"]:
    savollar = {s["id"]: s for s in json.load(open(TEZ / f"accuracy/suites/{t}/questions.json", encoding="utf-8"))}
    for prefiks in ("tez8g", "tez9g"):
        for j in map(json.loads, open(TEZ / f"results/{prefiks}_cpu_{t}.jsonl", encoding="utf-8")):
            tur = savollar[j["id"]].get("trap", "oddiy")
            h = tuzoqlar.setdefault(tur, {"savollar": 0, "tez8g": 0, "tez9g": 0})
            h["savollar"] += prefiks == "tez8g"
            h[prefiks] += j["correct"]
for tur, h in sorted(tuzoqlar.items(), key=lambda x: x[1]["tez9g"] - x[1]["tez8g"]):
    if h["tez8g"] != h["tez9g"]:
        print(f"{tur:12s} {h['savollar']:3d} savol:  tez8 {h['tez8g']},  tez9 {h['tez9g']}")
Chiqish
translation    9 savol:  tez8 8,  tez9 6
oddiy         37 savol:  tez8 34,  tez9 33
vague          6 savol:  tez8 5,  tez9 4
followup       7 savol:  tez8 6,  tez9 5
tool_gap       6 savol:  tez8 1,  tez9 5

Bitta katta yutuq — tool_gap: "qila olmayman" bir savoldan beshtaga. Va bir nechta yo'qotish: tarjima qilingan qiymatlar, davomli suhbat, noaniq so'rovlar, oddiy savollar. Yo'qotilgan savollarni birma-bir ko'raylik — tez8 to'g'ri, tez9 xato:

python7 qator
for t in GURUHLAR["real"]:
    savollar = {s["id"]: s for s in json.load(open(TEZ / f"accuracy/suites/{t}/questions.json", encoding="utf-8"))}
    t8 = hukmlar("tez8g", [t]); t9 = hukmlar("tez9g", [t])
    for k in sorted(t8):
        if t8[k]["correct"] and not t9[k]["correct"]:
            print(f"{t} #{k[1]} [{savollar[k[1]].get('trap', 'oddiy')}] {savollar[k[1]]['text']}")
            print(f"   tez9: {t9[k]['output'][:120]}")
Chiqish
real_banks #12 [oddiy] kreditlar bo'yicha diagramma
   tez9: {"steps":[{"tool":"make_chart","args":{"chart":"bar","x":"Kreditsumma","y":"Kreditulushi","agg":"sum"}}]}
real_fx_rates #9 [vague] kurslar
   tez9: {"steps":[{"tool":"select_columns","args":{"columns":["G4"]}}]}
real_regions #3 [translation] Samarqand viloyati
   tez9: {"steps":[{"tool":"filter","args":{"column":"Regions","op":"contains","value":"Samarqand"}}]}
real_regions #18 [translation] Qoraqalpog'iston
   tez9: {"steps":[{"tool":"filter","args":{"column":"Regions","op":"contains","value":"Qoraqalpog'iston"}}]}
real_regions #20 [followup] boshidan, barcha viloyatlarni kredit bo'yicha sarala
   tez9: {"on":"result","steps":[{"tool":"sort","args":{"by":"Total loan portfolio","descending":true}}]}
real_retail #10 [oddiy] oylik savdo miqdori oldingi oy bilan
   tez9: {"steps":[{"tool":"period_compare","args":{"date_column":"InvoiceDate","value_column":"UnitPrice","period":"month","comp

Ikkita xato — "Samarqand viloyati" va "Qoraqalpog'iston" — bir xil turda: jadvalda qiymat inglizcha ("Samarkand region"), model esa foydalanuvchining o'zbekcha so'zini contains bilan qidirdi. Bitta xato — "boshidan" deyilganda ham joriy natija ustida davom etish. Qolganlari — tasodifiy ko'rinadigan ustun tanlovlari.

Nega sababini bilib bo'lmaydi

Mana tez9 ning eng qimmat saboqi. Har bir yo'qotish uchun bir nechta mumkin bo'lgan sabab bor:

  • contains xatosi — yangi ma'lumotdanmi? Yoki "eng yaqin yozilish" qoidasidanmi? Yoki tez8 ham shu odatga ega edi-yu, bu safar tasodifan boshqa tomonga og'dimi? (Keyinroq tekshirildi: contains ga foydalanuvchi so'zini ko'chirish odati ikkala modelning training ma'lumotida bor edi — tez8 bu ikki savolda tasodifan = ni tanlagan.)
  • noaniq so'rovlarda taxmin qilish — "qila olmayman" qatorlaridanmi (model "savol bermaslik"ni ham o'rgandimi)? Yoki qisqa so'rovlar partiyasidanmi?
  • umumiy pasayish — to'rtta yangi jadvaldanmi? Yoki shunchaki ma'lumot ko'payib, eski ko'nikmalarning ulushi kamayganidanmi?

Javob yo'q. tez9 da bir vaqtda kamida oltita katta narsa o'zgargan, va bitta training ularning ta'sirini ajrata olmaydi. Har bir o'zgarishni alohida sinash — har biri olti-yetti soat.

Xatolar jurnalida bu 16-raqam:

tez9 ni yangi ma'lumot va schema o'zgarishi bilan birga o'qitdik, shuning uchun bitta training qaysi o'zgarish yordam berganini va qaysi biri zarar qilganini ko'rsata olmadi. Qoida: har bir o'qitilgan modelda imkon qadar bitta narsani o'zgartir.

eval_loss yana aldadi

Bitta kichik, lekin muhim kuzatuv. tez9 ning oxirgi eval_loss i 0.0446, tez8 niki 0.0366 — tez9 "yomonroq". tez7 niki esa 0.024 — hammasidan "yaxshi", garchi tez8 dan ancha past natija bergan bo'lsa ham. 19-bobdagi saboq yana tasdiqlandi: har bir modelning tekshirish qatorlari — o'z faylining oxirgi qismi, ular har xil, va eval_loss modellarni solishtirish uchun yaroqsiz. Hal qiluvchi narsa — test.

tez10 ning tug'ilishi

tez9 dan bitta aniq, o'lchangan yutuq qoldi: "qila olmayman" qatorlari ishlaydi (tool_gap birdan beshga). Qolgani — noaniq. Shuning uchun keyingi model shunday rejalashtirildi:

tez10 = tez8 ning aynan o'zi + faqat 858 ta "qila olmayman" qatori. Boshqa hech narsa.

15-bobda bu qanchalik qiyin ekanini ko'rdik: bitta seed muammosi tufayli tez8 ning qatorlarini alohida qayta eksport qilish, va tekshirish qismi oxirida qolishi uchun fayllarni maxsus tartibda birlashtirish kerak bo'ldi. tez10 bu kitob yozilayotgan paytda o'qitilmoqda. Agar u tez8 dan yutsa — "qila olmayman" qatorlari tasdiqlanadi. Yutmasa — biz kamida aniq bilamiz: ular o'zi zarar qiladi.

Xulosa

  • tez9 tez8 ning zaif joylarini bir vaqtda tuzatishga urindi: kamida oltita katta o'zgarish, olti yarim soatdan ko'p training.
  • Birinchi natija grammar xatosi tufayli soxta yomon edi; adolatli benchmarkda ham tez9 tez8 dan yutmadi: 745 savoldan 698 ga qarshi 707.
  • Bootstrap oralig'i: real jadvallarda farq tasodif chegarasida; hammasi bo'yicha tez9 biroz yomonroq.
  • Bitta aniq yutuq — "qila olmayman" (1 dan 5 ga); bir nechta yo'qotish.
  • Ko'p o'zgarish birga — sababni bilib bo'lmaydi. Qoida: bir modelda bitta o'zgarish. Undan tez10 tug'ildi.
  • eval_loss modellarni solishtirish uchun yaroqsiz.

Bu bobni bepul o'qidingiz.

Kitob o'rgatadi, lekin sizning kodingiz nega ishlamaganini ayta olmaydi. Kursda uy vazifangiz tekshiriladi.

Telegramda yozish Narxlar