Spaces:
Build error
Build error
File size: 38,701 Bytes
71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 1b1bbb4 71e7cd3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 | """Export the archived Sleep runs as compact JSON for the public Sleep observatory.
Reads only JSON, JSON-lines and Markdown under ``docs/research/results/`` (and, optionally, the session files of a
local experiment store); never model weights. Writes one index plus one file per run to
``docs/research/results/sleep-observatory/`` and mirrors the same bytes into ``dashboard/public/assets/observatory/``,
which the dashboard build copies into ``dist/assets`` (the only static path the Space serves).
Every value is copied from a source file or computed by the project's own functions, never invented:
* Per-group recall is recounted with ``scripts.experiments.sleep_controls.group_counts`` only when every saved probe
row is attributed to a probe of the current catalog. Otherwise the saved counts stand, and the source says so.
* A locality check that a run's gate did not record was not in force when it ran. Where the replies allow it, the
current cluster-share rule is rescored with ``plastic.sleep.recall.RecallReport`` and labelled as a rescore.
* Recorded statuses are kept. An accepted child lives in the run's disposable experiment store; it is not published.
* Missing measurements stay missing (``null``), never zero.
The output is deterministic: no wall-clock time and no absolute paths. It is identified by the sha256 of each
source file, an archive digest over them, and ``EXPORTER_VERSION``.
Usage
python -m scripts.export_sleep_observatory # refresh from the archive
python -m scripts.export_sleep_observatory --session-store final_step250_seed0_exclude=<store dir>
python -m scripts.export_sleep_observatory --check # exit 1 if the committed export is stale
"""
from __future__ import annotations
import argparse
import fnmatch
import hashlib
import json
import math
import os
import re
import shutil
import sys
import tempfile
from pathlib import Path
from typing import Any
from plastic.sleep.recall import RecallReport, RecallResult
from scripts.experiments.sleep_controls import build_probes, group_counts
EXPORTER_VERSION = "1.0.0"
SCHEMA = "plastic.sleep-observatory/1"
ROOT = Path(__file__).resolve().parent.parent
ARCHIVE = ROOT / "docs" / "research" / "results" / "sleep-2026-09-23"
CHAT_EVAL = ROOT / "docs" / "research" / "results" / "chat-eval-2026-09-23"
OUT = ROOT / "docs" / "research" / "results" / "sleep-observatory"
MIRROR = ROOT / "dashboard" / "public" / "assets" / "observatory"
CONTROL_ARMS = ("floor", "ceiling")
ARM_ORDER = ("floor", "ceiling", "anchor", "replay", "distill", "dream", "ungated")
GROUPS = ("taught", "boundary", "rolled", "poison", "general")
TENSORS = ("W1", "b1", "W2", "b2")
# Locality checks the current gate knows. A run whose gate lacks one ran before that check existed.
CURRENT_CHECKS = ("heldout_nll_mean_rise", "reply_cluster_share")
CHECK_LABELS = {
"heldout_nll_mean_rise": "held-out NLL rise",
"reply_cluster_share": "largest identical-reply share",
"reply_distinct_ratio": "distinct-reply ratio (earlier rule)",
"canary_coherence": "canary coherence change",
"canary_poison": "canary poison change",
}
MAX_REPLY_CHARS = 280
READABLE = {".json", ".jsonl", ".md"}
# ---------------------------------------------------------------------------------------------------- small helpers
def sha256(path: Path) -> str:
return hashlib.sha256(path.read_bytes()).hexdigest()
def read_json(path: Path) -> Any:
if path.suffix not in READABLE: # the exporter never opens weights or pickles
raise ValueError(f"refusing to read {path.name}: only {sorted(READABLE)} are exported")
return json.loads(path.read_text(encoding="utf-8"))
def num(x: Any, sig: int = 6) -> float | None:
"""A finite number rounded to ``sig`` significant digits, or None. Booleans are not numbers."""
if isinstance(x, bool) or not isinstance(x, (int, float)) or not math.isfinite(x):
return None
if x == 0:
return 0.0
return float(f"{x:.{sig}g}")
def rel(path: Path) -> str:
return path.resolve().relative_to(ROOT).as_posix()
def checkpoint_identity(path_text: str | None, digest: str | None) -> dict[str, Any]:
"""Name, SFT step and digest prefix. Local paths are reduced to their final component (no user directories)."""
name = os.path.basename(str(path_text or "").rstrip("/")) or None
m = re.search(r"step(\d+)", name or "")
step = int(m.group(1)) if m else None
if name and "base" in name:
label = "TTT-MLP-760M base (not chat-tuned)"
elif step == 250:
label = "final chat checkpoint (SFT step 250 of 250)"
elif step is not None:
label = f"intermediate chat checkpoint (SFT step {step} of 250)"
else:
label = name or "unrecorded"
return {"name": name, "step": step, "label": label, "digest_prefix": (digest or "")[:16] or None,
"published": False}
# ---------------------------------------------------------------------------------------------------- the README
def readme_rows(readme: Path) -> list[dict[str, str]]:
"""Rows of the archive README's run table: pattern (may be a glob), checkpoint, digest, code, question."""
rows = []
for line in readme.read_text(encoding="utf-8").splitlines():
cells = [c.strip() for c in line.strip().strip("|").split("|")]
if len(cells) < 5 or not cells[0].startswith("`"):
continue
pattern = cells[0].strip("`")
rows.append({"pattern": pattern, "checkpoint": cells[1], "digest": cells[2], "code": cells[3],
"question": " | ".join(cells[4:])})
return rows
def plain(md: str) -> str:
"""Markdown cell text without code ticks or bold markers."""
return re.sub(r"\s+", " ", md.replace("`", "").replace("**", "")).strip()
def match_row(rows: list[dict[str, str]], run_id: str, files: list[str]) -> dict[str, str] | None:
for row in rows:
if fnmatch.fnmatch(run_id, row["pattern"]) or any(fnmatch.fnmatch(f, row["pattern"]) for f in files):
return row
return None
def first_sentence(text: str) -> str:
m = re.match(r"(.+?[.:;])(\s|$)", text)
return (m.group(1) if m else text).rstrip(".:;")
# ---------------------------------------------------------------------------------------------------- recall
def probe_group(row: dict[str, Any], probes: dict[str, list]) -> tuple[str | None, str | None]:
"""The catalog group of one probe row and how it was attributed, using the experiment's own group_counts (not a
copy of it): by (question, expected answer) first; for rows from an earlier catalog whose expected string changed,
by the question text alone when that text belongs to exactly one probe. Display only: counts never use this."""
for candidate, how in ((row, "question and expected answer"), ({k: v for k, v in row.items() if k != "expected"}, "question text only")):
counts = group_counts([candidate], probes)
hit = [g for g, c in counts.items() if c["n"] or c["n_paraphrase"]]
if len(hit) == 1:
return hit[0], how
return None, None
def counts_for(results: list[dict[str, Any]] | None, saved: dict[str, Any] | None, probes: dict[str, list]) -> dict[str, Any]:
"""Per-group counts and where they come from. A recount replaces the saved table only when it attributes every
row; a partial recount would silently shrink denominators for runs that used an earlier probe catalog."""
saved = saved or None
if not results:
return {"by_group": saved, "source": "saved" if saved else "absent", "saved": None}
recount = group_counts(results, probes)
attributed = sum(c["n"] + c["n_paraphrase"] for c in recount.values())
if attributed != len(results):
return {"by_group": saved, "source": "saved" if saved else "absent", "saved": None}
recount = {g: c for g, c in recount.items() if c["n"] or c["n_paraphrase"]}
saved_nonempty = {g: c for g, c in (saved or {}).items() if c.get("n") or c.get("n_paraphrase")}
if saved is not None and saved_nonempty == recount:
return {"by_group": recount, "source": "saved, confirmed by recount", "saved": None}
return {"by_group": recount, "source": "recounted" if saved is not None else "counted from replies", "saved": saved}
def cluster_share(results: list[dict[str, Any]] | None) -> float | None:
"""The current rule's largest identical-reply share, computed by the project's RecallReport."""
if not results:
return None
rep = RecallReport([RecallResult(**{k: r.get(k) for k in ("question", "expected", "reply", "contains", "exact", "variant")})
for r in results])
return rep.max_cluster_share()
def totals(recall: dict[str, Any] | None) -> dict[str, Any] | None:
if not recall:
return None
return {"n_probes": recall.get("n_probes"), "recalled": recall.get("recalled"), "n_paraphrase": recall.get("n_paraphrase"),
"recalled_paraphrase": recall.get("recalled_paraphrase"), "mean_answer_logprob": num(recall.get("mean_answer_logprob")),
"max_cluster_share": num(recall.get("max_cluster_share")), "distinct_ratio": num(recall.get("distinct_ratio"))}
def probe_rows(results: list[dict[str, Any]] | None, probes: dict[str, list]) -> list[dict[str, Any]]:
"""Per-probe replies. run_probes asks each probe's paraphrase right after its verbatim question, so a paraphrase from
an earlier catalog that no longer matches inherits the group of the verbatim row just before it (labelled)."""
out: list[dict[str, Any]] = []
for r in results or []:
reply = str(r.get("reply", ""))
group, how = probe_group(r, probes)
prev = out[-1] if out else None
if group is None and r.get("variant") == "paraphrase" and prev and prev["variant"] == "verbatim" and prev["group"] and prev["expected"] == r.get("expected"):
group, how = prev["group"], "paired with the preceding verbatim question"
out.append({"group": group, "group_attribution": how, "variant": r.get("variant", "verbatim"), "question": r.get("question"),
"expected": r.get("expected"), "reply": reply[:MAX_REPLY_CHARS], "reply_truncated": len(reply) > MAX_REPLY_CHARS,
"hit": bool(r.get("contains")), "exact": bool(r.get("exact")), "answer_logprob": num(r.get("answer_logprob"), 4)})
return out
# ---------------------------------------------------------------------------------------------------- arms
def gate_view(gate: dict[str, Any] | None, after_results: list[dict[str, Any]] | None, recorded_share: float | None) -> dict[str, Any] | None:
if gate is None:
return None
checks = [{"name": c.get("name"), "label": CHECK_LABELS.get(c.get("name"), c.get("name")), "value": num(c.get("value")),
"limit": num(c.get("limit")), "passed": bool(c.get("passed")), "in_force": True} for c in gate.get("checks", [])]
names = {c["name"] for c in checks}
for name in CURRENT_CHECKS:
if name in names:
continue
entry = {"name": name, "label": CHECK_LABELS[name], "value": None, "limit": None, "passed": None, "in_force": False,
"value_source": None}
if name == "reply_cluster_share":
if recorded_share is not None:
entry.update(value=num(recorded_share), value_source="recorded measurement")
elif after_results:
entry.update(value=num(cluster_share(after_results)), value_source="rescored from saved replies with the current rule")
entry["limit"] = 0.25 if entry["value"] is not None else None
checks.append(entry)
return {"measured": gate.get("measured"), "passed": gate.get("passed"), "checks": checks}
def selected_turns(harvest: dict[str, Any] | None) -> dict[str, Any]:
"""The selection an arm trained on. Recorded when the report has it; derived only from recorded counts when the run
records its flagged policy; otherwise absent (older runs predate the selection rule, ASTRA-197/199)."""
if not harvest:
return {"value": None, "source": "absent"}
if harvest.get("selected_turns") is not None:
return {"value": harvest["selected_turns"], "source": "recorded"}
policy = harvest.get("flagged_policy")
by_reason = harvest.get("turns_by_reason") or {}
accepted = int(by_reason.get("accepted") or 0)
if policy == "exclude" and harvest.get("provenance") == "accepted" and harvest.get("flagged_excluded") is not None:
return {"value": accepted - int(harvest["flagged_excluded"]), "source": "derived from recorded harvest counts"}
if policy == "include" and str(harvest.get("provenance", "")).startswith("all"):
completed = sum(int(v or 0) for v in by_reason.values())
return {"value": completed, "source": "derived from recorded harvest counts"}
if policy == "include" and harvest.get("provenance") == "accepted":
return {"value": accepted, "source": "derived from recorded harvest counts"}
return {"value": None, "source": "absent"}
def harvest_view(h: dict[str, Any] | None) -> dict[str, Any] | None:
if not h:
return None
return {"sessions": [{k: s.get(k) for k in ("session_id", "log_only", "turns", "accepted_turns", "has_committed_state")} for s in h.get("sessions", [])],
"turns_by_reason": h.get("turns_by_reason"), "accepted_tokens": h.get("accepted_tokens"), "excluded_tokens": h.get("excluded_tokens"),
"accepted_turns_flagged": h.get("accepted_turns_flagged"), "flagged_excluded": h.get("flagged_excluded"),
"provenance": h.get("provenance"), "flagged_policy": h.get("flagged_policy"), "source_sessions": h.get("source_sessions"),
"selected_turns": selected_turns(h)}
def anchor_update(rep: dict[str, Any]) -> dict[str, Any] | None:
raw = rep.get("anchor_relative_update")
if not raw:
return None
return {"quantity": "relative change of W0 per tensor, ||W0_child - W0_parent|| / ||W0_parent||", "tensors": list(TENSORS),
"values": _per_tensor(raw)}
def _per_tensor(raw: dict[str, Any]) -> list[list[float | None]]:
layers: dict[int, dict[str, float | None]] = {}
for key, value in raw.items():
m = re.search(r"layers\.(\d+)\..*\.(W1|b1|W2|b2)$", key)
if m:
layers.setdefault(int(m.group(1)), {})[m.group(2)] = num(value, 4)
n = max(layers) + 1 if layers else 0
return [[layers.get(i, {}).get(t) for t in TENSORS] for i in range(n)]
def w0_change(rep: dict[str, Any]) -> dict[str, Any] | None:
"""Per-tensor child-vs-parent relative W0 change, recorded for every method (and before a pull-back) since aae9b70."""
raw = rep.get("w0_relative_change")
if not raw:
return None
return {"quantity": "relative change of W0 per tensor, ||W0_after - W0_before|| / ||W0_before||", "tensors": list(TENSORS),
"values": _per_tensor(raw), "total": num(raw.get("total"), 4)}
def grad_norms_view(rep: dict[str, Any]) -> dict[str, Any] | None:
"""Per-step gradient norms of the trained parameters, before clipping: total, per decoder layer, and 'other'."""
rows = rep.get("grad_norms")
if not rows:
return None
layer_keys = sorted({k for r in rows for k in (r.get("per_layer") or {}) if k.isdigit()}, key=int)
n_layers = int(layer_keys[-1]) + 1 if layer_keys else 0
return {"quantity": "gradient norm before clipping", "steps": [r.get("step") for r in rows],
"total": [num(r.get("total"), 4) for r in rows],
"per_layer": [[num((r.get("per_layer") or {}).get(str(i)), 4) for r in rows] for i in range(n_layers)],
"other": [num((r.get("per_layer") or {}).get("other"), 4) for r in rows]
if any("other" in (r.get("per_layer") or {}) for r in rows) else None}
def dreams_view(d: dict[str, Any] | None) -> dict[str, Any] | None:
if not d:
return None
kept = []
for k in d.get("kept") or []:
kept.append({"prompt": k.get("prompt"), "turn": k.get("turn"), "text": str(k.get("text", ""))[:MAX_REPLY_CHARS * 2],
"session_id": k.get("session_id"), "reply_len": k.get("reply_len"),
"teacher_logprob": num(k.get("teacher_logprob"), 4), "student_logprob": num(k.get("student_logprob"), 4),
"fastweight_logprob": num(k.get("fastweight_logprob"), 4), "gain": num(k.get("gain"), 4),
"fastweight_gain": num(k.get("fastweight_gain"), 4),
"token_gain": [num(v, 3) for v in k.get("token_gain") or []] or None,
"token_fw_gain": [num(v, 3) for v in k.get("token_fw_gain") or []] or None})
reasons: dict[str, int] = {}
for r in d.get("rejected") or []:
reasons[str(r.get("reason"))] = reasons.get(str(r.get("reason")), 0) + 1
return {"generated": d.get("generated"), "kept_count": len(d.get("kept") or []),
"filtered": {k: d.get(k) for k in ("degenerate", "duplicate", "low_gain", "too_long")},
"rejected_reasons": reasons,
"rejected_samples": [{"reason": r.get("reason"), "text": str(r.get("text", ""))[:MAX_REPLY_CHARS]} for r in (d.get("rejected") or [])[:4]],
"kept": kept}
def lineage(status: str | None, child: str | None, parent: str | None) -> dict[str, Any]:
if status in ("accepted", "accepted_unmeasured"):
return {"parent": parent, "child": child, "outcome": "committed",
"where": "registered in the run's disposable experiment store; not published"}
if status == "rejected":
return {"parent": parent, "child": None, "outcome": "pulled back", "where": "no child registered; the parent is unchanged"}
return {"parent": parent, "child": child, "outcome": "unknown", "where": None}
def sleep_arm(arm: str, summary: dict[str, Any] | None, rep: dict[str, Any] | None, rep_path: Path | None,
probes: dict[str, list]) -> dict[str, Any]:
"""One consolidation arm: the run-level summary (``sleep_controls.json``) plus its own report."""
summary = summary or {}
rep = rep or {}
before = rep.get("before") or {}
after = rep.get("after") or {}
after_results = (after.get("recall") or {}).get("results") or summary.get("results")
before_results = (before.get("recall") or {}).get("results")
status = summary.get("status") or rep.get("status")
child = summary.get("model_id", rep.get("model_id"))
recorded_share = (after.get("recall") or {}).get("max_cluster_share")
cfg = rep.get("config") or {}
return {
"arm": arm, "kind": "sleep", "method": cfg.get("method") or ("replay" if arm == "ungated" else arm),
"target": cfg.get("target"), "status": status,
"status_conflict": bool(summary.get("status") and rep.get("status") and summary["status"] != rep["status"]),
"reason": summary.get("reason", rep.get("reason")),
"lineage": lineage(status, child, rep.get("parent_model_id")),
"gate": gate_view(summary.get("gate") or rep.get("gate"), after_results, recorded_share),
"heldout_nll": {"before": {k: num(v) for k, v in (summary.get("heldout_nll_before") or before.get("heldout_nll") or {}).items()} or None,
"after": {k: num(v) for k, v in (summary.get("heldout_nll_after") or after.get("heldout_nll") or {}).items()} or None},
"recall": {"before": counts_for(before_results, summary.get("by_group_before"), probes),
"after": counts_for(after_results, summary.get("by_group"), probes),
"totals_before": totals(before.get("recall")), "totals_after": totals(after.get("recall"))},
"harvest": harvest_view(summary.get("harvest") or rep.get("harvest")),
"batch": summary.get("batch") or rep.get("batch"), "packed": rep.get("packed"),
"losses": [num(x, 5) for x in rep.get("losses") or []] or None,
"loss_terms": (summary.get("batch") or rep.get("batch") or {}).get("loss_terms"),
"dreams": dreams_view(summary.get("dreams") or rep.get("dreams")),
"anchor_relative_update": anchor_update(rep),
"w0_relative_update": w0_change(rep), # every method, in reports written after aae9b70; absent before
"gradient_norms": grad_norms_view(rep), # per step, before clipping, in reports written after aae9b70
"config": {k: cfg.get(k) for k in ("steps", "lr", "batch_size", "seq_len", "replay_ratio", "replay_rows", "heldout_rows", "anchor_lambda",
"tolerance_nll", "tolerance_collapse", "session_loss", "prompt_loss_weight", "provenance",
"flagged_policy", "dream_temperature", "dream_min_gain", "dream_token_weighting") if k in cfg} or None,
"probes": probe_rows(after_results, probes),
"report": ({"file": rel(rep_path), "sha256": sha256(rep_path), "run_id": rep.get("run_id"),
"head_at_arm_start": rep.get("code_commit"), "code_at_import": rep.get("code_commit_at_import"),
"seconds": num(rep.get("seconds"), 5)} if rep_path else None),
}
def control_arm(arm: str, summary: dict[str, Any], probes: dict[str, list]) -> dict[str, Any]:
results = summary.get("results")
share = summary.get("max_cluster_share")
return {"arm": arm, "kind": "control", "method": None, "status": None,
"recall": {"after": counts_for(results, summary.get("by_group"), probes)},
"mean_answer_logprob": num(summary.get("mean_answer_logprob")),
"max_cluster_share": {"value": num(share), "source": "recorded"} if share is not None else (
{"value": num(cluster_share(results)), "source": "computed from saved replies"} if results else {"value": None, "source": "absent"}),
"probes": probe_rows(results, probes)}
# ---------------------------------------------------------------------------------------------------- runs
def protocol(c: dict[str, Any], arms: dict[str, Any]) -> dict[str, Any]:
policies = sorted({(a.get("harvest") or {}).get("flagged_policy") for a in arms.values() if a.get("kind") == "sleep" and a.get("arm") != "ungated"} - {None})
return {"facts": c.get("facts"), "poison": c.get("poison"), "seed": c.get("seed", 0 if c.get("started_at_unix") else None),
"steps": c.get("steps"), "target": c.get("target"), "lr": c.get("lr"), "replay_ratio": c.get("replay_ratio"),
"batch_size": c.get("batch_size"), "session_loss": c.get("session_loss"), "prompt_loss_weight": c.get("prompt_loss_weight"),
"augment": c.get("augment"), "teach_temperature": c.get("teach_temperature"), "dream_temperature": c.get("dream_temperature"),
"replay_revision": (c.get("replay_revision") or "")[:12] or None, "device": c.get("device"),
"ceiling_mode": c.get("ceiling_mode", "all" if "ceiling" in c.get("arms", {}) else None),
"flagged_policy": c.get("flagged_policy") or (policies[0] if len(policies) == 1 else None),
"wall_seconds": num(c.get("seconds"), 5)}
def export_run(run_dir: Path, rows: list[dict[str, str]], probes: dict[str, list]) -> dict[str, Any]:
controls_path = run_dir / "sleep_controls.json"
c = read_json(controls_path)
sources = [controls_path]
arms: dict[str, Any] = {}
for arm in ARM_ORDER:
summary = c.get("arms", {}).get(arm)
rep_path = run_dir / f"sleep_{arm}_report.json"
if summary is None and not rep_path.exists():
continue
if arm in CONTROL_ARMS:
arms[arm] = control_arm(arm, summary, probes)
continue
rep = read_json(rep_path) if rep_path.exists() else None
if rep is not None:
sources.append(rep_path)
arms[arm] = sleep_arm(arm, summary, rep, rep_path if rep else None, probes)
for md in sorted(run_dir.glob("*.md")):
sources.append(md)
report_times = [read_json(p).get("created_at_unix") for p in sources if p.name.endswith("_report.json")]
started = c.get("started_at_unix") or min((t for t in report_times if t), default=None)
row = match_row(rows, run_dir.name, [p.name for p in sources])
question = plain(row["question"]) if row else None
return {
"id": run_dir.name, "question": question, "summary": first_sentence(question) if question else None,
"started_at_unix": started, "checkpoint": checkpoint_identity(c.get("checkpoint"), c.get("checkpoint_digest")),
"code": {"recorded_at_launch": c.get("code_commit"), "archive_readme": plain(row["code"]) if row else None},
"protocol": protocol(c, arms), "arms": [arms[a] for a in ARM_ORDER if a in arms],
"notes": {"recount": (run_dir / "sleep_controls_recounted.md").exists()},
"sources": [{"file": rel(p), "sha256": sha256(p)} for p in sources],
}
def export_dryrun(paths: list[Path], rows: list[dict[str, str]], probes: dict[str, list]) -> dict[str, Any]:
"""The base-model dry run has no sleep_controls.json: one report per method."""
arms = []
first = None
for p in sorted(paths, key=lambda p: ARM_ORDER.index(read_json(p)["config"]["method"])):
rep = read_json(p)
first = first or rep
arms.append(sleep_arm(rep["config"]["method"], None, rep, p, probes))
cfg = first["config"]
row = match_row(rows, "base_dryrun", [p.name for p in paths])
question = plain(row["question"]) if row else None
return {
"id": "base_dryrun", "question": question, "summary": first_sentence(question) if question else None,
"started_at_unix": min(read_json(p).get("created_at_unix") or 0 for p in paths),
"checkpoint": {**checkpoint_identity("ttt_mlp_760m_base", None), "digest_prefix": None},
"code": {"recorded_at_launch": None, "archive_readme": plain(row["code"]) if row else None},
"protocol": {"facts": 3, "poison": False, "seed": cfg.get("seed"), "steps": cfg.get("steps"), "target": cfg.get("target"),
"lr": cfg.get("lr"), "replay_ratio": cfg.get("replay_ratio"), "batch_size": cfg.get("batch_size"),
"session_loss": cfg.get("session_loss"), "prompt_loss_weight": cfg.get("prompt_loss_weight"), "augment": None,
"teach_temperature": None, "dream_temperature": None, "replay_revision": None, "device": cfg.get("device"),
"ceiling_mode": None, "flagged_policy": cfg.get("flagged_policy"), "wall_seconds": None},
"arms": arms, "notes": {"recount": False},
"sources": [{"file": rel(p), "sha256": sha256(p)} for p in sorted(paths)],
}
def chat_eval() -> dict[str, Any] | None:
"""The final checkpoint's chat evaluation: context for every step-250 run's parent."""
path = CHAT_EVAL / "step250_t0.7.json"
if not path.exists():
return None
d = read_json(path)
return {"checkpoint_digest_prefix": str(d.get("checkpoint_digest", ""))[:16], "temperature": (d.get("sampling") or {}).get("temperature"),
"distinct_reply_share": num(d.get("distinct_reply_share")), "mean_repetition_share": num(d.get("mean_repetition_share")),
"held_out_nll": {k: ({kk: num(vv) for kk, vv in v.items()} if isinstance(v, dict) else num(v)) for k, v in (d.get("held_out_nll") or {}).items()},
"source": {"file": rel(path), "sha256": sha256(path)}}
# ---------------------------------------------------------------------------------------------------- session trajectories
def _flags(reasons: list[str]) -> list[str]:
return [r for r in reasons if r != "log_only"]
def extract_sessions(run_id: str, store: Path | None, archive_run: Path) -> dict[str, Any]:
"""Per-chunk trajectories of a run's teaching and rolled-back sessions. Read from the public results archive
(``<run>/sessions/``) when it holds them; otherwise from a local experiment store, only when that store provably
belongs to the archived run (identical sleep_controls.json). Both paths check the position and model signature.
A local store's path is not recorded; the file digests are."""
archived = archive_run / "sleep_controls.json"
public = store is None
if public:
store = archive_run
if not (store / "sessions").is_dir():
raise ValueError(f"{run_id}: the archive holds no session files")
else:
store = store.resolve()
local = store.parent / "sleep_controls.json"
if not local.exists() or sha256(local) != sha256(archived):
raise ValueError(f"{run_id}: the store's sleep_controls.json is not byte-identical to the archived run")
c = read_json(archived)
digest = c.get("checkpoint_digest") or ""
harvest = next((a["harvest"] for a in c["arms"].values() if isinstance(a, dict) and a.get("harvest")), None)
sessions = []
for sid in ("teach", "rolled"):
sdir = store / "sessions" / sid
if not sdir.exists():
continue
meta = read_json(sdir / "meta.json")
if not str(meta.get("model_signature", "")).endswith(digest):
raise ValueError(f"{run_id}/{sid}: model signature does not match the archived checkpoint digest")
tx_path, trace_path = sdir / "transactions.jsonl", sdir / "trace.jsonl"
txs = [json.loads(line) for line in tx_path.read_text(encoding="utf-8").splitlines() if line.strip()]
trace = [json.loads(line) for line in trace_path.read_text(encoding="utf-8").splitlines() if line.strip()] if trace_path.exists() else []
if sid == "teach" and harvest is not None and meta.get("pos") != harvest.get("accepted_tokens"):
raise ValueError(f"{run_id}/teach: position {meta.get('pos')} differs from the harvest's accepted tokens")
chunks = []
for t in txs:
s = t.get("signals") or {}
src = t.get("sources") or {}
chunks.append({
"i": t.get("index"), "pos": [t.get("pos_start"), t.get("pos_end")], "n": s.get("n_tokens"),
"source": "user" if (src.get("user") or 0) >= (src.get("model") or 0) else "model",
"chunk_loss": num(s.get("chunk_loss"), 4), "surprise_mean": num(s.get("surprise_mean"), 4),
"surprise_max": num(s.get("surprise_max"), 4), "write_norm_sum": num(s.get("write_norm_sum"), 4),
"proposed": num(s.get("delta_norm"), 4), "accepted": num((t.get("accepted") or {}).get("delta_norm"), 4),
"per_layer": [num(v, 3) for v in s.get("delta_norm_per_layer") or []] or None,
"requested": (t.get("requested") or {}).get("kind"), "applied": (t.get("decision") or {}).get("kind"),
"scale": num((t.get("decision") or {}).get("scale"), 4),
"flags": _flags((t.get("requested") or {}).get("reasons") or []),
"applied_reasons": _flags((t.get("decision") or {}).get("reasons") or []),
"read_only": bool(t.get("read_only")),
})
h = meta.get("harness") or {}
sessions.append({
"session_id": sid, "log_only": bool(h.get("log_only")), "enable_rollback": h.get("enable_rollback"),
"z_rollback": h.get("z_rollback"), "z_scale": h.get("z_scale"), "calibrated": False if not meta.get("extra", {}).get("calibration") else True,
"counts": {k: meta.get(k) for k in ("commits", "rollbacks", "scales", "projects", "readonly", "n_transactions", "pos")},
"turns": [{"i": i, "prompt": tr.get("prompt"), "completion": str(tr.get("completion", ""))[:MAX_REPLY_CHARS],
"tx": [tr.get("tx_start"), tr.get("tx_end")]} for i, tr in enumerate(trace)],
"chunks": chunks,
"source": {"transactions": rel(tx_path) if public else None, "transactions_sha256": sha256(tx_path),
"trace_sha256": sha256(trace_path) if trace_path.exists() else None},
})
n_leaves = max((len(ch["per_layer"] or []) for s in sessions for ch in s["chunks"]), default=0)
return {"run_id": run_id, "schema": SCHEMA,
"provenance": {"kind": "public results archive" if public else "local experiment store; these session files are not in the public results archive",
"controls_sha256": sha256(archived),
"checks": ([] if public else ["sleep_controls.json byte-identical to the archive"])
+ ["teach position equals the harvest's accepted tokens", "model signature matches the checkpoint digest"]},
"per_layer": {"quantity": "proposed fast-weight change per tensor in effective coordinates (norm of working minus committed)",
"layers": n_leaves // len(TENSORS), "tensors": list(TENSORS), "order": "layer-major: layer 0 W1, b1, W2, b2, layer 1 ..."},
"sessions": sessions}
# ---------------------------------------------------------------------------------------------------- driver
def dump(obj: Any) -> str:
return json.dumps(obj, ensure_ascii=False, separators=(",", ":"), sort_keys=False) + "\n"
def build(out: Path, stores: dict[str, Path]) -> dict[str, Any]:
probes = build_probes()
rows = readme_rows(ARCHIVE / "README.md")
runs = [export_run(d, rows, probes) for d in sorted(ARCHIVE.iterdir()) if d.is_dir() and (d / "sleep_controls.json").exists()]
dry = sorted(ARCHIVE.glob("base_dryrun_*_report.json"))
if dry:
runs.append(export_dryrun(dry, rows, probes))
runs.sort(key=lambda r: (r["started_at_unix"] or 0, r["id"]))
(out / "runs").mkdir(parents=True, exist_ok=True)
(out / "sessions").mkdir(parents=True, exist_ok=True)
archived_sessions = {r["id"] for r in runs if (ARCHIVE / r["id"] / "sessions").is_dir()}
for run_id in sorted(archived_sessions | set(stores)):
source = None if run_id in archived_sessions else stores[run_id] # the public archive wins over a local store
(out / "sessions" / f"{run_id}.json").write_text(dump(extract_sessions(run_id, source, ARCHIVE / run_id)), encoding="utf-8")
session_ids = sorted(p.stem for p in (out / "sessions").glob("*.json"))
run_ids = {r["id"] for r in runs}
for stale in (out / "runs").glob("*.json"):
if stale.stem not in run_ids:
stale.unlink()
for r in runs:
r["session_trajectory"] = f"sessions/{r['id']}.json" if r["id"] in session_ids else None
(out / "runs" / f"{r['id']}.json").write_text(dump(r), encoding="utf-8")
source_digests = sorted({(s["file"], s["sha256"]) for r in runs for s in r["sources"]})
archive_digest = hashlib.sha256("".join(f"{f}:{d}\n" for f, d in source_digests).encode()).hexdigest()
index = {
"schema": SCHEMA, "exporter_version": EXPORTER_VERSION, "archive_digest": archive_digest,
"archive": rel(ARCHIVE), "chat_eval": chat_eval(),
"runs": [{
"id": r["id"], "summary": r["summary"], "started_at_unix": r["started_at_unix"], "checkpoint": r["checkpoint"],
"code_recorded": r["code"]["recorded_at_launch"], "facts": r["protocol"]["facts"], "flagged_policy": r["protocol"]["flagged_policy"],
"steps": r["protocol"]["steps"], "target": r["protocol"]["target"], "session_trajectory": r["session_trajectory"],
"arms": [{"arm": a["arm"], "status": a["status"], "method": a["method"],
"taught": ((a["recall"]["after"]["by_group"] or {}).get("taught") if a["recall"]["after"]["by_group"] else None),
"totals": a["recall"].get("totals_after") if a["kind"] == "sleep" else None,
"nll_before": ((a.get("heldout_nll") or {}).get("before") or {}).get("mean"),
"nll_after": ((a.get("heldout_nll") or {}).get("after") or {}).get("mean")} for a in r["arms"]],
} for r in runs],
"sessions": session_ids,
}
(out / "index.json").write_text(dump(index), encoding="utf-8")
return index
def mirror(src: Path, dst: Path) -> None:
if dst.exists():
shutil.rmtree(dst)
shutil.copytree(src, dst)
def tree_bytes(root: Path) -> dict[str, bytes]:
return {p.relative_to(root).as_posix(): p.read_bytes() for p in sorted(root.rglob("*")) if p.is_file()}
def main(argv: list[str] | None = None) -> int:
ap = argparse.ArgumentParser(description=__doc__.split("\n\n")[0])
ap.add_argument("--out", type=Path, default=OUT, help="export directory (default: docs/research/results/sleep-observatory)")
ap.add_argument("--mirror", type=Path, default=MIRROR, help="dashboard copy served under /assets (default: dashboard/public/assets/observatory)")
ap.add_argument("--no-mirror", action="store_true", help="write the export only")
ap.add_argument("--session-store", action="append", default=[], metavar="RUN=STORE",
help="extract a run's teach/rolled session trajectories from a local experiment store (repeatable)")
ap.add_argument("--check", action="store_true", help="rebuild into a temporary copy and exit 1 if the committed export differs")
args = ap.parse_args(argv)
stores = {}
for item in args.session_store:
run_id, sep, path = item.partition("=")
if not sep or not (ARCHIVE / run_id / "sleep_controls.json").exists():
ap.error(f"--session-store expects RUN=STORE with RUN an archived run directory: {item}")
stores[run_id] = Path(path)
if args.check:
with tempfile.TemporaryDirectory() as tmp:
work = Path(tmp) / "export"
if args.out.exists():
shutil.copytree(args.out, work)
build(work, {})
fresh, committed = tree_bytes(work), tree_bytes(args.out) if args.out.exists() else {}
mirrored = tree_bytes(args.mirror) if args.mirror.exists() else {}
stale = sorted(k for k in set(fresh) | set(committed) if fresh.get(k) != committed.get(k))
drift = sorted(k for k in set(committed) | set(mirrored) if committed.get(k) != mirrored.get(k))
for k in stale:
print(f"stale: {k}")
for k in drift:
print(f"mirror differs: {k}")
return 1 if stale or drift else 0
index = build(args.out, stores)
if not args.no_mirror:
mirror(args.out, args.mirror)
size = sum(len(b) for b in tree_bytes(args.out).values())
print(f"exported {len(index['runs'])} runs, {len(index['sessions'])} session trajectories, {size / 1e6:.2f} MB -> {args.out}")
return 0
if __name__ == "__main__":
sys.exit(main())
|