Asosiy qismga o'tish

Birinchi modellar: pilot4b dan tez5 gacha

19-bob 4 kod bloki 1865 so'z

To'rtta model, bitta sozlama

18-bobda Qwen3.5-4B tanlandi. Bu bobda u bilan o'qitilgan birinchi to'rtta model: pilot4b, tez3, tez4 va tez5. Ularning hammasi bir xil Soup sozlamasi bilan o'qitilgan — farq faqat ma'lumotda. Bu tasodif emas: sozlama o'zgarmasa, natijadagi farqni ma'lumotga bog'lash mumkin.

Har bir model haqida saqlangan narsalar — training fayli va training logi — ~/tez_runs papkasida. Ulardan jadval yasaymiz:

python19 qator
import json
import re
import pandas as pd

def log_qiymatlari(model):
    log = (Path.home() / f"tez_runs/{model}/train.log").read_text(encoding="utf-8", errors="replace").replace("\r", "\n")
    yoqotish = re.findall(r"'eval_loss': '([0-9.]+)'", log)
    vaqt = re.findall(r"'train_runtime': '([0-9.]+)'", log)
    return float(yoqotish[-1]) if yoqotish else "yozilmagan", round(float(vaqt[-1]) / 3600, 1) if vaqt else "yozilmagan"

qatorlar = []
for model in ("pilot4b", "tez3", "tez4", "tez5"):
    soni = sum(1 for _ in open(Path.home() / f"tez_runs/{model}/data/train.jsonl", encoding="utf-8"))
    yoqotish, soat = log_qiymatlari(model)
    qatorlar.append({"model": model, "o'qitish qatorlari": soni, "oxirgi eval_loss": yoqotish, "o'qitish, soat": soat})
show(pd.DataFrame(qatorlar))

sozlamalar = {m: (Path.home() / f"tez_runs/{m}/soup.yaml").read_text(encoding="utf-8") for m in ("pilot4b", "tez3", "tez4", "tez5")}
print("to'rtala sozlama bir xilmi:", len(set(sozlamalar.values())) == 1)
Chiqish
to'rtala sozlama bir xilmi: True
modelo'qitish qatorlarioxirgi eval_losso'qitish, soat
pilot4b1 6100.0631
tez35 2740.025yozilmagan
tez45 4660.033yozilmagan
tez55 4660.032yozilmagan

Uchta logda training vaqti yozilmagan — Soup ning o'sha versiyasi uni har doim ham chiqarmagan. Va bir narsa allaqachon ko'rinib turibdi: eval_loss (tekshirish qismidagi xato) tez3 dan keyin kamaymaydi, hatto biroz oshadi. Bu yomon belgimi? Keyinroq ko'ramiz.

Test: 200 savol

Bu bosqichda Tez to'rtta "toza" test to'plamiga ega edi: tranzaksiyalar va kreditlar (40 tadan), depozitlar va kassa (60 tadan). Kassa jadvali trainingda umuman bo'lmagan. Har bir model shu 200 savolda sinalgan; o'qitilmagan Qwen3.5-4B ham. Saqlangan hukmlar:

python13 qator
TOPLAMLAR = ("transactions", "loans", "deposits", "cash_desk")

def natija(prefiks):
    jami = {}
    for toplam in TOPLAMLAR:
        javoblar = [json.loads(q) for q in open(TEZ / f"results/{prefiks}_{toplam}.jsonl", encoding="utf-8")]
        jami[toplam] = sum(j["correct"] for j in javoblar)
    jami["jami (200)"] = sum(jami.values())
    return jami

jadval = pd.DataFrame({izoh: natija(p) for p, izoh in (("ab_A", "o'qitilmagan 4B"), ("pilot4b", "pilot4b"),
                                                       ("tez3", "tez3"), ("tez4", "tez4"), ("tez5", "tez5"))}).T
show(jadval.reset_index().rename(columns={"index": "model"}))
modeltransactionsloansdepositscash_deskjami (200)
o'qitilmagan 4B35374250164
pilot4b31343934138
tez339385155183
tez437375059183
tez538375355183

Ikki narsa darhol ko'rinadi. Birinchisi — yomon: pilot4b o'qitilmagan modeldan yomonroq. Ikkinchisi — g'alati: tez3, tez4 va tez5 — uchalasi ham aynan 183.

Bu hukmlar o'sha paytdagi engine bilan chiqarilgan. Keyinchalik engine va grammar o'zgargan (9-bob), shuning uchun bu jadvalni keyingi boblardagi raqamlar bilan to'g'ridan-to'g'ri solishtirib bo'lmaydi. Lekin bu to'rtta model o'zaro — bir xil sharoitda.

