aigencydev commited on
Commit
0b8f695
·
verified ·
1 Parent(s): 941efec

egitim/: v2 betikleri ve veri ozetleri

Browse files
Files changed (1) hide show
  1. egitim/dogal_egitim.py +133 -0
egitim/dogal_egitim.py ADDED
@@ -0,0 +1,133 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Dogal-CPT: Erk-14B'ye DOGAL Turkce metinle (FineWeb-2 tur_Latn, gorulmemis parcalar) tam-parametre devam egitimi.
3
+
4
+ NEDEN BU RECETE
5
+ Iki onceki recete (sozluk genisletme, sentetik kural-CPT) on-kayitli olcutleri gecemedi. Teshis: Erk'in
6
+ acigi istisna kovalarinda (unlu dusmesi, uyum kirici, ikizlesme, kisaltma, sayi) — bunlar SOZLUKSEL bilgi,
7
+ sablonla ogretilemez; dogal metinde dogal sikliklariyla gorulerek ogrenilir (2B Turkce-yerli modellerin yolu).
8
+ Sentetik veri tamami duzenli uyum ornegi oldugu icin uyum-kirici kovasini GERILETMISTI; dogal metinde bu
9
+ yanlilik yok.
10
+ Teknik duzeltme: onceki egitimler saf bf16 AdamW ile lr 1e-5 kullandi; bf16'da 1e-5'lik guncelleme cogu
11
+ agirlik icin yarim ulp'nin altinda kalir ve YUVARLANIR (agirlik_degisim.py teshisi). Burada fp32 ANA
12
+ AGIRLIK tutulur: ileri/geri bf16, optimizer fp32, her adimda bf16'ya kopyalanir.
13
+
14
+ VERI
15
+ dogal_metin.txt (dogal_secim.py: %70 rastgele paragraf + %30 kesme-isaretli-cekim yogun paragraf; kiyas
16
+ maddesi/sablonu/govde listesi/TDK sozlugu KULLANILMADI; sozluk-maddesi gorunumlu satirlar atildi).
17
+ Sohbet yetenegini korumak icin ~her 12 paragrafta bir SFT konusmasi (sft_clean_v2, sohbet sablonuyla).
18
+
19
+ ON-KAYITLI BASARI OLCUTLERI (sonuca bakilmadan yazildi; karar DEV kesitinde, cekirdek bir kez olculur)
20
+ A) TurkishMMLU, ayni betik, ayni 652 soru: dogal >= taban - 1,0 puan
21
+ B) DEV kesiti (2.000 cekirdek-disi madde, kova oranlari cekirdekle ayni): hucre-kumeli esli fark
22
+ anlamli pozitif VE >= +1,5 puan
23
+ C) DEV'de hicbir kovada anlamli gerileme yok
24
+ Ucu gecerse 3.6 cekirdegi BIR KEZ olculur ve tabloya o sayi girer; ayni recete 32B'ye uygulanir.
25
+ Gecmezse model yayimlanmaz, 32B'ye uygulanmaz. Kontrol noktasi secimi de yalniz DEV ile yapilir.
26
+ """
27
+ import os, random, time, json, torch, torch.nn.functional as F
28
+ from torch.utils.data import DataLoader, Dataset
29
+ from transformers import AutoModelForCausalLM, AutoTokenizer
30
+
31
+ MODEL = os.environ.get("MODEL", "/ari/users/ytanis/erk14b-gguf-kaynak")
32
+ GENEL = os.environ.get("GENEL", "/ari/users/ytanis/dogal_metin.txt")
33
+ SFT = os.environ.get("SFT", "/ari/users/ytanis/erk/sft_clean_v2.jsonl")
34
+ CIK = os.environ.get("CIK", "/ari/users/ytanis/erk14b-dogal")
35
+ UZUNLUK = int(os.environ.get("UZUNLUK", "1024"))
36
+ ADIM = int(os.environ.get("ADIM", "9000"))
37
+ YIGIN = int(os.environ.get("YIGIN", "4")); BIRIKIM = int(os.environ.get("BIRIKIM", "4"))
38
+ LR = float(os.environ.get("LR", "1e-5"))
39
+ SFT_HER = int(os.environ.get("SFT_HER", "12"))
40
+ SENTETIK = os.environ.get("SENTETIK", "") # tur 2: kural cumleleri (kisaltma/sayi/cati), kiyas govdeleri DISLANMIS
41
+ SENTETIK_ORAN = float(os.environ.get("SENTETIK_ORAN", "0.0"))
42
+ SURE_DK = float(os.environ.get("SURE_DK", "1560")); KAYIT_HER = int(os.environ.get("KAYIT_HER", "3000"))
43
+ yaz = lambda *a: print(*a, flush=True)
44
+ t_bas = time.time()
45
+ if not torch.cuda.is_available(): raise SystemExit("CUDA yok")
46
+ tok = AutoTokenizer.from_pretrained(MODEL)
47
+ model = AutoModelForCausalLM.from_pretrained(MODEL, dtype=torch.bfloat16, device_map="balanced")
48
+ model.gradient_checkpointing_enable(); model.config.use_cache = False
49
+ aygit = model.get_input_embeddings().weight.device
50
+ yaz("model yerlesimi:", sorted({str(p.device) for p in model.parameters()}))
51
+
52
+ class Karisim(Dataset):
53
+ def __init__(self, n_blok):
54
+ rng = random.Random(20260926)
55
+ sft_f = open(SFT, encoding="utf8"); self.blok, tampon, say, n_sft, n_sent = [], [], 0, 0, 0
56
+ sent = []
57
+ if SENTETIK:
58
+ sent = [l.strip() for l in open(SENTETIK, encoding="utf8", errors="ignore") if l.strip()]; rng.shuffle(sent)
59
+ with open(GENEL, encoding="utf8", errors="ignore") as f:
60
+ for satir in f:
61
+ say += 1
62
+ if sent and rng.random() < SENTETIK_ORAN:
63
+ # bir paragraf yerine 3-6 kural cumlesi (tek satir), dogal metnin arasina serpistirilir
64
+ k = rng.randint(3, 6); satir = " ".join(sent[n_sent % len(sent): n_sent % len(sent) + k]) + "\n"; n_sent += k
65
+ elif say % SFT_HER == 0:
66
+ ln = sft_f.readline()
67
+ if ln:
68
+ try:
69
+ msg = json.loads(ln)["messages"]
70
+ satir = tok.apply_chat_template(msg, tokenize=False) + "\n"; n_sft += 1
71
+ except Exception: pass
72
+ tampon += tok(satir, add_special_tokens=False).input_ids + [tok.eos_token_id]
73
+ while len(tampon) >= UZUNLUK + 1:
74
+ self.blok.append(tampon[:UZUNLUK + 1]); tampon = tampon[UZUNLUK:]
75
+ if len(self.blok) >= n_blok:
76
+ yaz("veri: %d blok · %d paragraf · %d SFT konusmasi · %d sentetik cumle" % (len(self.blok), say, n_sft, n_sent)); return
77
+ yaz("veri: %d blok (dosya bitti) · %d paragraf · %d SFT · %d sentetik" % (len(self.blok), say, n_sft, n_sent))
78
+ def __len__(self): return len(self.blok)
79
+ def __getitem__(self, i):
80
+ b = torch.tensor(self.blok[i]); return b[:-1], b[1:]
81
+
82
+ veri = Karisim(ADIM * YIGIN * BIRIKIM + 500)
83
+ dl = DataLoader(veri, batch_size=YIGIN, shuffle=True, num_workers=4, drop_last=True)
84
+
85
+ def ara_kayit(et):
86
+ y = CIK + "-" + et; os.makedirs(y, exist_ok=True)
87
+ model.save_pretrained(y, safe_serialization=True); tok.save_pretrained(y); yaz(" ara kayit:", y)
88
+
89
+ for p in model.parameters(): p.requires_grad = True
90
+ egitilen = [p for p in model.parameters()]
91
+ # fp32 ana agirliklar (ayni aygitta), optimizer bunlarin uzerinde
92
+ ana = [p.detach().to(torch.float32).clone() for p in egitilen]
93
+ for m in ana: m.requires_grad = True
94
+ opt = torch.optim.AdamW(ana, lr=LR, weight_decay=0.01, foreach=False)
95
+ plan = torch.optim.lr_scheduler.OneCycleLR(opt, max_lr=LR, total_steps=ADIM, pct_start=0.05)
96
+ yaz("=== DOGAL-CPT · %d adim · %d jeton/adim · lr %.1e · fp32 ana agirlik · %.2f B parametre"
97
+ % (ADIM, UZUNLUK * YIGIN * BIRIKIM, LR, sum(p.numel() for p in egitilen) / 1e9))
98
+ try:
99
+ for g in range(torch.cuda.device_count()):
100
+ yaz(" kart %d: %.1f / %.1f GB" % (g, torch.cuda.memory_allocated(g) / 2**30, torch.cuda.get_device_properties(g).total_memory / 2**30))
101
+ except Exception as e: yaz(" (bellek raporu yok: %s)" % e)
102
+
103
+ model.train(); i = biriken = 0; t0 = time.time(); kayip = None; degisen_ilk = None
104
+ while i < ADIM:
105
+ for x, y in dl:
106
+ if i >= ADIM: break
107
+ lg = model(input_ids=x.to(aygit)).logits
108
+ kayip = F.cross_entropy(lg.float().view(-1, lg.size(-1)), y.to(lg.device).view(-1))
109
+ (kayip / BIRIKIM).backward(); biriken += 1
110
+ if biriken == BIRIKIM:
111
+ torch.nn.utils.clip_grad_norm_(egitilen, 1.0)
112
+ with torch.no_grad():
113
+ for m, p in zip(ana, egitilen):
114
+ m.grad = p.grad.to(torch.float32); p.grad = None
115
+ opt.step(); plan.step(); opt.zero_grad(set_to_none=True)
116
+ with torch.no_grad():
117
+ if i == 0: # ilk adimda bf16 kopyada gercekten degisen agirlik orani (yuvarlama teshisi)
118
+ p0 = egitilen[len(egitilen)//2]; once = p0.detach().clone()
119
+ for m, p in zip(ana, egitilen): p.copy_(m.to(p.dtype))
120
+ if i == 0:
121
+ degisen_ilk = (p0 != once).float().mean().item()
122
+ yaz(" ilk adimda bf16'da degisen agirlik orani (orta katman): %.4f" % degisen_ilk)
123
+ biriken = 0; i += 1
124
+ if i % 100 == 0:
125
+ yaz(" adim %5d/%d | kayip %.4f | %.1f dk | %.0f jeton/sn" % (i, ADIM, float(kayip), (time.time() - t0) / 60,
126
+ i * UZUNLUK * YIGIN * BIRIKIM / (time.time() - t0)))
127
+ if i % KAYIT_HER == 0: ara_kayit("adim%d" % i)
128
+ if (time.time() - t_bas) / 60 > SURE_DK:
129
+ yaz(" !! sure butcesi doldu, %d. adimda kesiliyor" % i); i = ADIM; break
130
+
131
+ model.config.use_cache = True; os.makedirs(CIK, exist_ok=True)
132
+ model.save_pretrained(CIK, safe_serialization=True); tok.save_pretrained(CIK)
133
+ yaz("yazildi: %s (%.1f dk)" % (CIK, (time.time() - t_bas) / 60))