Publish Prizma — mirror of github.com/nazmiefearmutcu/Prizma (PRISM-Seq §4 bar + continual-learning Prizma)
5066d15 verified | """ | |
| The head-to-head harness. Defines the standard attention-diagnostic suite with CALIBRATED | |
| training budgets (enough that a proper Transformer masters each task — established empirically), | |
| and runs ANY model factory through it over multiple seeds with identical data/loss/optimiser/budget. | |
| A model_factory is `f(vocab:int, max_len:int) -> nn.Module` mapping inputs[B,T] long -> | |
| logits[B,T,vocab]. Both Transformer and Prizma-Seq are passed as factories so the comparison is | |
| apples-to-apples (same task instance, same TrainConfig, same seeds). | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import numpy as np | |
| from .common import TrainConfig, train_model, param_count, get_device | |
| from . import tasks as T | |
| # (task_factory, TrainConfig) — budgets calibrated so a 2-layer Transformer solves each. | |
| def standard_suite(): | |
| return { | |
| "induction": (lambda: T.Induction(vocab=32, seq_len=64), | |
| TrainConfig(steps=3000, batch_size=128, lr=1e-3, eval_every=1000, log=False)), | |
| "selcopy": (lambda: T.SelectiveCopy(vocab=32, mem_len=64, n_data=16), | |
| TrainConfig(steps=3000, batch_size=128, lr=1e-3, eval_every=1000, log=False)), | |
| "mqar_p8": (lambda: T.MQAR(vocab=64, num_pairs=8, num_queries=8), | |
| TrainConfig(steps=4000, batch_size=128, lr=1e-3, eval_every=1000, log=False)), | |
| "mqar_p16": (lambda: T.MQAR(vocab=64, num_pairs=16, num_queries=16), | |
| TrainConfig(steps=6000, batch_size=128, lr=1e-3, eval_every=1500, log=False)), | |
| "mqar_p8_gap": (lambda: T.MQAR(vocab=64, num_pairs=8, num_queries=8, gap=64), | |
| TrainConfig(steps=5000, batch_size=128, lr=1e-3, eval_every=1500, log=False)), | |
| } | |
| def run_model_on_suite(name, model_factory, seeds=(0, 1, 2), device=None, suite=None, log=True): | |
| device = device or get_device() | |
| suite = suite or standard_suite() | |
| out = {} | |
| for tname, (tfac, cfg) in suite.items(): | |
| accs, secs, params = [], [], None | |
| for s in seeds: | |
| task = tfac() | |
| model = model_factory(task.vocab, task.seq_len) | |
| params = param_count(model) | |
| r = train_model(model, task, cfg, device, seed=s) | |
| accs.append(r.best_acc) | |
| secs.append(r.seconds) | |
| if log: | |
| print(f" [{name}] {tname:<12} seed{s}: acc={r.best_acc:.3f} " | |
| f"params={params} {r.seconds:.0f}s", flush=True) | |
| out[tname] = {"accs": accs, "mean": float(np.mean(accs)), "std": float(np.std(accs)), | |
| "params": params, "sec_mean": float(np.mean(secs))} | |
| if log: | |
| print(f" [{name}] {tname:<12} => {out[tname]['mean']:.3f} ± {out[tname]['std']:.3f} " | |
| f"(params {params})", flush=True) | |
| return out | |
| if __name__ == "__main__": | |
| import sys | |
| from .transformer import Transformer, TFConfig | |
| def tf_factory(vocab, max_len): | |
| return Transformer(TFConfig(vocab=vocab, d_model=128, n_layers=2, n_heads=4, | |
| max_len=max_len + 4)) | |
| seeds = (0,) if "--quick" in sys.argv else (0, 1, 2) | |
| dev = get_device() | |
| print(f"device={dev} seeds={seeds}") | |
| res = run_model_on_suite("Transformer", tf_factory, seeds=seeds, device=dev) | |
| print("\n=== Transformer baseline ===") | |
| print(json.dumps(res, indent=2)) | |