SPB Git

spb/wp31_uqo

Public
6.2 KB · 121 lines python
1#!/usr/bin/env python2"""Generate LaTeX table fragments and the numbers macro file from structured results (never typed by hand).3Usage: python scripts/make_tables.py  -> paper/tables/*.tex, paper/tables/numbers.tex4"""5from __future__ import annotations67import json, re, sys8from pathlib import Path910sys.path.insert(0, str(Path(__file__).resolve().parents[1]))11OUT = Path("paper/tables"); OUT.mkdir(parents=True, exist_ok=True)12NUM: dict[str, str] = {}131415def macro(name: str, value) -> None:16    name = re.sub(r"[^A-Za-z]", "", name)17    NUM[name] = value if isinstance(value, str) else f"{value}"181920def fmt_int(n) -> str:21    return f"{int(n):,}"222324def table_configs():25    pc = json.loads(Path("results/tables/param_counts.json").read_text())26    rows = []27    order = ["prisme_103m", "prisme_459m", "prisme_1180m"]28    labels = {"prisme_103m": "PRISME-103M", "prisme_459m": "PRISME-459M", "prisme_1180m": "PRISME-1.18B"}29    head = r"""\begin{table}[t]\centering\small30\caption{Dimensioned configurations and exact unique parameter counts (meta-device instantiation,31\texttt{scripts/count\_params.py}). Backbone counts equal the reference design exactly; workspace+controller counts32differ from the proposal's figures (reconciled in Appendix~\ref{app:params}).}33\label{tab:configs}34\begin{tabular}{lrrr}\toprule35Property & PRISME-103M & PRISME-459M & PRISME-1.18B\\\midrule36"""37    cfgs = {}38    for k in order:39        c = json.loads(Path(f"configs/{k}.yaml").read_text().split("model:")[1].replace("\n", ",").replace("  ", "").replace(":", '":').replace(",", ',"').replace('{"', "{").replace(",}", "}") if False else "{}")40    import yaml41    cfgs = {k: yaml.safe_load(open(f"configs/{k}.yaml"))["model"] for k in order}42    def row(name, f):43        return name + " & " + " & ".join(f(k) for k in order) + r"\\" + "\n"44    body = ""45    body += row("Backbone layers $L$", lambda k: str(cfgs[k]["n_layers"]))46    body += row("Hidden $d$ / FFN", lambda k: f"{cfgs[k]['d_model']} / {cfgs[k]['ffn_width']}")47    body += row("Query / KV heads", lambda k: f"{cfgs[k]['n_heads']} / {cfgs[k]['n_kv_heads']}")48    body += row("Workspace $w$ / FFN$_w$", lambda k: f"{cfgs[k]['w']} / {cfgs[k]['ffn_w']}")49    body += row("Slots $M$, blocks $L_w$, cap $R_{\\max}$", lambda k: f"{cfgs[k]['n_slots']}, {cfgs[k]['n_editor_blocks']}, {cfgs[k]['r_max']}")50    body += r"\midrule" + "\n"51    body += row("Backbone parameters", lambda k: fmt_int(pc[k]["backbone"]))52    body += row("Workspace + controller", lambda k: fmt_int(pc[k]["workspace_controller"]))53    body += row("\\textbf{Total}", lambda k: "\\textbf{" + fmt_int(pc[k]["total"]) + "}")54    body += row("Proposal's workspace figure", lambda k: fmt_int(pc[k]["reference_brief"]["workspace"]))55    tail = r"\bottomrule\end{tabular}\end{table}" + "\n"56    (OUT / "configs.tex").write_text(head + body + tail)57    for k in order:58        macro("params" + {"prisme_103m": "Small", "prisme_459m": "Medium", "prisme_1180m": "Large"}[k] + "Total", fmt_int(pc[k]["total"]))59        macro("params" + {"prisme_103m": "Small", "prisme_459m": "Medium", "prisme_1180m": "Large"}[k] + "Ws", fmt_int(pc[k]["workspace_controller"]))606162def table_ops():63    o = json.loads(Path("results/tables/ops_459m_T4096.json").read_text())64    names = {"backbone_only": "Backbone only", "4_actions_k1": "4 actions, 1 slot each", "4_actions_k2": "4 actions, 2 slots each",65             "8_actions_k2": "8 actions, 2 slots each", "8_actions_dense16": "8 actions, dense 16-slot writes"}66    head = r"""\begin{table}[t]\centering\small67\caption{Analytic operations per generated token, PRISME-459M, context $T=4096$ (\texttt{scripts/estimate\_flops.py}).68``Proposal'' is the reference table of the original brief; ``implemented'' is the accounting of69Section~\ref{sec:compute} with the controller evaluated once per executed action plus once to stop. These are70arithmetic counts, not measured timings.}71\label{tab:ops}72\begin{tabular}{lrrrrr}\toprule73Policy & Proposal ($10^9$) & Implemented ($10^9$) & editor & controller & readout\\\midrule74"""75    body = ""76    for k, lab in names.items():77        r = o["rows"][k]78        ed = (r["editor_source_attn"] + r["editor_slot_attn"] + r["editor_ffn"] + r["editor_gate"]) / 1e979        body += f"{lab} & {o['brief_reference_459m_T4096'][k]/1e9:.3f} & {r['total']/1e9:.3f} & {ed:.3f} & {r['controller']/1e9:.3f} & {r['readout']/1e9:.3f}\\\\\n"80    (OUT / "ops.tex").write_text(head + body + r"\bottomrule\end{tabular}\end{table}" + "\n")81    o103 = json.loads(Path("results/tables/ops_103m_T512.json").read_text())82    macro("costsingle", f"{o103['action_cost_proxy'][0]:.3f}"); macro("costpair", f"{o103['action_cost_proxy'][-1]:.3f}")838485def table_families():86    man = json.loads(Path("data/splits/synthetic_v1/manifest.json").read_text())87    head = r"""\begin{table}[t]\centering\small88\caption{Synthetic suite v1: splits fixed before sampling. $n$ = items after cross-split exact-duplicate removal;89``dropped'' = duplicates removed. Test splits are locked until pre-registration is frozen.}90\label{tab:families}91\begin{tabular}{llllrr}\toprule92Split & Families & Templates & Depths & $n$ & dropped\\\midrule93"""94    body = ""95    for name, m in man.items():96        s = m["spec"]97        fam = ", ".join(s["families"]) if len(s["families"]) > 1 else s["families"][0]98        if len(s["families"]) == 5:99            fam = "arith, bind, fsm, excl, sched"100        body += f"{name.replace('_', '\\_')} & {fam} & {','.join(map(str, s['templates']))} & {','.join(map(str, s['depths']))} & {m['n']:,} & {m['duplicates_dropped']}\\\\\n"101    (OUT / "families.tex").write_text(head + body + r"\bottomrule\end{tabular}\end{table}" + "\n")102    macro("ntrainsynth", f"{man['train']['n']:,}")103104105def write_numbers():106    lines = ["% AUTO-GENERATED by scripts/make_tables.py — do not edit"]107    for k, v in sorted(NUM.items()):108        lines.append(f"\\newcommand{{\\{k}}}{{{v}}}")109    (OUT / "numbers.tex").write_text("\n".join(lines) + "\n")110111112if __name__ == "__main__":113    table_configs(); table_ops(); table_families()114    try:115        from scripts.make_results_tables import make_all  # results-dependent tables (added later)116        make_all(macro)117    except Exception as e:  # noqa: BLE001118        print("results tables skipped:", e)119    write_numbers()120    print("tables written:", sorted(p.name for p in OUT.glob("*.tex")))121
Files · a2c46f03643fdd75e8e87595931d35e18c590d57
Menu

Theme