Skip to content

Commit 2cfe61d

Browse files
author
gHashTag
committed
fix: анти-OOM авто-BATCH (NL=12/d=768) + GUARD коллапса baseline + провенанс треков A (2-й чекпоинт валиден, seed=123 коллапс)
1 parent c3ab826 commit 2cfe61d

2 files changed

Lines changed: 83 additions & 4 deletions

File tree

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
# GF+A вектор 2: обобщение границы инв. №18 по осям сид/чекпоинт/масштаб
2+
3+
**Дата:** 2026-07-23. **Железо:** RunPod NVIDIA RTX PRO 4500 Blackwell (sm_120),
4+
torch 2.11.0+cu128 (авто-reinstall+re-exec с cu124). **Автор:** Vasilev (gHashTag).
5+
**Статус:** `[измерено — GPU]`. **Скрипт:** `webterm_gfplus_v2scale.py`.
6+
7+
Метрика — первичный **bits-per-token** (BPT); порог значимости Parameter Golf
8+
0.005 BPB = **0.0195 BPT** (коэф 3.9 байт/ток). Модель 9L d=512 VOCAB=1024,
9+
FineWeb sp1024, 27 Linear под квант; Hessian снят с 18/27 (FFN), out_proj → MSE
10+
fallback (баг functional-MHA прошлого лупа). val 24 батча, seed=123 фикс.
11+
12+
## Трек A — 2-й чекпоинт (seed=42, STEPS=6000) — ВАЛИДНЫЙ
13+
14+
Здоровый baseline: train loss=3.35, FP32 BPT=**5.26133**.
15+
16+
| bits | MSE | Hessian(FFN) | гибрид(Hess@глуб-linear1) | ΔBPT(Hess−MSE) | ΔBPT(гибрид−MSE) |
17+
|---|---|---|---|---|---|
18+
| 4 | 5.26602 | 5.26681 | 5.26221 | **+0.00079** | −0.00381 |
19+
| 6 | 5.26147 | 5.26142 | 5.26122 | **−0.00005** | −0.00024 |
20+
| 8 | 5.26157 | 5.26155 | 5.26133 | **−0.00006** | −0.00024 |
21+
22+
Все |ΔBPT| на 1–2 порядка ниже порога 0.0195. **Подтверждает прошлый луп
23+
(seed=42, STEPS=3000)** на другом чекпоинте: нейтральность Hessian-выбора по
24+
model-BPT — НЕ артефакт одного чекпоинта.
25+
26+
Тонкость: на 4 битах Hessian(все FFN) слегка ХУЖЕ MSE (+0.00079), а гибрид
27+
(Hessian только в глубоких linear1) — лучший (−0.00381). Согласуется с
28+
локализацией SQNR-выигрыша в глубоких FFN (вектор 2), но и это ниже порога.
29+
30+
## Трек A — 2-й сид (seed=123, STEPS=3000) — НЕВАЛИДНЫЙ (коллапс)
31+
32+
train loss упал до **0.0088**, FP32 BPT=**0.00606** → модель переобучилась в
33+
память train-шарда. Все ΔBPT=0.00000 АРТЕФАКТНО (квантовать нечего на
34+
вырожденной модели), НЕ вывод. Отброшен. **Урок:** на мелком сете разные сиды
35+
дают либо здоровую модель (42), либо коллапс (123) при том же STEPS. BPT-замер
36+
валиден только при baseline BPT ≥ 1.0. В скрипт добавлен GUARD:
37+
`baseline_valid` в meta + предупреждение при FP32 BPT < 1.0.
38+
39+
## Трек B — масштаб (NL=12, DMODEL=768) — OOM → пофикшено
40+
41+
Первый прогон: `torch.OutOfMemoryError` (31.37 ГБ, tried 576 MiB) на forward
42+
FFN. Причина: BATCH=48/SEQ=1024 фиксированы. Фикс в скрипте:
43+
`PYTORCH_CUDA_ALLOC_CONF=expandable_segments:True` + авто-бюджет BATCH
44+
(`_budget=9*512*48*1024 / (NL*D*1024)`) → для NL=12/d=768 авто BATCH=24;
45+
базовый NL=9/d=512 остаётся BATCH=48 (прошлые числа не меняются). Также
46+
BATCH/SEQ теперь env-override. **Прогон трека B — за пользователем** (тот же
47+
скрипт после git pull).
48+
49+
## Свод (2 из 3 конфигураций замерены)
50+
51+
- **Обобщение по чекпоинту `[измерено — GPU]`:** нейтральность ΔBPT(Hessian−MSE)
52+
по model-BPT держится и на STEPS=6000. Инвариант №18 (SQNR выхода слоя был
53+
суррогатом, downstream-BPT нейтрален) — НЕ артефакт одной точки обучения.
54+
- **Обобщение по сиду:** seed=123 дал коллапс → не проверено; нужен здоровый
55+
2-й сид (напр. seed=7 STEPS=6000). GUARD добавлен.
56+
- **Масштаб:** OOM пофикшен, замер на NL=12/d=768 ожидает прогона.
57+
58+
## Границы (BINDING)
59+
29M PTQ-прокси, НЕ official Parameter Golf; PTQ ≠ QAT; BPB = BPT/3.9 `[прокси]`
60+
(vocab mismatch: поток sp1024 не декодируется найденным 8192-BPE); Hessian только
61+
FFN (18/27). Число 5.26 BPT = внутренний прокси, НЕ officialtrained-from-scratch.

