guychuk commited on
Commit
95bf5e7
·
verified ·
1 Parent(s): ec45129

Upload train_fast.py

Browse files
Files changed (1) hide show
  1. train_fast.py +106 -0
train_fast.py ADDED
@@ -0,0 +1,106 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os, random, json, sys
2
+ from pathlib import Path
3
+ import numpy as np, torch
4
+ from torch.utils.data import Dataset, DataLoader
5
+
6
+ HUB_DIR = Path(__file__).parent.resolve()
7
+ sys.path.insert(0, str(HUB_DIR / "src"))
8
+ sys.path.insert(0, str(HUB_DIR / "src" / "models"))
9
+
10
+ from models.grid_jepa import GridJEPA
11
+ import trackio
12
+
13
+ MAX_GRID = 30
14
+
15
+ def load_tasks(d):
16
+ tasks = []
17
+ for p in sorted(Path(d).glob("*.json")):
18
+ with open(p) as f: tasks.append(json.load(f))
19
+ return tasks
20
+
21
+ def to_tensor(grid):
22
+ arr = np.array(grid, dtype=np.int64)
23
+ H, W = arr.shape
24
+ t = torch.zeros(MAX_GRID, MAX_GRID, dtype=torch.long)
25
+ t[:H, :W] = torch.from_numpy(arr)
26
+ return t
27
+
28
+ class ARCDataset(Dataset):
29
+ def __init__(self, d):
30
+ self.samples = []
31
+ for task in load_tasks(d):
32
+ for pair in task.get("train", []):
33
+ self.samples.append({"input": to_tensor(pair["input"]), "output": to_tensor(pair["output"])})
34
+ def __len__(self): return len(self.samples)
35
+ def __getitem__(self, idx):
36
+ s = self.samples[idx]
37
+ return {"context_grid": s["input"], "target_grid": s["output"]}
38
+
39
+ def collate(batch):
40
+ return {"context_grid": torch.stack([b["context_grid"] for b in batch]), "target_grid": torch.stack([b["target_grid"] for b in batch])}
41
+
42
+ def sample_masks(B, H, W, ratio=0.4, device="cpu"):
43
+ N = H * W; nt = max(1, int(N * ratio))
44
+ ctx = torch.zeros(B, N, dtype=torch.bool, device=device)
45
+ tgt = torch.zeros(B, N, dtype=torch.bool, device=device)
46
+ for b in range(B):
47
+ idx = list(range(N)); random.shuffle(idx)
48
+ tgt[b, idx[:nt]] = True; ctx[b, idx[nt:]] = True
49
+ return ctx, tgt
50
+
51
+ device = torch.device("cuda" if torch.cuda.is_available() else "cpu")
52
+ print(f"[TRAIN] Device: {device}", flush=True)
53
+ run = trackio.init(project="arc-agi-3", name="grid-jepa-fast", group="pretrain")
54
+ print("[TRAIN] Trackio OK", flush=True)
55
+
56
+ model = GridJEPA(num_colors=10, embed_dim=192, encoder_depth=6, predictor_depth=6, num_heads=6, max_grid_size=MAX_GRID, ema_decay=0.996).to(device)
57
+ print(f"[TRAIN] Params: {sum(p.numel() for p in model.parameters()):,}", flush=True)
58
+
59
+ data_dir = HUB_DIR / "data" / "training"
60
+ if not data_dir.exists(): data_dir = Path("/app/arc_data_source/data/training")
61
+ ds = ARCDataset(str(data_dir))
62
+ print(f"[TRAIN] Samples: {len(ds)}", flush=True)
63
+
64
+ loader = DataLoader(ds, batch_size=8, shuffle=True, collate_fn=collate, num_workers=0)
65
+ opt = torch.optim.AdamW(model.parameters(), lr=3e-4, weight_decay=0.05)
66
+
67
+ save_dir = Path("/app/arc-jepa-hf/checkpoints")
68
+ save_dir.mkdir(exist_ok=True)
69
+
70
+ for epoch in range(1, 51):
71
+ model.train(); epoch_loss = 0.0; n = 0
72
+ for batch in loader:
73
+ ctx_g = batch["context_grid"].to(device)
74
+ tgt_g = batch["target_grid"].to(device)
75
+ B = ctx_g.shape[0]
76
+ ctx_mask, target_mask = sample_masks(B, MAX_GRID, MAX_GRID, ratio=0.5, device=device)
77
+ a_key = torch.zeros(B, dtype=torch.long, device=device)
78
+ a_pos = torch.zeros(B, dtype=torch.long, device=device)
79
+ opt.zero_grad()
80
+ loss, _ = model(tgt_g, ctx_mask, target_mask, a_key, a_pos)
81
+ if torch.isnan(loss) or loss.item() == 0: continue
82
+ loss.backward()
83
+ torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0)
84
+ opt.step(); model.update_ema()
85
+ epoch_loss += loss.item(); n += 1
86
+ avg = epoch_loss / max(n, 1)
87
+ print(f"[TRAIN] Epoch {epoch}/50: loss={avg:.4f}", flush=True)
88
+ run.log({"epoch_loss": avg, "epoch": epoch})
89
+ if epoch % 10 == 0 or epoch == 50:
90
+ ck = save_dir / f"ckpt_{epoch}.pt"
91
+ torch.save({"epoch": epoch, "model": model.state_dict()}, ck)
92
+ print(f"[TRAIN] Saved {ck}", flush=True)
93
+
94
+ final = save_dir / "final.pt"
95
+ torch.save({"model": model.state_dict(), "epoch": 50}, final)
96
+ print(f"[TRAIN] Final: {final}", flush=True)
97
+
98
+ from huggingface_hub import HfApi
99
+ try:
100
+ api = HfApi()
101
+ api.upload_file(path_or_fileobj=str(final), path_in_repo="checkpoints/final.pt", repo_id="guychuk/arc-agi-3-grid-jepa", repo_type="model")
102
+ print("[TRAIN] Pushed to hub", flush=True)
103
+ except Exception as e:
104
+ print(f"[TRAIN] Push failed: {e}", flush=True)
105
+ run.finish()
106
+ print("[TRAIN] Done", flush=True)