pilot4b: training modelni yomonlashtirdi

Birinchi o'qitilgan model o'qitilmaganidan 26 savolga yomonroq chiqdi. Eng yomoni — kassa jadvalida, ya'ni train qilishda ko'rilmagan jadvalda.

Sabab o'sha kuni topildi va 12-bobdagi "dangasa o'qituvchi" bilan bog'liq: birinchi partiyada so'rovlarning ko'pchiligida xom ustun nomlari bor edi — "summa_uzs bo'yicha jamla". Model foydalanuvchi so'rovidagi so'zni ustun nomi sifatida ko'chirishni o'rgandi. Kassa jadvalida esa ustun nomlari boshqacha edi, va model noto'g'ri — matnli — ustunni tanlab, uni jamlashga urindi.

Har bir modelning training faylida nechta so'rov o'z jadvalining pastki chiziqli ustun nomini o'z ichiga olishini sanaymiz:

python15 qator
ustun = re.compile(r"^- (.+?) \(\w+\), (?:all values|samples): ", re.M)

def xom_nom_ulushi(model):
    jami = topildi = 0
    for qator in open(Path.home() / f"tez_runs/{model}/data/train.jsonl", encoding="utf-8"):
        q = json.loads(qator)
        nomlar = [n for n in ustun.findall(q["messages"][0]["content"]) if "_" in n]
        sorov = [m for m in q["messages"] if m["role"] == "user"][-1]["content"].lower()
        jami += 1
        topildi += any(re.search(rf"(?<!\w){re.escape(n.lower())}(?!\w)", sorov) for n in nomlar)
    return topildi, jami

for model in ("run1", "pilot4b", "tez3", "tez4", "tez5"):
    topildi, jami = xom_nom_ulushi(model)
    print(f"{model:8s} {topildi:5,} / {jami:,} = {topildi / jami:.0%}")
Chiqish
run1       887 / 1,638 = 54%
pilot4b    884 / 1,610 = 55%
tez3       267 / 5,274 = 5%
tez4       339 / 5,466 = 6%
tez5       339 / 5,466 = 6%

pilot4b ning so'rovlarining yarmidan ko'pida xom ustun nomi bor. O'sha kuni yozilgan hisobotda bu ulush "75 foiz" deb aytilgan — u boshqacha sanash bilan olingan edi; yuqoridagi son aniq qoida bilan: so'rovda shu qatorning o'z jadvalidagi pastki chiziqli nom bormi. Qaysi sanash bo'lmasin, xulosa bir xil.

