aigencydev commited on
Commit
58a2d4a
·
verified ·
1 Parent(s): 6f41933

egitim/: v2 betikleri ve veri ozetleri

Browse files
Files changed (1) hide show
  1. egitim/dogal_egitim32.py +198 -0
egitim/dogal_egitim32.py ADDED
@@ -0,0 +1,198 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # -*- coding: utf-8 -*-
2
+ """Dogal-CPT (32B surumu): Erk-32B'ye (birlesik-075) 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/erk32b-birlesik-075")
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/erk32b-dogal")
35
+ OPT = os.environ.get("OPT", "adafactor_sr") # adafactor_sr: fp32 ana agirlik YOK, bf16 parametre + KARARLI (stokastik) YUVARLAMA # 32B: Adam durumlari (256 GB) 4xA100'a sigmaz; Adafactor faktorlu durum, fp32 ana agirlik korunur
36
+ KAYDET = os.environ.get("KAYDET", "1") == "1"
37
+ UZUNLUK = int(os.environ.get("UZUNLUK", "1024"))
38
+ ADIM = int(os.environ.get("ADIM", "9000"))
39
+ YIGIN = int(os.environ.get("YIGIN", "2")); BIRIKIM = int(os.environ.get("BIRIKIM", "8"))
40
+ LR = float(os.environ.get("LR", "1e-5"))
41
+ SFT_HER = int(os.environ.get("SFT_HER", "12"))
42
+ SENTETIK = os.environ.get("SENTETIK", "") # tur 2: kural cumleleri (kisaltma/sayi/cati), kiyas govdeleri DISLANMIS
43
+ SENTETIK_ORAN = float(os.environ.get("SENTETIK_ORAN", "0.0"))
44
+ SURE_DK = float(os.environ.get("SURE_DK", "1560")); KAYIT_HER = int(os.environ.get("KAYIT_HER", "3000"))
45
+ yaz = lambda *a: print(*a, flush=True)
46
+ t_bas = time.time()
47
+ if not torch.cuda.is_available(): raise SystemExit("CUDA yok")
48
+ tok = AutoTokenizer.from_pretrained(MODEL)
49
+ model = AutoModelForCausalLM.from_pretrained(MODEL, dtype=torch.bfloat16, device_map="balanced")
50
+ model.gradient_checkpointing_enable(); model.config.use_cache = False
51
+ aygit = model.get_input_embeddings().weight.device
52
+ yaz("model yerlesimi:", sorted({str(p.device) for p in model.parameters()}))
53
+
54
+ class Karisim(Dataset):
55
+ def __init__(self, n_blok):
56
+ rng = random.Random(20260926)
57
+ sft_f = open(SFT, encoding="utf8"); self.blok, tampon, say, n_sft, n_sent = [], [], 0, 0, 0
58
+ sent = []
59
+ if SENTETIK:
60
+ sent = [l.strip() for l in open(SENTETIK, encoding="utf8", errors="ignore") if l.strip()]; rng.shuffle(sent)
61
+ with open(GENEL, encoding="utf8", errors="ignore") as f:
62
+ for satir in f:
63
+ say += 1
64
+ if sent and rng.random() < SENTETIK_ORAN:
65
+ # bir paragraf yerine 3-6 kural cumlesi (tek satir), dogal metnin arasina serpistirilir
66
+ k = rng.randint(3, 6); satir = " ".join(sent[n_sent % len(sent): n_sent % len(sent) + k]) + "\n"; n_sent += k
67
+ elif say % SFT_HER == 0:
68
+ ln = sft_f.readline()
69
+ if ln:
70
+ try:
71
+ msg = json.loads(ln)["messages"]
72
+ satir = tok.apply_chat_template(msg, tokenize=False) + "\n"; n_sft += 1
73
+ except Exception: pass
74
+ tampon += tok(satir, add_special_tokens=False).input_ids + [tok.eos_token_id]
75
+ while len(tampon) >= UZUNLUK + 1:
76
+ self.blok.append(tampon[:UZUNLUK + 1]); tampon = tampon[UZUNLUK:]
77
+ if len(self.blok) >= n_blok:
78
+ yaz("veri: %d blok · %d paragraf · %d SFT konusmasi · %d sentetik cumle" % (len(self.blok), say, n_sft, n_sent)); return
79
+ yaz("veri: %d blok (dosya bitti) · %d paragraf · %d SFT · %d sentetik" % (len(self.blok), say, n_sft, n_sent))
80
+ def __len__(self): return len(self.blok)
81
+ def __getitem__(self, i):
82
+ b = torch.tensor(self.blok[i]); return b[:-1], b[1:]
83
+
84
+ veri = Karisim(ADIM * YIGIN * BIRIKIM + 500)
85
+ dl = DataLoader(veri, batch_size=YIGIN, shuffle=True, num_workers=4, drop_last=True)
86
+
87
+ def ara_kayit(et):
88
+ y = CIK + "-" + et; os.makedirs(y, exist_ok=True)
89
+ model.save_pretrained(y, safe_serialization=True); tok.save_pretrained(y); yaz(" ara kayit:", y)
90
+
91
+ for p in model.parameters(): p.requires_grad = True
92
+ egitilen = [p for p in model.parameters()]
93
+ ANA = OPT != "adafactor_sr"
94
+ if ANA:
95
+ # fp32 ana agirliklar (ayni aygitta), optimizer bunlarin uzerinde
96
+ ana = [p.detach().to(torch.float32).clone() for p in egitilen]
97
+ for m in ana: m.requires_grad = True
98
+ else:
99
+ ana = egitilen
100
+
101
+ def sr_bf16(x32):
102
+ """fp32 -> bf16 KARARLI yuvarlama: alt 16 bite rastgele ekle, sonra kes. Kucuk guncellemeler
103
+ ortalamada korunur (deterministik yuvarlama 1e-5'lik guncellemeyi cogu agirlikta yutar)."""
104
+ b = x32.view(torch.int32)
105
+ b = b + torch.randint(0, 1 << 16, b.shape, device=b.device, dtype=torch.int32)
106
+ return (b & -65536).view(torch.float32).to(torch.bfloat16)
107
+
108
+ if OPT == "adafactor_sr":
109
+ import math
110
+ from transformers.optimization import Adafactor
111
+ class AdafactorSR(Adafactor):
112
+ """transformers 5.13 Adafactor.step ile birebir; tek fark: bf16 parametreye geri yazarken sr_bf16."""
113
+ @torch.no_grad()
114
+ def step(self, closure=None):
115
+ for group in self.param_groups:
116
+ for p in group["params"]:
117
+ if p.grad is None: continue
118
+ grad = p.grad.float() if p.grad.dtype in (torch.float16, torch.bfloat16) else p.grad
119
+ state = self.state[p]; grad_shape = grad.shape
120
+ factored, use_first_moment = self._get_options(group, grad_shape)
121
+ if len(state) == 0:
122
+ state["step"] = 0
123
+ if use_first_moment: state["exp_avg"] = torch.zeros_like(grad)
124
+ if factored:
125
+ state["exp_avg_sq_row"] = torch.zeros(grad_shape[:-1]).to(grad)
126
+ state["exp_avg_sq_col"] = torch.zeros(grad_shape[:-2] + grad_shape[-1:]).to(grad)
127
+ else: state["exp_avg_sq"] = torch.zeros_like(grad)
128
+ state["RMS"] = 0
129
+ p32 = p.float()
130
+ state["step"] += 1; state["RMS"] = self._rms(p32); lr = self._get_lr(group, state)
131
+ beta2t = 1.0 - math.pow(state["step"], group["decay_rate"])
132
+ update = (grad ** 2) + group["eps"][0]
133
+ if factored:
134
+ r, c = state["exp_avg_sq_row"], state["exp_avg_sq_col"]
135
+ r.mul_(beta2t).add_(update.mean(dim=-1), alpha=(1.0 - beta2t))
136
+ c.mul_(beta2t).add_(update.mean(dim=-2), alpha=(1.0 - beta2t))
137
+ update = self._approx_sq_grad(r, c); update.mul_(grad)
138
+ else:
139
+ v = state["exp_avg_sq"]; v.mul_(beta2t).add_(update, alpha=(1.0 - beta2t)); update = v.rsqrt().mul_(grad)
140
+ update.div_((self._rms(update) / group["clip_threshold"]).clamp_(min=1.0)); update.mul_(lr)
141
+ if use_first_moment:
142
+ e = state["exp_avg"]; e.mul_(group["beta1"]).add_(update, alpha=(1 - group["beta1"])); update = e
143
+ if group["weight_decay"] != 0: p32.add_(p32, alpha=(-group["weight_decay"] * lr))
144
+ p32.add_(-update)
145
+ p.copy_(sr_bf16(p32) if p.dtype == torch.bfloat16 else p32)
146
+ del p32, update
147
+ return None
148
+ opt = AdafactorSR(ana, lr=LR, scale_parameter=False, relative_step=False, warmup_init=False, weight_decay=0.01, beta1=None)
149
+ elif OPT == "adafactor":
150
+ from transformers.optimization import Adafactor
151
+ opt = Adafactor(ana, lr=LR, scale_parameter=False, relative_step=False, warmup_init=False, weight_decay=0.01, beta1=None)
152
+ else:
153
+ opt = torch.optim.AdamW(ana, lr=LR, weight_decay=0.01, foreach=False)
154
+ plan = torch.optim.lr_scheduler.OneCycleLR(opt, max_lr=LR, total_steps=ADIM, pct_start=0.05, cycle_momentum=(OPT not in ("adafactor", "adafactor_sr")))
155
+ yaz("=== DOGAL-CPT-32B · optimizer %s" % OPT)
156
+ yaz("=== DOGAL-CPT · %d adim · %d jeton/adim · lr %.1e · %s · %.2f B parametre"
157
+ % (ADIM, UZUNLUK * YIGIN * BIRIKIM, LR, "fp32 ana agirlik" if ANA else "bf16 + kararli yuvarlama", sum(p.numel() for p in egitilen) / 1e9))
158
+ try:
159
+ for g in range(torch.cuda.device_count()):
160
+ yaz(" kart %d: %.1f / %.1f GB" % (g, torch.cuda.memory_allocated(g) / 2**30, torch.cuda.get_device_properties(g).total_memory / 2**30))
161
+ except Exception as e: yaz(" (bellek raporu yok: %s)" % e)
162
+
163
+ model.train(); i = biriken = 0; t0 = time.time(); kayip = None; degisen_ilk = None
164
+ while i < ADIM:
165
+ for x, y in dl:
166
+ if i >= ADIM: break
167
+ lg = model(input_ids=x.to(aygit)).logits
168
+ kayip = F.cross_entropy(lg.float().view(-1, lg.size(-1)), y.to(lg.device).view(-1))
169
+ (kayip / BIRIKIM).backward(); biriken += 1
170
+ if biriken == BIRIKIM:
171
+ torch.nn.utils.clip_grad_norm_(egitilen, 1.0)
172
+ if ANA:
173
+ with torch.no_grad():
174
+ for m, p in zip(ana, egitilen):
175
+ m.grad = p.grad.to(torch.float32); p.grad = None
176
+ with torch.no_grad():
177
+ if i == 0: p0 = egitilen[len(egitilen)//2]; once = p0.detach().clone()
178
+ opt.step(); plan.step(); opt.zero_grad(set_to_none=True)
179
+ with torch.no_grad():
180
+ if ANA:
181
+ for m, p in zip(ana, egitilen): p.copy_(m.to(p.dtype))
182
+ if i == 0:
183
+ yaz(" ilk adimda bf16'da degisen agirlik orani (orta katman): %.4f" % (p0 != once).float().mean().item())
184
+ biriken = 0; i += 1
185
+ if i % 100 == 0:
186
+ yaz(" adim %5d/%d | kayip %.4f | %.1f dk | %.0f jeton/sn" % (i, ADIM, float(kayip), (time.time() - t0) / 60,
187
+ i * UZUNLUK * YIGIN * BIRIKIM / (time.time() - t0)))
188
+ if i % KAYIT_HER == 0 and KAYDET: ara_kayit("adim%d" % i)
189
+ if i == 3 or i % 500 == 0:
190
+ try: yaz(" bellek zirve:", " ".join("%d:%.0fGB" % (g, torch.cuda.max_memory_allocated(g)/2**30) for g in range(torch.cuda.device_count())))
191
+ except Exception: pass
192
+ if (time.time() - t_bas) / 60 > SURE_DK:
193
+ yaz(" !! sure butcesi doldu, %d. adimda kesiliyor" % i); i = ADIM; break
194
+
195
+ model.config.use_cache = True
196
+ if KAYDET:
197
+ os.makedirs(CIK, exist_ok=True); model.save_pretrained(CIK, safe_serialization=True); tok.save_pretrained(CIK)
198
+ yaz("yazildi: %s (%.1f dk)" % (CIK, (time.time() - t_bas) / 60))