webterm_gfplus_v2scale.py

Lines changed: 22 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,14 +126,21 @@ def select(W, N, hess=None, metric="mse"):
126126
return torch.stack(cands)[ch, torch.arange(W.shape[0], device=W.device)]
127127

128128
# ── модель (параметризовано env: SEED/STEPS — трек A, NL/DMODEL — трек B) ──
129-
device = 'cuda'; VOCAB=1024; SEQ=1024; BATCH=48
129+
# АНТИ-OOM: BATCH/SEQ параметризованы + авто-снижение для крупной модели (урок: NL=12/d=768 выбил 31ГБ).
130+
os.environ.setdefault("PYTORCH_CUDA_ALLOC_CONF", "expandable_segments:True")
131+
device = 'cuda'; VOCAB=1024
130132
SEED = int(os.environ.get("SEED", 42))
131133
D = int(os.environ.get("DMODEL", 512))
132134
NL = int(os.environ.get("NL", 9))
133135
STEPS = int(os.environ.get("STEPS", 3000))
134136
assert D % 8 == 0, "DMODEL должен быть кратен nhead=8"
137+
# авто-бюджет памяти: целевой ~ NL*D*BATCH*SEQ активаций; держим под 512*9*48*1024
138+
_budget = 9 * 512 * 48 * 1024
139+
_auto_bs = max(8, min(48, _budget // (NL * D * 1024)))
140+
BATCH = int(os.environ.get("BATCH", _auto_bs))
141+
SEQ = int(os.environ.get("SEQ", 1024))
135142
RUN_TAG = f"seed{SEED}_nl{NL}_d{D}_st{STEPS}"
136-
print(f"[config] {RUN_TAG} (трек A=сид/чекпоинт, трек B=NL/DMODEL)", flush=True)
143+
print(f"[config] {RUN_TAG} BATCH={BATCH} SEQ={SEQ} (трек A=сид/чекпоинт, трек B=NL/DMODEL)", flush=True)
137144
os.chdir("/workspace")
138145
if not os.path.exists("parameter-golf"):
139146
os.system("git clone --depth 1 https://github.com/openai/parameter-golf.git")
@@ -167,14 +174,15 @@ def forward(s,x):
167174
return s.h(s.f(h))
168175

169176
print(f"GPU: {torch.cuda.get_device_name(0)} | torch {torch.__version__}")
170-
print(f"Training {NL}L d={D} {STEPS} steps...")
177+
print(f"Training {NL}L d={D} {STEPS} steps (BATCH={BATCH})...")
171178
torch.manual_seed(SEED); model=Model().to(device)
179+
_last_loss = None
172180
op=torch.optim.AdamW(model.parameters(),lr=0.003,weight_decay=0.1,betas=(0.95,0.95))
173181
for s in range(STEPS+1):
174182
idx=torch.randint(0,len(train_t)-SEQ-1,(BATCH,))
175183
x=torch.stack([train_t[i:i+SEQ] for i in idx]).to(device)
176184
y=torch.stack([train_t[i+1:i+SEQ+1] for i in idx]).to(device)
177-
loss=F.cross_entropy(model(x).reshape(-1,VOCAB),y.reshape(-1))
185+
loss=F.cross_entropy(model(x).reshape(-1,VOCAB),y.reshape(-1)); _last_loss=float(loss)
178186
op.zero_grad(); loss.backward(); torch.nn.utils.clip_grad_norm_(model.parameters(),1.0); op.step()
179187
if s%1000==0: print(f" {s}/{STEPS}: loss={loss.item():.4f}", flush=True)
180188
model.eval()
@@ -265,6 +273,16 @@ def deep_ffn(n):
265273
seed=SEED, run_tag=RUN_TAG)}
266274

267275
restore_fp32(); report["fp32"] = eval_bpb("FP32 baseline")
276+
report["meta"]["train_last_loss"] = _last_loss
277+
report["meta"]["baseline_bpt"] = report["fp32"]["bits_per_token"]
278+
# GUARD (урок seed=123): коллапс в память (loss→0, baseline BPT→0) делает замер НЕВАЛИДНЫМ:
279+
# квантование нечего портить на вырожденной модели → все ΔBPT≈0 артефактно, не вывод.
280+
_valid = report["fp32"]["bits_per_token"] >= 1.0
281+
report["meta"]["baseline_valid"] = bool(_valid)
282+
if not _valid:
283+
print(f"\n⚠ BASELINE НЕВАЛИДЕН: FP32 BPT={report['fp32']['bits_per_token']:.5f} < 1.0 "
284+
f"(train loss={_last_loss:.4f}). Модель сколлапсировала в память на этом сиде/STEPS."
285+
f"\n Замер ΔBPT НЕВАЛИДЕН (квантовать нечего). Сменить SEED или уменьшить STEPS.", flush=True)
268286

269287
for N in (4, 6, 8):
270288
print(f"\n--- {N}-bit ---")

0 commit comments

Comments
 (0)