Tuzatish ikki qismli edi: 12-bobdagi leaked tekshiruvi (xom nomli matn qayta yoziladi yoki tashlanadi) va 15-bobdagi sarlavhalarni qayta nomlash (model bitta jadvalni har xil nomlar bilan ko'radi va nomni ko'chirish o'rniga ma'noni tushunishga majbur bo'ladi). tez3 da ulush yigirmadan birga tushdi — nol emas: ba'zi so'rovlar ustun nomini qiymat sifatida haqli ravishda ishlatadi.

tez3: birinchi yaxshi model

tez3 — 5 274 qator, uch baravardan ko'p ma'lumot, xom nomlarsiz va qayta nomlangan sarlavhalar bilan. Natija: 200 dan 183, o'qitilmagan modeldan 19 savol yaxshi. Kassa — trainingda ko'rilmagan jadval — 55 dan 60.

Qolgan 17 xatoning sababi tahlil qilindi, va asosiy topilma 14-bobdagi tekshiruv bilan bog'liq edi: o'sha paytda training ma'lumotini Gemma tekshirardi va faqat Gemma tushungan matnlar qolardi. Gemma xato tushunadigan, lekin to'g'ri matnlar tashlanardi — va aynan o'sha holatlar modelning zaif joylari bo'lib qoldi. Shundan keyin "qutqarish" bosqichi qo'shildi (14-bob).

tez4 va tez5: bir xil ball, har xil savollar

tez4 tez3 ning aniq xatolarini nishonga oldi: suhbatda "boshidan boshla" ("on": "table") uchun 149 ta aniq qator, noaniq davom so'rovlari uchun 92 ta savol qatori, allaqachon jamlangan natija ustida grafik uchun 146 qator, va filtr qiymatlari faqat jadvaldagi ro'yxatdan. tez5 esa suhbatdagi "on" maydonini javobning boshiga qo'ydi.

Ikkalasi ham — 183. Lekin bir xil 183 mi? Uchta modelning javoblarini savolma-savol solishtiramiz:

python13 qator
def hukmlar(prefiks):
    return {(toplam, j["id"]): j["correct"]
            for toplam in TOPLAMLAR
            for j in map(json.loads, open(TEZ / f"results/{prefiks}_{toplam}.jsonl", encoding="utf-8"))}

t3, t4, t5 = hukmlar("tez3"), hukmlar("tez4"), hukmlar("tez5")
for nom, oldin, keyin in (("tez3 -> tez4", t3, t4), ("tez4 -> tez5", t4, t5), ("tez3 -> tez5", t3, t5)):
    tuzaldi = sum(1 for k in oldin if not oldin[k] and keyin[k])
    buzildi = sum(1 for k in oldin if oldin[k] and not keyin[k])
    print(f"{nom}: tuzaldi {tuzaldi}, buzildi {buzildi}, ball {sum(oldin.values())} -> {sum(keyin.values())}")
uchalasi_togri = sum(1 for k in t3 if t3[k] and t4[k] and t5[k])
kamida_bittasi_xato = sum(1 for k in t3 if not (t3[k] and t4[k] and t5[k]))
print(f"uchala model ham to'g'ri topgan savollar: {uchalasi_togri}, kamida bittasi xato qilgan: {kamida_bittasi_xato}")
Chiqish
tez3 -> tez4: tuzaldi 6, buzildi 6, ball 183 -> 183
tez4 -> tez5: tuzaldi 5, buzildi 5, ball 183 -> 183
tez3 -> tez5: tuzaldi 7, buzildi 7, ball 183 -> 183
uchala model ham to'g'ri topgan savollar: 173, kamida bittasi xato qilgan: 27

Har bir yangi model nishonga olingan xatolarni tuzatdi — va shuncha boshqa savolni buzdi. Ball joyida turdi, lekin javoblar almashdi.

Bu bobning eng muhim saboqi shu yerda: 200 savollik testda modellar orasida bir necha savollik "shovqin" bor. Har bir training tasodifiy son bilan boshlanadi, ma'lumot biroz farq qiladi, va chegarada turgan savollar u yoqqa ham, bu yoqqa ham og'adi. O'sha kuni yozilgan xulosa: bu test modellar orasidagi besh savollik farqni ajrata olmaydi.

Bu saboq keyinchalik ikki narsaga aylandi. Birinchi: training qatorlarining o'zida ma'lum turdagi holatlar qanchalik to'g'ri ekanini o'lchash (masalan, tez5 da "boshidan boshla" 65 foizdan 90 foizga ko'tarilgan — 200 savollik ball buni ko'rsatmagan). Ikkinchi: testlarni kattalashtirish — keyinroq 745 ta savol va real jadvallar (6-qism), va eng oxirida ishonch oralig'i (14-model-dasturida).

eval_loss nima demaydi

Jadvaldagi eval_loss ga qaytamiz. tez3 — 0.025, tez4 — 0.033, tez5 — 0.032. Xato oshdi, lekin test ball bir xil qoldi. Nega?

Chunki har bir modelning tekshirish qismi — o'z faylining oxirgi 5 foizi — boshqa qatorlar. tez4 ning ma'lumotiga qiyinroq qatorlar qo'shilgan (suhbatlar, savollar), va uning tekshirish qismi ham qiyinroq. Shuning uchun turli modellarning eval_loss ini solishtirib bo'lmaydi — u bitta modelning training jarayonini kuzatish uchun (xato kamayyaptimi, qayta o'sib ketmayaptimi), modellarni solishtirish uchun emas.

Bu saboq kitobda yana qaytadi: tez8 va tez9 da ham eval_loss va real test natijasi bir-biriga to'g'ri kelmagan.

Xulosa

  • pilot4b, tez3, tez4, tez5 — bir xil sozlama, faqat ma'lumot farq qiladi.
  • pilot4b o'qitilmagan modeldan 26 savolga yomon chiqdi: so'rovlarning yarmidan ko'pida xom ustun nomi bor edi, va model nomni ko'chirishni o'rgandi. Tuzatish — xom nom tekshiruvi va sarlavhalarni qayta nomlash.
  • tez3 — birinchi yaxshi model: 200 dan 183, o'qitilmagan modeldan 19 savol yaxshi.
  • tez4 va tez5 nishonga olingan xatolarni tuzatdi, lekin shuncha savolni buzdi — ball 183 da qoldi. 200 savollik test bir necha savollik farqni ajrata olmaydi.
  • eval_loss turli modellarni solishtirish uchun emas: har birining tekshirish qatorlari boshqa.

Keyingi bobda bu saboqlardan keyingi uchta model: tez6, tez7 va hozirgacha eng yaxshisi — tez8.

Bu bobni bepul o'qidingiz.

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

Telegramda yozish Narxlar