Prizma / seq /bench.py
AylinMaylinn's picture
Publish Prizma — mirror of github.com/nazmiefearmutcu/Prizma (PRISM-Seq §4 bar + continual-learning Prizma)
5066d15 verified
Raw
History Blame Contribute Delete
3.39 kB
"""
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))