WP-AI-0001: protocol, harness, Tier-0 pilot (sprints 0-2)
- Research gap (40 verified arXiv records), preregistration v0.1, experiment plan, compute budget, risk register, logs - Harness: OPSEQ/FSA/MORPH generators with exact validators, toy transformer with exact hook points, training, patching, bootstrap, manifests/registry - Pilot pilot_tier0_opseq_451ef5087182: donor/recipient gap, bitwise hook no-op, within-donor localization of the target operator - Paper skeleton with explicit placeholders; figures regenerated by scripts/build_figures.py Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
93 changed files +9,007 −0
added
.gitignore
+39 −0
@@ -0,0 +1,39 @@ | ||
| 1 | +# Raw & processed data — never committed (see data/raw/README.md for provenance) | |
| 2 | +data/raw/* | |
| 3 | +!data/raw/README.md | |
| 4 | +data/processed/* | |
| 5 | +!data/processed/.gitkeep | |
| 6 | + | |
| 7 | +# Python | |
| 8 | +__pycache__/ | |
| 9 | +*.pyc | |
| 10 | +.pytest_cache/ | |
| 11 | +.venv/ | |
| 12 | +*.egg-info/ | |
| 13 | + | |
| 14 | +# LaTeX build artifacts (paper/main.pdf IS committed) | |
| 15 | +paper/*.aux | |
| 16 | +paper/*.log | |
| 17 | +paper/*.out | |
| 18 | +paper/*.toc | |
| 19 | +paper/*.lof | |
| 20 | +paper/*.lot | |
| 21 | +paper/*.fls | |
| 22 | +paper/*.fdb_latexmk | |
| 23 | +paper/*.bbl | |
| 24 | +paper/*.blg | |
| 25 | +paper/*.spl | |
| 26 | +paper/*.synctex.gz | |
| 27 | +paper/*.run.xml | |
| 28 | +paper/*.bcf | |
| 29 | + | |
| 30 | +# Logs | |
| 31 | +logs/ | |
| 32 | +*.log | |
| 33 | + | |
| 34 | +# macOS | |
| 35 | +.DS_Store | |
| 36 | + | |
| 37 | +# WP-AI-0001 artifacts (regenerable; models + per-item outputs + run logs) | |
| 38 | +artifacts/ | |
| 39 | +!artifacts/.gitkeep | |
added
CLAUDE.md
+32 −0
@@ -0,0 +1,32 @@ | ||
| 1 | +# CLAUDE.md — WP-AI-0001: The Neural Organ Transplant Experiment | |
| 2 | + | |
| 3 | +**Causal transfer of cognitive capabilities across local large language models.** Research home: UQO | |
| 4 | +Research (`Recherche-UQO/ia/wp-ai-0001`). Language: English for all code, docs, figures, paper, logs. | |
| 5 | +Status: protocol + implementation in progress; **no transfer result has been established**. | |
| 6 | + | |
| 7 | +The full research mandate (sections 0–18: mission, estimands, RQ1–RQ8, task design, model matrix, | |
| 8 | +pipeline phases 1–8, metrics, statistics, architecture, gates A–F, figures, paper, registry, licensing, | |
| 9 | +roadmap, autonomous work rules) was supplied by the author on 2026-11-09 and is reproduced verbatim in | |
| 10 | +`docs/MANDATE.md`. It binds every session. Operational rules that follow from it: | |
| 11 | + | |
| 12 | +1. **Never fabricate** runs, metrics, citations, hardware or references. Every number in `docs/`, | |
| 13 | + `experiments/summaries/` and `paper/` must trace to a run id in `experiments/registry/runs.jsonl` and a | |
| 14 | + manifest in `experiments/manifests/`. Pending measurements are explicit placeholders. | |
| 15 | +2. **Gates in order** (A repository readiness → B baseline integrity → C mechanistic sanity → D transplant | |
| 16 | + validity → E confirmatory evidence → F paper integrity). A failed gate is diagnosed, not reinterpreted. | |
| 17 | +3. **Exploratory ≠ confirmatory.** `docs/PREREGISTRATION.md` v0.1 is registered; the confirmatory freeze | |
| 18 | + (v1.0) must precede generation of confirmatory splits. Design changes go to `docs/DECISION_LOG.md` | |
| 19 | + with "before/after freeze"; failures go to `docs/EXPERIMENT_LOG.md`. Unfavourable runs are never deleted. | |
| 20 | +4. **Persistence vocabulary.** Distinguish single-token intervention, within-sequence effect, | |
| 21 | + cross-prompt reuse, and saved checkpoint/adapter. Transient steering is never called learning. | |
| 22 | +5. **Controls are mandatory** for any transfer claim: unmodified recipient/donor, sham, norm-matched random, | |
| 23 | + unrelated-skill donor, shuffled-token/layer grafts, prompting, steering, matched adapter fine-tuning. | |
| 24 | +6. **Resources.** Laptop (M5 Max 48 GB) and the existing MacLustr SSH access only. Ask before paid compute, | |
| 25 | + checkpoints > 20 GB, publishing/submitting, or touching shared infrastructure. No secrets in the repo. | |
| 26 | +7. **Backends.** Tier 0 = PyTorch toy models (hooks exact, CPU-testable). Tier ≥ 1 = MLX layer wrapping | |
| 27 | + with a no-op test and a Transformers equivalence test; never claim a hook MLX does not expose. | |
| 28 | +8. **Remote.** `origin = gitsrv:srv/git/wpai0001_uqo.git` (spbgit on M1M32). Commit after each sprint | |
| 29 | + deliverable; `paper/main.pdf` is committed when it exists. | |
| 30 | + | |
| 31 | +Quick start: `python3 -m pytest tests -q` · `python3 scripts/audit_environment.py` · | |
| 32 | +`python3 scripts/run_pilot.py --quick --device cpu` · see `docs/REPRODUCIBILITY.md` and `docs/TASKS.md`. | |
added
README.md
+146 −0
@@ -0,0 +1,146 @@ | ||
| 1 | +<!-- Author: Simon-Pierre Boucher — simon-pierre.boucher@uqo.ca --> | |
| 2 | +# 🧠 The Neural Organ Transplant Experiment | |
| 3 | + | |
| 4 | +**UQO Working Paper No. AI-0001** — *Causal Transfer of Cognitive Capabilities Across Local Large Language Models* | |
| 5 | + | |
| 6 | +[](paper/main.pdf) | |
| 7 | +[](pyproject.toml) | |
| 8 | +[](tests/) | |
| 9 | +[](docs/REPRODUCIBILITY.md) | |
| 10 | +[](https://uqo.ca) | |
| 11 | +[](mailto:simon-pierre.boucher@uqo.ca) | |
| 12 | + | |
| 13 | +> **TL;DR** — Can a bounded, *causally identified* subsystem that implements a measurable capability in a | |
| 14 | +> donor language model be transplanted into a recipient that demonstrably lacks it, without full-model | |
| 15 | +> training? This repository holds the preregistered protocol, the experiment harness (toy transformers with | |
| 16 | +> exact hook semantics; MLX/Transformers backends planned), the registry of runs and the paper. | |
| 17 | +> **State on 2026-11-09:** Sprints 0–2 done on Tier 0 — donor/recipient gap manufactured and measured | |
| 18 | +> (donor 1.000 vs recipient 0.092 on the target operator, 3 seeds), hooks verified bitwise no-op, and the | |
| 19 | +> target operator localized by activation patching (executed at the read position by layer-0 attention and | |
| 20 | +> layer-0–2 MLPs; reproducible across seeds, r ≥ 0.96). **No transplant has been run yet.** | |
| 21 | + | |
| 22 | +--- | |
| 23 | + | |
| 24 | +## 📌 Status | |
| 25 | + | |
| 26 | +| Item | Value | | |
| 27 | +|---|---| | |
| 28 | +| Version | 0.1 protocol draft (November 2026) | | |
| 29 | +| SSRN | not yet submitted | | |
| 30 | +| Journal | to be assessed after results (ML / mechanistic interpretability venue) | | |
| 31 | +| Code & data | synthetic data regenerated from seeds; every run has a manifest in `experiments/manifests/` | | |
| 32 | +| Gates | A ✔ · B ✔ (Tier 0) · C ✔ (Tier 0) · D–F pending | | |
| 33 | + | |
| 34 | +## 🎯 What this paper does | |
| 35 | + | |
| 36 | +Prior work maps whole residual streams or concept directions between models (model stitching, activation | |
| 37 | +buses, cross-model steering) and the one controlled attempt at activation-mediated *capability* transfer | |
| 38 | +reports a null. We (i) causally localize a capability in the donor by interchange interventions, | |
| 39 | +(ii) manufacture or verify the recipient's lack of it, and (iii) compare each transplant family | |
| 40 | +(activation, subspace, circuit, weight, adapter, persistent) against matched sham, random and | |
| 41 | +unrelated-donor controls on held-out, leakage-controlled tasks. Estimands: | |
| 42 | + | |
| 43 | +``` | |
| 44 | +Δ_T = Q_T(R') − Q_T(R) transfer gain | |
| 45 | +Δ_T^adj = Δ_T − [Q_T(R_sham) − Q_T(R)] control-adjusted transfer (primary) | |
| 46 | +ρ_c = Q_c(R') / Q_c(R) retention on control strata | |
| 47 | +N_D = Q_T(D) − Q_T(D \ S_D) donor necessity | |
| 48 | +``` | |
| 49 | + | |
| 50 | +## 🏆 Headline results | |
| 51 | + | |
| 52 | +No transfer results yet. Pilot (exploratory, run `pilot_tier0_opseq_451ef5087182`): | |
| 53 | + | |
| 54 | +| Object | Estimate | | |
| 55 | +|---|---| | |
| 56 | +| Donor vs recipient, target stratum (final answer, 3 seeds) | 1.000 vs 0.092 (chance 0.105); paired gap seed 0 +0.847 [+0.825, +0.870] | | |
| 57 | +| Ω-step accuracy | donor 1.000, recipient 0.062 | | |
| 58 | +| Control stratum | 1.000 vs 1.000 | | |
| 59 | +| Hook no-op (6 models) | bitwise identity in all checks | | |
| 60 | +| Localization of Ω (restored-answer rate) | 1.00 at the read position for `resid_post` L0–L3 and `attn_out` L0; 0.00 elsewhere; sham 0.00 | | |
| 61 | + | |
| 62 | +## 🗂 Repository layout | |
| 63 | + | |
| 64 | +``` | |
| 65 | +wp-ai-0001/ | |
| 66 | +├── CLAUDE.md · docs/MANDATE.md # binding rules and the verbatim research mandate | |
| 67 | +├── src/wp_ai_0001/ # datasets (OPSEQ/FSA/MORPH), models + hooks, training, localization, | |
| 68 | +│ # evaluation, statistics, instrumentation, orchestration, visualization | |
| 69 | +├── tests/{unit,causal_sanity,...} # generators, bootstrap, hook no-op and intervention algebra | |
| 70 | +├── scripts/ # audit_environment, run_pilot, build_figures, build_paper | |
| 71 | +├── experiments/{registry,manifests,summaries} | |
| 72 | +├── artifacts/ # models, per-item outputs, figures (git-ignored) | |
| 73 | +├── docs/ # RESEARCH_GAP, PREREGISTRATION, EXPERIMENT_PLAN, COMPUTE_BUDGET, | |
| 74 | +│ # RISK_REGISTER, REPRODUCIBILITY, EXPERIMENT_LOG, DECISION_LOG, TASKS | |
| 75 | +├── literature/ # verified arXiv records + BibTeX; unverified candidates listed apart | |
| 76 | +└── paper/ # main.tex + sections/ + references.bib → main.pdf | |
| 77 | +``` | |
| 78 | + | |
| 79 | +## 🚀 Quick start | |
| 80 | + | |
| 81 | +```bash | |
| 82 | +python3 -m pip install -e ".[dev]" | |
| 83 | +python3 -m pytest tests -q | |
| 84 | +python3 scripts/audit_environment.py --cluster | |
| 85 | +python3 scripts/run_pilot.py --quick --device cpu --seeds 0 1 --n-boot 200 # ≈ 25 s CPU | |
| 86 | +python3 scripts/run_pilot.py --seeds 0 1 2 --steps 3000 # ≈ 5 min on an M5 Max (MPS) | |
| 87 | +python3 scripts/build_figures.py --run <run_id> && scripts/build_paper.sh | |
| 88 | +``` | |
| 89 | + | |
| 90 | +## 🗃 Data | |
| 91 | + | |
| 92 | +Synthetic micro-worlds generated from seeds (`src/wp_ai_0001/datasets/`), validated by exact recomputation, | |
| 93 | +hashed and checked for item-level disjointness across splits; see `data/README.md`. Tier-1 checkpoints | |
| 94 | +(Qwen2.5-1.5B/3B-Instruct, Llama-3.2-3B-Instruct, bf16) are cached locally and not redistributed. | |
| 95 | + | |
| 96 | +## 🔬 Methodology | |
| 97 | + | |
| 98 | +1. Gap qualification (Phase 1) — `scripts/run_pilot.py`, `training/train_toy.py`, `evaluation/metrics.py`. | |
| 99 | +2. Causal localization (Phase 2) — `localization/patching.py` (interchange, ablation, heads). | |
| 100 | +3. Alignment (Phase 3) — `alignment/` (to implement: Procrustes, ridge, CCA, random, unrelated-data). | |
| 101 | +4. Transplant families and controls (Phases 4–5) — `transplantation/` (to implement). | |
| 102 | +5. Robustness, mechanism, confirmatory (Phases 6–8) — planned, see `docs/EXPERIMENT_PLAN.md`. | |
| 103 | +6. Statistics — `statistics/bootstrap.py` (cluster bootstrap over programs; seed-level summaries). | |
| 104 | + | |
| 105 | +## 🖼 Figures & tables inventory | |
| 106 | + | |
| 107 | +| Figure | Content | Source run | | |
| 108 | +|---|---|---| | |
| 109 | +| `fig_gap_tier0.pdf` | donor/recipient accuracy per stratum, seeds, chance | `pilot_tier0_opseq_451ef5087182` | | |
| 110 | +| `fig_localization_patching_tier0.pdf` | layer × position restored-answer rate, 3 families | idem | | |
| 111 | +| `fig_localization_ablation_tier0.pdf` | layer × position accuracy after zero-ablation | idem | | |
| 112 | +| `fig_localization_heads_tier0.pdf` | layer × head patching at Ω token and read position | idem | | |
| 113 | + | |
| 114 | +## ⚠️ Limitations | |
| 115 | + | |
| 116 | +- Tier-0 capability is a per-step map once the trace is visible (risk R1); multi-step claims need | |
| 117 | + `trace_stride > 1` and Tier ≥ 1 evidence. | |
| 118 | +- No transplant, alignment or control battery has been executed; the paper contains placeholders. | |
| 119 | +- Length generalization fails for both roles (absolute positions); it is a stratum, not a target. | |
| 120 | + | |
| 121 | +## 📝 Citation | |
| 122 | + | |
| 123 | +```bibtex | |
| 124 | +@techreport{boucher2026organtransplant, | |
| 125 | + author = {Boucher, Simon-Pierre}, | |
| 126 | + title = {The Neural Organ Transplant Experiment: Causal Transfer of Cognitive Capabilities Across Local Large Language Models}, | |
| 127 | + institution = {Universit\'e du Qu\'ebec en Outaouais, D\'epartement des sciences administratives}, | |
| 128 | + type = {Working Paper}, | |
| 129 | + number = {AI-0001}, | |
| 130 | + year = {2026}, | |
| 131 | + month = {November} | |
| 132 | +} | |
| 133 | +``` | |
| 134 | + | |
| 135 | +## 👤 Author & contact | |
| 136 | + | |
| 137 | +**Simon-Pierre Boucher** — Département des sciences administratives, | |
| 138 | +Université du Québec en Outaouais (UQO), Gatineau, QC. | |
| 139 | +📧 [simon-pierre.boucher@uqo.ca](mailto:simon-pierre.boucher@uqo.ca) | |
| 140 | + | |
| 141 | +## 🗒 Notes | |
| 142 | + | |
| 143 | +- Numbering: project id `wp-ai-0001` (series "AI", number 0001) as requested in the mandate; repository | |
| 144 | + `wpai0001_uqo.git` on spbgit, following the FIRC-0001 precedent rather than the `wpN` sequence. | |
| 145 | +- Deviation from the template layout: `src/wp_ai_0001/training/` added (Tier-0 models are trained here); | |
| 146 | + experiment artifacts live under `experiments/` and `artifacts/` per the mandate instead of `results/`. | |
added
configs/experiments/.gitkeep
+0 −0
added
configs/interventions/.gitkeep
+0 −0
added
configs/models/.gitkeep
+0 −0
added
configs/tasks/.gitkeep
+0 −0
added
data/README.md
+10 −0
@@ -0,0 +1,10 @@ | ||
| 1 | +# Data policy — WP-AI-0001 | |
| 2 | + | |
| 3 | +All Tier-0 data are **synthetic** and regenerated from seeds by `src/wp_ai_0001/datasets/` (generator | |
| 4 | +versions are recorded in every split). Concrete split files are written under `artifacts/runs/<run_id>/data/` | |
| 5 | +(git-ignored) with SHA-256-derived hashes recorded in `experiments/manifests/<run_id>.json`. | |
| 6 | + | |
| 7 | +Tier ≥ 1 model checkpoints are downloaded from the Hugging Face hub into the user's cache (not committed). | |
| 8 | +Licenses: Qwen2.5 (Apache-2.0), Llama 3.2 (Llama 3.2 Community License — redistribution of derived | |
| 9 | +weights to be checked before release). No restricted or personal data are used. Nothing under `data/` is | |
| 10 | +committed except this file. | |
added
docs/COMPUTE_BUDGET.md
+30 −0
@@ -0,0 +1,30 @@ | ||
| 1 | +# Compute budget — WP-AI-0001 (measured where stated) | |
| 2 | + | |
| 3 | +## Resources audited 2026-11-09 (`scripts/audit_environment.py --cluster`, `docs/ENVIRONMENT_AUDIT.json`) | |
| 4 | + | |
| 5 | +- Laptop: Apple M5 Max, 48 GB unified memory, 18 cores, 921 GB free; Python 3.14.4; torch 2.12.0 (MPS on), | |
| 6 | + MLX 0.32.2 (Metal on), mlx_lm 0.31.3, transformers 5.8.1. Cached checkpoints: Qwen2.5-1.5B-Instruct-bf16, | |
| 7 | + Qwen2.5-3B-Instruct-bf16, Llama-3.2-3B-Instruct-bf16 (mlx-community), OLMoE-1B-7B-0125-Instruct-4bit. | |
| 8 | +- MacLustr nodes reachable with Python ≥ 3.14: M3U96a (M3 Ultra 96 GB, mlx_lm 0.31.3), M3U96b (M3 Ultra 96 GB, | |
| 9 | + mlx_lm 0.31.3, 110 GB free), M4M64a (M4 Max 64 GB, torch 2.12.1), M4M64b (M4 Max 64 GB, 16 GB free — not | |
| 10 | + usable for checkpoints). Nodes with only system Python 3.9 (M2U64, M4M64c, M5M36, M4BP48, m4mm, m4mn) | |
| 11 | + need `mld prepare`-style setup before use. M4M36 was unreachable. | |
| 12 | +- No paid compute is required for Tiers 0–1. Tier 2 fits M3U96a/b. | |
| 13 | + | |
| 14 | +## Measured costs (Tier 0) | |
| 15 | + | |
| 16 | +| Item | Measurement | | |
| 17 | +|---|---| | |
| 18 | +| Toy model 0.80 M params, 200 optimizer steps, batch 256 | 5.3 s MPS, 10.0 s CPU | | |
| 19 | +| 3 000 steps (one model) | ≈ 44 s MPS | | |
| 20 | +| Quick CPU smoke test (2 seeds × 2 roles, 200 steps, localization) | 22 s | | |
| 21 | +| Full pilot (3 seeds × 2 roles, 3 000 steps ≈ 45 s each, localization 3 families × 4 layers × 7 positions × 2 repeats + heads, bootstrap 2 000) | **276 s** on the laptop (MPS), run `pilot_tier0_opseq_451ef5087182` | | |
| 22 | + | |
| 23 | +## Projected (not measured) — to be replaced by pilot measurements | |
| 24 | + | |
| 25 | +- Tier 1 activation capture on a 3B bf16 model: ≈ 6–7 GB weights + activations; one layer × 1 000 prompts × | |
| 26 | + 32 tokens × 3 072 dims in fp16 ≈ 200 MB; feasible on the laptop. Full-layer capture for 36 layers is to be | |
| 27 | + streamed to disk (do not hold in memory). | |
| 28 | +- Tier 2 (7B–14B bf16): 14–28 GB weights; M3U96a/b only; one node per model. | |
| 29 | + | |
| 30 | +Rule: no parallel heavy runs until the single-node profile is recorded in `EXPERIMENT_LOG.md`. | |
added
docs/DECISION_LOG.md
+23 −0
@@ -0,0 +1,23 @@ | ||
| 1 | +# Decision log — WP-AI-0001 | |
| 2 | + | |
| 3 | +All entries are dated; "before freeze" refers to the confirmatory freeze (PREREGISTRATION v1.0, not yet done). | |
| 4 | + | |
| 5 | +- **D1 (2026-11-09, before freeze).** Project located at `Recherche-UQO/ia/wp-ai-0001` with git remote | |
| 6 | + `gitsrv:srv/git/wpai0001_uqo.git`, following the FIRC-0001 precedent for non-numeric IDs; UQO paper | |
| 7 | + template (`_modele-working-paper`) adopted; English throughout. | |
| 8 | +- **D2 (2026-11-09, before freeze).** OPSEQ output format changed from single final answer to a | |
| 9 | + *scratchpad trace* after the single-token variant failed to generalize (train loss → 0, dev ≈ 0.24–0.34 | |
| 10 | + on length ≤ 3; ≈ 0.13 on length ≤ 5). Consequence: the Tier-0 target capability is "execute Ω in context", | |
| 11 | + a per-step map, and compositional difficulty is controlled by `trace_stride`. Risk R1 recorded. | |
| 12 | +- **D3 (2026-11-09, before freeze).** Micro-world enlarged from 6 operators / length ≤ 4 (≈ 14 k unique | |
| 13 | + items, too small for 40 k training items) to 8 operators / length ≤ 5 (≈ 400 k). | |
| 14 | +- **D4 (2026-11-09, before freeze).** Toy models are PyTorch (hooks trivially exact, CPU-testable); MLX is | |
| 15 | + reserved for Tier ≥ 1 with a layer-wrapping intervention mechanism and an equivalence test. | |
| 16 | +- **D5 (2026-11-09, before freeze).** The pilot is exploratory; localization selection uses the pilot's | |
| 17 | + development localization set; confirmatory evaluation splits will be generated from new seeds after | |
| 18 | + freeze. | |
| 19 | +- **D6 (2026-11-09, before freeze).** Localization sweep families in the pilot were `resid_post`, `attn_out`, | |
| 20 | + `mlp_out` (plus heads). The `embed`/`resid_pre.0` family was not swept, which is why patching at the Ω | |
| 21 | + token restores nothing; it is added to the next sweep. The pilot's localization set (length-3 programs, | |
| 22 | + Ω at index 1, corrupt = `zib`) is a *development* set; confirmatory localization will use new seeds and | |
| 23 | + other corrupt operators. | |
added
docs/ENVIRONMENT_AUDIT.json
+175 −0
@@ -0,0 +1,175 @@ | ||
| 1 | +{ | |
| 2 | + "utc": "2026-11-09T06:50:06+00:00", | |
| 3 | + "hardware": { | |
| 4 | + "platform": "macOS-27.0-arm64-arm-64bit-Mach-O", | |
| 5 | + "machine": "arm64", | |
| 6 | + "hostname_hash": "9ad7358c662e", | |
| 7 | + "cpu_count": 18, | |
| 8 | + "chip": "Apple M5 Max", | |
| 9 | + "memory_gb": 48.0, | |
| 10 | + "torch_mps": true, | |
| 11 | + "torch_cuda": false | |
| 12 | + }, | |
| 13 | + "libraries": { | |
| 14 | + "python": "3.14.4", | |
| 15 | + "numpy": "2.4.4", | |
| 16 | + "torch": "2.12.0", | |
| 17 | + "scipy": "1.17.1", | |
| 18 | + "pydantic": "2.13.4", | |
| 19 | + "mlx": "?", | |
| 20 | + "mlx_lm": "0.31.3", | |
| 21 | + "transformers": "5.8.1", | |
| 22 | + "safetensors": "0.7.0" | |
| 23 | + }, | |
| 24 | + "backends": { | |
| 25 | + "mlx": { | |
| 26 | + "version": "0.32.2", | |
| 27 | + "metal": true | |
| 28 | + }, | |
| 29 | + "torch": { | |
| 30 | + "version": "2.12.0", | |
| 31 | + "mps": true, | |
| 32 | + "cuda": false | |
| 33 | + } | |
| 34 | + }, | |
| 35 | + "hf_cache": [ | |
| 36 | + { | |
| 37 | + "repo": "microsoft/llmlingua-2-xlm-roberta-large-meetingbank", | |
| 38 | + "size_gb": 5.46 | |
| 39 | + }, | |
| 40 | + { | |
| 41 | + "repo": "mlx-community/Llama-3.2-3B-Instruct-bf16", | |
| 42 | + "size_gb": 11.99 | |
| 43 | + }, | |
| 44 | + { | |
| 45 | + "repo": "mlx-community/OLMoE-1B-7B-0125-Instruct-4bit", | |
| 46 | + "size_gb": 7.26 | |
| 47 | + }, | |
| 48 | + { | |
| 49 | + "repo": "mlx-community/Qwen2.5-1.5B-Instruct-bf16", | |
| 50 | + "size_gb": 5.77 | |
| 51 | + }, | |
| 52 | + { | |
| 53 | + "repo": "mlx-community/Qwen2.5-3B-Instruct-bf16", | |
| 54 | + "size_gb": 11.52 | |
| 55 | + }, | |
| 56 | + { | |
| 57 | + "repo": "mlx-community/whisper-large-v3-turbo", | |
| 58 | + "size_gb": 3.01 | |
| 59 | + }, | |
| 60 | + { | |
| 61 | + "repo": "sentence-transformers/all-MiniLM-L6-v2", | |
| 62 | + "size_gb": 0.17 | |
| 63 | + }, | |
| 64 | + { | |
| 65 | + "repo": "sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2", | |
| 66 | + "size_gb": 0.89 | |
| 67 | + } | |
| 68 | + ], | |
| 69 | + "cluster": { | |
| 70 | + "M3U96a": { | |
| 71 | + "reachable": true, | |
| 72 | + "chip": "Apple M3 Ultra", | |
| 73 | + "memory_gb": 96, | |
| 74 | + "free_disk_gb": 231, | |
| 75 | + "python": "3.14.5", | |
| 76 | + "mlx_lm": "0.31.3", | |
| 77 | + "torch": "none", | |
| 78 | + "hf_models_cached": 9 | |
| 79 | + }, | |
| 80 | + "M3U96b": { | |
| 81 | + "reachable": true, | |
| 82 | + "chip": "Apple M3 Ultra", | |
| 83 | + "memory_gb": 96, | |
| 84 | + "free_disk_gb": 109, | |
| 85 | + "python": "3.14.4", | |
| 86 | + "mlx_lm": "0.31.3", | |
| 87 | + "torch": "none", | |
| 88 | + "hf_models_cached": 11 | |
| 89 | + }, | |
| 90 | + "M2U64": { | |
| 91 | + "reachable": true, | |
| 92 | + "chip": "Apple M2 Ultra", | |
| 93 | + "memory_gb": 64, | |
| 94 | + "free_disk_gb": 244, | |
| 95 | + "python": "3.9.6", | |
| 96 | + "mlx_lm": "none", | |
| 97 | + "torch": "none", | |
| 98 | + "hf_models_cached": 2 | |
| 99 | + }, | |
| 100 | + "M4M64a": { | |
| 101 | + "reachable": true, | |
| 102 | + "chip": "Apple M4 Max", | |
| 103 | + "memory_gb": 64, | |
| 104 | + "free_disk_gb": 285, | |
| 105 | + "python": "3.14.4", | |
| 106 | + "mlx_lm": "none", | |
| 107 | + "torch": "2.12.1", | |
| 108 | + "hf_models_cached": 9 | |
| 109 | + }, | |
| 110 | + "M4M64b": { | |
| 111 | + "reachable": true, | |
| 112 | + "chip": "Apple M4 Max", | |
| 113 | + "memory_gb": 64, | |
| 114 | + "free_disk_gb": 16, | |
| 115 | + "python": "3.14.4", | |
| 116 | + "mlx_lm": "none", | |
| 117 | + "torch": "none", | |
| 118 | + "hf_models_cached": 2 | |
| 119 | + }, | |
| 120 | + "M4M64c": { | |
| 121 | + "reachable": true, | |
| 122 | + "chip": "Apple M4 Max", | |
| 123 | + "memory_gb": 64, | |
| 124 | + "free_disk_gb": 277, | |
| 125 | + "python": "3.9.6", | |
| 126 | + "mlx_lm": "none", | |
| 127 | + "torch": "none", | |
| 128 | + "hf_models_cached": 2 | |
| 129 | + }, | |
| 130 | + "M5M36": { | |
| 131 | + "reachable": true, | |
| 132 | + "chip": "Apple M5 Max", | |
| 133 | + "memory_gb": 36, | |
| 134 | + "free_disk_gb": 302, | |
| 135 | + "python": "3.9.6", | |
| 136 | + "mlx_lm": "none", | |
| 137 | + "torch": "none", | |
| 138 | + "hf_models_cached": 5 | |
| 139 | + }, | |
| 140 | + "M4M36": { | |
| 141 | + "reachable": false, | |
| 142 | + "error": "ssh: connect to host m4m36.maclustr.io port 22: Operation timed out" | |
| 143 | + }, | |
| 144 | + "M4BP48": { | |
| 145 | + "reachable": true, | |
| 146 | + "chip": "Apple M4 Max", | |
| 147 | + "memory_gb": 48, | |
| 148 | + "free_disk_gb": 806, | |
| 149 | + "python": "3.9.6", | |
| 150 | + "mlx_lm": "none", | |
| 151 | + "torch": "none", | |
| 152 | + "hf_models_cached": 5 | |
| 153 | + }, | |
| 154 | + "m4mm": { | |
| 155 | + "reachable": true, | |
| 156 | + "chip": "Apple M4 Pro", | |
| 157 | + "memory_gb": 48, | |
| 158 | + "free_disk_gb": 346, | |
| 159 | + "python": "3.9.6", | |
| 160 | + "mlx_lm": "none", | |
| 161 | + "torch": "none", | |
| 162 | + "hf_models_cached": 1 | |
| 163 | + }, | |
| 164 | + "m4mn": { | |
| 165 | + "reachable": true, | |
| 166 | + "chip": "Apple M4 Pro", | |
| 167 | + "memory_gb": 48, | |
| 168 | + "free_disk_gb": 338, | |
| 169 | + "python": "3.9.6", | |
| 170 | + "mlx_lm": "none", | |
| 171 | + "torch": "none", | |
| 172 | + "hf_models_cached": 1 | |
| 173 | + } | |
| 174 | + } | |
| 175 | +} | |
| \ No newline at end of file | ||
added
docs/EXPERIMENT_LOG.md
+43 −0
@@ -0,0 +1,43 @@ | ||
| 1 | +# Experiment log — WP-AI-0001 | |
| 2 | + | |
| 3 | +| Date (UTC) | Run / action | Status | Evidence | Notes | | |
| 4 | +|---|---|---|---|---| | |
| 5 | +| 2026-11-09 | Environment audit (laptop + 11 cluster nodes) | completed | `docs/ENVIRONMENT_AUDIT.json` | M4M36 unreachable; mlx_lm only on M3U96a/b + laptop | | |
| 6 | +| 2026-11-09 | Literature verification (40 arXiv records) | completed | `literature/arxiv_verified_2026-11-09.txt`, `literature/references_verified.bib` | abstracts read for 9 closest works | | |
| 7 | +| 2026-11-09 | Single-token OPSEQ learnability probe (4 layers, d=128, 4 000 steps) | failed (dev ≈ 0.13; length ≤ 3 subset: train loss → 0, dev 0.24) | console only, not archived | led to D2 (scratchpad) | | |
| 8 | +| 2026-11-09 | Scratchpad OPSEQ learnability probe (3 000 steps) | completed | console only | dev 1.0 by step 500; held-out compositions 1.0; length OOD 0.086 | | |
| 9 | +| 2026-11-09 | `pilot_tier0_opseq_quick_d5339bcad6b3` (CPU smoke, 2 seeds, 200 steps) | completed | `experiments/summaries/pilot_tier0_opseq_quick_d5339bcad6b3/` | pipeline end-to-end; models untrained by design | | |
| 10 | +| 2026-11-09 | `pilot_tier0_opseq_451ef5087182` (MPS, 3 seeds × 2 roles, 3 000 steps, 0.80 M params) | **completed** (276 s) | `experiments/summaries/pilot_tier0_opseq_451ef5087182/{results.json,SUMMARY.md}`, manifest, 4 figures | see §Pilot results below | | |
| 11 | + | |
| 12 | +## Pilot results — `pilot_tier0_opseq_451ef5087182` (exploratory; 2026-11-09) | |
| 13 | + | |
| 14 | +**Gate B (gap).** Final-answer exact match, mean over 3 seeds (sd): donor 1.000 (0.000) vs recipient | |
| 15 | +0.092 (0.053) on `target_iid` (majority-class chance 0.105); both 1.000 on `control_iid`; `comp_heldout` | |
| 16 | +1.000 vs 0.450 (held-out pairs often contain Ω); `len_ood` 0.086 vs 0.091 (both fail: absolute positions | |
| 17 | +beyond training length). Ω-step accuracy on `target_iid`: donor 1.000, recipient 0.062. Paired gap on | |
| 18 | +identical items, seed 0: +0.847 [+0.825, +0.870] (cluster bootstrap over programs, 2 000 draws). | |
| 19 | +Recipient trace accuracy on `target_iid`: 0.110 / 0.024 / 0.013 (seeds 0/1/2). | |
| 20 | + | |
| 21 | +**Gate C (hooks).** For all 6 trained models: repeat-run bitwise equality, capture-all bitwise identity, | |
| 22 | +disabled-modifying-hook bitwise identity = True; enabled zero hook changes output = True (256 items). | |
| 23 | + | |
| 24 | +**RQ1 (localization, within donor, n = 490 clean/corrupt pairs, read position r1 → predicts r2).** | |
| 25 | +Clean 1.000, sham (corrupted run scored on clean answer) 0.000 in all seeds. Restored-answer rate when | |
| 26 | +patching clean into corrupt (mean of 3 seeds): `resid_post` = 1.00 at the read position r1 at every layer | |
| 27 | +L0–L3 and 0.00 at every other position (including the Ω token position); `attn_out` = 1.00 at (L0, r1) only; | |
| 28 | +`mlp_out` at r1: L0 1.00, L1 0.90, L2 0.83, L3 0.17. Zero-ablation accuracy at r1: `resid_post` 0.04–0.09, | |
| 29 | +`attn_out` L0 0.13 (L1–L3 1.00), `mlp_out` L0 0.21, L1 0.97. Head patching at r1: L0 h0 0.62, h1 0.16, | |
| 30 | +h2 0.04, others 0.00; head patching at the Ω token: 0.00 everywhere. Repeat max |Δ| = 0.0000 for all | |
| 31 | +sweeps; across-seed Pearson of flip heatmaps: resid_post 1.000, attn_out 1.000, mlp_out 0.964 (min pair). | |
| 32 | + | |
| 33 | +**Reading (observed → interpretation).** Observed: the Ω computation is executed entirely at the read | |
| 34 | +position: layer-0 attention (mostly head 0) moves the operator identity from the Ω token to r1, and | |
| 35 | +layer-0–2 MLPs at r1 compute the value map. Patching the Ω token position itself restores nothing because | |
| 36 | +layer-0 attention reads the *embedding* (hook `resid_pre.0`/`embed`, not swept) and no later attention | |
| 37 | +re-reads it. Interpretation (not yet tested): the candidate organ for an activation graft is the | |
| 38 | +residual stream at r1 after L0 (or the L0 attention output at r1); its *content* is the (operator, value) | |
| 39 | +pair, so a transplant must convey the Ω-specific part of that content. Go/no-go for Sprint 3: all three | |
| 40 | +criteria of EXPERIMENT_PLAN §4 are met. | |
| 41 | + | |
| 42 | +**Pilot variability for power (PREREGISTRATION §5).** Seed sd of recipient target accuracy 0.053; cluster | |
| 43 | +bootstrap half-width of the paired gap ≈ 0.022 with 1 000 items / ≈ 900 programs. | |
added
docs/EXPERIMENT_PLAN.md
+56 −0
@@ -0,0 +1,56 @@ | ||
| 1 | +# Experiment plan — WP-AI-0001 | |
| 2 | + | |
| 3 | +## 1. Tiers and model matrix | |
| 4 | + | |
| 5 | +| Tier | Models | Purpose | Backend | Status | | |
| 6 | +|---|---|---|---|---| | |
| 7 | +| 0 | toy decoder transformers trained from scratch (0.8 M params default; 4 layers, d = 128) | full visibility, controlled gap, exhaustive interventions | PyTorch (CPU/MPS) | **pilot running** | | |
| 8 | +| 1 | Qwen2.5-1.5B-Instruct, Qwen2.5-3B-Instruct, Llama-3.2-3B-Instruct (bf16, cached locally) | external validity, same-family different-size, cross-family, cross-tokenizer | MLX (layer-wrapping interventions) with a PyTorch/Transformers equivalence check | planned (after Gate D on Tier 0) | | |
| 9 | +| 2 | 7B–14B open weights (e.g. Qwen2.5-7B/14B, Llama-3.1-8B) | scale | MLX on M3U96a/b (96 GB) | conditional | | |
| 10 | +| 3 | larger | only with explicit approval | — | not planned | | |
| 11 | + | |
| 12 | +Pairs (Tier 1): Qwen2.5-1.5B→3B (same family, same tokenizer, 28→36 layers); Llama-3.2-3B↔Qwen2.5-3B | |
| 13 | +(different family, different tokenizer, 28 vs 36 layers); Tier 0: same architecture / different seeds, | |
| 14 | +same architecture / different widths, different depths. | |
| 15 | + | |
| 16 | +## 2. Task families | |
| 17 | + | |
| 18 | +- **A — OPSEQ** (implemented): invented operators on Z_11, scratchpad trace; strata `target_iid`, | |
| 19 | + `control_iid`, `comp_heldout`, `len_ood`; difficulty knob `trace_stride`. | |
| 20 | +- **B — FSA** (generator implemented): random DFA execution over an invented alphabet. | |
| 21 | +- **C — MORPH** (generator implemented): context-dependent suffix rule on pseudo-words; Tier 1 variant | |
| 22 | + with natural-language pseudo-morphology to be specified at Sprint 4. | |
| 23 | +- Negative-control battery (Tier 1): unrelated arithmetic, factual recall, instruction following, | |
| 24 | + held-out text perplexity, calibration, refusal behaviour. | |
| 25 | + | |
| 26 | +## 3. Phases (per CLAUDE.md §6) and their scripts | |
| 27 | + | |
| 28 | +| Phase | Script | Output | | |
| 29 | +|---|---|---| | |
| 30 | +| 1 Baseline & gap | `scripts/run_pilot.py` | gap table, Ω-step accuracies, no-op checks | | |
| 31 | +| 2 Localization | `scripts/run_pilot.py` (within-donor patching, ablation, heads) | heatmaps, reproducibility | | |
| 32 | +| 3 Alignment | `scripts/run_alignment.py` (to write) | Procrustes / ridge / CCA / random / unrelated-data maps with leakage audit | | |
| 33 | +| 4 Transplant | `scripts/run_transplant.py` (to write) | activation graft, subspace graft, weight graft (same-arch), adapter graft | | |
| 34 | +| 5 Controls | same | sham, norm-matched random, unrelated-skill donor, shuffled token/layer, few-shot, steering, matched adapter FT, distillation | | |
| 35 | +| 6 Robustness | `scripts/run_sweeps.py` (to write) | strength × layer × position × dimension × pair | | |
| 36 | +| 7 Mechanism | `scripts/run_mechanism.py` (to write) | ablation→loss→rescue, bidirectional, dose-response | | |
| 37 | +| 8 Confirmatory | `scripts/run_confirmatory.py` (to write) | frozen protocol on untouched splits | | |
| 38 | + | |
| 39 | +## 4. Minimal viable experiment (MVE) and go/no-go | |
| 40 | + | |
| 41 | +MVE = Tier 0, OPSEQ, Ω = `qua`, donor (all operators) vs recipient (Ω excluded), 3 seeds each. | |
| 42 | +Go to Sprint 3 (first graft) iff: (a) donor Ω-step accuracy ≥ 0.95 and recipient ≤ chance + 0.1 on | |
| 43 | +`target_iid`; (b) all no-op checks true; (c) at least one localization cell with restored-answer rate | |
| 44 | +≥ 0.8 and across-seed heatmap correlation ≥ 0.8. Otherwise diagnose (see RISK_REGISTER R1–R3). | |
| 45 | + | |
| 46 | +## 5. Pre-declared confirmatory contrasts (Tier 0) | |
| 47 | + | |
| 48 | +1. activation graft vs matched sham (primary); 2. subspace graft vs norm-matched random subspace; | |
| 49 | +3. weight graft (same architecture) vs shuffled-layer weight graft; 4. adapter graft vs matched-size | |
| 50 | +adapter trained on the same alignment data without donor signal. Each: Δ_T^adj with cluster-bootstrap CI, | |
| 51 | +Holm-corrected across the four families; retention on `control_iid`. | |
| 52 | + | |
| 53 | +## 6. Figures that the plan can support (data-dependent) | |
| 54 | + | |
| 55 | +Gap distributions (F2), localization heatmap (F3), Pareto target-vs-retention (F5), portability matrix | |
| 56 | +(F6), graft size vs effect (F7), ablation→rescue chain (F8), robustness (F9), failure taxonomy (F10). | |
added
docs/MANDATE.md
+367 −0
@@ -0,0 +1,367 @@ | ||
| 1 | +# Research mandate — WP-AI-0001 (supplied by the author on 2026-11-09, reproduced verbatim) | |
| 2 | + | |
| 3 | +CLAUDE.md — WP-AI-0001 | |
| 4 | + | |
| 5 | +The Neural Organ Transplant Experiment | |
| 6 | + | |
| 7 | +Causal Transfer of Cognitive Capabilities Across Local Large Language Models | |
| 8 | + | |
| 9 | +Project ID: wp-ai-0001 | |
| 10 | +Research home: UQO Research | |
| 11 | +Document language: English (all code documentation, figures, paper, logs, and reports) | |
| 12 | +Status: Research protocol and implementation mandate; no results may be claimed before execution. | |
| 13 | + | |
| 14 | +──────── | |
| 15 | + | |
| 16 | +0. MISSION AND NON-NEGOTIABLE STANDARD | |
| 17 | + | |
| 18 | +You are Claude Code acting as a principal research engineer, computational scientist, and rigorous coauthor. Build a complete, reproducible research program within the existing UQO Research environment under a new project named wp-ai-0001. | |
| 19 | + | |
| 20 | +Central question: Can a bounded, causally identified computational subsystem responsible for a measurable cognitive capability be transplanted from one open-weight language model (the donor) into another (the recipient), such that the recipient acquires or materially improves that capability without conventional full-model training? | |
| 21 | + | |
| 22 | +The word organ is a metaphor. Do not imply that LLMs have biological organs, consciousness, or localized faculties by default. The paper must operationalize a candidate functional subsystem and test whether it is transferable. | |
| 23 | + | |
| 24 | +A publication-quality result may be positive, negative, or conditional. Never fabricate empirical outcomes, references, citations, benchmarks, or performance numbers. Do not confuse a change in output distribution with genuine skill acquisition. Explicitly distinguish causal interventions, associations, and mechanistic interpretation. | |
| 25 | + | |
| 26 | +Primary deliverables: (1) executable open-weight experimentation framework, (2) documented experiment registry and artifacts, (3) validated empirical analysis, (4) rigorous English LaTeX paper, (5) publication-grade figures, (6) independent replication guide, and (7) honest limitations and failure analyses. | |
| 27 | + | |
| 28 | +1. FIRST ACTIONS: DISCOVER, AUDIT, PLAN | |
| 29 | + | |
| 30 | +Before writing implementation code: | |
| 31 | + | |
| 32 | +1. Locate the existing UQO Research repository/workspace. Inspect its README, project naming conventions, build systems, paper directories, data policies, Git remotes, and existing experimental frameworks. Never assume a path or remote URL. | |
| 33 | +2. Inspect the current machine and accessible MacLustr compute nodes, CPU/GPU/Metal support, RAM, storage, installed Python environments, MLX/PyTorch/Transformers versions, network accessibility, and permission boundaries. Never assume a cluster node is online. | |
| 34 | +3. Check whether wp-ai-0001 already exists. If so, preserve work and reconcile rather than overwrite. | |
| 35 | +4. Search current peer-reviewed and preprint literature with primary-source verification. At minimum investigate causal tracing, activation patching, interchange interventions, causal abstraction, sparse autoencoders, circuit discovery, model editing, task vectors, model merging, cross-model representation alignment, cross-architecture transfer, model stitching, knowledge transplantation, and inference-time activation steering. Record URLs, identifiers, publication dates, precise contributions, and how our approach differs. If web access is unavailable, mark literature review unverified and do not invent citations. | |
| 36 | +5. Write docs/RESEARCH_GAP.md, docs/PREREGISTRATION.md, docs/EXPERIMENT_PLAN.md, docs/COMPUTE_BUDGET.md, docs/RISK_REGISTER.md, and an implementation task tracker before major experiments. | |
| 37 | +6. Identify the minimal viable experiment and its go/no-go criteria. Begin with a small, affordable pilot before scaling. | |
| 38 | + | |
| 39 | +Do not claim novelty merely because the term "neural organ transplant" sounds new. The scientific novelty must survive comparison with prior model stitching, representation transfer, circuit transplantation, and activation interventions. | |
| 40 | + | |
| 41 | +2. CORE DEFINITIONS AND ESTIMANDS | |
| 42 | + | |
| 43 | +Let donor model be D, recipient model be R, task distribution T, candidate subsystem S_D, alignment/transplant operator A, and intervention operator I. Define a transplanted recipient R' = I(R, A(S_D)). | |
| 44 | + | |
| 45 | +Predefine a primary capability score Q_T(M) and control-task score Q_C(M), with uncertainty intervals. Let recipient baseline improvement be Δ_T = Q_T(R') - Q_T(R), and control retention Δ_C = Q_C(R') - Q_C(R). | |
| 46 | + | |
| 47 | +The primary causal estimand is the excess effect of a donor-specific intervention over matched sham, random, and nonfunctional donor interventions, estimated on held-out, leakage-controlled tasks. Report the difference in differences against a matched intervention control where appropriate, not only raw Δ_T. | |
| 48 | + | |
| 49 | +Operational definitions: | |
| 50 | + | |
| 51 | +• Candidate organ: a specified set of layers, heads, MLP units, activation subspaces, sparse features, or pathways whose perturbation produces repeatable, task-selective causal effects. | |
| 52 | +• Transplant: a predeclared intervention that injects, replaces, composes, or maps a donor-derived functional component into the recipient. | |
| 53 | +• Acquisition: held-out improvement on the target capability, beyond controls and chance, with retention of general capabilities and evidence against answer leakage. | |
| 54 | +• Selectivity: target-task improvement relative to prespecified negative-control tasks and matched compute/parameter interventions. | |
| 55 | +• Persistence: distinguish single-token intervention, within-sequence effect, across-prompts reuse, and saved model modification. Never call transient activation steering permanent learning. | |
| 56 | +• Portability: transfer across seeds, prompts, domains, model pairs, and architectures. | |
| 57 | + | |
| 58 | +A successful transplant does not require a literal physical copy of identical neurons. Separately evaluate exact-weight copying, mapped activation transfer, and learned adapter-based transplantation; label them precisely. | |
| 59 | + | |
| 60 | +3. RESEARCH QUESTIONS AND FALSIFIABLE HYPOTHESES | |
| 61 | + | |
| 62 | +RQ1 — Localization: Can a candidate capability-relevant subsystem be identified reproducibly through causal intervention rather than correlation alone? | |
| 63 | + | |
| 64 | +RQ2 — Sufficiency: Does transferring the subsystem increase recipient target-task performance relative to matched controls? | |
| 65 | + | |
| 66 | +RQ3 — Necessity: Does removing or perturbing the corresponding donor subsystem reduce donor performance selectively? | |
| 67 | + | |
| 68 | +RQ4 — Portability: How does transplant effectiveness vary with model family, architecture, size, layer depth, representation similarity, and tokenizer differences? | |
| 69 | + | |
| 70 | +RQ5 — Collateral damage: Which recipient capabilities degrade after transplantation, and how does damage scale with intervention strength and size? | |
| 71 | + | |
| 72 | +RQ6 — Persistence and mechanism: Are improvements sustained on unseen prompts, multi-step reasoning, compositional generalization, and adversarial paraphrases? Is the effect explained by reusable representations rather than answer copying? | |
| 73 | + | |
| 74 | +RQ7 — Transfer frontier: What is the minimum transplanted dimensionality/parameter budget needed for a specified improvement? | |
| 75 | + | |
| 76 | +RQ8 — Failure regimes: Under what conditions is transplantation impossible, unstable, or indistinguishable from simpler baselines? | |
| 77 | + | |
| 78 | +Preregister directional hypotheses, null hypotheses, primary outcomes, familywise comparisons, smallest effect size of interest, and failure thresholds. Do not retroactively relabel exploratory findings as confirmatory. | |
| 79 | + | |
| 80 | +4. TASK DESIGN: DEMONSTRATE A REAL CAPABILITY | |
| 81 | + | |
| 82 | +Use at least three distinct task families and separate development from confirmatory evaluation. | |
| 83 | + | |
| 84 | +A. Synthetic compositional reasoning (primary identification environment) | |
| 85 | + | |
| 86 | +Create a controlled, procedurally generated micro-world with invented operators, typed rules, multi-step transformations, and held-out compositions. Control training exposure, difficulty, and ground-truth answers. Build donor competence and recipient weakness through explicitly documented small-scale training or selection; do not assume an arbitrary donor has a capability the recipient lacks. | |
| 87 | + | |
| 88 | +Separate: memorization, operator recognition, length generalization, novel symbol substitutions, unseen compositions, distractors, and out-of-distribution combinations. Ensure disjoint generation seeds and avoid shared templates across splits. Test whether transplant conveys a rule rather than cached answers. | |
| 89 | + | |
| 90 | +B. Formal algorithmic reasoning | |
| 91 | + | |
| 92 | +Use verifiable tasks such as modular arithmetic, finite-state transformations, structured symbolic execution, constrained graph problems, and small proof checking. Prefer exact-match validators and independently generated solutions. Avoid evaluating solely with a judge LLM. | |
| 93 | + | |
| 94 | +C. Language/semantic capability | |
| 95 | + | |
| 96 | +Use narrowly defined multilingual morphological transformations, compositional syntax, or domain-specific semantic distinctions. Control lexical overlap and translation artifacts. Evaluate semantic transfer separately from superficial token copying. | |
| 97 | + | |
| 98 | +Negative-control battery | |
| 99 | + | |
| 100 | +Include unrelated arithmetic, general language modeling, factual recall, instruction following, calibration, refusal/safety behavior, and perplexity on clean held-out text where legally and technically appropriate. The battery must detect broad degradation, not just target improvements. | |
| 101 | + | |
| 102 | +Contamination safeguards | |
| 103 | + | |
| 104 | +Generate held-out samples after intervention design freeze where possible. Hash datasets, version generators, preserve seeds, record overlap tests, and audit leakage through adapters, mapping datasets, prompt exemplars, and evaluation harnesses. | |
| 105 | + | |
| 106 | +5. MODEL MATRIX AND HARDWARE STRATEGY | |
| 107 | + | |
| 108 | +Use openly licensed/open-weight models compatible with local inspection, selecting exact checkpoints only after license, architecture, and compute audits. | |
| 109 | + | |
| 110 | +Tier 0: tiny synthetic transformers trained from scratch (approximately 10M–100M parameters if practical). Full visibility, controlled training data, repeated seeds, and inexpensive exhaustive interventions. | |
| 111 | + | |
| 112 | +Tier 1: small open-weight instruction/base models (roughly 0.5B–3B) from at least two families where available. Prioritize reproducibility and manageable activations. | |
| 113 | + | |
| 114 | +Tier 2: medium open-weight models (roughly 7B–14B) for external validity, only after the Tier 0/1 methods work. | |
| 115 | + | |
| 116 | +Tier 3: larger models only if their scientific marginal value justifies measured time and memory costs. | |
| 117 | + | |
| 118 | +Construct donor/recipient pairs covering: same architecture/different seeds; same family/different sizes; different families/similar sizes; different tokenizers; matched and mismatched layer counts. Distinguish base from instruction-tuned checkpoints. | |
| 119 | + | |
| 120 | +On Apple Silicon, prefer MLX/MLX-LM where hooks and interventions are demonstrably supported. Use PyTorch/Transformers or an isolated reference implementation where MLX does not expose necessary internals. Never pretend a framework supports a hook that it does not. Maintain equivalence tests across backends. Account for unified memory, KV-cache footprint, activation capture, quantization, and memory pressure. Do not launch heavy parallel runs until resource profiling is complete. | |
| 121 | + | |
| 122 | +Record for every run: exact model ID and revision, architecture, license, tokenizer, precision, quantization, library versions, host hardware, memory, seed, generation settings, runtime, energy estimate if measured, and intervention provenance. | |
| 123 | + | |
| 124 | +6. EXPERIMENTAL PIPELINE | |
| 125 | + | |
| 126 | +Phase 1 — Baseline and gap qualification | |
| 127 | + | |
| 128 | +Measure donor and recipient capability across task strata. Require a meaningful, reproducible donor-recipient gap before attempting transplant. Run multiple seeds and report variance. Document any donor training separately from transplantation. | |
| 129 | + | |
| 130 | +Phase 2 — Localization and causal validation | |
| 131 | + | |
| 132 | +Collect activations with strict memory limits. Screen candidate layers, attention heads, MLP outputs, residual-stream subspaces, and sparse features. Use activation patching, ablation, causal tracing, path patching where valid, and independent validation. Compare against activation-norm-matched random subspaces and arbitrary heads/layers. Check whether localization findings persist under paraphrase and held-out data. Do not equate attention weights with causal explanations. | |
| 133 | + | |
| 134 | +Phase 3 — Representation alignment | |
| 135 | + | |
| 136 | +Test orthogonal Procrustes, linear mappings, canonical correlation or related similarity methods, low-rank adapters, and architecture-aware projection. Train mappings only on disjoint alignment data. Quantify alignment data size, parameter count, fitting compute, and information leaked through alignment. Include a random mapping and a mapping trained on unrelated data. | |
| 137 | + | |
| 138 | +Phase 4 — Transplant families | |
| 139 | + | |
| 140 | +Implement each as a separately named, auditable method: | |
| 141 | + | |
| 142 | +1. Activation graft: inject mapped donor activation at a specified recipient layer/token position. | |
| 143 | +2. Subspace graft: replace or add a selected capability-associated low-dimensional representation. | |
| 144 | +3. Circuit/path graft: replace or couple a bounded pathway where architectures and interfaces allow it. | |
| 145 | +4. Weight graft: transfer structurally compatible parameter subsets only with shape, scaling, and functional checks. | |
| 146 | +5. Adapter graft: install a small learned interface; account explicitly for any supervised learning in the adapter. | |
| 147 | +6. Persistent graft: optionally save a modified checkpoint or adapter and evaluate it across independent sessions. | |
| 148 | + | |
| 149 | +Not every transplant type will be feasible for every pair. Mark unsupported configurations explicitly rather than silently substituting methods. | |
| 150 | + | |
| 151 | +Phase 5 — Controls and alternatives | |
| 152 | + | |
| 153 | +At minimum compare with: unmodified recipient, unmodified donor, random graft, norm-matched random graft, unrelated-skill donor graft, shuffled-token graft, shuffled-layer graft, sham mapping, direct prompting/few-shot, retrieval of equivalent information, simple activation steering, matched-size adapter fine-tuning, and a conventional distillation baseline where budget permits. | |
| 154 | + | |
| 155 | +Match parameter counts, inference-time overhead, training examples, and compute where possible. If comparisons cannot be matched, state why and interpret narrowly. | |
| 156 | + | |
| 157 | +Phase 6 — Robustness and stress tests | |
| 158 | + | |
| 159 | +Sweep intervention strength, layer, token position, dimensionality, donor/recipient pair, prompt format, context length, temperature, task difficulty, and quantization. Evaluate repeated independent seeds and withheld families. Measure harmful interference and stability, including catastrophic failures and invalid outputs. | |
| 160 | + | |
| 161 | +Phase 7 — Causal mechanism tests | |
| 162 | + | |
| 163 | +Use bidirectional and reciprocal transfers when meaningful; donor ablation followed by rescue; transplant into incompatible recipients; dose-response; mediation-style analyses with assumptions stated; and specificity tests. Establish whether the transplanted component carries task-relevant information or merely biases answer tokens. | |
| 164 | + | |
| 165 | +Phase 8 — Final confirmatory evaluation | |
| 166 | + | |
| 167 | +Freeze primary methods, hyperparameters, model pairs, and evaluation scripts. Run on untouched confirmatory datasets. Publish both successes and failures, with all preregistered metrics and comparisons. | |
| 168 | + | |
| 169 | +7. QUANTITATIVE METRICS | |
| 170 | + | |
| 171 | +Primary: held-out exact accuracy or task-specific objectively validated score; treatment effect versus matched sham; target-control selectivity; retention of general capability. | |
| 172 | + | |
| 173 | +Secondary: donor ablation effect, rescue effect, transplant dimensionality, number of modified parameters, alignment data requirements, inference latency, peak memory, energy if measured, success across task strata, and stability across seeds. | |
| 174 | + | |
| 175 | +Useful derived quantities (define precisely before use): | |
| 176 | + | |
| 177 | +• Transfer gain: Q_target(R_graft) - Q_target(R_base). | |
| 178 | +• Control-adjusted transfer: [Q_target(R_graft)-Q_target(R_base)] - [Q_target(R_sham)-Q_target(R_base)]. | |
| 179 | +• Retention ratio for each control task, with careful treatment of near-zero baselines. | |
| 180 | +• Transfer efficiency: gain per graft dimension, parameter, training example, or compute unit (report units and avoid misleading cross-metric comparisons). | |
| 181 | +• Donor-necessity score: donor target performance before minus after selective ablation. | |
| 182 | +• Portability matrix: donor-by-recipient effect with uncertainty. | |
| 183 | + | |
| 184 | +Do not compress all outcomes into one opaque "intelligence transfer score" unless weights and sensitivity analyses are fully justified. | |
| 185 | + | |
| 186 | +8. STATISTICAL DESIGN | |
| 187 | + | |
| 188 | +Predefine the unit of inference and avoid pseudoreplication: questions nested within task templates, random seeds, model pairs, and intervention conditions are not independent. Use hierarchical or mixed-effects models where appropriate; cluster bootstrap or robust uncertainty estimates at the correct generation/template/model level; paired comparisons on identical questions; and multiple-comparison corrections for large intervention searches. | |
| 189 | + | |
| 190 | +Report confidence intervals, effect sizes, p-values where relevant, exact sample sizes, random seeds, and full null results. Separate exploratory localization selection from confirmatory testing. Perform prospective power/simulation analyses using pilot variability, not invented effect sizes. Test equivalence/non-inferiority for collateral damage only with justified margins. Include sensitivity to evaluation metric, task composition, and model pair. | |
| 191 | + | |
| 192 | +Avoid strong causal claims when intervention assignment, alignment training, or sample selection creates confounding. State precisely what is randomized and what is not. | |
| 193 | + | |
| 194 | +9. ENGINEERING ARCHITECTURE | |
| 195 | + | |
| 196 | +Create or adapt a maintainable project structure consistent with UQO Research: | |
| 197 | + | |
| 198 | +wp-ai-0001/ | |
| 199 | + CLAUDE.md | |
| 200 | + README.md | |
| 201 | + pyproject.toml | |
| 202 | + configs/ | |
| 203 | + models/ tasks/ experiments/ interventions/ | |
| 204 | + src/wp_ai_0001/ | |
| 205 | + models/ # model adapters, tokenizer compatibility, hooks | |
| 206 | + datasets/ # synthetic generators, validators, splits | |
| 207 | + baselines/ # model/task baselines and alternative methods | |
| 208 | + localization/ # ablation, patching, circuit discovery | |
| 209 | + alignment/ # donor-recipient representation mapping | |
| 210 | + transplantation/ # explicit intervention implementations | |
| 211 | + evaluation/ # blinded metrics and controls | |
| 212 | + statistics/ # estimation, uncertainty, multiplicity | |
| 213 | + instrumentation/ # memory, runtime, provenance, logs | |
| 214 | + visualization/ # publication figures | |
| 215 | + orchestration/ # local/cluster jobs, resumability | |
| 216 | + tests/ | |
| 217 | + unit/ integration/ causal_sanity/ regression/ | |
| 218 | + experiments/ | |
| 219 | + registry/ manifests/ summaries/ | |
| 220 | + data/ | |
| 221 | + README.md # data policy; do not commit restricted data | |
| 222 | + artifacts/ # generated artifacts, Git-ignored as appropriate | |
| 223 | + docs/ | |
| 224 | + RESEARCH_GAP.md | |
| 225 | + PREREGISTRATION.md | |
| 226 | + EXPERIMENT_PLAN.md | |
| 227 | + COMPUTE_BUDGET.md | |
| 228 | + RISK_REGISTER.md | |
| 229 | + REPRODUCIBILITY.md | |
| 230 | + EXPERIMENT_LOG.md | |
| 231 | + DECISION_LOG.md | |
| 232 | + paper/ | |
| 233 | + main.tex | |
| 234 | + references.bib | |
| 235 | + sections/ | |
| 236 | + figures/ | |
| 237 | + tables/ | |
| 238 | + appendix/ | |
| 239 | + submission/ | |
| 240 | + scripts/ | |
| 241 | + audit_environment.py | |
| 242 | + run_pilot.py | |
| 243 | + run_confirmatory.py | |
| 244 | + build_figures.py | |
| 245 | + build_paper.sh | |
| 246 | + | |
| 247 | +Use typed configuration and deterministic run IDs. Each experiment must have a manifest containing git commit, config hash, checkpoint revisions, data hashes, seeds, backend, hardware, timestamps, and outcome files. Support checkpoint/resume, interrupted jobs, structured logging, and a dry-run mode. Provide CPU-compatible smoke tests on toy models. Make paths configurable; never hardcode private tokens, endpoints, or personal file paths. Keep secrets in environment variables and redact them from logs. | |
| 248 | + | |
| 249 | +Do not create unnecessary distributed infrastructure before proving the scientific experiment works on one machine. | |
| 250 | + | |
| 251 | +10. VALIDATION AND QUALITY GATES | |
| 252 | + | |
| 253 | +Gate A — Repository readiness: existing workspace understood, new project isolated, environment audit passed, literature gap documented. | |
| 254 | + | |
| 255 | +Gate B — Baseline integrity: data validators correct, donor/recipient skill gap verified, contamination tests passed, repeated baseline runs consistent. | |
| 256 | + | |
| 257 | +Gate C — Mechanistic sanity: positive controls work on toy models; negative controls behave plausibly; hooks do not change outputs when disabled; activation shapes and token alignments are verified. | |
| 258 | + | |
| 259 | +Gate D — Transplant validity: graft is reproducible; sham and random controls implemented; information leakage audit passed; overhead and training cost disclosed. | |
| 260 | + | |
| 261 | +Gate E — Confirmatory evidence: untouched data, locked analysis, uncertainty estimates, and negative results all reported. | |
| 262 | + | |
| 263 | +Gate F — Paper integrity: every numeric claim traces to an artifact; every figure regenerates; citations verified; LaTeX compiles cleanly; independent reproduction instructions tested. | |
| 264 | + | |
| 265 | +A failed gate requires diagnosis, not rhetorical reinterpretation of failure as success. | |
| 266 | + | |
| 267 | +11. FIGURES AND TABLES — PUBLICATION STANDARD | |
| 268 | + | |
| 269 | +Produce vector PDF/SVG wherever feasible, legible at journal column widths, with accessible palettes, labeled units, uncertainty intervals, and no decorative pseudo-scientific graphics. | |
| 270 | + | |
| 271 | +Target figures (only when data support them): | |
| 272 | + | |
| 273 | +1. Conceptual donor → causal localization → alignment → recipient graft → evaluation diagram, clearly distinguishing hypotheses from observations. | |
| 274 | +2. Donor/recipient capability gap and held-out baseline distributions. | |
| 275 | +3. Layer × component causal localization heatmap with corrected significance/uncertainty. | |
| 276 | +4. Transplant mechanism architecture, token alignment, and dimensionality flow. | |
| 277 | +5. Target improvement versus control-task retention (Pareto frontier). | |
| 278 | +6. Donor-recipient portability matrix with confidence intervals. | |
| 279 | +7. Graft size versus effect size and latency/memory cost. | |
| 280 | +8. Ablation → loss → rescue causal chain. | |
| 281 | +9. Robustness across seeds, paraphrases, task difficulty, and unseen compositions. | |
| 282 | +10. Negative results and failure-mode taxonomy. | |
| 283 | + | |
| 284 | +Tables: model/checkpoint specifications; task splits; interventions and controls; primary effects with confidence intervals; collateral damage; compute cost; ablation study; reproducibility inventory. | |
| 285 | + | |
| 286 | +Never manufacture a figure to fill a visual quota. Every plotted point must derive from an identified data artifact. | |
| 287 | + | |
| 288 | +12. PAPER STRUCTURE AND WRITING STANDARD | |
| 289 | + | |
| 290 | +Target a strong machine-learning/mechanistic-interpretability contribution, not a marketing narrative. Assess fit for NeurIPS, ICLR, ICML, or an appropriate journal only after results and verified current submission rules; do not promise acceptance or assume formatting requirements. | |
| 291 | + | |
| 292 | +Suggested sections: | |
| 293 | + | |
| 294 | +1. Introduction: precise question, conceptual motivation, why transfer differs from conventional training and model merging, explicit contributions. | |
| 295 | +2. Related Work: critical positioning against model stitching, activation transfer, causal abstraction, representation alignment, editing, distillation, and mechanistic interpretability. | |
| 296 | +3. Operational Theory: candidate organs, transfer operators, causal estimands, and falsifiable hypotheses. | |
| 297 | +4. Experimental Design: controlled tasks, model pairs, interventions, controls, and identification. | |
| 298 | +5. Results: preregistered outcomes, uncertainty, generalization, costs, and negative findings. | |
| 299 | +6. Mechanistic Analysis: necessity, sufficiency, rescue, specificity, and limits. | |
| 300 | +7. Robustness and Failure Modes. | |
| 301 | +8. Discussion: what results establish, what they do not establish, and alternative explanations. | |
| 302 | +9. Limitations, Ethics, and Reproducibility. | |
| 303 | +10. Conclusion. | |
| 304 | +11. Appendices: full prompts, configs, model cards, supplementary tables, derivations, diagnostics, and compute details. | |
| 305 | + | |
| 306 | +The manuscript must have a substantial theoretical framework but not pretend that an intuitive metaphor is a theorem. Derive only justified mathematical statements and explicitly label conjectures. Use BibTeX records verified against primary sources. Do not invent author lists, publication metadata, DOIs, or conference versions. | |
| 307 | + | |
| 308 | +Paper title may be refined if findings warrant narrower claims. Do not use "transfer of intelligence" if evidence only shows task-specific activation bias. | |
| 309 | + | |
| 310 | +13. EXPERIMENT REGISTRY AND SCIENTIFIC AUDIT TRAIL | |
| 311 | + | |
| 312 | +For each run save: | |
| 313 | + | |
| 314 | +• research question, hypothesis, model pair, intervention family, control condition; | |
| 315 | +• code commit, environment lock, config and data hashes; | |
| 316 | +• training and alignment datasets and their split IDs; | |
| 317 | +• seed, intervention strength, layer, token positions, dimensionality; | |
| 318 | +• per-item outputs, ground truth, metrics, confidence intervals; | |
| 319 | +• resource usage, warnings, crashes, exclusions, and retry history; | |
| 320 | +• explicit status: planned / running / failed / completed / invalidated; | |
| 321 | +• a brief interpretation that separates observed evidence from speculation. | |
| 322 | + | |
| 323 | +Maintain docs/DECISION_LOG.md explaining methodological changes and whether they occurred before or after confirmatory lock. Never silently discard failed runs or change primary metrics after seeing outcomes. | |
| 324 | + | |
| 325 | +14. REPRODUCIBILITY, LICENSING, AND SECURITY | |
| 326 | + | |
| 327 | +Respect each model license and dataset license. Verify redistribution rights before releasing checkpoints or weights. Default to publishing code, configurations, synthetic generators, aggregate outputs, and scripts; release model-derived artifacts only when allowed. Do not exfiltrate proprietary model weights or secrets. Do not run arbitrary remote scripts without review. Avoid destructive changes to the wider UQO Research repository. | |
| 328 | + | |
| 329 | +Provide one-command setup where possible, a tiny CPU smoke test, a single-machine reference experiment, and optional multi-node execution. Record hardware-specific limitations, particularly MLX/Metal support. Include expected resource ranges measured from pilots, not guessed as facts. | |
| 330 | + | |
| 331 | +15. EXECUTION ROADMAP | |
| 332 | + | |
| 333 | +Sprint 0 — Research audit: inspect UQO Research, verify literature and licenses, write preregistration, resource budget, and gap statement. | |
| 334 | + | |
| 335 | +Sprint 1 — Controlled micro-world: build task generators and tiny-model baselines; validate donor competence and recipient weakness. | |
| 336 | + | |
| 337 | +Sprint 2 — Causal discovery: localize candidate subsystems, verify necessity and specificity, and benchmark null interventions. | |
| 338 | + | |
| 339 | +Sprint 3 — First transplant: implement one simple, falsifiable activation/subspace graft and a complete control battery. Do not prematurely scale. | |
| 340 | + | |
| 341 | +Sprint 4 — Generalization: extend to open-weight model families, mapping methods, and held-out compositional tasks. | |
| 342 | + | |
| 343 | +Sprint 5 — Mechanistic robustness: ablation/rescue, portability, persistence, collateral damage, and compute-efficiency frontiers. | |
| 344 | + | |
| 345 | +Sprint 6 — Confirmatory analysis: freeze protocol, run held-out tests, produce statistical tables and reproducible figures. | |
| 346 | + | |
| 347 | +Sprint 7 — Manuscript: write, audit, compile, and internally peer-review the paper. Maintain a claim-to-evidence traceability table. | |
| 348 | + | |
| 349 | +At each sprint: report completed artifacts, commands executed, actual results, unresolved risks, estimated remaining compute, and the next smallest scientifically meaningful experiment. | |
| 350 | + | |
| 351 | +16. AUTONOMOUS WORK RULES FOR CLAUDE CODE | |
| 352 | + | |
| 353 | +Work proactively within authorized resources. You may inspect code, design protocols, implement tests, and run bounded local experiments. Request explicit approval before substantial paid compute, destructive operations, publishing/submitting, modifying shared infrastructure, downloading exceptionally large checkpoints, or accessing restricted resources. | |
| 354 | + | |
| 355 | +Use independent critique passes for (a) causal inference, (b) representation alignment and leakage, (c) statistical validity, (d) code correctness, (e) literature novelty, and (f) paper claim-evidence consistency. If subagents are available, assign them scoped tasks and reconcile disagreements; do not treat agent agreement as empirical validation. | |
| 356 | + | |
| 357 | +Do not stop after writing a plan. Progress from the smallest working experiment through validated results, respecting approval and compute gates. Do not state that an experiment ran unless logs and artifacts prove it. Do not write fictional results sections. Use explicit placeholders for pending measurements. | |
| 358 | + | |
| 359 | +17. FIRST CONCRETE COMMAND TO EXECUTE | |
| 360 | + | |
| 361 | +Start by identifying the UQO Research root and current repository state. Create or safely reconcile wp-ai-0001. Perform the environment and literature audits. Write the preregistration and smallest pilot plan. Then implement a deterministic toy-model test that demonstrates the activation hook is a true no-op when disabled and that a controlled intervention produces a measurable, reproducible effect. Report those results before proceeding to transplantation claims. | |
| 362 | + | |
| 363 | +18. DEFINITION OF SUCCESS | |
| 364 | + | |
| 365 | +The strongest outcome is a causally validated, reproducible, selective, portable skill transfer that exceeds matched controls on genuinely unseen tasks without unacceptable collateral degradation. A rigorous demonstration that transplantation fails under well-defined architectural or representation mismatches is also a publishable scientific contribution if the boundary conditions are carefully established. | |
| 366 | + | |
| 367 | +Final principle: Build evidence strong enough that a skeptical independent researcher can reproduce the effect, rule out trivial explanations, and understand precisely what was—and was not—transferred. | |
added
docs/PREREGISTRATION.md
+67 −0
@@ -0,0 +1,67 @@ | ||
| 1 | +# Preregistration — WP-AI-0001 (v0.1, 2026-11-09) | |
| 2 | + | |
| 3 | +**Status:** draft registered *before* any transplant experiment. The Tier-0 pilot (`scripts/run_pilot.py`) | |
| 4 | +is explicitly *exploratory*: it serves to measure gap, verify hooks and localize the target subsystem. | |
| 5 | +Confirmatory analyses will be frozen in v1.0 of this document (hash recorded in `DECISION_LOG.md`) before | |
| 6 | +confirmatory data are generated. Changes after freeze are deviations and are logged. | |
| 7 | + | |
| 8 | +## 1. Estimands | |
| 9 | + | |
| 10 | +Notation as in CLAUDE.md §2. For a model pair (D, R), task family T with target stratum and control strata: | |
| 11 | + | |
| 12 | +- **Transfer gain** Δ_T = Q_T(R′) − Q_T(R), exact-match accuracy on held-out target items. | |
| 13 | +- **Control-adjusted transfer** Δ_T^adj = Δ_T − [Q_T(R_sham) − Q_T(R)] where R_sham is the *matched sham* | |
| 14 | + (same positions, layers, dimensionality and norm; donor content replaced by the control defined per method). | |
| 15 | +- **Retention** ρ_c = Q_c(R′) / Q_c(R) for each control stratum c with Q_c(R) ≥ 0.5; otherwise report Δ_c. | |
| 16 | +- **Donor necessity** N_D = Q_T(D) − Q_T(D_ablated) for the localized component. | |
| 17 | +- **Rescue** = Q_T(D_ablated + graft) − Q_T(D_ablated). | |
| 18 | + | |
| 19 | +Unit of inference: *items nested in programs (clusters)*; model seeds are a second level. CIs: cluster | |
| 20 | +bootstrap over programs within a seed; seed-level summaries report mean, sd and min over ≥ 3 seeds. | |
| 21 | + | |
| 22 | +## 2. Hypotheses (Tier 0, micro-world A, target operator Ω = `qua`) | |
| 23 | + | |
| 24 | +- **H1 (localization).** In donors trained on all operators, interchange interventions identify a set of | |
| 25 | + (layer, position) locations whose patching restores ≥ 0.8 of the clean answer rate at the Ω step, with | |
| 26 | + the sham (corrupt-into-corrupt) rate ≤ chance + 0.1. Null: no location exceeds sham + 0.2. | |
| 27 | +- **H2 (sufficiency / activation graft).** Mapped donor activations grafted at the identified location | |
| 28 | + raise the recipient's Ω-step accuracy by Δ_T^adj ≥ 0.25 (smallest effect of interest, SESOI) on | |
| 29 | + held-out target items. Null: Δ_T^adj ≤ 0.05. | |
| 30 | +- **H3 (necessity).** Ablating the identified donor component reduces donor Ω-step accuracy by | |
| 31 | + N_D ≥ 0.5 while control-stratum accuracy drops by ≤ 0.05. | |
| 32 | +- **H4 (selectivity).** Retention ρ_c ≥ 0.95 on `control_iid` for the graft that achieves H2. | |
| 33 | +- **H5 (rule vs cache).** The graft's effect on programs whose (Ω-neighbour, v0) combinations were absent | |
| 34 | + from the alignment data is at least 0.8 × its effect on seen combinations. Null: ≤ 0.5 ×. | |
| 35 | +- **H6 (portability, Tier 1).** Effects replicate (Δ_T^adj ≥ SESOI) for at least one cross-family pair; | |
| 36 | + we predict *failure* for mismatched-tokenizer pairs without a tokenizer bridge and record it as such. | |
| 37 | + | |
| 38 | +Directional predictions are stated for honesty; a null on any hypothesis is reported in full. | |
| 39 | + | |
| 40 | +## 3. Primary and secondary outcomes | |
| 41 | + | |
| 42 | +Primary (confirmatory): Δ_T^adj on `target_confirmatory` (generated after freeze from a new seed), | |
| 43 | +and ρ_c on `control_confirmatory`. Secondary: trace accuracy, Ω-step accuracy, N_D, rescue, graft | |
| 44 | +dimensionality, parameter count, latency, peak memory, seed stability. | |
| 45 | + | |
| 46 | +## 4. Multiplicity | |
| 47 | + | |
| 48 | +Localization sweeps (layers × positions × families × heads) are exploratory and selection is made on the | |
| 49 | +*development* localization set only. Confirmatory comparisons are limited to the pre-declared list in | |
| 50 | +`EXPERIMENT_PLAN.md` §5 (one primary contrast per method family; Holm correction across method families). | |
| 51 | + | |
| 52 | +## 5. Power | |
| 53 | + | |
| 54 | +Pilot variability will be recorded in `EXPERIMENT_LOG.md` after the pilot; the confirmatory sample size | |
| 55 | +(items and clusters) will be chosen by simulation from the pilot cluster bootstrap so that an effect of | |
| 56 | +SESOI = 0.25 has ≥ 0.9 power at α = 0.05 (two-sided) on the primary contrast. No effect sizes are invented. | |
| 57 | + | |
| 58 | +## 6. Exclusion rules | |
| 59 | + | |
| 60 | +Runs are excluded only for crashes, NaNs, or manifest/data-hash mismatches; all exclusions are listed in | |
| 61 | +the run manifest and in `EXPERIMENT_LOG.md`. No run is excluded for its outcome. | |
| 62 | + | |
| 63 | +## 7. Contamination safeguards | |
| 64 | + | |
| 65 | +Split hashes are stored in manifests; evaluation splits are generated with seeds disjoint from training | |
| 66 | +and alignment seeds; `assert_disjoint` is enforced at build time; alignment data for mappings never | |
| 67 | +include evaluation items (checked by item hash). | |
added
docs/REPRODUCIBILITY.md
+22 −0
@@ -0,0 +1,22 @@ | ||
| 1 | +# Reproducibility — WP-AI-0001 | |
| 2 | + | |
| 3 | +```bash | |
| 4 | +cd ia/wp-ai-0001 | |
| 5 | +python3 -m pip install -e ".[dev]" # or: uv pip install -e ".[dev]" | |
| 6 | +python3 -m pytest tests -q # unit + causal-sanity tests (CPU, < 30 s) | |
| 7 | +python3 scripts/audit_environment.py # writes docs/ENVIRONMENT_AUDIT.json (add --cluster to probe nodes) | |
| 8 | +python3 scripts/run_pilot.py --quick --device cpu --seeds 0 1 --n-boot 200 # CPU smoke test, ≈ 25 s | |
| 9 | +python3 scripts/run_pilot.py --seeds 0 1 2 --steps 3000 # Tier-0 pilot (MPS ≈ minutes) | |
| 10 | +``` | |
| 11 | + | |
| 12 | +- Every run writes `experiments/manifests/<run_id>.json` (git commit, config hash, data hashes, seeds, | |
| 13 | + libraries, hardware, status history), appends to `experiments/registry/runs.jsonl`, and stores results in | |
| 14 | + `experiments/summaries/<run_id>/` (`results.json`, `SUMMARY.md`). Per-item predictions are in | |
| 15 | + `artifacts/runs/<run_id>/` (git-ignored), models in `artifacts/models/<run_id>/`. | |
| 16 | +- Run IDs are deterministic functions of the experiment id and config hash; re-running with the same config | |
| 17 | + reuses trained models from `artifacts/models/<run_id>/` (delete to retrain). | |
| 18 | +- Determinism: PyTorch on MPS was verified bitwise-repeatable for this model (`noop.deterministic_repeat`); | |
| 19 | + localization sweeps repeated twice differ by 0.0. Training determinism across devices is *not* claimed | |
| 20 | + (CPU vs MPS kernels differ); seeds reproduce training on the same device/library versions. | |
| 21 | +- Data are synthetic and regenerated from seeds; the split hashes recorded in manifests must match. | |
| 22 | +- Secrets: none required. No tokens are read; paths are relative to the project root. | |
added
docs/RESEARCH_GAP.md
+84 −0
@@ -0,0 +1,84 @@ | ||
| 1 | +# Research gap — WP-AI-0001 (written 2026-11-09, before any transplant experiment) | |
| 2 | + | |
| 3 | +Literature status: **verified via arXiv API metadata and abstracts on 2026-11-09** for every record in | |
| 4 | +`literature/arxiv_verified_2026-11-09.txt` (identifiers, titles, first-submission dates, authors) and | |
| 5 | +`literature/references_verified.bib`. Full texts were not re-read for every item; claims below about | |
| 6 | +*what each paper does* come from the verified abstracts and the project's search notes. Anything not in | |
| 7 | +the verified list is marked (unverified) and must not be cited. | |
| 8 | + | |
| 9 | +## 1. What is already known | |
| 10 | + | |
| 11 | +**Representation similarity across models.** SVCCA (Raghu et al. 2017, 1706.05806), CKA (Kornblith et al. | |
| 12 | +2019, 1905.00414), the Platonic Representation Hypothesis (Huh et al. 2024, 2405.07987) and Multi-Way | |
| 13 | +Representation Alignment (Achara et al. 2026, 2602.06205) establish that independently trained networks | |
| 14 | +have *linearly related* representation spaces. Shared embedding geometry allows steering vectors to move | |
| 15 | +between models (Lee et al. 2025, 2503.21073). | |
| 16 | + | |
| 17 | +**Model stitching.** Bansal, Nakkiran & Barak (2021, 2106.07682) revisit stitching as a representation | |
| 18 | +comparison tool (vision). Chen, Merullo, Stolfo & Pavlick (2025, 2506.06609; NeurIPS 2025) show that affine | |
| 19 | +maps between residual streams of *same-family* language models of different sizes transfer SAEs, probes | |
| 20 | +and steering vectors. Kim, Mun & Han (2026, 2608.09521) learn a shared dense "activation bus" with one | |
| 21 | +encoder–decoder pair per model and show that an intermediate activation of one model can be consumed by | |
| 22 | +another model's frozen upper layers. | |
| 23 | + | |
| 24 | +**Cross-model feature dictionaries.** Lan et al. (2024, 2410.06981), Universal SAEs (Thasarathan et al. | |
| 25 | +2025, 2502.03714), SPARC (2025, 2507.06265) and SharedSAE (Ognev et al. 2026, 2609.04344) build concept | |
| 26 | +spaces shared across models, mostly for *interpretation*, not for conferring capabilities. | |
| 27 | + | |
| 28 | +**Cross-model steering and circuit transfer.** Agarwal (2026, 2608.05164) transfers SAE-derived steering | |
| 29 | +directions across five models (0.8B–8B) and reports functional transfer above ≈1.7B parameters for | |
| 30 | +*semantic concepts*. Cristofano (2026, 2601.16034) transfers *refusal* interventions across eight model | |
| 31 | +pairs by concept-basis reconstruction. Sinii et al. (2025, 2509.06608) find RL-induced reasoning steering | |
| 32 | +vectors transfer only within a family. | |
| 33 | + | |
| 34 | +**Capability transfer across scales.** Panigrahi et al. (2023, 2302.06600) graft ≈0.01 % of fine-tuned | |
| 35 | +parameters back onto a pre-trained model ("skill localization", same model). APM (Fan et al. 2026, | |
| 36 | +2608.13596) prunes a larger donor to a recipient's architecture and mixes it in with a micro coefficient; | |
| 37 | +SemAlign (Gu et al. 2025, 2510.24208) uses activations as the transfer medium but *trains* the recipient | |
| 38 | +layer by layer. Task arithmetic (Ilharco et al. 2022, 2212.04089), TIES (Yadav et al. 2023, 2306.01708) and | |
| 39 | +Git Re-Basin (Ainsworth et al. 2022, 2209.04836) merge *weights* of models with a common initialization. | |
| 40 | +Zero-shot tokenizer transfer (Minixhofer et al. 2024, 2405.07883) addresses the tokenizer boundary. | |
| 41 | + | |
| 42 | +**Causal methods.** Causal mediation (Vig et al. 2020, 2004.12265), causal tracing / ROME (Meng et al. 2022, | |
| 43 | +2202.05262), interchange interventions and causal abstraction (Geiger et al. 2023, 2301.04709 and DAS, | |
| 44 | +2303.02536), circuit discovery (Wang et al. 2022, 2211.00593; Conmy et al. 2023, 2304.14997), function / | |
| 45 | +task vectors (Todd et al. 2023, 2310.15213; Hendel et al. 2023, 2310.15916), activation steering (Turner | |
| 46 | +et al. 2023, 2308.10248; Li et al. 2023, 2306.03341; Zou et al. 2023, 2310.01405). | |
| 47 | + | |
| 48 | +**The closest negative result.** Zhang & Xin (2026, 2606.03280) learn a linear bridge from Pythia-160M to | |
| 49 | +Pythia-410M hidden states (cosine ≈ 0.97) and find that injected activations **do not** improve multi-hop | |
| 50 | +answering: additive injection is null, replacement is destructive. Their conclusion: *offline | |
| 51 | +representational alignment is not sufficient for useful causal communication inside the receiver.* | |
| 52 | + | |
| 53 | +## 2. What is missing (the gap this project targets) | |
| 54 | + | |
| 55 | +1. **No study starts from a causally identified subsystem.** Stitching, activation-bus and steering-transfer | |
| 56 | + work map *whole residual streams* or *concept directions*; APM prunes by activation salience. None first | |
| 57 | + establishes, by interchange interventions in the donor, that a bounded component is necessary and | |
| 58 | + sufficient for a *measurable capability*, and then asks whether *that* component transfers. | |
| 59 | +2. **No controlled donor/recipient capability gap.** Prior work takes two off-the-shelf models and measures | |
| 60 | + benchmark deltas. We *manufacture* the gap (recipient trained without the capability; Tier 0) or | |
| 61 | + verify it with repeated held-out measurement (Tier 1–2), so that "acquisition" is identifiable. | |
| 62 | +3. **No matched-control battery.** Sham mappings, norm-matched random grafts, unrelated-skill donors, | |
| 63 | + shuffled-token/layer grafts and matched-size adapter fine-tuning are not reported together in any of | |
| 64 | + the above; the negative result of 2606.03280 is itself uncontrolled with respect to these. | |
| 65 | +4. **Persistence is conflated.** Inference-time steering, saved adapters and weight edits are different | |
| 66 | + claims; we label single-token, within-sequence, cross-prompt and saved-checkpoint effects separately. | |
| 67 | +5. **Rule versus cache.** Whether a transferred component carries a *rule* (generalizing to unseen | |
| 68 | + compositions / symbols) rather than a bias toward answer tokens is not tested by existing transfer work. | |
| 69 | +6. **Failure boundaries.** Agarwal (2026) reports a scale discontinuity and Sinii et al. (2025) a family | |
| 70 | + boundary for *steering*; nothing comparable exists for *capability* transfer with causal controls. | |
| 71 | + | |
| 72 | +## 3. What would *not* be novel (and we will not claim) | |
| 73 | + | |
| 74 | +- Affine residual-stream mappings as such (Chen et al. 2025; Kim et al. 2026). | |
| 75 | +- Cross-model steering of concepts (Agarwal 2026; Lee et al. 2025). | |
| 76 | +- Grafting fine-tuned parameters within one model (Panigrahi et al. 2023). | |
| 77 | +- Any "organ" metaphor as a theoretical contribution; the contribution must be the causal design and the | |
| 78 | + measured transfer / non-transfer boundaries. | |
| 79 | + | |
| 80 | +## 4. Positioning sentence (to be refined after results) | |
| 81 | + | |
| 82 | +*We ask whether a component that is causally necessary and sufficient for a capability in a donor can be | |
| 83 | +installed in a recipient that demonstrably lacks it, under sham, random and matched-training controls, | |
| 84 | +and we map where this fails.* A rigorous negative result with boundary conditions is an acceptable outcome. | |
added
docs/RISK_REGISTER.md
+16 −0
@@ -0,0 +1,16 @@ | ||
| 1 | +# Risk register — WP-AI-0001 | |
| 2 | + | |
| 3 | +| ID | Risk | Likelihood | Impact | Mitigation / detection | | |
| 4 | +|---|---|---|---|---| | |
| 5 | +| R1 | Tier-0 task too easy (scratchpad makes Ω a lookup) → transfer of a table, not a rule | high | medium | `trace_stride > 1` variants; FSA family; H5 rule-vs-cache test on unseen (neighbour, v0) combinations | | |
| 6 | +| R2 | Tier-0 task too hard (single-token format failed to generalize in the first attempt, dev ≈ 0.3) | observed | high | scratchpad adopted (DECISION_LOG D2); keep single-token variant as a difficulty stratum only | | |
| 7 | +| R3 | Localization not reproducible across seeds | low (pilot smoke: r ≥ 0.97) | high | across-seed Pearson on heatmaps; selection on development set only | | |
| 8 | +| R4 | Graft effect is answer-token bias, not capability | medium | high | rule-vs-cache split, shuffled-token graft, logit-lens of grafted stream, control strata | | |
| 9 | +| R5 | Leakage through alignment data (mapping fitted on evaluation items) | medium | high | item-hash audit of alignment vs evaluation splits in every manifest | | |
| 10 | +| R6 | MLX does not expose hooks → silent substitution | medium | medium | layer-wrapping implementation with bitwise no-op test; equivalence test vs PyTorch on logits | | |
| 11 | +| R7 | Memory pressure on 3B activation capture | medium | medium | streamed capture; per-layer limits; profiling before sweeps | | |
| 12 | +| R8 | Multiple comparisons in sweeps inflate findings | high | high | exploratory/confirmatory separation; Holm across families; pre-declared contrasts | | |
| 13 | +| R9 | Literature overlap (2606.03280 negative; 2608.09521 activation bus) | certain | medium | position as controlled, causally identified extension; cite and compare explicitly | | |
| 14 | +| R10 | Cluster node unavailability | medium | low | laptop suffices for Tiers 0–1; nodes probed, never assumed | | |
| 15 | +| R11 | License restrictions on redistributing derived weights | medium | low | release code/configs/synthetic data; adapters only where licenses permit (Qwen: Apache-2.0; Llama 3.2: community license — check before release) | | |
| 16 | +| R12 | Over-claiming "intelligence transfer" | medium | high | title and claims limited to measured task-specific effects; claim-evidence table (Gate F) | | |
added
docs/TASKS.md
+37 −0
@@ -0,0 +1,37 @@ | ||
| 1 | +# Implementation task tracker — WP-AI-0001 | |
| 2 | + | |
| 3 | +Legend: [x] done · [~] in progress · [ ] todo · (gate) quality gate per CLAUDE.md §10 | |
| 4 | + | |
| 5 | +## Sprint 0 — Research audit | |
| 6 | +- [x] Locate UQO Research workspace, conventions, remotes | |
| 7 | +- [x] Environment audit (laptop + cluster) → `docs/ENVIRONMENT_AUDIT.json` | |
| 8 | +- [x] Literature verification → `literature/` | |
| 9 | +- [x] RESEARCH_GAP, PREREGISTRATION v0.1, EXPERIMENT_PLAN, COMPUTE_BUDGET, RISK_REGISTER, REPRODUCIBILITY, logs | |
| 10 | +- [x] Project skeleton, pyproject, tests (Gate A) | |
| 11 | +- [x] `scripts/build_figures.py`, `scripts/build_paper.sh`, paper skeleton compiles (placeholders) | |
| 12 | +- [x] git repo + `origin = gitsrv:srv/git/wpai0001_uqo.git` | |
| 13 | + | |
| 14 | +## Sprint 1 — Controlled micro-world | |
| 15 | +- [x] OPSEQ / FSA / MORPH generators + exact validators + disjointness + hashing | |
| 16 | +- [x] Toy transformer with hook points; no-op tests (Gate C part 1) | |
| 17 | +- [x] Training loop (teacher-forced scratchpad), greedy decoding, metrics, cluster bootstrap | |
| 18 | +- [x] Pilot run (3 seeds) — gap qualification (Gate B passed; run `pilot_tier0_opseq_451ef5087182`) | |
| 19 | +- [ ] FSA / MORPH toy baselines | |
| 20 | +- [ ] `trace_stride = 2` difficulty variant baseline | |
| 21 | + | |
| 22 | +## Sprint 2 — Causal discovery | |
| 23 | +- [x] Within-donor localization (patching, ablation, heads) with sham baseline and reproducibility (RQ1 pilot: Ω executed at the read position; L0 attention + L0–L2 MLPs) | |
| 24 | +- [ ] Add `embed`/`resid_pre` family and path patching Ω-token → r1 to the sweep | |
| 25 | +- [ ] Subspace localization (DAS-style / PCA of Ω-contrast) with norm-matched random subspaces | |
| 26 | +- [ ] Necessity test on donor (H3) with control-stratum retention | |
| 27 | + | |
| 28 | +## Sprint 3 — First transplant | |
| 29 | +- [ ] Alignment module: Procrustes, ridge, CCA, random, unrelated-data maps; leakage audit | |
| 30 | +- [ ] Activation graft + sham + norm-matched random + shuffled-token controls | |
| 31 | +- [ ] Gate D: reproducibility, overhead disclosure | |
| 32 | + | |
| 33 | +## Sprint 4–7 | |
| 34 | +- [ ] Tier 1 MLX interventions (layer wrapping) + Transformers equivalence test | |
| 35 | +- [ ] Portability matrix, persistence (saved adapter), collateral battery | |
| 36 | +- [ ] Confirmatory freeze (PREREGISTRATION v1.0) and run | |
| 37 | +- [ ] Paper, figures, claim-evidence table (Gate F) | |
added
experiments/manifests/pilot_tier0_opseq_451ef5087182.json
+223 −0
@@ -0,0 +1,223 @@ | ||
| 1 | +{ | |
| 2 | + "config": { | |
| 3 | + "description": "Tier-0 pilot: donor/recipient gap, hook no-op test, within-model causal localization", | |
| 4 | + "donor": { | |
| 5 | + "model": { | |
| 6 | + "d_ff": 512, | |
| 7 | + "d_model": 128, | |
| 8 | + "dropout": 0.0, | |
| 9 | + "max_seq_len": 24, | |
| 10 | + "n_heads": 4, | |
| 11 | + "n_layers": 4, | |
| 12 | + "tie_embeddings": false | |
| 13 | + }, | |
| 14 | + "name": "donor", | |
| 15 | + "role": "donor", | |
| 16 | + "task": { | |
| 17 | + "excluded_operators": [], | |
| 18 | + "family": "opseq", | |
| 19 | + "held_out_pairs": [ | |
| 20 | + [ | |
| 21 | + "zob", | |
| 22 | + "lar" | |
| 23 | + ], | |
| 24 | + [ | |
| 25 | + "qua", | |
| 26 | + "neg" | |
| 27 | + ] | |
| 28 | + ], | |
| 29 | + "max_len": 5, | |
| 30 | + "min_len": 1, | |
| 31 | + "modulus": 11, | |
| 32 | + "operators": [ | |
| 33 | + "zib", | |
| 34 | + "zob", | |
| 35 | + "qua", | |
| 36 | + "lar", | |
| 37 | + "neg", | |
| 38 | + "flip", | |
| 39 | + "dro", | |
| 40 | + "mik" | |
| 41 | + ], | |
| 42 | + "trace_stride": 1 | |
| 43 | + }, | |
| 44 | + "train": { | |
| 45 | + "batch_size": 256, | |
| 46 | + "device": "mps", | |
| 47 | + "eval_every": 500, | |
| 48 | + "lr": 0.001, | |
| 49 | + "n_dev": 1000, | |
| 50 | + "n_train": 40000, | |
| 51 | + "seed": 0, | |
| 52 | + "steps": 3000, | |
| 53 | + "warmup_steps": 100, | |
| 54 | + "weight_decay": 0.01 | |
| 55 | + } | |
| 56 | + }, | |
| 57 | + "experiment_id": "pilot_tier0_opseq", | |
| 58 | + "n_bootstrap": 2000, | |
| 59 | + "n_eval": 1000, | |
| 60 | + "recipient": { | |
| 61 | + "model": { | |
| 62 | + "d_ff": 512, | |
| 63 | + "d_model": 128, | |
| 64 | + "dropout": 0.0, | |
| 65 | + "max_seq_len": 24, | |
| 66 | + "n_heads": 4, | |
| 67 | + "n_layers": 4, | |
| 68 | + "tie_embeddings": false | |
| 69 | + }, | |
| 70 | + "name": "recipient", | |
| 71 | + "role": "recipient", | |
| 72 | + "task": { | |
| 73 | + "excluded_operators": [ | |
| 74 | + "qua" | |
| 75 | + ], | |
| 76 | + "family": "opseq", | |
| 77 | + "held_out_pairs": [ | |
| 78 | + [ | |
| 79 | + "zob", | |
| 80 | + "lar" | |
| 81 | + ], | |
| 82 | + [ | |
| 83 | + "qua", | |
| 84 | + "neg" | |
| 85 | + ] | |
| 86 | + ], | |
| 87 | + "max_len": 5, | |
| 88 | + "min_len": 1, | |
| 89 | + "modulus": 11, | |
| 90 | + "operators": [ | |
| 91 | + "zib", | |
| 92 | + "zob", | |
| 93 | + "qua", | |
| 94 | + "lar", | |
| 95 | + "neg", | |
| 96 | + "flip", | |
| 97 | + "dro", | |
| 98 | + "mik" | |
| 99 | + ], | |
| 100 | + "trace_stride": 1 | |
| 101 | + }, | |
| 102 | + "train": { | |
| 103 | + "batch_size": 256, | |
| 104 | + "device": "mps", | |
| 105 | + "eval_every": 500, | |
| 106 | + "lr": 0.001, | |
| 107 | + "n_dev": 1000, | |
| 108 | + "n_train": 40000, | |
| 109 | + "seed": 0, | |
| 110 | + "steps": 3000, | |
| 111 | + "warmup_steps": 100, | |
| 112 | + "weight_decay": 0.01 | |
| 113 | + } | |
| 114 | + }, | |
| 115 | + "seeds": [ | |
| 116 | + 0, | |
| 117 | + 1, | |
| 118 | + 2 | |
| 119 | + ], | |
| 120 | + "target_operator": "qua" | |
| 121 | + }, | |
| 122 | + "created_utc": "2026-11-09T06:49:35+00:00", | |
| 123 | + "data_hashes": { | |
| 124 | + "comp_heldout": { | |
| 125 | + "generator": "opseq@opseq-1.0", | |
| 126 | + "hash": "b1c6aebefbf3a5d5", | |
| 127 | + "n": 1000, | |
| 128 | + "seed": 20261121 | |
| 129 | + }, | |
| 130 | + "control_iid": { | |
| 131 | + "generator": "opseq@opseq-1.0", | |
| 132 | + "hash": "fa7c2327072b7d56", | |
| 133 | + "n": 1000, | |
| 134 | + "seed": 20261120 | |
| 135 | + }, | |
| 136 | + "donor_dev": { | |
| 137 | + "generator": "opseq@opseq-1.0", | |
| 138 | + "hash": "67055896a5ce52ea", | |
| 139 | + "n": 1000, | |
| 140 | + "seed": 20261112 | |
| 141 | + }, | |
| 142 | + "donor_train": { | |
| 143 | + "generator": "opseq@opseq-1.0", | |
| 144 | + "hash": "d213971f9e1feabf", | |
| 145 | + "n": 40000, | |
| 146 | + "seed": 20261110 | |
| 147 | + }, | |
| 148 | + "len_ood": { | |
| 149 | + "generator": "opseq@opseq-1.0", | |
| 150 | + "hash": "7ecb075ac45796ac", | |
| 151 | + "n": 500, | |
| 152 | + "seed": 20261122 | |
| 153 | + }, | |
| 154 | + "recipient_dev": { | |
| 155 | + "generator": "opseq@opseq-1.0", | |
| 156 | + "hash": "aa252ba85caa5d1f", | |
| 157 | + "n": 1000, | |
| 158 | + "seed": 20261113 | |
| 159 | + }, | |
| 160 | + "recipient_train": { | |
| 161 | + "generator": "opseq@opseq-1.0", | |
| 162 | + "hash": "c464e2683affd837", | |
| 163 | + "n": 40000, | |
| 164 | + "seed": 20261111 | |
| 165 | + }, | |
| 166 | + "target_iid": { | |
| 167 | + "generator": "opseq@opseq-1.0", | |
| 168 | + "hash": "f1a1ef205c8f35db", | |
| 169 | + "n": 1000, | |
| 170 | + "seed": 20261119 | |
| 171 | + } | |
| 172 | + }, | |
| 173 | + "experiment_id": "pilot_tier0_opseq", | |
| 174 | + "git": { | |
| 175 | + "branch": null, | |
| 176 | + "commit": null, | |
| 177 | + "dirty": null | |
| 178 | + }, | |
| 179 | + "hardware": { | |
| 180 | + "chip": "Apple M5 Max", | |
| 181 | + "cpu_count": 18, | |
| 182 | + "hostname_hash": "9ad7358c662e", | |
| 183 | + "machine": "arm64", | |
| 184 | + "memory_gb": 48.0, | |
| 185 | + "platform": "macOS-27.0-arm64-arm-64bit-Mach-O", | |
| 186 | + "torch_cuda": false, | |
| 187 | + "torch_mps": true | |
| 188 | + }, | |
| 189 | + "history": [ | |
| 190 | + { | |
| 191 | + "note": "", | |
| 192 | + "status": "running", | |
| 193 | + "utc": "2026-11-09T06:49:38+00:00" | |
| 194 | + }, | |
| 195 | + { | |
| 196 | + "note": "", | |
| 197 | + "status": "completed", | |
| 198 | + "utc": "2026-11-09T06:54:13+00:00" | |
| 199 | + } | |
| 200 | + ], | |
| 201 | + "interpretation": "", | |
| 202 | + "libraries": { | |
| 203 | + "mlx": "?", | |
| 204 | + "mlx_lm": "0.31.3", | |
| 205 | + "numpy": "2.4.4", | |
| 206 | + "pydantic": "2.13.4", | |
| 207 | + "python": "3.14.4", | |
| 208 | + "safetensors": "0.7.0", | |
| 209 | + "scipy": "1.17.1", | |
| 210 | + "torch": "2.12.0", | |
| 211 | + "transformers": "5.8.1" | |
| 212 | + }, | |
| 213 | + "outputs": { | |
| 214 | + "figures": "artifacts/figures/pilot_tier0_opseq_451ef5087182", | |
| 215 | + "items": "artifacts/runs/pilot_tier0_opseq_451ef5087182", | |
| 216 | + "models": "artifacts/models/pilot_tier0_opseq_451ef5087182", | |
| 217 | + "results": "experiments/summaries/pilot_tier0_opseq_451ef5087182/results.json" | |
| 218 | + }, | |
| 219 | + "run_id": "pilot_tier0_opseq_451ef5087182", | |
| 220 | + "seeds": {}, | |
| 221 | + "status": "completed", | |
| 222 | + "warnings": [] | |
| 223 | +} | |
| \ No newline at end of file | ||
added
experiments/manifests/pilot_tier0_opseq_quick_d5339bcad6b3.json
+222 −0
@@ -0,0 +1,222 @@ | ||
| 1 | +{ | |
| 2 | + "config": { | |
| 3 | + "description": "Tier-0 pilot: donor/recipient gap, hook no-op test, within-model causal localization", | |
| 4 | + "donor": { | |
| 5 | + "model": { | |
| 6 | + "d_ff": 128, | |
| 7 | + "d_model": 64, | |
| 8 | + "dropout": 0.0, | |
| 9 | + "max_seq_len": 24, | |
| 10 | + "n_heads": 2, | |
| 11 | + "n_layers": 3, | |
| 12 | + "tie_embeddings": false | |
| 13 | + }, | |
| 14 | + "name": "donor", | |
| 15 | + "role": "donor", | |
| 16 | + "task": { | |
| 17 | + "excluded_operators": [], | |
| 18 | + "family": "opseq", | |
| 19 | + "held_out_pairs": [ | |
| 20 | + [ | |
| 21 | + "zob", | |
| 22 | + "lar" | |
| 23 | + ], | |
| 24 | + [ | |
| 25 | + "qua", | |
| 26 | + "neg" | |
| 27 | + ] | |
| 28 | + ], | |
| 29 | + "max_len": 5, | |
| 30 | + "min_len": 1, | |
| 31 | + "modulus": 11, | |
| 32 | + "operators": [ | |
| 33 | + "zib", | |
| 34 | + "zob", | |
| 35 | + "qua", | |
| 36 | + "lar", | |
| 37 | + "neg", | |
| 38 | + "flip", | |
| 39 | + "dro", | |
| 40 | + "mik" | |
| 41 | + ], | |
| 42 | + "trace_stride": 1 | |
| 43 | + }, | |
| 44 | + "train": { | |
| 45 | + "batch_size": 256, | |
| 46 | + "device": "cpu", | |
| 47 | + "eval_every": 500, | |
| 48 | + "lr": 0.001, | |
| 49 | + "n_dev": 300, | |
| 50 | + "n_train": 3000, | |
| 51 | + "seed": 0, | |
| 52 | + "steps": 200, | |
| 53 | + "warmup_steps": 100, | |
| 54 | + "weight_decay": 0.01 | |
| 55 | + } | |
| 56 | + }, | |
| 57 | + "experiment_id": "pilot_tier0_opseq_quick", | |
| 58 | + "n_bootstrap": 200, | |
| 59 | + "n_eval": 300, | |
| 60 | + "recipient": { | |
| 61 | + "model": { | |
| 62 | + "d_ff": 128, | |
| 63 | + "d_model": 64, | |
| 64 | + "dropout": 0.0, | |
| 65 | + "max_seq_len": 24, | |
| 66 | + "n_heads": 2, | |
| 67 | + "n_layers": 3, | |
| 68 | + "tie_embeddings": false | |
| 69 | + }, | |
| 70 | + "name": "recipient", | |
| 71 | + "role": "recipient", | |
| 72 | + "task": { | |
| 73 | + "excluded_operators": [ | |
| 74 | + "qua" | |
| 75 | + ], | |
| 76 | + "family": "opseq", | |
| 77 | + "held_out_pairs": [ | |
| 78 | + [ | |
| 79 | + "zob", | |
| 80 | + "lar" | |
| 81 | + ], | |
| 82 | + [ | |
| 83 | + "qua", | |
| 84 | + "neg" | |
| 85 | + ] | |
| 86 | + ], | |
| 87 | + "max_len": 5, | |
| 88 | + "min_len": 1, | |
| 89 | + "modulus": 11, | |
| 90 | + "operators": [ | |
| 91 | + "zib", | |
| 92 | + "zob", | |
| 93 | + "qua", | |
| 94 | + "lar", | |
| 95 | + "neg", | |
| 96 | + "flip", | |
| 97 | + "dro", | |
| 98 | + "mik" | |
| 99 | + ], | |
| 100 | + "trace_stride": 1 | |
| 101 | + }, | |
| 102 | + "train": { | |
| 103 | + "batch_size": 256, | |
| 104 | + "device": "cpu", | |
| 105 | + "eval_every": 500, | |
| 106 | + "lr": 0.001, | |
| 107 | + "n_dev": 300, | |
| 108 | + "n_train": 3000, | |
| 109 | + "seed": 0, | |
| 110 | + "steps": 200, | |
| 111 | + "warmup_steps": 100, | |
| 112 | + "weight_decay": 0.01 | |
| 113 | + } | |
| 114 | + }, | |
| 115 | + "seeds": [ | |
| 116 | + 0, | |
| 117 | + 1 | |
| 118 | + ], | |
| 119 | + "target_operator": "qua" | |
| 120 | + }, | |
| 121 | + "created_utc": "2026-11-09T06:49:08+00:00", | |
| 122 | + "data_hashes": { | |
| 123 | + "comp_heldout": { | |
| 124 | + "generator": "opseq@opseq-1.0", | |
| 125 | + "hash": "68e83ab8472513d2", | |
| 126 | + "n": 300, | |
| 127 | + "seed": 20261121 | |
| 128 | + }, | |
| 129 | + "control_iid": { | |
| 130 | + "generator": "opseq@opseq-1.0", | |
| 131 | + "hash": "76bdfaf36a5f7519", | |
| 132 | + "n": 300, | |
| 133 | + "seed": 20261120 | |
| 134 | + }, | |
| 135 | + "donor_dev": { | |
| 136 | + "generator": "opseq@opseq-1.0", | |
| 137 | + "hash": "79b849f32dd6df25", | |
| 138 | + "n": 300, | |
| 139 | + "seed": 20261112 | |
| 140 | + }, | |
| 141 | + "donor_train": { | |
| 142 | + "generator": "opseq@opseq-1.0", | |
| 143 | + "hash": "da62d95aa07ed95a", | |
| 144 | + "n": 3000, | |
| 145 | + "seed": 20261110 | |
| 146 | + }, | |
| 147 | + "len_ood": { | |
| 148 | + "generator": "opseq@opseq-1.0", | |
| 149 | + "hash": "6d8c13dc8b5c47fa", | |
| 150 | + "n": 200, | |
| 151 | + "seed": 20261122 | |
| 152 | + }, | |
| 153 | + "recipient_dev": { | |
| 154 | + "generator": "opseq@opseq-1.0", | |
| 155 | + "hash": "c697914975bb93d3", | |
| 156 | + "n": 300, | |
| 157 | + "seed": 20261113 | |
| 158 | + }, | |
| 159 | + "recipient_train": { | |
| 160 | + "generator": "opseq@opseq-1.0", | |
| 161 | + "hash": "6d121a82cc83fe31", | |
| 162 | + "n": 3000, | |
| 163 | + "seed": 20261111 | |
| 164 | + }, | |
| 165 | + "target_iid": { | |
| 166 | + "generator": "opseq@opseq-1.0", | |
| 167 | + "hash": "88d9bb27db961222", | |
| 168 | + "n": 300, | |
| 169 | + "seed": 20261119 | |
| 170 | + } | |
| 171 | + }, | |
| 172 | + "experiment_id": "pilot_tier0_opseq_quick", | |
| 173 | + "git": { | |
| 174 | + "branch": null, | |
| 175 | + "commit": null, | |
| 176 | + "dirty": null | |
| 177 | + }, | |
| 178 | + "hardware": { | |
| 179 | + "chip": "Apple M5 Max", | |
| 180 | + "cpu_count": 18, | |
| 181 | + "hostname_hash": "9ad7358c662e", | |
| 182 | + "machine": "arm64", | |
| 183 | + "memory_gb": 48.0, | |
| 184 | + "platform": "macOS-27.0-arm64-arm-64bit-Mach-O", | |
| 185 | + "torch_cuda": false, | |
| 186 | + "torch_mps": true | |
| 187 | + }, | |
| 188 | + "history": [ | |
| 189 | + { | |
| 190 | + "note": "", | |
| 191 | + "status": "running", | |
| 192 | + "utc": "2026-11-09T06:49:09+00:00" | |
| 193 | + }, | |
| 194 | + { | |
| 195 | + "note": "", | |
| 196 | + "status": "completed", | |
| 197 | + "utc": "2026-11-09T06:49:31+00:00" | |
| 198 | + } | |
| 199 | + ], | |
| 200 | + "interpretation": "", | |
| 201 | + "libraries": { | |
| 202 | + "mlx": "?", | |
| 203 | + "mlx_lm": "0.31.3", | |
| 204 | + "numpy": "2.4.4", | |
| 205 | + "pydantic": "2.13.4", | |
| 206 | + "python": "3.14.4", | |
| 207 | + "safetensors": "0.7.0", | |
| 208 | + "scipy": "1.17.1", | |
| 209 | + "torch": "2.12.0", | |
| 210 | + "transformers": "5.8.1" | |
| 211 | + }, | |
| 212 | + "outputs": { | |
| 213 | + "figures": "artifacts/figures/pilot_tier0_opseq_quick_d5339bcad6b3", | |
| 214 | + "items": "artifacts/runs/pilot_tier0_opseq_quick_d5339bcad6b3", | |
| 215 | + "models": "artifacts/models/pilot_tier0_opseq_quick_d5339bcad6b3", | |
| 216 | + "results": "experiments/summaries/pilot_tier0_opseq_quick_d5339bcad6b3/results.json" | |
| 217 | + }, | |
| 218 | + "run_id": "pilot_tier0_opseq_quick_d5339bcad6b3", | |
| 219 | + "seeds": {}, | |
| 220 | + "status": "completed", | |
| 221 | + "warnings": [] | |
| 222 | +} | |
| \ No newline at end of file | ||
added
experiments/registry/runs.jsonl
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +{"config_hash": "d5339bcad6b3", "experiment_id": "pilot_tier0_opseq_quick", "run_id": "pilot_tier0_opseq_quick_d5339bcad6b3", "status": "planned", "utc": "2026-11-09T06:49:09+00:00"} | |
| 2 | +{"experiment_id": "pilot_tier0_opseq_quick", "run_id": "pilot_tier0_opseq_quick_d5339bcad6b3", "status": "running", "utc": "2026-11-09T06:49:09+00:00"} | |
| 3 | +{"experiment_id": "pilot_tier0_opseq_quick", "results": "experiments/summaries/pilot_tier0_opseq_quick_d5339bcad6b3/results.json", "run_id": "pilot_tier0_opseq_quick_d5339bcad6b3", "status": "completed", "utc": "2026-11-09T06:49:31+00:00"} | |
| 4 | +{"config_hash": "451ef5087182", "experiment_id": "pilot_tier0_opseq", "run_id": "pilot_tier0_opseq_451ef5087182", "status": "planned", "utc": "2026-11-09T06:49:37+00:00"} | |
| 5 | +{"experiment_id": "pilot_tier0_opseq", "run_id": "pilot_tier0_opseq_451ef5087182", "status": "running", "utc": "2026-11-09T06:49:38+00:00"} | |
| 6 | +{"experiment_id": "pilot_tier0_opseq", "results": "experiments/summaries/pilot_tier0_opseq_451ef5087182/results.json", "run_id": "pilot_tier0_opseq_451ef5087182", "status": "completed", "utc": "2026-11-09T06:54:13+00:00"} | |
added
experiments/summaries/pilot_tier0_opseq_451ef5087182/SUMMARY.md
+44 −0
@@ -0,0 +1,44 @@ | ||
| 1 | +# Pilot summary — pilot_tier0_opseq_451ef5087182 | |
| 2 | + | |
| 3 | +Generated 2026-11-09T06:54:13+00:00 on device `mps`; config hash `451ef5087182`; seeds [0, 1, 2]. | |
| 4 | + | |
| 5 | +## Gate B — donor/recipient gap (final-answer exact match, mean over seeds; CI = cluster bootstrap on programs) | |
| 6 | + | |
| 7 | +| split | chance | donor mean (sd) | recipient mean (sd) | paired gap seed 0 [95% CI] | | |
| 8 | +|---|---|---|---|---| | |
| 9 | +| target_iid | 0.105 | 1.000 (0.000) | 0.092 (0.053) | +0.847 [+0.825, +0.870] | | |
| 10 | +| control_iid | 0.129 | 1.000 (0.000) | 1.000 (0.000) | +0.000 [+0.000, +0.000] | | |
| 11 | +| comp_heldout | 0.110 | 1.000 (0.000) | 0.450 (0.032) | +0.513 [+0.468, +0.560] | | |
| 12 | +| len_ood | 0.140 | 0.086 (0.017) | 0.091 (0.016) | -0.002 [-0.034, +0.032] | | |
| 13 | + | |
| 14 | +Ω-step accuracy on target_iid (token emitted at the first Ω step): donor 1.000, recipient 0.062. | |
| 15 | + | |
| 16 | +## Gate C — hook no-op checks (bitwise equality of logits on 256 dev items) | |
| 17 | + | |
| 18 | +| model | repeat | capture-all | disabled hook | enabled zero hook changes output | | |
| 19 | +|---|---|---|---|---| | |
| 20 | +| donor_s0 | True | True | True | True | | |
| 21 | +| recipient_s0 | True | True | True | True | | |
| 22 | +| donor_s1 | True | True | True | True | | |
| 23 | +| recipient_s1 | True | True | True | True | | |
| 24 | +| donor_s2 | True | True | True | True | | |
| 25 | +| recipient_s2 | True | True | True | True | | |
| 26 | + | |
| 27 | +## RQ1 — within-donor localization of Ω (n = 490 clean/corrupt pairs, read position = r1, predicting r2) | |
| 28 | + | |
| 29 | +Baselines: s0: clean 1.000, sham (corrupt run scored on clean answer) 0.000; s1: clean 1.000, sham (corrupt run scored on clean answer) 0.000; s2: clean 1.000, sham (corrupt run scored on clean answer) 0.000 | |
| 30 | + | |
| 31 | +Mean restored-answer rate after patching the clean activation into the corrupted run (rows = layers, columns = positions <bos>, v0, op1, Ω, op3, =, r1): | |
| 32 | + | |
| 33 | +- `resid_post`: L0: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | L1: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | L2: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | L3: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | |
| 34 | +- `attn_out`: L0: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | L1: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 | L2: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 | L3: 0.00 0.00 0.00 0.00 0.00 0.00 0.00 | |
| 35 | +- `mlp_out`: L0: 0.00 0.00 0.00 0.00 0.00 0.00 1.00 | L1: 0.00 0.00 0.00 0.00 0.00 0.00 0.90 | L2: 0.00 0.00 0.00 0.00 0.00 0.00 0.83 | L3: 0.00 0.00 0.00 0.00 0.00 0.00 0.17 | |
| 36 | + | |
| 37 | +Reproducibility: resid_post_s0_repeat_max_abs_diff = 0.0000; attn_out_s0_repeat_max_abs_diff = 0.0000; mlp_out_s0_repeat_max_abs_diff = 0.0000; resid_post_s1_repeat_max_abs_diff = 0.0000; attn_out_s1_repeat_max_abs_diff = 0.0000; mlp_out_s1_repeat_max_abs_diff = 0.0000; resid_post_s2_repeat_max_abs_diff = 0.0000; attn_out_s2_repeat_max_abs_diff = 0.0000; mlp_out_s2_repeat_max_abs_diff = 0.0000; resid_post_across_seed_pearson_min = 1.0000; attn_out_across_seed_pearson_min = 1.0000; mlp_out_across_seed_pearson_min = 0.9642 | |
| 38 | + | |
| 39 | +Figures: `fig_gap_tier0.pdf`, `fig_localization_ablation_tier0.pdf`, `fig_localization_heads_tier0.pdf`, `fig_localization_patching_tier0.pdf` | |
| 40 | + | |
| 41 | +## Interpretation (observed vs. speculative) | |
| 42 | + | |
| 43 | +Observed: the numbers above are produced by the artifacts listed in the manifest. Any statement about *transfer* is out of scope for this run: no transplant was performed. | |
| 44 | +Speculative: whether the localized positions/layers constitute a transferable 'organ' is the object of the next experiment (activation graft with sham/random controls). | |
added
experiments/summaries/pilot_tier0_opseq_451ef5087182/results.json
+2303 −0
@@ -0,0 +1,2303 @@ | ||
| 1 | +{ | |
| 2 | + "run_id": "pilot_tier0_opseq_451ef5087182", | |
| 3 | + "config_hash": "451ef5087182", | |
| 4 | + "device": "mps", | |
| 5 | + "chance_level": { | |
| 6 | + "target_iid": 0.105, | |
| 7 | + "control_iid": 0.129, | |
| 8 | + "comp_heldout": 0.11, | |
| 9 | + "len_ood": 0.14 | |
| 10 | + }, | |
| 11 | + "seeds": { | |
| 12 | + "0": { | |
| 13 | + "donor": { | |
| 14 | + "n_params": 800000, | |
| 15 | + "train_seconds": 45.07666206359863, | |
| 16 | + "final_dev": { | |
| 17 | + "step": 3000, | |
| 18 | + "loss": 1.4056669606077321e-08, | |
| 19 | + "dev_acc": 1.0, | |
| 20 | + "dev_trace_acc": 1.0, | |
| 21 | + "lr": 0.0, | |
| 22 | + "elapsed_s": 44.99317193031311 | |
| 23 | + }, | |
| 24 | + "eval": { | |
| 25 | + "target_iid": { | |
| 26 | + "split": "target_iid", | |
| 27 | + "split_hash": "f1a1ef205c8f35db", | |
| 28 | + "n": 1000, | |
| 29 | + "accuracy": 1.0, | |
| 30 | + "trace_accuracy": 1.0, | |
| 31 | + "ci95": { | |
| 32 | + "estimate": 1.0, | |
| 33 | + "low": 1.0, | |
| 34 | + "high": 1.0, | |
| 35 | + "level": 0.95, | |
| 36 | + "n_items": 1000, | |
| 37 | + "n_clusters": 944, | |
| 38 | + "n_boot": 2000 | |
| 39 | + }, | |
| 40 | + "omega_step_acc": { | |
| 41 | + "estimate": 1.0, | |
| 42 | + "low": 1.0, | |
| 43 | + "high": 1.0, | |
| 44 | + "level": 0.95, | |
| 45 | + "n_items": 1000, | |
| 46 | + "n_clusters": 944, | |
| 47 | + "n_boot": 2000 | |
| 48 | + }, | |
| 49 | + "chance": 0.105 | |
| 50 | + }, | |
| 51 | + "control_iid": { | |
| 52 | + "split": "control_iid", | |
| 53 | + "split_hash": "fa7c2327072b7d56", | |
| 54 | + "n": 1000, | |
| 55 | + "accuracy": 1.0, | |
| 56 | + "trace_accuracy": 1.0, | |
| 57 | + "ci95": { | |
| 58 | + "estimate": 1.0, | |
| 59 | + "low": 1.0, | |
| 60 | + "high": 1.0, | |
| 61 | + "level": 0.95, | |
| 62 | + "n_items": 1000, | |
| 63 | + "n_clusters": 970, | |
| 64 | + "n_boot": 2000 | |
| 65 | + }, | |
| 66 | + "omega_step_acc": null, | |
| 67 | + "chance": 0.129 | |
| 68 | + }, | |
| 69 | + "comp_heldout": { | |
| 70 | + "split": "comp_heldout", | |
| 71 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 72 | + "n": 1000, | |
| 73 | + "accuracy": 1.0, | |
| 74 | + "trace_accuracy": 1.0, | |
| 75 | + "ci95": { | |
| 76 | + "estimate": 1.0, | |
| 77 | + "low": 1.0, | |
| 78 | + "high": 1.0, | |
| 79 | + "level": 0.95, | |
| 80 | + "n_items": 1000, | |
| 81 | + "n_clusters": 681, | |
| 82 | + "n_boot": 2000 | |
| 83 | + }, | |
| 84 | + "omega_step_acc": { | |
| 85 | + "estimate": 1.0, | |
| 86 | + "low": 1.0, | |
| 87 | + "high": 1.0, | |
| 88 | + "level": 0.95, | |
| 89 | + "n_items": 592, | |
| 90 | + "n_clusters": 420, | |
| 91 | + "n_boot": 2000 | |
| 92 | + }, | |
| 93 | + "chance": 0.11 | |
| 94 | + }, | |
| 95 | + "len_ood": { | |
| 96 | + "split": "len_ood", | |
| 97 | + "split_hash": "7ecb075ac45796ac", | |
| 98 | + "n": 500, | |
| 99 | + "accuracy": 0.076, | |
| 100 | + "trace_accuracy": 0.0, | |
| 101 | + "ci95": { | |
| 102 | + "estimate": 0.076, | |
| 103 | + "low": 0.054, | |
| 104 | + "high": 0.1, | |
| 105 | + "level": 0.95, | |
| 106 | + "n_items": 500, | |
| 107 | + "n_clusters": 500, | |
| 108 | + "n_boot": 2000 | |
| 109 | + }, | |
| 110 | + "omega_step_acc": { | |
| 111 | + "estimate": 0.09830508474576272, | |
| 112 | + "low": 0.06440677966101695, | |
| 113 | + "high": 0.13220338983050847, | |
| 114 | + "level": 0.95, | |
| 115 | + "n_items": 295, | |
| 116 | + "n_clusters": 295, | |
| 117 | + "n_boot": 2000 | |
| 118 | + }, | |
| 119 | + "chance": 0.14 | |
| 120 | + } | |
| 121 | + } | |
| 122 | + }, | |
| 123 | + "recipient": { | |
| 124 | + "n_params": 800000, | |
| 125 | + "train_seconds": 44.30060911178589, | |
| 126 | + "final_dev": { | |
| 127 | + "step": 3000, | |
| 128 | + "loss": 6.440794120265991e-09, | |
| 129 | + "dev_acc": 1.0, | |
| 130 | + "dev_trace_acc": 1.0, | |
| 131 | + "lr": 0.0, | |
| 132 | + "elapsed_s": 44.22483992576599 | |
| 133 | + }, | |
| 134 | + "eval": { | |
| 135 | + "target_iid": { | |
| 136 | + "split": "target_iid", | |
| 137 | + "split_hash": "f1a1ef205c8f35db", | |
| 138 | + "n": 1000, | |
| 139 | + "accuracy": 0.153, | |
| 140 | + "trace_accuracy": 0.11, | |
| 141 | + "ci95": { | |
| 142 | + "estimate": 0.153, | |
| 143 | + "low": 0.13021422874046046, | |
| 144 | + "high": 0.17482830290981383, | |
| 145 | + "level": 0.95, | |
| 146 | + "n_items": 1000, | |
| 147 | + "n_clusters": 944, | |
| 148 | + "n_boot": 2000 | |
| 149 | + }, | |
| 150 | + "omega_step_acc": { | |
| 151 | + "estimate": 0.142, | |
| 152 | + "low": 0.12102406103286387, | |
| 153 | + "high": 0.16371086200231927, | |
| 154 | + "level": 0.95, | |
| 155 | + "n_items": 1000, | |
| 156 | + "n_clusters": 944, | |
| 157 | + "n_boot": 2000 | |
| 158 | + }, | |
| 159 | + "chance": 0.105 | |
| 160 | + }, | |
| 161 | + "control_iid": { | |
| 162 | + "split": "control_iid", | |
| 163 | + "split_hash": "fa7c2327072b7d56", | |
| 164 | + "n": 1000, | |
| 165 | + "accuracy": 1.0, | |
| 166 | + "trace_accuracy": 1.0, | |
| 167 | + "ci95": { | |
| 168 | + "estimate": 1.0, | |
| 169 | + "low": 1.0, | |
| 170 | + "high": 1.0, | |
| 171 | + "level": 0.95, | |
| 172 | + "n_items": 1000, | |
| 173 | + "n_clusters": 970, | |
| 174 | + "n_boot": 2000 | |
| 175 | + }, | |
| 176 | + "omega_step_acc": null, | |
| 177 | + "chance": 0.129 | |
| 178 | + }, | |
| 179 | + "comp_heldout": { | |
| 180 | + "split": "comp_heldout", | |
| 181 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 182 | + "n": 1000, | |
| 183 | + "accuracy": 0.487, | |
| 184 | + "trace_accuracy": 0.466, | |
| 185 | + "ci95": { | |
| 186 | + "estimate": 0.487, | |
| 187 | + "low": 0.4403249441330549, | |
| 188 | + "high": 0.5318091451292246, | |
| 189 | + "level": 0.95, | |
| 190 | + "n_items": 1000, | |
| 191 | + "n_clusters": 681, | |
| 192 | + "n_boot": 2000 | |
| 193 | + }, | |
| 194 | + "omega_step_acc": { | |
| 195 | + "estimate": 0.13006756756756757, | |
| 196 | + "low": 0.10363636363636364, | |
| 197 | + "high": 0.15476609657947685, | |
| 198 | + "level": 0.95, | |
| 199 | + "n_items": 592, | |
| 200 | + "n_clusters": 420, | |
| 201 | + "n_boot": 2000 | |
| 202 | + }, | |
| 203 | + "chance": 0.11 | |
| 204 | + }, | |
| 205 | + "len_ood": { | |
| 206 | + "split": "len_ood", | |
| 207 | + "split_hash": "7ecb075ac45796ac", | |
| 208 | + "n": 500, | |
| 209 | + "accuracy": 0.078, | |
| 210 | + "trace_accuracy": 0.0, | |
| 211 | + "ci95": { | |
| 212 | + "estimate": 0.078, | |
| 213 | + "low": 0.054, | |
| 214 | + "high": 0.102, | |
| 215 | + "level": 0.95, | |
| 216 | + "n_items": 500, | |
| 217 | + "n_clusters": 500, | |
| 218 | + "n_boot": 2000 | |
| 219 | + }, | |
| 220 | + "omega_step_acc": { | |
| 221 | + "estimate": 0.11186440677966102, | |
| 222 | + "low": 0.07796610169491526, | |
| 223 | + "high": 0.14576271186440679, | |
| 224 | + "level": 0.95, | |
| 225 | + "n_items": 295, | |
| 226 | + "n_clusters": 295, | |
| 227 | + "n_boot": 2000 | |
| 228 | + }, | |
| 229 | + "chance": 0.14 | |
| 230 | + } | |
| 231 | + } | |
| 232 | + }, | |
| 233 | + "gap": { | |
| 234 | + "target_iid": { | |
| 235 | + "estimate": 0.847, | |
| 236 | + "low": 0.8251716970901862, | |
| 237 | + "high": 0.8697857712595395, | |
| 238 | + "level": 0.95, | |
| 239 | + "n_items": 1000, | |
| 240 | + "n_clusters": 944, | |
| 241 | + "n_boot": 2000 | |
| 242 | + }, | |
| 243 | + "control_iid": { | |
| 244 | + "estimate": 0.0, | |
| 245 | + "low": 0.0, | |
| 246 | + "high": 0.0, | |
| 247 | + "level": 0.95, | |
| 248 | + "n_items": 1000, | |
| 249 | + "n_clusters": 970, | |
| 250 | + "n_boot": 2000 | |
| 251 | + }, | |
| 252 | + "comp_heldout": { | |
| 253 | + "estimate": 0.513, | |
| 254 | + "low": 0.46819085487077533, | |
| 255 | + "high": 0.5596750558669451, | |
| 256 | + "level": 0.95, | |
| 257 | + "n_items": 1000, | |
| 258 | + "n_clusters": 681, | |
| 259 | + "n_boot": 2000 | |
| 260 | + }, | |
| 261 | + "len_ood": { | |
| 262 | + "estimate": -0.002, | |
| 263 | + "low": -0.034, | |
| 264 | + "high": 0.032, | |
| 265 | + "level": 0.95, | |
| 266 | + "n_items": 500, | |
| 267 | + "n_clusters": 500, | |
| 268 | + "n_boot": 2000 | |
| 269 | + } | |
| 270 | + } | |
| 271 | + }, | |
| 272 | + "1": { | |
| 273 | + "donor": { | |
| 274 | + "n_params": 800000, | |
| 275 | + "train_seconds": 44.552977085113525, | |
| 276 | + "final_dev": { | |
| 277 | + "step": 3000, | |
| 278 | + "loss": 2.2240537189688325e-10, | |
| 279 | + "dev_acc": 1.0, | |
| 280 | + "dev_trace_acc": 1.0, | |
| 281 | + "lr": 0.0, | |
| 282 | + "elapsed_s": 44.468523025512695 | |
| 283 | + }, | |
| 284 | + "eval": { | |
| 285 | + "target_iid": { | |
| 286 | + "split": "target_iid", | |
| 287 | + "split_hash": "f1a1ef205c8f35db", | |
| 288 | + "n": 1000, | |
| 289 | + "accuracy": 1.0, | |
| 290 | + "trace_accuracy": 1.0, | |
| 291 | + "ci95": { | |
| 292 | + "estimate": 1.0, | |
| 293 | + "low": 1.0, | |
| 294 | + "high": 1.0, | |
| 295 | + "level": 0.95, | |
| 296 | + "n_items": 1000, | |
| 297 | + "n_clusters": 944, | |
| 298 | + "n_boot": 2000 | |
| 299 | + }, | |
| 300 | + "omega_step_acc": { | |
| 301 | + "estimate": 1.0, | |
| 302 | + "low": 1.0, | |
| 303 | + "high": 1.0, | |
| 304 | + "level": 0.95, | |
| 305 | + "n_items": 1000, | |
| 306 | + "n_clusters": 944, | |
| 307 | + "n_boot": 2000 | |
| 308 | + }, | |
| 309 | + "chance": 0.105 | |
| 310 | + }, | |
| 311 | + "control_iid": { | |
| 312 | + "split": "control_iid", | |
| 313 | + "split_hash": "fa7c2327072b7d56", | |
| 314 | + "n": 1000, | |
| 315 | + "accuracy": 1.0, | |
| 316 | + "trace_accuracy": 1.0, | |
| 317 | + "ci95": { | |
| 318 | + "estimate": 1.0, | |
| 319 | + "low": 1.0, | |
| 320 | + "high": 1.0, | |
| 321 | + "level": 0.95, | |
| 322 | + "n_items": 1000, | |
| 323 | + "n_clusters": 970, | |
| 324 | + "n_boot": 2000 | |
| 325 | + }, | |
| 326 | + "omega_step_acc": null, | |
| 327 | + "chance": 0.129 | |
| 328 | + }, | |
| 329 | + "comp_heldout": { | |
| 330 | + "split": "comp_heldout", | |
| 331 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 332 | + "n": 1000, | |
| 333 | + "accuracy": 1.0, | |
| 334 | + "trace_accuracy": 1.0, | |
| 335 | + "ci95": { | |
| 336 | + "estimate": 1.0, | |
| 337 | + "low": 1.0, | |
| 338 | + "high": 1.0, | |
| 339 | + "level": 0.95, | |
| 340 | + "n_items": 1000, | |
| 341 | + "n_clusters": 681, | |
| 342 | + "n_boot": 2000 | |
| 343 | + }, | |
| 344 | + "omega_step_acc": { | |
| 345 | + "estimate": 1.0, | |
| 346 | + "low": 1.0, | |
| 347 | + "high": 1.0, | |
| 348 | + "level": 0.95, | |
| 349 | + "n_items": 592, | |
| 350 | + "n_clusters": 420, | |
| 351 | + "n_boot": 2000 | |
| 352 | + }, | |
| 353 | + "chance": 0.11 | |
| 354 | + }, | |
| 355 | + "len_ood": { | |
| 356 | + "split": "len_ood", | |
| 357 | + "split_hash": "7ecb075ac45796ac", | |
| 358 | + "n": 500, | |
| 359 | + "accuracy": 0.076, | |
| 360 | + "trace_accuracy": 0.0, | |
| 361 | + "ci95": { | |
| 362 | + "estimate": 0.076, | |
| 363 | + "low": 0.054, | |
| 364 | + "high": 0.1, | |
| 365 | + "level": 0.95, | |
| 366 | + "n_items": 500, | |
| 367 | + "n_clusters": 500, | |
| 368 | + "n_boot": 2000 | |
| 369 | + }, | |
| 370 | + "omega_step_acc": { | |
| 371 | + "estimate": 0.16271186440677965, | |
| 372 | + "low": 0.12203389830508475, | |
| 373 | + "high": 0.20677966101694914, | |
| 374 | + "level": 0.95, | |
| 375 | + "n_items": 295, | |
| 376 | + "n_clusters": 295, | |
| 377 | + "n_boot": 2000 | |
| 378 | + }, | |
| 379 | + "chance": 0.14 | |
| 380 | + } | |
| 381 | + } | |
| 382 | + }, | |
| 383 | + "recipient": { | |
| 384 | + "n_params": 800000, | |
| 385 | + "train_seconds": 44.89582920074463, | |
| 386 | + "final_dev": { | |
| 387 | + "step": 3000, | |
| 388 | + "loss": 2.1306395536768719e-10, | |
| 389 | + "dev_acc": 1.0, | |
| 390 | + "dev_trace_acc": 1.0, | |
| 391 | + "lr": 0.0, | |
| 392 | + "elapsed_s": 44.8197238445282 | |
| 393 | + }, | |
| 394 | + "eval": { | |
| 395 | + "target_iid": { | |
| 396 | + "split": "target_iid", | |
| 397 | + "split_hash": "f1a1ef205c8f35db", | |
| 398 | + "n": 1000, | |
| 399 | + "accuracy": 0.064, | |
| 400 | + "trace_accuracy": 0.024, | |
| 401 | + "ci95": { | |
| 402 | + "estimate": 0.064, | |
| 403 | + "low": 0.04909696770919216, | |
| 404 | + "high": 0.07923771313941826, | |
| 405 | + "level": 0.95, | |
| 406 | + "n_items": 1000, | |
| 407 | + "n_clusters": 944, | |
| 408 | + "n_boot": 2000 | |
| 409 | + }, | |
| 410 | + "omega_step_acc": { | |
| 411 | + "estimate": 0.026, | |
| 412 | + "low": 0.01693227091633466, | |
| 413 | + "high": 0.03625377643504532, | |
| 414 | + "level": 0.95, | |
| 415 | + "n_items": 1000, | |
| 416 | + "n_clusters": 944, | |
| 417 | + "n_boot": 2000 | |
| 418 | + }, | |
| 419 | + "chance": 0.105 | |
| 420 | + }, | |
| 421 | + "control_iid": { | |
| 422 | + "split": "control_iid", | |
| 423 | + "split_hash": "fa7c2327072b7d56", | |
| 424 | + "n": 1000, | |
| 425 | + "accuracy": 1.0, | |
| 426 | + "trace_accuracy": 1.0, | |
| 427 | + "ci95": { | |
| 428 | + "estimate": 1.0, | |
| 429 | + "low": 1.0, | |
| 430 | + "high": 1.0, | |
| 431 | + "level": 0.95, | |
| 432 | + "n_items": 1000, | |
| 433 | + "n_clusters": 970, | |
| 434 | + "n_boot": 2000 | |
| 435 | + }, | |
| 436 | + "omega_step_acc": null, | |
| 437 | + "chance": 0.129 | |
| 438 | + }, | |
| 439 | + "comp_heldout": { | |
| 440 | + "split": "comp_heldout", | |
| 441 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 442 | + "n": 1000, | |
| 443 | + "accuracy": 0.435, | |
| 444 | + "trace_accuracy": 0.421, | |
| 445 | + "ci95": { | |
| 446 | + "estimate": 0.435, | |
| 447 | + "low": 0.38675184162062615, | |
| 448 | + "high": 0.48358677815112916, | |
| 449 | + "level": 0.95, | |
| 450 | + "n_items": 1000, | |
| 451 | + "n_clusters": 681, | |
| 452 | + "n_boot": 2000 | |
| 453 | + }, | |
| 454 | + "omega_step_acc": { | |
| 455 | + "estimate": 0.02364864864864865, | |
| 456 | + "low": 0.01279649114613219, | |
| 457 | + "high": 0.035415924087713664, | |
| 458 | + "level": 0.95, | |
| 459 | + "n_items": 592, | |
| 460 | + "n_clusters": 420, | |
| 461 | + "n_boot": 2000 | |
| 462 | + }, | |
| 463 | + "chance": 0.11 | |
| 464 | + }, | |
| 465 | + "len_ood": { | |
| 466 | + "split": "len_ood", | |
| 467 | + "split_hash": "7ecb075ac45796ac", | |
| 468 | + "n": 500, | |
| 469 | + "accuracy": 0.086, | |
| 470 | + "trace_accuracy": 0.0, | |
| 471 | + "ci95": { | |
| 472 | + "estimate": 0.086, | |
| 473 | + "low": 0.062, | |
| 474 | + "high": 0.11004999999999973, | |
| 475 | + "level": 0.95, | |
| 476 | + "n_items": 500, | |
| 477 | + "n_clusters": 500, | |
| 478 | + "n_boot": 2000 | |
| 479 | + }, | |
| 480 | + "omega_step_acc": { | |
| 481 | + "estimate": 0.0711864406779661, | |
| 482 | + "low": 0.04406779661016949, | |
| 483 | + "high": 0.1016949152542373, | |
| 484 | + "level": 0.95, | |
| 485 | + "n_items": 295, | |
| 486 | + "n_clusters": 295, | |
| 487 | + "n_boot": 2000 | |
| 488 | + }, | |
| 489 | + "chance": 0.14 | |
| 490 | + } | |
| 491 | + } | |
| 492 | + }, | |
| 493 | + "gap": { | |
| 494 | + "target_iid": { | |
| 495 | + "estimate": 0.936, | |
| 496 | + "low": 0.9207622868605817, | |
| 497 | + "high": 0.9509030322908079, | |
| 498 | + "level": 0.95, | |
| 499 | + "n_items": 1000, | |
| 500 | + "n_clusters": 944, | |
| 501 | + "n_boot": 2000 | |
| 502 | + }, | |
| 503 | + "control_iid": { | |
| 504 | + "estimate": 0.0, | |
| 505 | + "low": 0.0, | |
| 506 | + "high": 0.0, | |
| 507 | + "level": 0.95, | |
| 508 | + "n_items": 1000, | |
| 509 | + "n_clusters": 970, | |
| 510 | + "n_boot": 2000 | |
| 511 | + }, | |
| 512 | + "comp_heldout": { | |
| 513 | + "estimate": 0.565, | |
| 514 | + "low": 0.5164132218488708, | |
| 515 | + "high": 0.6132481583793739, | |
| 516 | + "level": 0.95, | |
| 517 | + "n_items": 1000, | |
| 518 | + "n_clusters": 681, | |
| 519 | + "n_boot": 2000 | |
| 520 | + }, | |
| 521 | + "len_ood": { | |
| 522 | + "estimate": -0.01, | |
| 523 | + "low": -0.044, | |
| 524 | + "high": 0.02, | |
| 525 | + "level": 0.95, | |
| 526 | + "n_items": 500, | |
| 527 | + "n_clusters": 500, | |
| 528 | + "n_boot": 2000 | |
| 529 | + } | |
| 530 | + } | |
| 531 | + }, | |
| 532 | + "2": { | |
| 533 | + "donor": { | |
| 534 | + "n_params": 800000, | |
| 535 | + "train_seconds": 44.78438401222229, | |
| 536 | + "final_dev": { | |
| 537 | + "step": 3000, | |
| 538 | + "loss": 0.0, | |
| 539 | + "dev_acc": 1.0, | |
| 540 | + "dev_trace_acc": 1.0, | |
| 541 | + "lr": 0.0, | |
| 542 | + "elapsed_s": 44.687108755111694 | |
| 543 | + }, | |
| 544 | + "eval": { | |
| 545 | + "target_iid": { | |
| 546 | + "split": "target_iid", | |
| 547 | + "split_hash": "f1a1ef205c8f35db", | |
| 548 | + "n": 1000, | |
| 549 | + "accuracy": 1.0, | |
| 550 | + "trace_accuracy": 1.0, | |
| 551 | + "ci95": { | |
| 552 | + "estimate": 1.0, | |
| 553 | + "low": 1.0, | |
| 554 | + "high": 1.0, | |
| 555 | + "level": 0.95, | |
| 556 | + "n_items": 1000, | |
| 557 | + "n_clusters": 944, | |
| 558 | + "n_boot": 2000 | |
| 559 | + }, | |
| 560 | + "omega_step_acc": { | |
| 561 | + "estimate": 1.0, | |
| 562 | + "low": 1.0, | |
| 563 | + "high": 1.0, | |
| 564 | + "level": 0.95, | |
| 565 | + "n_items": 1000, | |
| 566 | + "n_clusters": 944, | |
| 567 | + "n_boot": 2000 | |
| 568 | + }, | |
| 569 | + "chance": 0.105 | |
| 570 | + }, | |
| 571 | + "control_iid": { | |
| 572 | + "split": "control_iid", | |
| 573 | + "split_hash": "fa7c2327072b7d56", | |
| 574 | + "n": 1000, | |
| 575 | + "accuracy": 1.0, | |
| 576 | + "trace_accuracy": 1.0, | |
| 577 | + "ci95": { | |
| 578 | + "estimate": 1.0, | |
| 579 | + "low": 1.0, | |
| 580 | + "high": 1.0, | |
| 581 | + "level": 0.95, | |
| 582 | + "n_items": 1000, | |
| 583 | + "n_clusters": 970, | |
| 584 | + "n_boot": 2000 | |
| 585 | + }, | |
| 586 | + "omega_step_acc": null, | |
| 587 | + "chance": 0.129 | |
| 588 | + }, | |
| 589 | + "comp_heldout": { | |
| 590 | + "split": "comp_heldout", | |
| 591 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 592 | + "n": 1000, | |
| 593 | + "accuracy": 1.0, | |
| 594 | + "trace_accuracy": 1.0, | |
| 595 | + "ci95": { | |
| 596 | + "estimate": 1.0, | |
| 597 | + "low": 1.0, | |
| 598 | + "high": 1.0, | |
| 599 | + "level": 0.95, | |
| 600 | + "n_items": 1000, | |
| 601 | + "n_clusters": 681, | |
| 602 | + "n_boot": 2000 | |
| 603 | + }, | |
| 604 | + "omega_step_acc": { | |
| 605 | + "estimate": 1.0, | |
| 606 | + "low": 1.0, | |
| 607 | + "high": 1.0, | |
| 608 | + "level": 0.95, | |
| 609 | + "n_items": 592, | |
| 610 | + "n_clusters": 420, | |
| 611 | + "n_boot": 2000 | |
| 612 | + }, | |
| 613 | + "chance": 0.11 | |
| 614 | + }, | |
| 615 | + "len_ood": { | |
| 616 | + "split": "len_ood", | |
| 617 | + "split_hash": "7ecb075ac45796ac", | |
| 618 | + "n": 500, | |
| 619 | + "accuracy": 0.106, | |
| 620 | + "trace_accuracy": 0.0, | |
| 621 | + "ci95": { | |
| 622 | + "estimate": 0.106, | |
| 623 | + "low": 0.08, | |
| 624 | + "high": 0.134, | |
| 625 | + "level": 0.95, | |
| 626 | + "n_items": 500, | |
| 627 | + "n_clusters": 500, | |
| 628 | + "n_boot": 2000 | |
| 629 | + }, | |
| 630 | + "omega_step_acc": { | |
| 631 | + "estimate": 0.15593220338983052, | |
| 632 | + "low": 0.1152542372881356, | |
| 633 | + "high": 0.2, | |
| 634 | + "level": 0.95, | |
| 635 | + "n_items": 295, | |
| 636 | + "n_clusters": 295, | |
| 637 | + "n_boot": 2000 | |
| 638 | + }, | |
| 639 | + "chance": 0.14 | |
| 640 | + } | |
| 641 | + } | |
| 642 | + }, | |
| 643 | + "recipient": { | |
| 644 | + "n_params": 800000, | |
| 645 | + "train_seconds": 43.506938219070435, | |
| 646 | + "final_dev": { | |
| 647 | + "step": 3000, | |
| 648 | + "loss": 7.384645672736667e-10, | |
| 649 | + "dev_acc": 1.0, | |
| 650 | + "dev_trace_acc": 1.0, | |
| 651 | + "lr": 0.0, | |
| 652 | + "elapsed_s": 43.429972887039185 | |
| 653 | + }, | |
| 654 | + "eval": { | |
| 655 | + "target_iid": { | |
| 656 | + "split": "target_iid", | |
| 657 | + "split_hash": "f1a1ef205c8f35db", | |
| 658 | + "n": 1000, | |
| 659 | + "accuracy": 0.059, | |
| 660 | + "trace_accuracy": 0.013, | |
| 661 | + "ci95": { | |
| 662 | + "estimate": 0.059, | |
| 663 | + "low": 0.04481960218826188, | |
| 664 | + "high": 0.07522622322412784, | |
| 665 | + "level": 0.95, | |
| 666 | + "n_items": 1000, | |
| 667 | + "n_clusters": 944, | |
| 668 | + "n_boot": 2000 | |
| 669 | + }, | |
| 670 | + "omega_step_acc": { | |
| 671 | + "estimate": 0.017, | |
| 672 | + "low": 0.009910312626519584, | |
| 673 | + "high": 0.025768726304529074, | |
| 674 | + "level": 0.95, | |
| 675 | + "n_items": 1000, | |
| 676 | + "n_clusters": 944, | |
| 677 | + "n_boot": 2000 | |
| 678 | + }, | |
| 679 | + "chance": 0.105 | |
| 680 | + }, | |
| 681 | + "control_iid": { | |
| 682 | + "split": "control_iid", | |
| 683 | + "split_hash": "fa7c2327072b7d56", | |
| 684 | + "n": 1000, | |
| 685 | + "accuracy": 1.0, | |
| 686 | + "trace_accuracy": 1.0, | |
| 687 | + "ci95": { | |
| 688 | + "estimate": 1.0, | |
| 689 | + "low": 1.0, | |
| 690 | + "high": 1.0, | |
| 691 | + "level": 0.95, | |
| 692 | + "n_items": 1000, | |
| 693 | + "n_clusters": 970, | |
| 694 | + "n_boot": 2000 | |
| 695 | + }, | |
| 696 | + "omega_step_acc": null, | |
| 697 | + "chance": 0.129 | |
| 698 | + }, | |
| 699 | + "comp_heldout": { | |
| 700 | + "split": "comp_heldout", | |
| 701 | + "split_hash": "b1c6aebefbf3a5d5", | |
| 702 | + "n": 1000, | |
| 703 | + "accuracy": 0.429, | |
| 704 | + "trace_accuracy": 0.417, | |
| 705 | + "ci95": { | |
| 706 | + "estimate": 0.429, | |
| 707 | + "low": 0.3773348057922526, | |
| 708 | + "high": 0.47867104972724117, | |
| 709 | + "level": 0.95, | |
| 710 | + "n_items": 1000, | |
| 711 | + "n_clusters": 681, | |
| 712 | + "n_boot": 2000 | |
| 713 | + }, | |
| 714 | + "omega_step_acc": { | |
| 715 | + "estimate": 0.02195945945945946, | |
| 716 | + "low": 0.0105074216501537, | |
| 717 | + "high": 0.03460972052542356, | |
| 718 | + "level": 0.95, | |
| 719 | + "n_items": 592, | |
| 720 | + "n_clusters": 420, | |
| 721 | + "n_boot": 2000 | |
| 722 | + }, | |
| 723 | + "chance": 0.11 | |
| 724 | + }, | |
| 725 | + "len_ood": { | |
| 726 | + "split": "len_ood", | |
| 727 | + "split_hash": "7ecb075ac45796ac", | |
| 728 | + "n": 500, | |
| 729 | + "accuracy": 0.108, | |
| 730 | + "trace_accuracy": 0.0, | |
| 731 | + "ci95": { | |
| 732 | + "estimate": 0.108, | |
| 733 | + "low": 0.082, | |
| 734 | + "high": 0.136, | |
| 735 | + "level": 0.95, | |
| 736 | + "n_items": 500, | |
| 737 | + "n_clusters": 500, | |
| 738 | + "n_boot": 2000 | |
| 739 | + }, | |
| 740 | + "omega_step_acc": { | |
| 741 | + "estimate": 0.08135593220338982, | |
| 742 | + "low": 0.05084745762711865, | |
| 743 | + "high": 0.11186440677966102, | |
| 744 | + "level": 0.95, | |
| 745 | + "n_items": 295, | |
| 746 | + "n_clusters": 295, | |
| 747 | + "n_boot": 2000 | |
| 748 | + }, | |
| 749 | + "chance": 0.14 | |
| 750 | + } | |
| 751 | + } | |
| 752 | + }, | |
| 753 | + "gap": { | |
| 754 | + "target_iid": { | |
| 755 | + "estimate": 0.941, | |
| 756 | + "low": 0.9247737767758721, | |
| 757 | + "high": 0.9551803978117381, | |
| 758 | + "level": 0.95, | |
| 759 | + "n_items": 1000, | |
| 760 | + "n_clusters": 944, | |
| 761 | + "n_boot": 2000 | |
| 762 | + }, | |
| 763 | + "control_iid": { | |
| 764 | + "estimate": 0.0, | |
| 765 | + "low": 0.0, | |
| 766 | + "high": 0.0, | |
| 767 | + "level": 0.95, | |
| 768 | + "n_items": 1000, | |
| 769 | + "n_clusters": 970, | |
| 770 | + "n_boot": 2000 | |
| 771 | + }, | |
| 772 | + "comp_heldout": { | |
| 773 | + "estimate": 0.571, | |
| 774 | + "low": 0.5213289502727588, | |
| 775 | + "high": 0.6226651942077474, | |
| 776 | + "level": 0.95, | |
| 777 | + "n_items": 1000, | |
| 778 | + "n_clusters": 681, | |
| 779 | + "n_boot": 2000 | |
| 780 | + }, | |
| 781 | + "len_ood": { | |
| 782 | + "estimate": -0.002, | |
| 783 | + "low": -0.038, | |
| 784 | + "high": 0.034, | |
| 785 | + "level": 0.95, | |
| 786 | + "n_items": 500, | |
| 787 | + "n_clusters": 500, | |
| 788 | + "n_boot": 2000 | |
| 789 | + } | |
| 790 | + } | |
| 791 | + } | |
| 792 | + }, | |
| 793 | + "noop": { | |
| 794 | + "donor_s0": { | |
| 795 | + "deterministic_repeat": true, | |
| 796 | + "capture_all_bitwise_identity": true, | |
| 797 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 798 | + "enabled_zero_hook_changes_output": true, | |
| 799 | + "n_hook_points": 26, | |
| 800 | + "n_items": 256 | |
| 801 | + }, | |
| 802 | + "recipient_s0": { | |
| 803 | + "deterministic_repeat": true, | |
| 804 | + "capture_all_bitwise_identity": true, | |
| 805 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 806 | + "enabled_zero_hook_changes_output": true, | |
| 807 | + "n_hook_points": 26, | |
| 808 | + "n_items": 256 | |
| 809 | + }, | |
| 810 | + "donor_s1": { | |
| 811 | + "deterministic_repeat": true, | |
| 812 | + "capture_all_bitwise_identity": true, | |
| 813 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 814 | + "enabled_zero_hook_changes_output": true, | |
| 815 | + "n_hook_points": 26, | |
| 816 | + "n_items": 256 | |
| 817 | + }, | |
| 818 | + "recipient_s1": { | |
| 819 | + "deterministic_repeat": true, | |
| 820 | + "capture_all_bitwise_identity": true, | |
| 821 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 822 | + "enabled_zero_hook_changes_output": true, | |
| 823 | + "n_hook_points": 26, | |
| 824 | + "n_items": 256 | |
| 825 | + }, | |
| 826 | + "donor_s2": { | |
| 827 | + "deterministic_repeat": true, | |
| 828 | + "capture_all_bitwise_identity": true, | |
| 829 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 830 | + "enabled_zero_hook_changes_output": true, | |
| 831 | + "n_hook_points": 26, | |
| 832 | + "n_items": 256 | |
| 833 | + }, | |
| 834 | + "recipient_s2": { | |
| 835 | + "deterministic_repeat": true, | |
| 836 | + "capture_all_bitwise_identity": true, | |
| 837 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 838 | + "enabled_zero_hook_changes_output": true, | |
| 839 | + "n_hook_points": 26, | |
| 840 | + "n_items": 256 | |
| 841 | + } | |
| 842 | + }, | |
| 843 | + "localization": { | |
| 844 | + "n_items": 490, | |
| 845 | + "read_position": 6, | |
| 846 | + "positions": [ | |
| 847 | + "<bos>", | |
| 848 | + "v0", | |
| 849 | + "op1", | |
| 850 | + "\u03a9", | |
| 851 | + "op3", | |
| 852 | + "=", | |
| 853 | + "r1" | |
| 854 | + ], | |
| 855 | + "families": { | |
| 856 | + "resid_post": { | |
| 857 | + "s0": { | |
| 858 | + "flip_rate": [ | |
| 859 | + [ | |
| 860 | + 0.0, | |
| 861 | + 0.0, | |
| 862 | + 0.0, | |
| 863 | + 0.0, | |
| 864 | + 0.0, | |
| 865 | + 0.0, | |
| 866 | + 1.0 | |
| 867 | + ], | |
| 868 | + [ | |
| 869 | + 0.0, | |
| 870 | + 0.0, | |
| 871 | + 0.0, | |
| 872 | + 0.0, | |
| 873 | + 0.0, | |
| 874 | + 0.0, | |
| 875 | + 1.0 | |
| 876 | + ], | |
| 877 | + [ | |
| 878 | + 0.0, | |
| 879 | + 0.0, | |
| 880 | + 0.0, | |
| 881 | + 0.0, | |
| 882 | + 0.0, | |
| 883 | + 0.0, | |
| 884 | + 1.0 | |
| 885 | + ], | |
| 886 | + [ | |
| 887 | + 0.0, | |
| 888 | + 0.0, | |
| 889 | + 0.0, | |
| 890 | + 0.0, | |
| 891 | + 0.0, | |
| 892 | + 0.0, | |
| 893 | + 1.0 | |
| 894 | + ] | |
| 895 | + ], | |
| 896 | + "logit_recovery": [ | |
| 897 | + [ | |
| 898 | + 0.0, | |
| 899 | + 0.0, | |
| 900 | + 0.0, | |
| 901 | + -0.0029584874864667654, | |
| 902 | + 0.0002881789696402848, | |
| 903 | + 6.067532467568526e-06, | |
| 904 | + 0.9983479380607605 | |
| 905 | + ], | |
| 906 | + [ | |
| 907 | + 0.0, | |
| 908 | + 0.0, | |
| 909 | + 0.0, | |
| 910 | + -0.000898381054867059, | |
| 911 | + 0.00018582800112199038, | |
| 912 | + -7.255208038259298e-05, | |
| 913 | + 0.9993993639945984 | |
| 914 | + ], | |
| 915 | + [ | |
| 916 | + 0.0, | |
| 917 | + 0.0, | |
| 918 | + 0.0, | |
| 919 | + 7.875546725699678e-05, | |
| 920 | + 6.0847491113236174e-05, | |
| 921 | + -9.433332888875157e-05, | |
| 922 | + 0.9998680949211121 | |
| 923 | + ], | |
| 924 | + [ | |
| 925 | + 0.0, | |
| 926 | + 0.0, | |
| 927 | + 0.0, | |
| 928 | + 0.0, | |
| 929 | + 0.0, | |
| 930 | + 0.0, | |
| 931 | + 1.0 | |
| 932 | + ] | |
| 933 | + ] | |
| 934 | + }, | |
| 935 | + "s1": { | |
| 936 | + "flip_rate": [ | |
| 937 | + [ | |
| 938 | + 0.0, | |
| 939 | + 0.0, | |
| 940 | + 0.0, | |
| 941 | + 0.0, | |
| 942 | + 0.0, | |
| 943 | + 0.0, | |
| 944 | + 1.0 | |
| 945 | + ], | |
| 946 | + [ | |
| 947 | + 0.0, | |
| 948 | + 0.0, | |
| 949 | + 0.0, | |
| 950 | + 0.0, | |
| 951 | + 0.0, | |
| 952 | + 0.0, | |
| 953 | + 1.0 | |
| 954 | + ], | |
| 955 | + [ | |
| 956 | + 0.0, | |
| 957 | + 0.0, | |
| 958 | + 0.0, | |
| 959 | + 0.0, | |
| 960 | + 0.0, | |
| 961 | + 0.0, | |
| 962 | + 1.0 | |
| 963 | + ], | |
| 964 | + [ | |
| 965 | + 0.0, | |
| 966 | + 0.0, | |
| 967 | + 0.0, | |
| 968 | + 0.0, | |
| 969 | + 0.0, | |
| 970 | + 0.0, | |
| 971 | + 1.0 | |
| 972 | + ] | |
| 973 | + ], | |
| 974 | + "logit_recovery": [ | |
| 975 | + [ | |
| 976 | + 0.0, | |
| 977 | + 0.0, | |
| 978 | + 0.0, | |
| 979 | + 0.0004672935465350747, | |
| 980 | + 0.00017617014236748219, | |
| 981 | + -1.2608468047403676e-08, | |
| 982 | + 0.9994205236434937 | |
| 983 | + ], | |
| 984 | + [ | |
| 985 | + 0.0, | |
| 986 | + 0.0, | |
| 987 | + 0.0, | |
| 988 | + 0.00011902503320015967, | |
| 989 | + 8.649702795082703e-05, | |
| 990 | + 4.641553630335693e-07, | |
| 991 | + 0.9994013905525208 | |
| 992 | + ], | |
| 993 | + [ | |
| 994 | + 0.0, | |
| 995 | + 0.0, | |
| 996 | + 0.0, | |
| 997 | + 3.435093822190538e-05, | |
| 998 | + 2.089686404360691e-06, | |
| 999 | + 1.4695291611133143e-05, | |
| 1000 | + 1.0002325773239136 | |
| 1001 | + ], | |
| 1002 | + [ | |
| 1003 | + 0.0, | |
| 1004 | + 0.0, | |
| 1005 | + 0.0, | |
| 1006 | + 0.0, | |
| 1007 | + 0.0, | |
| 1008 | + 0.0, | |
| 1009 | + 1.0 | |
| 1010 | + ] | |
| 1011 | + ] | |
| 1012 | + }, | |
| 1013 | + "s2": { | |
| 1014 | + "flip_rate": [ | |
| 1015 | + [ | |
| 1016 | + 0.0, | |
| 1017 | + 0.0, | |
| 1018 | + 0.0, | |
| 1019 | + 0.0, | |
| 1020 | + 0.0, | |
| 1021 | + 0.0, | |
| 1022 | + 1.0 | |
| 1023 | + ], | |
| 1024 | + [ | |
| 1025 | + 0.0, | |
| 1026 | + 0.0, | |
| 1027 | + 0.0, | |
| 1028 | + 0.0, | |
| 1029 | + 0.0, | |
| 1030 | + 0.0, | |
| 1031 | + 1.0 | |
| 1032 | + ], | |
| 1033 | + [ | |
| 1034 | + 0.0, | |
| 1035 | + 0.0, | |
| 1036 | + 0.0, | |
| 1037 | + 0.0, | |
| 1038 | + 0.0, | |
| 1039 | + 0.0, | |
| 1040 | + 1.0 | |
| 1041 | + ], | |
| 1042 | + [ | |
| 1043 | + 0.0, | |
| 1044 | + 0.0, | |
| 1045 | + 0.0, | |
| 1046 | + 0.0, | |
| 1047 | + 0.0, | |
| 1048 | + 0.0, | |
| 1049 | + 1.0 | |
| 1050 | + ] | |
| 1051 | + ], | |
| 1052 | + "logit_recovery": [ | |
| 1053 | + [ | |
| 1054 | + 0.0, | |
| 1055 | + 0.0, | |
| 1056 | + 0.0, | |
| 1057 | + 0.00033169190282933414, | |
| 1058 | + -4.887258546659723e-05, | |
| 1059 | + 1.5617764574926696e-06, | |
| 1060 | + 1.0001285076141357 | |
| 1061 | + ], | |
| 1062 | + [ | |
| 1063 | + 0.0, | |
| 1064 | + 0.0, | |
| 1065 | + 0.0, | |
| 1066 | + 0.0004198819224257022, | |
| 1067 | + -2.6704077754402533e-05, | |
| 1068 | + 1.01509458545479e-05, | |
| 1069 | + 0.9998666644096375 | |
| 1070 | + ], | |
| 1071 | + [ | |
| 1072 | + 0.0, | |
| 1073 | + 0.0, | |
| 1074 | + 0.0, | |
| 1075 | + 8.019314554985613e-05, | |
| 1076 | + 1.6664354518525215e-07, | |
| 1077 | + -1.2479076758609153e-06, | |
| 1078 | + 1.0002455711364746 | |
| 1079 | + ], | |
| 1080 | + [ | |
| 1081 | + 0.0, | |
| 1082 | + 0.0, | |
| 1083 | + 0.0, | |
| 1084 | + 0.0, | |
| 1085 | + 0.0, | |
| 1086 | + 0.0, | |
| 1087 | + 1.0 | |
| 1088 | + ] | |
| 1089 | + ] | |
| 1090 | + }, | |
| 1091 | + "mean_flip_rate": [ | |
| 1092 | + [ | |
| 1093 | + 0.0, | |
| 1094 | + 0.0, | |
| 1095 | + 0.0, | |
| 1096 | + 0.0, | |
| 1097 | + 0.0, | |
| 1098 | + 0.0, | |
| 1099 | + 1.0 | |
| 1100 | + ], | |
| 1101 | + [ | |
| 1102 | + 0.0, | |
| 1103 | + 0.0, | |
| 1104 | + 0.0, | |
| 1105 | + 0.0, | |
| 1106 | + 0.0, | |
| 1107 | + 0.0, | |
| 1108 | + 1.0 | |
| 1109 | + ], | |
| 1110 | + [ | |
| 1111 | + 0.0, | |
| 1112 | + 0.0, | |
| 1113 | + 0.0, | |
| 1114 | + 0.0, | |
| 1115 | + 0.0, | |
| 1116 | + 0.0, | |
| 1117 | + 1.0 | |
| 1118 | + ], | |
| 1119 | + [ | |
| 1120 | + 0.0, | |
| 1121 | + 0.0, | |
| 1122 | + 0.0, | |
| 1123 | + 0.0, | |
| 1124 | + 0.0, | |
| 1125 | + 0.0, | |
| 1126 | + 1.0 | |
| 1127 | + ] | |
| 1128 | + ] | |
| 1129 | + }, | |
| 1130 | + "attn_out": { | |
| 1131 | + "s0": { | |
| 1132 | + "flip_rate": [ | |
| 1133 | + [ | |
| 1134 | + 0.0, | |
| 1135 | + 0.0, | |
| 1136 | + 0.0, | |
| 1137 | + 0.0, | |
| 1138 | + 0.0, | |
| 1139 | + 0.0, | |
| 1140 | + 1.0 | |
| 1141 | + ], | |
| 1142 | + [ | |
| 1143 | + 0.0, | |
| 1144 | + 0.0, | |
| 1145 | + 0.0, | |
| 1146 | + 0.0, | |
| 1147 | + 0.0, | |
| 1148 | + 0.0, | |
| 1149 | + 0.0 | |
| 1150 | + ], | |
| 1151 | + [ | |
| 1152 | + 0.0, | |
| 1153 | + 0.0, | |
| 1154 | + 0.0, | |
| 1155 | + 0.0, | |
| 1156 | + 0.0, | |
| 1157 | + 0.0, | |
| 1158 | + 0.0 | |
| 1159 | + ], | |
| 1160 | + [ | |
| 1161 | + 0.0, | |
| 1162 | + 0.0, | |
| 1163 | + 0.0, | |
| 1164 | + 0.0, | |
| 1165 | + 0.0, | |
| 1166 | + 0.0, | |
| 1167 | + 0.0 | |
| 1168 | + ] | |
| 1169 | + ], | |
| 1170 | + "logit_recovery": [ | |
| 1171 | + [ | |
| 1172 | + 0.0, | |
| 1173 | + 0.0, | |
| 1174 | + 0.0, | |
| 1175 | + -0.0025477122981101274, | |
| 1176 | + 0.0002881789696402848, | |
| 1177 | + 6.067532467568526e-06, | |
| 1178 | + 0.9983479380607605 | |
| 1179 | + ], | |
| 1180 | + [ | |
| 1181 | + 0.0, | |
| 1182 | + 0.0, | |
| 1183 | + 0.0, | |
| 1184 | + -0.00013427382509689778, | |
| 1185 | + -3.3803276892285794e-05, | |
| 1186 | + -8.034344500629231e-05, | |
| 1187 | + -0.0031254987698048353 | |
| 1188 | + ], | |
| 1189 | + [ | |
| 1190 | + 0.0, | |
| 1191 | + 0.0, | |
| 1192 | + 0.0, | |
| 1193 | + -2.6091085601365194e-05, | |
| 1194 | + 1.4899030247761402e-05, | |
| 1195 | + -4.782400719705038e-05, | |
| 1196 | + -0.005556679796427488 | |
| 1197 | + ], | |
| 1198 | + [ | |
| 1199 | + 0.0, | |
| 1200 | + 0.0, | |
| 1201 | + 0.0, | |
| 1202 | + 0.0, | |
| 1203 | + 0.0, | |
| 1204 | + 0.0, | |
| 1205 | + -0.00683206832036376 | |
| 1206 | + ] | |
| 1207 | + ] | |
| 1208 | + }, | |
| 1209 | + "s1": { | |
| 1210 | + "flip_rate": [ | |
| 1211 | + [ | |
| 1212 | + 0.0, | |
| 1213 | + 0.0, | |
| 1214 | + 0.0, | |
| 1215 | + 0.0, | |
| 1216 | + 0.0, | |
| 1217 | + 0.0, | |
| 1218 | + 1.0 | |
| 1219 | + ], | |
| 1220 | + [ | |
| 1221 | + 0.0, | |
| 1222 | + 0.0, | |
| 1223 | + 0.0, | |
| 1224 | + 0.0, | |
| 1225 | + 0.0, | |
| 1226 | + 0.0, | |
| 1227 | + 0.0 | |
| 1228 | + ], | |
| 1229 | + [ | |
| 1230 | + 0.0, | |
| 1231 | + 0.0, | |
| 1232 | + 0.0, | |
| 1233 | + 0.0, | |
| 1234 | + 0.0, | |
| 1235 | + 0.0, | |
| 1236 | + 0.0 | |
| 1237 | + ], | |
| 1238 | + [ | |
| 1239 | + 0.0, | |
| 1240 | + 0.0, | |
| 1241 | + 0.0, | |
| 1242 | + 0.0, | |
| 1243 | + 0.0, | |
| 1244 | + 0.0, | |
| 1245 | + 0.0 | |
| 1246 | + ] | |
| 1247 | + ], | |
| 1248 | + "logit_recovery": [ | |
| 1249 | + [ | |
| 1250 | + 0.0, | |
| 1251 | + 0.0, | |
| 1252 | + 0.0, | |
| 1253 | + 0.000488389516249299, | |
| 1254 | + 0.00017617014236748219, | |
| 1255 | + -1.2608468047403676e-08, | |
| 1256 | + 0.9994205236434937 | |
| 1257 | + ], | |
| 1258 | + [ | |
| 1259 | + 0.0, | |
| 1260 | + 0.0, | |
| 1261 | + 0.0, | |
| 1262 | + 7.775469566695392e-05, | |
| 1263 | + 3.9568527427036315e-05, | |
| 1264 | + 5.730797170144797e-07, | |
| 1265 | + 0.0032321682665497065 | |
| 1266 | + ], | |
| 1267 | + [ | |
| 1268 | + 0.0, | |
| 1269 | + 0.0, | |
| 1270 | + 0.0, | |
| 1271 | + 0.0002074985095532611, | |
| 1272 | + 2.0777781173819676e-05, | |
| 1273 | + 1.012419852486346e-05, | |
| 1274 | + 0.00023662605963181704 | |
| 1275 | + ], | |
| 1276 | + [ | |
| 1277 | + 0.0, | |
| 1278 | + 0.0, | |
| 1279 | + 0.0, | |
| 1280 | + 0.0, | |
| 1281 | + 0.0, | |
| 1282 | + 0.0, | |
| 1283 | + -0.005255246534943581 | |
| 1284 | + ] | |
| 1285 | + ] | |
| 1286 | + }, | |
| 1287 | + "s2": { | |
| 1288 | + "flip_rate": [ | |
| 1289 | + [ | |
| 1290 | + 0.0, | |
| 1291 | + 0.0, | |
| 1292 | + 0.0, | |
| 1293 | + 0.0, | |
| 1294 | + 0.0, | |
| 1295 | + 0.0, | |
| 1296 | + 1.0 | |
| 1297 | + ], | |
| 1298 | + [ | |
| 1299 | + 0.0, | |
| 1300 | + 0.0, | |
| 1301 | + 0.0, | |
| 1302 | + 0.0, | |
| 1303 | + 0.0, | |
| 1304 | + 0.0, | |
| 1305 | + 0.0 | |
| 1306 | + ], | |
| 1307 | + [ | |
| 1308 | + 0.0, | |
| 1309 | + 0.0, | |
| 1310 | + 0.0, | |
| 1311 | + 0.0, | |
| 1312 | + 0.0, | |
| 1313 | + 0.0, | |
| 1314 | + 0.0 | |
| 1315 | + ], | |
| 1316 | + [ | |
| 1317 | + 0.0, | |
| 1318 | + 0.0, | |
| 1319 | + 0.0, | |
| 1320 | + 0.0, | |
| 1321 | + 0.0, | |
| 1322 | + 0.0, | |
| 1323 | + 0.0 | |
| 1324 | + ] | |
| 1325 | + ], | |
| 1326 | + "logit_recovery": [ | |
| 1327 | + [ | |
| 1328 | + 0.0, | |
| 1329 | + 0.0, | |
| 1330 | + 0.0, | |
| 1331 | + 0.00030576580320484936, | |
| 1332 | + -4.887258546659723e-05, | |
| 1333 | + 1.5617764574926696e-06, | |
| 1334 | + 1.0001285076141357 | |
| 1335 | + ], | |
| 1336 | + [ | |
| 1337 | + 0.0, | |
| 1338 | + 0.0, | |
| 1339 | + 0.0, | |
| 1340 | + 3.7193756725173444e-05, | |
| 1341 | + 2.403900543868076e-05, | |
| 1342 | + 8.416523996856995e-06, | |
| 1343 | + -2.933492032752838e-05 | |
| 1344 | + ], | |
| 1345 | + [ | |
| 1346 | + 0.0, | |
| 1347 | + 0.0, | |
| 1348 | + 0.0, | |
| 1349 | + -7.816145080141723e-05, | |
| 1350 | + 1.2711129784293007e-05, | |
| 1351 | + -1.1673649169097189e-05, | |
| 1352 | + -0.00023561605485156178 | |
| 1353 | + ], | |
| 1354 | + [ | |
| 1355 | + 0.0, | |
| 1356 | + 0.0, | |
| 1357 | + 0.0, | |
| 1358 | + 0.0, | |
| 1359 | + 0.0, | |
| 1360 | + 0.0, | |
| 1361 | + -0.004809986799955368 | |
| 1362 | + ] | |
| 1363 | + ] | |
| 1364 | + }, | |
| 1365 | + "mean_flip_rate": [ | |
| 1366 | + [ | |
| 1367 | + 0.0, | |
| 1368 | + 0.0, | |
| 1369 | + 0.0, | |
| 1370 | + 0.0, | |
| 1371 | + 0.0, | |
| 1372 | + 0.0, | |
| 1373 | + 1.0 | |
| 1374 | + ], | |
| 1375 | + [ | |
| 1376 | + 0.0, | |
| 1377 | + 0.0, | |
| 1378 | + 0.0, | |
| 1379 | + 0.0, | |
| 1380 | + 0.0, | |
| 1381 | + 0.0, | |
| 1382 | + 0.0 | |
| 1383 | + ], | |
| 1384 | + [ | |
| 1385 | + 0.0, | |
| 1386 | + 0.0, | |
| 1387 | + 0.0, | |
| 1388 | + 0.0, | |
| 1389 | + 0.0, | |
| 1390 | + 0.0, | |
| 1391 | + 0.0 | |
| 1392 | + ], | |
| 1393 | + [ | |
| 1394 | + 0.0, | |
| 1395 | + 0.0, | |
| 1396 | + 0.0, | |
| 1397 | + 0.0, | |
| 1398 | + 0.0, | |
| 1399 | + 0.0, | |
| 1400 | + 0.0 | |
| 1401 | + ] | |
| 1402 | + ] | |
| 1403 | + }, | |
| 1404 | + "mlp_out": { | |
| 1405 | + "s0": { | |
| 1406 | + "flip_rate": [ | |
| 1407 | + [ | |
| 1408 | + 0.0, | |
| 1409 | + 0.0, | |
| 1410 | + 0.0, | |
| 1411 | + 0.0, | |
| 1412 | + 0.0, | |
| 1413 | + 0.0, | |
| 1414 | + 1.0 | |
| 1415 | + ], | |
| 1416 | + [ | |
| 1417 | + 0.0, | |
| 1418 | + 0.0, | |
| 1419 | + 0.0, | |
| 1420 | + 0.0, | |
| 1421 | + 0.0, | |
| 1422 | + 0.0, | |
| 1423 | + 1.0 | |
| 1424 | + ], | |
| 1425 | + [ | |
| 1426 | + 0.0, | |
| 1427 | + 0.0, | |
| 1428 | + 0.0, | |
| 1429 | + 0.0, | |
| 1430 | + 0.0, | |
| 1431 | + 0.0, | |
| 1432 | + 0.8142856955528259 | |
| 1433 | + ], | |
| 1434 | + [ | |
| 1435 | + 0.0, | |
| 1436 | + 0.0, | |
| 1437 | + 0.0, | |
| 1438 | + 0.0, | |
| 1439 | + 0.0, | |
| 1440 | + 0.0, | |
| 1441 | + 0.40612244606018066 | |
| 1442 | + ] | |
| 1443 | + ], | |
| 1444 | + "logit_recovery": [ | |
| 1445 | + [ | |
| 1446 | + 0.0, | |
| 1447 | + 0.0, | |
| 1448 | + 0.0, | |
| 1449 | + -0.00376747059635818, | |
| 1450 | + 0.0001691565994406119, | |
| 1451 | + 3.0771909678151133e-06, | |
| 1452 | + 0.9886849522590637 | |
| 1453 | + ], | |
| 1454 | + [ | |
| 1455 | + 0.0, | |
| 1456 | + 0.0, | |
| 1457 | + 0.0, | |
| 1458 | + -0.004375732969492674, | |
| 1459 | + -6.94971313350834e-05, | |
| 1460 | + -2.2410305973608047e-05, | |
| 1461 | + 0.716352105140686 | |
| 1462 | + ], | |
| 1463 | + [ | |
| 1464 | + 0.0, | |
| 1465 | + 0.0, | |
| 1466 | + 0.0, | |
| 1467 | + -5.74394543946255e-05, | |
| 1468 | + 2.9751297915936448e-05, | |
| 1469 | + -2.8927430321346037e-05, | |
| 1470 | + 0.5956922769546509 | |
| 1471 | + ], | |
| 1472 | + [ | |
| 1473 | + 0.0, | |
| 1474 | + 0.0, | |
| 1475 | + 0.0, | |
| 1476 | + 0.0, | |
| 1477 | + 0.0, | |
| 1478 | + 0.0, | |
| 1479 | + 0.5033453106880188 | |
| 1480 | + ] | |
| 1481 | + ] | |
| 1482 | + }, | |
| 1483 | + "s1": { | |
| 1484 | + "flip_rate": [ | |
| 1485 | + [ | |
| 1486 | + 0.0, | |
| 1487 | + 0.0, | |
| 1488 | + 0.0, | |
| 1489 | + 0.0, | |
| 1490 | + 0.0, | |
| 1491 | + 0.0, | |
| 1492 | + 1.0 | |
| 1493 | + ], | |
| 1494 | + [ | |
| 1495 | + 0.0, | |
| 1496 | + 0.0, | |
| 1497 | + 0.0, | |
| 1498 | + 0.0, | |
| 1499 | + 0.0, | |
| 1500 | + 0.0, | |
| 1501 | + 0.9755101799964905 | |
| 1502 | + ], | |
| 1503 | + [ | |
| 1504 | + 0.0, | |
| 1505 | + 0.0, | |
| 1506 | + 0.0, | |
| 1507 | + 0.0, | |
| 1508 | + 0.0, | |
| 1509 | + 0.0, | |
| 1510 | + 0.9448979496955872 | |
| 1511 | + ], | |
| 1512 | + [ | |
| 1513 | + 0.0, | |
| 1514 | + 0.0, | |
| 1515 | + 0.0, | |
| 1516 | + 0.0, | |
| 1517 | + 0.0, | |
| 1518 | + 0.0, | |
| 1519 | + 0.0 | |
| 1520 | + ] | |
| 1521 | + ], | |
| 1522 | + "logit_recovery": [ | |
| 1523 | + [ | |
| 1524 | + 0.0, | |
| 1525 | + 0.0, | |
| 1526 | + 0.0, | |
| 1527 | + 0.0005149293574504554, | |
| 1528 | + 0.000171999228768982, | |
| 1529 | + 1.244249716592094e-07, | |
| 1530 | + 0.9941860437393188 | |
| 1531 | + ], | |
| 1532 | + [ | |
| 1533 | + 0.0, | |
| 1534 | + 0.0, | |
| 1535 | + 0.0, | |
| 1536 | + -0.00022421055473387241, | |
| 1537 | + 6.864670285722241e-05, | |
| 1538 | + 1.3663714071299182e-06, | |
| 1539 | + 0.8590080142021179 | |
| 1540 | + ], | |
| 1541 | + [ | |
| 1542 | + 0.0, | |
| 1543 | + 0.0, | |
| 1544 | + 0.0, | |
| 1545 | + -0.00016121681255754083, | |
| 1546 | + -2.486043558747042e-05, | |
| 1547 | + 3.6747774174727965e-06, | |
| 1548 | + 0.620472252368927 | |
| 1549 | + ], | |
| 1550 | + [ | |
| 1551 | + 0.0, | |
| 1552 | + 0.0, | |
| 1553 | + 0.0, | |
| 1554 | + 0.0, | |
| 1555 | + 0.0, | |
| 1556 | + 0.0, | |
| 1557 | + 0.24915674328804016 | |
| 1558 | + ] | |
| 1559 | + ] | |
| 1560 | + }, | |
| 1561 | + "s2": { | |
| 1562 | + "flip_rate": [ | |
| 1563 | + [ | |
| 1564 | + 0.0, | |
| 1565 | + 0.0, | |
| 1566 | + 0.0, | |
| 1567 | + 0.0, | |
| 1568 | + 0.0, | |
| 1569 | + 0.0, | |
| 1570 | + 1.0 | |
| 1571 | + ], | |
| 1572 | + [ | |
| 1573 | + 0.0, | |
| 1574 | + 0.0, | |
| 1575 | + 0.0, | |
| 1576 | + 0.0, | |
| 1577 | + 0.0, | |
| 1578 | + 0.0, | |
| 1579 | + 0.7326530814170837 | |
| 1580 | + ], | |
| 1581 | + [ | |
| 1582 | + 0.0, | |
| 1583 | + 0.0, | |
| 1584 | + 0.0, | |
| 1585 | + 0.0, | |
| 1586 | + 0.0, | |
| 1587 | + 0.0, | |
| 1588 | + 0.722449004650116 | |
| 1589 | + ], | |
| 1590 | + [ | |
| 1591 | + 0.0, | |
| 1592 | + 0.0, | |
| 1593 | + 0.0, | |
| 1594 | + 0.0, | |
| 1595 | + 0.0, | |
| 1596 | + 0.0, | |
| 1597 | + 0.11428571492433548 | |
| 1598 | + ] | |
| 1599 | + ], | |
| 1600 | + "logit_recovery": [ | |
| 1601 | + [ | |
| 1602 | + 0.0, | |
| 1603 | + 0.0, | |
| 1604 | + 0.0, | |
| 1605 | + 0.0005150199285708368, | |
| 1606 | + -3.605287474783836e-06, | |
| 1607 | + 1.780065531420405e-06, | |
| 1608 | + 0.9959874749183655 | |
| 1609 | + ], | |
| 1610 | + [ | |
| 1611 | + 0.0, | |
| 1612 | + 0.0, | |
| 1613 | + 0.0, | |
| 1614 | + -0.00022224811255000532, | |
| 1615 | + -4.047781476401724e-05, | |
| 1616 | + 2.9307227578101447e-06, | |
| 1617 | + 0.656613826751709 | |
| 1618 | + ], | |
| 1619 | + [ | |
| 1620 | + 0.0, | |
| 1621 | + 0.0, | |
| 1622 | + 0.0, | |
| 1623 | + -4.242335489834659e-05, | |
| 1624 | + -7.299037406482967e-06, | |
| 1625 | + 5.311194854584755e-06, | |
| 1626 | + 0.6160171031951904 | |
| 1627 | + ], | |
| 1628 | + [ | |
| 1629 | + 0.0, | |
| 1630 | + 0.0, | |
| 1631 | + 0.0, | |
| 1632 | + 0.0, | |
| 1633 | + 0.0, | |
| 1634 | + 0.0, | |
| 1635 | + 0.3720884919166565 | |
| 1636 | + ] | |
| 1637 | + ] | |
| 1638 | + }, | |
| 1639 | + "mean_flip_rate": [ | |
| 1640 | + [ | |
| 1641 | + 0.0, | |
| 1642 | + 0.0, | |
| 1643 | + 0.0, | |
| 1644 | + 0.0, | |
| 1645 | + 0.0, | |
| 1646 | + 0.0, | |
| 1647 | + 1.0 | |
| 1648 | + ], | |
| 1649 | + [ | |
| 1650 | + 0.0, | |
| 1651 | + 0.0, | |
| 1652 | + 0.0, | |
| 1653 | + 0.0, | |
| 1654 | + 0.0, | |
| 1655 | + 0.0, | |
| 1656 | + 0.902721087137858 | |
| 1657 | + ], | |
| 1658 | + [ | |
| 1659 | + 0.0, | |
| 1660 | + 0.0, | |
| 1661 | + 0.0, | |
| 1662 | + 0.0, | |
| 1663 | + 0.0, | |
| 1664 | + 0.0, | |
| 1665 | + 0.8272108832995096 | |
| 1666 | + ], | |
| 1667 | + [ | |
| 1668 | + 0.0, | |
| 1669 | + 0.0, | |
| 1670 | + 0.0, | |
| 1671 | + 0.0, | |
| 1672 | + 0.0, | |
| 1673 | + 0.0, | |
| 1674 | + 0.17346938699483871 | |
| 1675 | + ] | |
| 1676 | + ] | |
| 1677 | + } | |
| 1678 | + }, | |
| 1679 | + "ablation": { | |
| 1680 | + "resid_post": { | |
| 1681 | + "s0": [ | |
| 1682 | + [ | |
| 1683 | + 1.0, | |
| 1684 | + 1.0, | |
| 1685 | + 1.0, | |
| 1686 | + 1.0, | |
| 1687 | + 1.0, | |
| 1688 | + 1.0, | |
| 1689 | + 0.0 | |
| 1690 | + ], | |
| 1691 | + [ | |
| 1692 | + 1.0, | |
| 1693 | + 1.0, | |
| 1694 | + 1.0, | |
| 1695 | + 1.0, | |
| 1696 | + 1.0, | |
| 1697 | + 1.0, | |
| 1698 | + 0.0 | |
| 1699 | + ], | |
| 1700 | + [ | |
| 1701 | + 1.0, | |
| 1702 | + 1.0, | |
| 1703 | + 1.0, | |
| 1704 | + 1.0, | |
| 1705 | + 1.0, | |
| 1706 | + 1.0, | |
| 1707 | + 0.08775509893894196 | |
| 1708 | + ], | |
| 1709 | + [ | |
| 1710 | + 1.0, | |
| 1711 | + 1.0, | |
| 1712 | + 1.0, | |
| 1713 | + 1.0, | |
| 1714 | + 1.0, | |
| 1715 | + 1.0, | |
| 1716 | + 0.08571428805589676 | |
| 1717 | + ] | |
| 1718 | + ], | |
| 1719 | + "s1": [ | |
| 1720 | + [ | |
| 1721 | + 1.0, | |
| 1722 | + 1.0, | |
| 1723 | + 1.0, | |
| 1724 | + 1.0, | |
| 1725 | + 1.0, | |
| 1726 | + 1.0, | |
| 1727 | + 0.08979591727256775 | |
| 1728 | + ], | |
| 1729 | + [ | |
| 1730 | + 1.0, | |
| 1731 | + 1.0, | |
| 1732 | + 1.0, | |
| 1733 | + 1.0, | |
| 1734 | + 1.0, | |
| 1735 | + 1.0, | |
| 1736 | + 0.0367346927523613 | |
| 1737 | + ], | |
| 1738 | + [ | |
| 1739 | + 1.0, | |
| 1740 | + 1.0, | |
| 1741 | + 1.0, | |
| 1742 | + 1.0, | |
| 1743 | + 1.0, | |
| 1744 | + 1.0, | |
| 1745 | + 0.07959183305501938 | |
| 1746 | + ], | |
| 1747 | + [ | |
| 1748 | + 1.0, | |
| 1749 | + 1.0, | |
| 1750 | + 1.0, | |
| 1751 | + 1.0, | |
| 1752 | + 1.0, | |
| 1753 | + 1.0, | |
| 1754 | + 0.08571428805589676 | |
| 1755 | + ] | |
| 1756 | + ], | |
| 1757 | + "s2": [ | |
| 1758 | + [ | |
| 1759 | + 1.0, | |
| 1760 | + 1.0, | |
| 1761 | + 1.0, | |
| 1762 | + 1.0, | |
| 1763 | + 1.0, | |
| 1764 | + 1.0, | |
| 1765 | + 0.01836734637618065 | |
| 1766 | + ], | |
| 1767 | + [ | |
| 1768 | + 1.0, | |
| 1769 | + 1.0, | |
| 1770 | + 1.0, | |
| 1771 | + 1.0, | |
| 1772 | + 1.0, | |
| 1773 | + 1.0, | |
| 1774 | + 0.08775509893894196 | |
| 1775 | + ], | |
| 1776 | + [ | |
| 1777 | + 1.0, | |
| 1778 | + 1.0, | |
| 1779 | + 1.0, | |
| 1780 | + 1.0, | |
| 1781 | + 1.0, | |
| 1782 | + 1.0, | |
| 1783 | + 0.09183673560619354 | |
| 1784 | + ], | |
| 1785 | + [ | |
| 1786 | + 1.0, | |
| 1787 | + 1.0, | |
| 1788 | + 1.0, | |
| 1789 | + 1.0, | |
| 1790 | + 1.0, | |
| 1791 | + 1.0, | |
| 1792 | + 0.08571428805589676 | |
| 1793 | + ] | |
| 1794 | + ] | |
| 1795 | + }, | |
| 1796 | + "attn_out": { | |
| 1797 | + "s0": [ | |
| 1798 | + [ | |
| 1799 | + 1.0, | |
| 1800 | + 1.0, | |
| 1801 | + 1.0, | |
| 1802 | + 1.0, | |
| 1803 | + 1.0, | |
| 1804 | + 1.0, | |
| 1805 | + 0.11632653325796127 | |
| 1806 | + ], | |
| 1807 | + [ | |
| 1808 | + 1.0, | |
| 1809 | + 1.0, | |
| 1810 | + 1.0, | |
| 1811 | + 1.0, | |
| 1812 | + 1.0, | |
| 1813 | + 1.0, | |
| 1814 | + 1.0 | |
| 1815 | + ], | |
| 1816 | + [ | |
| 1817 | + 1.0, | |
| 1818 | + 1.0, | |
| 1819 | + 1.0, | |
| 1820 | + 1.0, | |
| 1821 | + 1.0, | |
| 1822 | + 1.0, | |
| 1823 | + 1.0 | |
| 1824 | + ], | |
| 1825 | + [ | |
| 1826 | + 1.0, | |
| 1827 | + 1.0, | |
| 1828 | + 1.0, | |
| 1829 | + 1.0, | |
| 1830 | + 1.0, | |
| 1831 | + 1.0, | |
| 1832 | + 1.0 | |
| 1833 | + ] | |
| 1834 | + ], | |
| 1835 | + "s1": [ | |
| 1836 | + [ | |
| 1837 | + 1.0, | |
| 1838 | + 1.0, | |
| 1839 | + 1.0, | |
| 1840 | + 1.0, | |
| 1841 | + 1.0, | |
| 1842 | + 1.0, | |
| 1843 | + 0.17142857611179352 | |
| 1844 | + ], | |
| 1845 | + [ | |
| 1846 | + 1.0, | |
| 1847 | + 1.0, | |
| 1848 | + 1.0, | |
| 1849 | + 1.0, | |
| 1850 | + 1.0, | |
| 1851 | + 1.0, | |
| 1852 | + 1.0 | |
| 1853 | + ], | |
| 1854 | + [ | |
| 1855 | + 1.0, | |
| 1856 | + 1.0, | |
| 1857 | + 1.0, | |
| 1858 | + 1.0, | |
| 1859 | + 1.0, | |
| 1860 | + 1.0, | |
| 1861 | + 1.0 | |
| 1862 | + ], | |
| 1863 | + [ | |
| 1864 | + 1.0, | |
| 1865 | + 1.0, | |
| 1866 | + 1.0, | |
| 1867 | + 1.0, | |
| 1868 | + 1.0, | |
| 1869 | + 1.0, | |
| 1870 | + 1.0 | |
| 1871 | + ] | |
| 1872 | + ], | |
| 1873 | + "s2": [ | |
| 1874 | + [ | |
| 1875 | + 1.0, | |
| 1876 | + 1.0, | |
| 1877 | + 1.0, | |
| 1878 | + 1.0, | |
| 1879 | + 1.0, | |
| 1880 | + 1.0, | |
| 1881 | + 0.08979591727256775 | |
| 1882 | + ], | |
| 1883 | + [ | |
| 1884 | + 1.0, | |
| 1885 | + 1.0, | |
| 1886 | + 1.0, | |
| 1887 | + 1.0, | |
| 1888 | + 1.0, | |
| 1889 | + 1.0, | |
| 1890 | + 1.0 | |
| 1891 | + ], | |
| 1892 | + [ | |
| 1893 | + 1.0, | |
| 1894 | + 1.0, | |
| 1895 | + 1.0, | |
| 1896 | + 1.0, | |
| 1897 | + 1.0, | |
| 1898 | + 1.0, | |
| 1899 | + 1.0 | |
| 1900 | + ], | |
| 1901 | + [ | |
| 1902 | + 1.0, | |
| 1903 | + 1.0, | |
| 1904 | + 1.0, | |
| 1905 | + 1.0, | |
| 1906 | + 1.0, | |
| 1907 | + 1.0, | |
| 1908 | + 1.0 | |
| 1909 | + ] | |
| 1910 | + ] | |
| 1911 | + }, | |
| 1912 | + "mlp_out": { | |
| 1913 | + "s0": [ | |
| 1914 | + [ | |
| 1915 | + 1.0, | |
| 1916 | + 1.0, | |
| 1917 | + 1.0, | |
| 1918 | + 1.0, | |
| 1919 | + 1.0, | |
| 1920 | + 1.0, | |
| 1921 | + 0.12653061747550964 | |
| 1922 | + ], | |
| 1923 | + [ | |
| 1924 | + 1.0, | |
| 1925 | + 1.0, | |
| 1926 | + 1.0, | |
| 1927 | + 1.0, | |
| 1928 | + 1.0, | |
| 1929 | + 1.0, | |
| 1930 | + 0.9142857193946838 | |
| 1931 | + ], | |
| 1932 | + [ | |
| 1933 | + 1.0, | |
| 1934 | + 1.0, | |
| 1935 | + 1.0, | |
| 1936 | + 1.0, | |
| 1937 | + 1.0, | |
| 1938 | + 1.0, | |
| 1939 | + 1.0 | |
| 1940 | + ], | |
| 1941 | + [ | |
| 1942 | + 1.0, | |
| 1943 | + 1.0, | |
| 1944 | + 1.0, | |
| 1945 | + 1.0, | |
| 1946 | + 1.0, | |
| 1947 | + 1.0, | |
| 1948 | + 1.0 | |
| 1949 | + ] | |
| 1950 | + ], | |
| 1951 | + "s1": [ | |
| 1952 | + [ | |
| 1953 | + 1.0, | |
| 1954 | + 1.0, | |
| 1955 | + 1.0, | |
| 1956 | + 1.0, | |
| 1957 | + 1.0, | |
| 1958 | + 1.0, | |
| 1959 | + 0.3918367326259613 | |
| 1960 | + ], | |
| 1961 | + [ | |
| 1962 | + 1.0, | |
| 1963 | + 1.0, | |
| 1964 | + 1.0, | |
| 1965 | + 1.0, | |
| 1966 | + 1.0, | |
| 1967 | + 1.0, | |
| 1968 | + 1.0 | |
| 1969 | + ], | |
| 1970 | + [ | |
| 1971 | + 1.0, | |
| 1972 | + 1.0, | |
| 1973 | + 1.0, | |
| 1974 | + 1.0, | |
| 1975 | + 1.0, | |
| 1976 | + 1.0, | |
| 1977 | + 1.0 | |
| 1978 | + ], | |
| 1979 | + [ | |
| 1980 | + 1.0, | |
| 1981 | + 1.0, | |
| 1982 | + 1.0, | |
| 1983 | + 1.0, | |
| 1984 | + 1.0, | |
| 1985 | + 1.0, | |
| 1986 | + 1.0 | |
| 1987 | + ] | |
| 1988 | + ], | |
| 1989 | + "s2": [ | |
| 1990 | + [ | |
| 1991 | + 1.0, | |
| 1992 | + 1.0, | |
| 1993 | + 1.0, | |
| 1994 | + 1.0, | |
| 1995 | + 1.0, | |
| 1996 | + 1.0, | |
| 1997 | + 0.11020407825708389 | |
| 1998 | + ], | |
| 1999 | + [ | |
| 2000 | + 1.0, | |
| 2001 | + 1.0, | |
| 2002 | + 1.0, | |
| 2003 | + 1.0, | |
| 2004 | + 1.0, | |
| 2005 | + 1.0, | |
| 2006 | + 1.0 | |
| 2007 | + ], | |
| 2008 | + [ | |
| 2009 | + 1.0, | |
| 2010 | + 1.0, | |
| 2011 | + 1.0, | |
| 2012 | + 1.0, | |
| 2013 | + 1.0, | |
| 2014 | + 1.0, | |
| 2015 | + 1.0 | |
| 2016 | + ], | |
| 2017 | + [ | |
| 2018 | + 1.0, | |
| 2019 | + 1.0, | |
| 2020 | + 1.0, | |
| 2021 | + 1.0, | |
| 2022 | + 1.0, | |
| 2023 | + 1.0, | |
| 2024 | + 1.0 | |
| 2025 | + ] | |
| 2026 | + ] | |
| 2027 | + } | |
| 2028 | + }, | |
| 2029 | + "heads": { | |
| 2030 | + "omega_token": { | |
| 2031 | + "s0": [ | |
| 2032 | + [ | |
| 2033 | + 0.0, | |
| 2034 | + 0.0, | |
| 2035 | + 0.0, | |
| 2036 | + 0.0 | |
| 2037 | + ], | |
| 2038 | + [ | |
| 2039 | + 0.0, | |
| 2040 | + 0.0, | |
| 2041 | + 0.0, | |
| 2042 | + 0.0 | |
| 2043 | + ], | |
| 2044 | + [ | |
| 2045 | + 0.0, | |
| 2046 | + 0.0, | |
| 2047 | + 0.0, | |
| 2048 | + 0.0 | |
| 2049 | + ], | |
| 2050 | + [ | |
| 2051 | + 0.0, | |
| 2052 | + 0.0, | |
| 2053 | + 0.0, | |
| 2054 | + 0.0 | |
| 2055 | + ] | |
| 2056 | + ], | |
| 2057 | + "s1": [ | |
| 2058 | + [ | |
| 2059 | + 0.0, | |
| 2060 | + 0.0, | |
| 2061 | + 0.0, | |
| 2062 | + 0.0 | |
| 2063 | + ], | |
| 2064 | + [ | |
| 2065 | + 0.0, | |
| 2066 | + 0.0, | |
| 2067 | + 0.0, | |
| 2068 | + 0.0 | |
| 2069 | + ], | |
| 2070 | + [ | |
| 2071 | + 0.0, | |
| 2072 | + 0.0, | |
| 2073 | + 0.0, | |
| 2074 | + 0.0 | |
| 2075 | + ], | |
| 2076 | + [ | |
| 2077 | + 0.0, | |
| 2078 | + 0.0, | |
| 2079 | + 0.0, | |
| 2080 | + 0.0 | |
| 2081 | + ] | |
| 2082 | + ], | |
| 2083 | + "s2": [ | |
| 2084 | + [ | |
| 2085 | + 0.0, | |
| 2086 | + 0.0, | |
| 2087 | + 0.0, | |
| 2088 | + 0.0 | |
| 2089 | + ], | |
| 2090 | + [ | |
| 2091 | + 0.0, | |
| 2092 | + 0.0, | |
| 2093 | + 0.0, | |
| 2094 | + 0.0 | |
| 2095 | + ], | |
| 2096 | + [ | |
| 2097 | + 0.0, | |
| 2098 | + 0.0, | |
| 2099 | + 0.0, | |
| 2100 | + 0.0 | |
| 2101 | + ], | |
| 2102 | + [ | |
| 2103 | + 0.0, | |
| 2104 | + 0.0, | |
| 2105 | + 0.0, | |
| 2106 | + 0.0 | |
| 2107 | + ] | |
| 2108 | + ] | |
| 2109 | + }, | |
| 2110 | + "read_position": { | |
| 2111 | + "s0": [ | |
| 2112 | + [ | |
| 2113 | + 0.9346938729286194, | |
| 2114 | + 0.4734693765640259, | |
| 2115 | + 0.0, | |
| 2116 | + 0.0 | |
| 2117 | + ], | |
| 2118 | + [ | |
| 2119 | + 0.0, | |
| 2120 | + 0.0, | |
| 2121 | + 0.0, | |
| 2122 | + 0.0 | |
| 2123 | + ], | |
| 2124 | + [ | |
| 2125 | + 0.0, | |
| 2126 | + 0.0, | |
| 2127 | + 0.0, | |
| 2128 | + 0.0 | |
| 2129 | + ], | |
| 2130 | + [ | |
| 2131 | + 0.0, | |
| 2132 | + 0.0, | |
| 2133 | + 0.0, | |
| 2134 | + 0.0 | |
| 2135 | + ] | |
| 2136 | + ], | |
| 2137 | + "s1": [ | |
| 2138 | + [ | |
| 2139 | + 0.9163265228271484, | |
| 2140 | + 0.0, | |
| 2141 | + 0.0, | |
| 2142 | + 0.0 | |
| 2143 | + ], | |
| 2144 | + [ | |
| 2145 | + 0.0, | |
| 2146 | + 0.0, | |
| 2147 | + 0.0, | |
| 2148 | + 0.0 | |
| 2149 | + ], | |
| 2150 | + [ | |
| 2151 | + 0.0, | |
| 2152 | + 0.0, | |
| 2153 | + 0.0, | |
| 2154 | + 0.0 | |
| 2155 | + ], | |
| 2156 | + [ | |
| 2157 | + 0.0, | |
| 2158 | + 0.0, | |
| 2159 | + 0.0, | |
| 2160 | + 0.0 | |
| 2161 | + ] | |
| 2162 | + ], | |
| 2163 | + "s2": [ | |
| 2164 | + [ | |
| 2165 | + 0.0, | |
| 2166 | + 0.0, | |
| 2167 | + 0.11428571492433548, | |
| 2168 | + 0.0 | |
| 2169 | + ], | |
| 2170 | + [ | |
| 2171 | + 0.0, | |
| 2172 | + 0.0, | |
| 2173 | + 0.0, | |
| 2174 | + 0.0 | |
| 2175 | + ], | |
| 2176 | + [ | |
| 2177 | + 0.0, | |
| 2178 | + 0.0, | |
| 2179 | + 0.0, | |
| 2180 | + 0.0 | |
| 2181 | + ], | |
| 2182 | + [ | |
| 2183 | + 0.0, | |
| 2184 | + 0.0, | |
| 2185 | + 0.0, | |
| 2186 | + 0.0 | |
| 2187 | + ] | |
| 2188 | + ] | |
| 2189 | + } | |
| 2190 | + }, | |
| 2191 | + "reproducibility": { | |
| 2192 | + "resid_post_s0_repeat_max_abs_diff": 0.0, | |
| 2193 | + "attn_out_s0_repeat_max_abs_diff": 0.0, | |
| 2194 | + "mlp_out_s0_repeat_max_abs_diff": 0.0, | |
| 2195 | + "resid_post_s1_repeat_max_abs_diff": 0.0, | |
| 2196 | + "attn_out_s1_repeat_max_abs_diff": 0.0, | |
| 2197 | + "mlp_out_s1_repeat_max_abs_diff": 0.0, | |
| 2198 | + "resid_post_s2_repeat_max_abs_diff": 0.0, | |
| 2199 | + "attn_out_s2_repeat_max_abs_diff": 0.0, | |
| 2200 | + "mlp_out_s2_repeat_max_abs_diff": 0.0, | |
| 2201 | + "resid_post_across_seed_pearson_min": 0.9999999999999999, | |
| 2202 | + "attn_out_across_seed_pearson_min": 0.9999999999999999, | |
| 2203 | + "mlp_out_across_seed_pearson_min": 0.9642362448310298 | |
| 2204 | + }, | |
| 2205 | + "baselines": { | |
| 2206 | + "s0": { | |
| 2207 | + "clean_acc_on_clean_answer": 1.0, | |
| 2208 | + "corrupt_run_acc_on_clean_answer(sham)": 0.0 | |
| 2209 | + }, | |
| 2210 | + "s1": { | |
| 2211 | + "clean_acc_on_clean_answer": 1.0, | |
| 2212 | + "corrupt_run_acc_on_clean_answer(sham)": 0.0 | |
| 2213 | + }, | |
| 2214 | + "s2": { | |
| 2215 | + "clean_acc_on_clean_answer": 1.0, | |
| 2216 | + "corrupt_run_acc_on_clean_answer(sham)": 0.0 | |
| 2217 | + } | |
| 2218 | + } | |
| 2219 | + }, | |
| 2220 | + "across_seeds": { | |
| 2221 | + "target_iid": { | |
| 2222 | + "donor": { | |
| 2223 | + "n_seeds": 3, | |
| 2224 | + "mean": 1.0, | |
| 2225 | + "sd": 0.0, | |
| 2226 | + "min": 1.0, | |
| 2227 | + "max": 1.0 | |
| 2228 | + }, | |
| 2229 | + "recipient": { | |
| 2230 | + "n_seeds": 3, | |
| 2231 | + "mean": 0.09200000000000001, | |
| 2232 | + "sd": 0.05288667128870941, | |
| 2233 | + "min": 0.059, | |
| 2234 | + "max": 0.153 | |
| 2235 | + } | |
| 2236 | + }, | |
| 2237 | + "control_iid": { | |
| 2238 | + "donor": { | |
| 2239 | + "n_seeds": 3, | |
| 2240 | + "mean": 1.0, | |
| 2241 | + "sd": 0.0, | |
| 2242 | + "min": 1.0, | |
| 2243 | + "max": 1.0 | |
| 2244 | + }, | |
| 2245 | + "recipient": { | |
| 2246 | + "n_seeds": 3, | |
| 2247 | + "mean": 1.0, | |
| 2248 | + "sd": 0.0, | |
| 2249 | + "min": 1.0, | |
| 2250 | + "max": 1.0 | |
| 2251 | + } | |
| 2252 | + }, | |
| 2253 | + "comp_heldout": { | |
| 2254 | + "donor": { | |
| 2255 | + "n_seeds": 3, | |
| 2256 | + "mean": 1.0, | |
| 2257 | + "sd": 0.0, | |
| 2258 | + "min": 1.0, | |
| 2259 | + "max": 1.0 | |
| 2260 | + }, | |
| 2261 | + "recipient": { | |
| 2262 | + "n_seeds": 3, | |
| 2263 | + "mean": 0.4503333333333333, | |
| 2264 | + "sd": 0.031895663237081824, | |
| 2265 | + "min": 0.429, | |
| 2266 | + "max": 0.487 | |
| 2267 | + } | |
| 2268 | + }, | |
| 2269 | + "len_ood": { | |
| 2270 | + "donor": { | |
| 2271 | + "n_seeds": 3, | |
| 2272 | + "mean": 0.08600000000000001, | |
| 2273 | + "sd": 0.017320508075688773, | |
| 2274 | + "min": 0.076, | |
| 2275 | + "max": 0.106 | |
| 2276 | + }, | |
| 2277 | + "recipient": { | |
| 2278 | + "n_seeds": 3, | |
| 2279 | + "mean": 0.09066666666666666, | |
| 2280 | + "sd": 0.015534906930308057, | |
| 2281 | + "min": 0.078, | |
| 2282 | + "max": 0.108 | |
| 2283 | + } | |
| 2284 | + } | |
| 2285 | + }, | |
| 2286 | + "across_seeds_omega_step": { | |
| 2287 | + "donor": { | |
| 2288 | + "n_seeds": 3, | |
| 2289 | + "mean": 1.0, | |
| 2290 | + "sd": 0.0, | |
| 2291 | + "min": 1.0, | |
| 2292 | + "max": 1.0 | |
| 2293 | + }, | |
| 2294 | + "recipient": { | |
| 2295 | + "n_seeds": 3, | |
| 2296 | + "mean": 0.06166666666666667, | |
| 2297 | + "sd": 0.0697160909212022, | |
| 2298 | + "min": 0.017, | |
| 2299 | + "max": 0.142 | |
| 2300 | + } | |
| 2301 | + }, | |
| 2302 | + "elapsed_seconds": 275.5419456958771 | |
| 2303 | +} | |
| \ No newline at end of file | ||
added
experiments/summaries/pilot_tier0_opseq_quick_d5339bcad6b3/SUMMARY.md
+42 −0
@@ -0,0 +1,42 @@ | ||
| 1 | +# Pilot summary — pilot_tier0_opseq_quick_d5339bcad6b3 | |
| 2 | + | |
| 3 | +Generated 2026-11-09T06:49:31+00:00 on device `cpu`; config hash `d5339bcad6b3`; seeds [0, 1]. | |
| 4 | + | |
| 5 | +## Gate B — donor/recipient gap (final-answer exact match, mean over seeds; CI = cluster bootstrap on programs) | |
| 6 | + | |
| 7 | +| split | chance | donor mean (sd) | recipient mean (sd) | paired gap seed 0 [95% CI] | | |
| 8 | +|---|---|---|---|---| | |
| 9 | +| target_iid | 0.113 | 0.120 (0.009) | 0.098 (0.012) | +0.007 [-0.034, +0.049] | | |
| 10 | +| control_iid | 0.130 | 0.155 (0.007) | 0.162 (0.021) | -0.027 [-0.064, +0.010] | | |
| 11 | +| comp_heldout | 0.117 | 0.128 (0.026) | 0.095 (0.002) | +0.053 [+0.013, +0.103] | | |
| 12 | +| len_ood | 0.150 | 0.082 (0.032) | 0.055 (0.007) | +0.055 [+0.005, +0.105] | | |
| 13 | + | |
| 14 | +Ω-step accuracy on target_iid (token emitted at the first Ω step): donor 0.268, recipient 0.070. | |
| 15 | + | |
| 16 | +## Gate C — hook no-op checks (bitwise equality of logits on 256 dev items) | |
| 17 | + | |
| 18 | +| model | repeat | capture-all | disabled hook | enabled zero hook changes output | | |
| 19 | +|---|---|---|---|---| | |
| 20 | +| donor_s0 | True | True | True | True | | |
| 21 | +| recipient_s0 | True | True | True | True | | |
| 22 | +| donor_s1 | True | True | True | True | | |
| 23 | +| recipient_s1 | True | True | True | True | | |
| 24 | + | |
| 25 | +## RQ1 — within-donor localization of Ω (n = 490 clean/corrupt pairs, read position = r1, predicting r2) | |
| 26 | + | |
| 27 | +Baselines: s0: clean 0.316, sham (corrupt run scored on clean answer) 0.108; s1: clean 0.551, sham (corrupt run scored on clean answer) 0.155 | |
| 28 | + | |
| 29 | +Mean restored-answer rate after patching the clean activation into the corrupted run (rows = layers, columns = positions <bos>, v0, op1, Ω, op3, =, r1): | |
| 30 | + | |
| 31 | +- `resid_post`: L0: 0.13 0.13 0.13 0.16 0.13 0.13 0.39 | L1: 0.13 0.13 0.13 0.13 0.13 0.13 0.43 | L2: 0.13 0.13 0.13 0.13 0.13 0.13 0.43 | |
| 32 | +- `attn_out`: L0: 0.13 0.13 0.13 0.14 0.13 0.13 0.39 | L1: 0.13 0.13 0.13 0.13 0.13 0.13 0.17 | L2: 0.13 0.13 0.13 0.13 0.13 0.13 0.12 | |
| 33 | +- `mlp_out`: L0: 0.13 0.13 0.13 0.15 0.13 0.13 0.29 | L1: 0.13 0.13 0.13 0.13 0.13 0.13 0.32 | L2: 0.13 0.13 0.13 0.13 0.13 0.13 0.22 | |
| 34 | + | |
| 35 | +Reproducibility: resid_post_s0_repeat_max_abs_diff = 0.0000; attn_out_s0_repeat_max_abs_diff = 0.0000; mlp_out_s0_repeat_max_abs_diff = 0.0000; resid_post_s1_repeat_max_abs_diff = 0.0000; attn_out_s1_repeat_max_abs_diff = 0.0000; mlp_out_s1_repeat_max_abs_diff = 0.0000; resid_post_across_seed_pearson_min = 0.9930; attn_out_across_seed_pearson_min = 0.9706; mlp_out_across_seed_pearson_min = 0.9732 | |
| 36 | + | |
| 37 | +Figures: `fig_gap_tier0.pdf`, `fig_localization_ablation_tier0.pdf`, `fig_localization_heads_tier0.pdf`, `fig_localization_patching_tier0.pdf` | |
| 38 | + | |
| 39 | +## Interpretation (observed vs. speculative) | |
| 40 | + | |
| 41 | +Observed: the numbers above are produced by the artifacts listed in the manifest. Any statement about *transfer* is out of scope for this run: no transplant was performed. | |
| 42 | +Speculative: whether the localized positions/layers constitute a transferable 'organ' is the object of the next experiment (activation graft with sham/random controls). | |
added
experiments/summaries/pilot_tier0_opseq_quick_d5339bcad6b3/results.json
+1383 −0
@@ -0,0 +1,1383 @@ | ||
| 1 | +{ | |
| 2 | + "run_id": "pilot_tier0_opseq_quick_d5339bcad6b3", | |
| 3 | + "config_hash": "d5339bcad6b3", | |
| 4 | + "device": "cpu", | |
| 5 | + "chance_level": { | |
| 6 | + "target_iid": 0.11333333333333333, | |
| 7 | + "control_iid": 0.13, | |
| 8 | + "comp_heldout": 0.11666666666666667, | |
| 9 | + "len_ood": 0.15 | |
| 10 | + }, | |
| 11 | + "seeds": { | |
| 12 | + "0": { | |
| 13 | + "donor": { | |
| 14 | + "n_params": 104128, | |
| 15 | + "train_seconds": 3.7347042560577393, | |
| 16 | + "final_dev": { | |
| 17 | + "step": 200, | |
| 18 | + "loss": 1.581451177597046, | |
| 19 | + "dev_acc": 0.13333333333333333, | |
| 20 | + "dev_trace_acc": 0.056666666666666664, | |
| 21 | + "lr": 0.0, | |
| 22 | + "elapsed_s": 3.7261741161346436 | |
| 23 | + }, | |
| 24 | + "eval": { | |
| 25 | + "target_iid": { | |
| 26 | + "split": "target_iid", | |
| 27 | + "split_hash": "88d9bb27db961222", | |
| 28 | + "n": 300, | |
| 29 | + "accuracy": 0.11333333333333333, | |
| 30 | + "trace_accuracy": 0.03666666666666667, | |
| 31 | + "ci95": { | |
| 32 | + "estimate": 0.11333333333333333, | |
| 33 | + "low": 0.07478037572644952, | |
| 34 | + "high": 0.15052945301542778, | |
| 35 | + "level": 0.95, | |
| 36 | + "n_items": 300, | |
| 37 | + "n_clusters": 269, | |
| 38 | + "n_boot": 200 | |
| 39 | + }, | |
| 40 | + "omega_step_acc": { | |
| 41 | + "estimate": 0.24, | |
| 42 | + "low": 0.19278817587641117, | |
| 43 | + "high": 0.29099073414112614, | |
| 44 | + "level": 0.95, | |
| 45 | + "n_items": 300, | |
| 46 | + "n_clusters": 269, | |
| 47 | + "n_boot": 200 | |
| 48 | + }, | |
| 49 | + "chance": 0.11333333333333333 | |
| 50 | + }, | |
| 51 | + "control_iid": { | |
| 52 | + "split": "control_iid", | |
| 53 | + "split_hash": "76bdfaf36a5f7519", | |
| 54 | + "n": 300, | |
| 55 | + "accuracy": 0.15, | |
| 56 | + "trace_accuracy": 0.06, | |
| 57 | + "ci95": { | |
| 58 | + "estimate": 0.15, | |
| 59 | + "low": 0.11329661016949152, | |
| 60 | + "high": 0.1926864887462714, | |
| 61 | + "level": 0.95, | |
| 62 | + "n_items": 300, | |
| 63 | + "n_clusters": 293, | |
| 64 | + "n_boot": 200 | |
| 65 | + }, | |
| 66 | + "omega_step_acc": null, | |
| 67 | + "chance": 0.13 | |
| 68 | + }, | |
| 69 | + "comp_heldout": { | |
| 70 | + "split": "comp_heldout", | |
| 71 | + "split_hash": "68e83ab8472513d2", | |
| 72 | + "n": 300, | |
| 73 | + "accuracy": 0.14666666666666667, | |
| 74 | + "trace_accuracy": 0.05, | |
| 75 | + "ci95": { | |
| 76 | + "estimate": 0.14666666666666667, | |
| 77 | + "low": 0.11493486906095715, | |
| 78 | + "high": 0.1844807034516118, | |
| 79 | + "level": 0.95, | |
| 80 | + "n_items": 300, | |
| 81 | + "n_clusters": 241, | |
| 82 | + "n_boot": 200 | |
| 83 | + }, | |
| 84 | + "omega_step_acc": { | |
| 85 | + "estimate": 0.2833333333333333, | |
| 86 | + "low": 0.21729360039081583, | |
| 87 | + "high": 0.34242126532887407, | |
| 88 | + "level": 0.95, | |
| 89 | + "n_items": 180, | |
| 90 | + "n_clusters": 148, | |
| 91 | + "n_boot": 200 | |
| 92 | + }, | |
| 93 | + "chance": 0.11666666666666667 | |
| 94 | + }, | |
| 95 | + "len_ood": { | |
| 96 | + "split": "len_ood", | |
| 97 | + "split_hash": "6d8c13dc8b5c47fa", | |
| 98 | + "n": 200, | |
| 99 | + "accuracy": 0.105, | |
| 100 | + "trace_accuracy": 0.0, | |
| 101 | + "ci95": { | |
| 102 | + "estimate": 0.105, | |
| 103 | + "low": 0.06487500000000002, | |
| 104 | + "high": 0.145, | |
| 105 | + "level": 0.95, | |
| 106 | + "n_items": 200, | |
| 107 | + "n_clusters": 200, | |
| 108 | + "n_boot": 200 | |
| 109 | + }, | |
| 110 | + "omega_step_acc": { | |
| 111 | + "estimate": 0.10434782608695652, | |
| 112 | + "low": 0.043478260869565216, | |
| 113 | + "high": 0.1565217391304348, | |
| 114 | + "level": 0.95, | |
| 115 | + "n_items": 115, | |
| 116 | + "n_clusters": 115, | |
| 117 | + "n_boot": 200 | |
| 118 | + }, | |
| 119 | + "chance": 0.15 | |
| 120 | + } | |
| 121 | + } | |
| 122 | + }, | |
| 123 | + "recipient": { | |
| 124 | + "n_params": 104128, | |
| 125 | + "train_seconds": 3.605180263519287, | |
| 126 | + "final_dev": { | |
| 127 | + "step": 200, | |
| 128 | + "loss": 1.4595788717269897, | |
| 129 | + "dev_acc": 0.18, | |
| 130 | + "dev_trace_acc": 0.09333333333333334, | |
| 131 | + "lr": 0.0, | |
| 132 | + "elapsed_s": 3.598365068435669 | |
| 133 | + }, | |
| 134 | + "eval": { | |
| 135 | + "target_iid": { | |
| 136 | + "split": "target_iid", | |
| 137 | + "split_hash": "88d9bb27db961222", | |
| 138 | + "n": 300, | |
| 139 | + "accuracy": 0.10666666666666667, | |
| 140 | + "trace_accuracy": 0.006666666666666667, | |
| 141 | + "ci95": { | |
| 142 | + "estimate": 0.10666666666666667, | |
| 143 | + "low": 0.0701905896366885, | |
| 144 | + "high": 0.13959436641338555, | |
| 145 | + "level": 0.95, | |
| 146 | + "n_items": 300, | |
| 147 | + "n_clusters": 269, | |
| 148 | + "n_boot": 200 | |
| 149 | + }, | |
| 150 | + "omega_step_acc": { | |
| 151 | + "estimate": 0.06333333333333334, | |
| 152 | + "low": 0.04009817671809257, | |
| 153 | + "high": 0.09277440017370536, | |
| 154 | + "level": 0.95, | |
| 155 | + "n_items": 300, | |
| 156 | + "n_clusters": 269, | |
| 157 | + "n_boot": 200 | |
| 158 | + }, | |
| 159 | + "chance": 0.11333333333333333 | |
| 160 | + }, | |
| 161 | + "control_iid": { | |
| 162 | + "split": "control_iid", | |
| 163 | + "split_hash": "76bdfaf36a5f7519", | |
| 164 | + "n": 300, | |
| 165 | + "accuracy": 0.17666666666666667, | |
| 166 | + "trace_accuracy": 0.09666666666666666, | |
| 167 | + "ci95": { | |
| 168 | + "estimate": 0.17666666666666667, | |
| 169 | + "low": 0.136201348705199, | |
| 170 | + "high": 0.22591362126245848, | |
| 171 | + "level": 0.95, | |
| 172 | + "n_items": 300, | |
| 173 | + "n_clusters": 293, | |
| 174 | + "n_boot": 200 | |
| 175 | + }, | |
| 176 | + "omega_step_acc": null, | |
| 177 | + "chance": 0.13 | |
| 178 | + }, | |
| 179 | + "comp_heldout": { | |
| 180 | + "split": "comp_heldout", | |
| 181 | + "split_hash": "68e83ab8472513d2", | |
| 182 | + "n": 300, | |
| 183 | + "accuracy": 0.09333333333333334, | |
| 184 | + "trace_accuracy": 0.02, | |
| 185 | + "ci95": { | |
| 186 | + "estimate": 0.09333333333333334, | |
| 187 | + "low": 0.06004459903808402, | |
| 188 | + "high": 0.1262532812435913, | |
| 189 | + "level": 0.95, | |
| 190 | + "n_items": 300, | |
| 191 | + "n_clusters": 241, | |
| 192 | + "n_boot": 200 | |
| 193 | + }, | |
| 194 | + "omega_step_acc": { | |
| 195 | + "estimate": 0.027777777777777776, | |
| 196 | + "low": 0.005317060265121978, | |
| 197 | + "high": 0.05296173308032891, | |
| 198 | + "level": 0.95, | |
| 199 | + "n_items": 180, | |
| 200 | + "n_clusters": 148, | |
| 201 | + "n_boot": 200 | |
| 202 | + }, | |
| 203 | + "chance": 0.11666666666666667 | |
| 204 | + }, | |
| 205 | + "len_ood": { | |
| 206 | + "split": "len_ood", | |
| 207 | + "split_hash": "6d8c13dc8b5c47fa", | |
| 208 | + "n": 200, | |
| 209 | + "accuracy": 0.05, | |
| 210 | + "trace_accuracy": 0.0, | |
| 211 | + "ci95": { | |
| 212 | + "estimate": 0.05, | |
| 213 | + "low": 0.02, | |
| 214 | + "high": 0.075, | |
| 215 | + "level": 0.95, | |
| 216 | + "n_items": 200, | |
| 217 | + "n_clusters": 200, | |
| 218 | + "n_boot": 200 | |
| 219 | + }, | |
| 220 | + "omega_step_acc": { | |
| 221 | + "estimate": 0.06086956521739131, | |
| 222 | + "low": 0.017391304347826087, | |
| 223 | + "high": 0.1045652173913044, | |
| 224 | + "level": 0.95, | |
| 225 | + "n_items": 115, | |
| 226 | + "n_clusters": 115, | |
| 227 | + "n_boot": 200 | |
| 228 | + }, | |
| 229 | + "chance": 0.15 | |
| 230 | + } | |
| 231 | + } | |
| 232 | + }, | |
| 233 | + "gap": { | |
| 234 | + "target_iid": { | |
| 235 | + "estimate": 0.006666666666666667, | |
| 236 | + "low": -0.03395843821670302, | |
| 237 | + "high": 0.049048298249065515, | |
| 238 | + "level": 0.95, | |
| 239 | + "n_items": 300, | |
| 240 | + "n_clusters": 269, | |
| 241 | + "n_boot": 200 | |
| 242 | + }, | |
| 243 | + "control_iid": { | |
| 244 | + "estimate": -0.02666666666666667, | |
| 245 | + "low": -0.06404597817641294, | |
| 246 | + "high": 0.010067961494135991, | |
| 247 | + "level": 0.95, | |
| 248 | + "n_items": 300, | |
| 249 | + "n_clusters": 293, | |
| 250 | + "n_boot": 200 | |
| 251 | + }, | |
| 252 | + "comp_heldout": { | |
| 253 | + "estimate": 0.05333333333333334, | |
| 254 | + "low": 0.012669551600821054, | |
| 255 | + "high": 0.10274132633465625, | |
| 256 | + "level": 0.95, | |
| 257 | + "n_items": 300, | |
| 258 | + "n_clusters": 241, | |
| 259 | + "n_boot": 200 | |
| 260 | + }, | |
| 261 | + "len_ood": { | |
| 262 | + "estimate": 0.055, | |
| 263 | + "low": 0.005, | |
| 264 | + "high": 0.105, | |
| 265 | + "level": 0.95, | |
| 266 | + "n_items": 200, | |
| 267 | + "n_clusters": 200, | |
| 268 | + "n_boot": 200 | |
| 269 | + } | |
| 270 | + } | |
| 271 | + }, | |
| 272 | + "1": { | |
| 273 | + "donor": { | |
| 274 | + "n_params": 104128, | |
| 275 | + "train_seconds": 4.102132081985474, | |
| 276 | + "final_dev": { | |
| 277 | + "step": 200, | |
| 278 | + "loss": 1.6042448282241821, | |
| 279 | + "dev_acc": 0.14333333333333334, | |
| 280 | + "dev_trace_acc": 0.06333333333333334, | |
| 281 | + "lr": 0.0, | |
| 282 | + "elapsed_s": 4.0953710079193115 | |
| 283 | + }, | |
| 284 | + "eval": { | |
| 285 | + "target_iid": { | |
| 286 | + "split": "target_iid", | |
| 287 | + "split_hash": "88d9bb27db961222", | |
| 288 | + "n": 300, | |
| 289 | + "accuracy": 0.12666666666666668, | |
| 290 | + "trace_accuracy": 0.043333333333333335, | |
| 291 | + "ci95": { | |
| 292 | + "estimate": 0.12666666666666668, | |
| 293 | + "low": 0.08705976579761379, | |
| 294 | + "high": 0.16720369270757476, | |
| 295 | + "level": 0.95, | |
| 296 | + "n_items": 300, | |
| 297 | + "n_clusters": 269, | |
| 298 | + "n_boot": 200 | |
| 299 | + }, | |
| 300 | + "omega_step_acc": { | |
| 301 | + "estimate": 0.2966666666666667, | |
| 302 | + "low": 0.25, | |
| 303 | + "high": 0.3500085034013605, | |
| 304 | + "level": 0.95, | |
| 305 | + "n_items": 300, | |
| 306 | + "n_clusters": 269, | |
| 307 | + "n_boot": 200 | |
| 308 | + }, | |
| 309 | + "chance": 0.11333333333333333 | |
| 310 | + }, | |
| 311 | + "control_iid": { | |
| 312 | + "split": "control_iid", | |
| 313 | + "split_hash": "76bdfaf36a5f7519", | |
| 314 | + "n": 300, | |
| 315 | + "accuracy": 0.16, | |
| 316 | + "trace_accuracy": 0.07333333333333333, | |
| 317 | + "ci95": { | |
| 318 | + "estimate": 0.16, | |
| 319 | + "low": 0.12496946254071661, | |
| 320 | + "high": 0.19806930693069308, | |
| 321 | + "level": 0.95, | |
| 322 | + "n_items": 300, | |
| 323 | + "n_clusters": 293, | |
| 324 | + "n_boot": 200 | |
| 325 | + }, | |
| 326 | + "omega_step_acc": null, | |
| 327 | + "chance": 0.13 | |
| 328 | + }, | |
| 329 | + "comp_heldout": { | |
| 330 | + "split": "comp_heldout", | |
| 331 | + "split_hash": "68e83ab8472513d2", | |
| 332 | + "n": 300, | |
| 333 | + "accuracy": 0.11, | |
| 334 | + "trace_accuracy": 0.04, | |
| 335 | + "ci95": { | |
| 336 | + "estimate": 0.11, | |
| 337 | + "low": 0.07416016814914099, | |
| 338 | + "high": 0.14744774919614148, | |
| 339 | + "level": 0.95, | |
| 340 | + "n_items": 300, | |
| 341 | + "n_clusters": 241, | |
| 342 | + "n_boot": 200 | |
| 343 | + }, | |
| 344 | + "omega_step_acc": { | |
| 345 | + "estimate": 0.2833333333333333, | |
| 346 | + "low": 0.21655303030303033, | |
| 347 | + "high": 0.34637783891524665, | |
| 348 | + "level": 0.95, | |
| 349 | + "n_items": 180, | |
| 350 | + "n_clusters": 148, | |
| 351 | + "n_boot": 200 | |
| 352 | + }, | |
| 353 | + "chance": 0.11666666666666667 | |
| 354 | + }, | |
| 355 | + "len_ood": { | |
| 356 | + "split": "len_ood", | |
| 357 | + "split_hash": "6d8c13dc8b5c47fa", | |
| 358 | + "n": 200, | |
| 359 | + "accuracy": 0.06, | |
| 360 | + "trace_accuracy": 0.0, | |
| 361 | + "ci95": { | |
| 362 | + "estimate": 0.06, | |
| 363 | + "low": 0.03, | |
| 364 | + "high": 0.1, | |
| 365 | + "level": 0.95, | |
| 366 | + "n_items": 200, | |
| 367 | + "n_clusters": 200, | |
| 368 | + "n_boot": 200 | |
| 369 | + }, | |
| 370 | + "omega_step_acc": { | |
| 371 | + "estimate": 0.12173913043478261, | |
| 372 | + "low": 0.06086956521739131, | |
| 373 | + "high": 0.18282608695652178, | |
| 374 | + "level": 0.95, | |
| 375 | + "n_items": 115, | |
| 376 | + "n_clusters": 115, | |
| 377 | + "n_boot": 200 | |
| 378 | + }, | |
| 379 | + "chance": 0.15 | |
| 380 | + } | |
| 381 | + } | |
| 382 | + }, | |
| 383 | + "recipient": { | |
| 384 | + "n_params": 104128, | |
| 385 | + "train_seconds": 4.027623891830444, | |
| 386 | + "final_dev": { | |
| 387 | + "step": 200, | |
| 388 | + "loss": 1.5427294969558716, | |
| 389 | + "dev_acc": 0.18333333333333332, | |
| 390 | + "dev_trace_acc": 0.08, | |
| 391 | + "lr": 0.0, | |
| 392 | + "elapsed_s": 4.020693302154541 | |
| 393 | + }, | |
| 394 | + "eval": { | |
| 395 | + "target_iid": { | |
| 396 | + "split": "target_iid", | |
| 397 | + "split_hash": "88d9bb27db961222", | |
| 398 | + "n": 300, | |
| 399 | + "accuracy": 0.09, | |
| 400 | + "trace_accuracy": 0.01, | |
| 401 | + "ci95": { | |
| 402 | + "estimate": 0.09, | |
| 403 | + "low": 0.06476109215017066, | |
| 404 | + "high": 0.1189967845659164, | |
| 405 | + "level": 0.95, | |
| 406 | + "n_items": 300, | |
| 407 | + "n_clusters": 269, | |
| 408 | + "n_boot": 200 | |
| 409 | + }, | |
| 410 | + "omega_step_acc": { | |
| 411 | + "estimate": 0.07666666666666666, | |
| 412 | + "low": 0.05049660484443093, | |
| 413 | + "high": 0.10544057835108876, | |
| 414 | + "level": 0.95, | |
| 415 | + "n_items": 300, | |
| 416 | + "n_clusters": 269, | |
| 417 | + "n_boot": 200 | |
| 418 | + }, | |
| 419 | + "chance": 0.11333333333333333 | |
| 420 | + }, | |
| 421 | + "control_iid": { | |
| 422 | + "split": "control_iid", | |
| 423 | + "split_hash": "76bdfaf36a5f7519", | |
| 424 | + "n": 300, | |
| 425 | + "accuracy": 0.14666666666666667, | |
| 426 | + "trace_accuracy": 0.07, | |
| 427 | + "ci95": { | |
| 428 | + "estimate": 0.14666666666666667, | |
| 429 | + "low": 0.10328378378378379, | |
| 430 | + "high": 0.1875822368421053, | |
| 431 | + "level": 0.95, | |
| 432 | + "n_items": 300, | |
| 433 | + "n_clusters": 293, | |
| 434 | + "n_boot": 200 | |
| 435 | + }, | |
| 436 | + "omega_step_acc": null, | |
| 437 | + "chance": 0.13 | |
| 438 | + }, | |
| 439 | + "comp_heldout": { | |
| 440 | + "split": "comp_heldout", | |
| 441 | + "split_hash": "68e83ab8472513d2", | |
| 442 | + "n": 300, | |
| 443 | + "accuracy": 0.09666666666666666, | |
| 444 | + "trace_accuracy": 0.02, | |
| 445 | + "ci95": { | |
| 446 | + "estimate": 0.09666666666666666, | |
| 447 | + "low": 0.062289429055963824, | |
| 448 | + "high": 0.12638747170519454, | |
| 449 | + "level": 0.95, | |
| 450 | + "n_items": 300, | |
| 451 | + "n_clusters": 241, | |
| 452 | + "n_boot": 200 | |
| 453 | + }, | |
| 454 | + "omega_step_acc": { | |
| 455 | + "estimate": 0.05, | |
| 456 | + "low": 0.022308542830540044, | |
| 457 | + "high": 0.08298133753051525, | |
| 458 | + "level": 0.95, | |
| 459 | + "n_items": 180, | |
| 460 | + "n_clusters": 148, | |
| 461 | + "n_boot": 200 | |
| 462 | + }, | |
| 463 | + "chance": 0.11666666666666667 | |
| 464 | + }, | |
| 465 | + "len_ood": { | |
| 466 | + "split": "len_ood", | |
| 467 | + "split_hash": "6d8c13dc8b5c47fa", | |
| 468 | + "n": 200, | |
| 469 | + "accuracy": 0.06, | |
| 470 | + "trace_accuracy": 0.0, | |
| 471 | + "ci95": { | |
| 472 | + "estimate": 0.06, | |
| 473 | + "low": 0.03, | |
| 474 | + "high": 0.09, | |
| 475 | + "level": 0.95, | |
| 476 | + "n_items": 200, | |
| 477 | + "n_clusters": 200, | |
| 478 | + "n_boot": 200 | |
| 479 | + }, | |
| 480 | + "omega_step_acc": { | |
| 481 | + "estimate": 0.09565217391304348, | |
| 482 | + "low": 0.034782608695652174, | |
| 483 | + "high": 0.14782608695652175, | |
| 484 | + "level": 0.95, | |
| 485 | + "n_items": 115, | |
| 486 | + "n_clusters": 115, | |
| 487 | + "n_boot": 200 | |
| 488 | + }, | |
| 489 | + "chance": 0.15 | |
| 490 | + } | |
| 491 | + } | |
| 492 | + }, | |
| 493 | + "gap": { | |
| 494 | + "target_iid": { | |
| 495 | + "estimate": 0.03666666666666667, | |
| 496 | + "low": -8.064516129030941e-05, | |
| 497 | + "high": 0.07962905401442731, | |
| 498 | + "level": 0.95, | |
| 499 | + "n_items": 300, | |
| 500 | + "n_clusters": 269, | |
| 501 | + "n_boot": 200 | |
| 502 | + }, | |
| 503 | + "control_iid": { | |
| 504 | + "estimate": 0.013333333333333334, | |
| 505 | + "low": -0.026917070901721032, | |
| 506 | + "high": 0.06333862876254182, | |
| 507 | + "level": 0.95, | |
| 508 | + "n_items": 300, | |
| 509 | + "n_clusters": 293, | |
| 510 | + "n_boot": 200 | |
| 511 | + }, | |
| 512 | + "comp_heldout": { | |
| 513 | + "estimate": 0.013333333333333334, | |
| 514 | + "low": -0.017094429635534737, | |
| 515 | + "high": 0.05065326224103545, | |
| 516 | + "level": 0.95, | |
| 517 | + "n_items": 300, | |
| 518 | + "n_clusters": 241, | |
| 519 | + "n_boot": 200 | |
| 520 | + }, | |
| 521 | + "len_ood": { | |
| 522 | + "estimate": 0.0, | |
| 523 | + "low": -0.04, | |
| 524 | + "high": 0.03512500000000003, | |
| 525 | + "level": 0.95, | |
| 526 | + "n_items": 200, | |
| 527 | + "n_clusters": 200, | |
| 528 | + "n_boot": 200 | |
| 529 | + } | |
| 530 | + } | |
| 531 | + } | |
| 532 | + }, | |
| 533 | + "noop": { | |
| 534 | + "donor_s0": { | |
| 535 | + "deterministic_repeat": true, | |
| 536 | + "capture_all_bitwise_identity": true, | |
| 537 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 538 | + "enabled_zero_hook_changes_output": true, | |
| 539 | + "n_hook_points": 20, | |
| 540 | + "n_items": 256 | |
| 541 | + }, | |
| 542 | + "recipient_s0": { | |
| 543 | + "deterministic_repeat": true, | |
| 544 | + "capture_all_bitwise_identity": true, | |
| 545 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 546 | + "enabled_zero_hook_changes_output": true, | |
| 547 | + "n_hook_points": 20, | |
| 548 | + "n_items": 256 | |
| 549 | + }, | |
| 550 | + "donor_s1": { | |
| 551 | + "deterministic_repeat": true, | |
| 552 | + "capture_all_bitwise_identity": true, | |
| 553 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 554 | + "enabled_zero_hook_changes_output": true, | |
| 555 | + "n_hook_points": 20, | |
| 556 | + "n_items": 256 | |
| 557 | + }, | |
| 558 | + "recipient_s1": { | |
| 559 | + "deterministic_repeat": true, | |
| 560 | + "capture_all_bitwise_identity": true, | |
| 561 | + "disabled_modifying_hook_bitwise_identity": true, | |
| 562 | + "enabled_zero_hook_changes_output": true, | |
| 563 | + "n_hook_points": 20, | |
| 564 | + "n_items": 256 | |
| 565 | + } | |
| 566 | + }, | |
| 567 | + "localization": { | |
| 568 | + "n_items": 490, | |
| 569 | + "read_position": 6, | |
| 570 | + "positions": [ | |
| 571 | + "<bos>", | |
| 572 | + "v0", | |
| 573 | + "op1", | |
| 574 | + "\u03a9", | |
| 575 | + "op3", | |
| 576 | + "=", | |
| 577 | + "r1" | |
| 578 | + ], | |
| 579 | + "families": { | |
| 580 | + "resid_post": { | |
| 581 | + "s0": { | |
| 582 | + "flip_rate": [ | |
| 583 | + [ | |
| 584 | + 0.1081632673740387, | |
| 585 | + 0.1081632673740387, | |
| 586 | + 0.1081632673740387, | |
| 587 | + 0.14897958934307098, | |
| 588 | + 0.11020407825708389, | |
| 589 | + 0.1081632673740387, | |
| 590 | + 0.2938775420188904 | |
| 591 | + ], | |
| 592 | + [ | |
| 593 | + 0.1081632673740387, | |
| 594 | + 0.1081632673740387, | |
| 595 | + 0.1081632673740387, | |
| 596 | + 0.10408163070678711, | |
| 597 | + 0.1061224490404129, | |
| 598 | + 0.1081632673740387, | |
| 599 | + 0.3306122422218323 | |
| 600 | + ], | |
| 601 | + [ | |
| 602 | + 0.1081632673740387, | |
| 603 | + 0.1081632673740387, | |
| 604 | + 0.1081632673740387, | |
| 605 | + 0.1081632673740387, | |
| 606 | + 0.1081632673740387, | |
| 607 | + 0.1081632673740387, | |
| 608 | + 0.3163265287876129 | |
| 609 | + ] | |
| 610 | + ], | |
| 611 | + "logit_recovery": [ | |
| 612 | + [ | |
| 613 | + 0.0, | |
| 614 | + 0.0, | |
| 615 | + 0.0, | |
| 616 | + 0.6777816414833069, | |
| 617 | + 0.17032797634601593, | |
| 618 | + 0.044533759355545044, | |
| 619 | + 0.24952709674835205 | |
| 620 | + ], | |
| 621 | + [ | |
| 622 | + 0.0, | |
| 623 | + 0.0, | |
| 624 | + 0.0, | |
| 625 | + 0.5468828678131104, | |
| 626 | + 0.21181631088256836, | |
| 627 | + 0.0718715488910675, | |
| 628 | + 0.43368828296661377 | |
| 629 | + ], | |
| 630 | + [ | |
| 631 | + 0.0, | |
| 632 | + 0.0, | |
| 633 | + 0.0, | |
| 634 | + 0.0, | |
| 635 | + 0.0, | |
| 636 | + 0.0, | |
| 637 | + 0.7673469185829163 | |
| 638 | + ] | |
| 639 | + ] | |
| 640 | + }, | |
| 641 | + "s1": { | |
| 642 | + "flip_rate": [ | |
| 643 | + [ | |
| 644 | + 0.15510204434394836, | |
| 645 | + 0.15510204434394836, | |
| 646 | + 0.15510204434394836, | |
| 647 | + 0.16938775777816772, | |
| 648 | + 0.15306122601032257, | |
| 649 | + 0.15510204434394836, | |
| 650 | + 0.48367348313331604 | |
| 651 | + ], | |
| 652 | + [ | |
| 653 | + 0.15510204434394836, | |
| 654 | + 0.15510204434394836, | |
| 655 | + 0.15510204434394836, | |
| 656 | + 0.15510204434394836, | |
| 657 | + 0.15306122601032257, | |
| 658 | + 0.15510204434394836, | |
| 659 | + 0.5224489569664001 | |
| 660 | + ], | |
| 661 | + [ | |
| 662 | + 0.15510204434394836, | |
| 663 | + 0.15510204434394836, | |
| 664 | + 0.15510204434394836, | |
| 665 | + 0.15510204434394836, | |
| 666 | + 0.15510204434394836, | |
| 667 | + 0.15510204434394836, | |
| 668 | + 0.5510203838348389 | |
| 669 | + ] | |
| 670 | + ], | |
| 671 | + "logit_recovery": [ | |
| 672 | + [ | |
| 673 | + 0.0, | |
| 674 | + 0.0, | |
| 675 | + 0.0, | |
| 676 | + 0.5372936725616455, | |
| 677 | + 0.15368731319904327, | |
| 678 | + -0.08139883726835251, | |
| 679 | + 0.4371233284473419 | |
| 680 | + ], | |
| 681 | + [ | |
| 682 | + 0.0, | |
| 683 | + 0.0, | |
| 684 | + 0.0, | |
| 685 | + 0.2054908275604248, | |
| 686 | + 0.10810171812772751, | |
| 687 | + -0.11871961504220963, | |
| 688 | + 0.5426056385040283 | |
| 689 | + ], | |
| 690 | + [ | |
| 691 | + 0.0, | |
| 692 | + 0.0, | |
| 693 | + 0.0, | |
| 694 | + 0.0, | |
| 695 | + 0.0, | |
| 696 | + 0.0, | |
| 697 | + 0.640816330909729 | |
| 698 | + ] | |
| 699 | + ] | |
| 700 | + }, | |
| 701 | + "mean_flip_rate": [ | |
| 702 | + [ | |
| 703 | + 0.13163265585899353, | |
| 704 | + 0.13163265585899353, | |
| 705 | + 0.13163265585899353, | |
| 706 | + 0.15918367356061935, | |
| 707 | + 0.13163265213370323, | |
| 708 | + 0.13163265585899353, | |
| 709 | + 0.3887755125761032 | |
| 710 | + ], | |
| 711 | + [ | |
| 712 | + 0.13163265585899353, | |
| 713 | + 0.13163265585899353, | |
| 714 | + 0.13163265585899353, | |
| 715 | + 0.12959183752536774, | |
| 716 | + 0.12959183752536774, | |
| 717 | + 0.13163265585899353, | |
| 718 | + 0.4265305995941162 | |
| 719 | + ], | |
| 720 | + [ | |
| 721 | + 0.13163265585899353, | |
| 722 | + 0.13163265585899353, | |
| 723 | + 0.13163265585899353, | |
| 724 | + 0.13163265585899353, | |
| 725 | + 0.13163265585899353, | |
| 726 | + 0.13163265585899353, | |
| 727 | + 0.4336734563112259 | |
| 728 | + ] | |
| 729 | + ] | |
| 730 | + }, | |
| 731 | + "attn_out": { | |
| 732 | + "s0": { | |
| 733 | + "flip_rate": [ | |
| 734 | + [ | |
| 735 | + 0.1081632673740387, | |
| 736 | + 0.1081632673740387, | |
| 737 | + 0.1081632673740387, | |
| 738 | + 0.12448979914188385, | |
| 739 | + 0.11020407825708389, | |
| 740 | + 0.1081632673740387, | |
| 741 | + 0.2938775420188904 | |
| 742 | + ], | |
| 743 | + [ | |
| 744 | + 0.1081632673740387, | |
| 745 | + 0.1081632673740387, | |
| 746 | + 0.1081632673740387, | |
| 747 | + 0.1081632673740387, | |
| 748 | + 0.1061224490404129, | |
| 749 | + 0.1081632673740387, | |
| 750 | + 0.16734693944454193 | |
| 751 | + ], | |
| 752 | + [ | |
| 753 | + 0.1081632673740387, | |
| 754 | + 0.1081632673740387, | |
| 755 | + 0.1081632673740387, | |
| 756 | + 0.1081632673740387, | |
| 757 | + 0.1081632673740387, | |
| 758 | + 0.1081632673740387, | |
| 759 | + 0.09795918315649033 | |
| 760 | + ] | |
| 761 | + ], | |
| 762 | + "logit_recovery": [ | |
| 763 | + [ | |
| 764 | + 0.0, | |
| 765 | + 0.0, | |
| 766 | + 0.0, | |
| 767 | + 0.6502549052238464, | |
| 768 | + 0.17032797634601593, | |
| 769 | + 0.044533759355545044, | |
| 770 | + 0.24952709674835205 | |
| 771 | + ], | |
| 772 | + [ | |
| 773 | + 0.0, | |
| 774 | + 0.0, | |
| 775 | + 0.0, | |
| 776 | + 0.16967330873012543, | |
| 777 | + 0.0522448793053627, | |
| 778 | + 0.0550827831029892, | |
| 779 | + 0.31173965334892273 | |
| 780 | + ], | |
| 781 | + [ | |
| 782 | + 0.0, | |
| 783 | + 0.0, | |
| 784 | + 0.0, | |
| 785 | + 0.0, | |
| 786 | + 0.0, | |
| 787 | + 0.0, | |
| 788 | + 0.5542861819267273 | |
| 789 | + ] | |
| 790 | + ] | |
| 791 | + }, | |
| 792 | + "s1": { | |
| 793 | + "flip_rate": [ | |
| 794 | + [ | |
| 795 | + 0.15510204434394836, | |
| 796 | + 0.15510204434394836, | |
| 797 | + 0.15510204434394836, | |
| 798 | + 0.15510204434394836, | |
| 799 | + 0.15306122601032257, | |
| 800 | + 0.15510204434394836, | |
| 801 | + 0.48367348313331604 | |
| 802 | + ], | |
| 803 | + [ | |
| 804 | + 0.15510204434394836, | |
| 805 | + 0.15510204434394836, | |
| 806 | + 0.15510204434394836, | |
| 807 | + 0.15510204434394836, | |
| 808 | + 0.15510204434394836, | |
| 809 | + 0.15510204434394836, | |
| 810 | + 0.1816326528787613 | |
| 811 | + ], | |
| 812 | + [ | |
| 813 | + 0.15510204434394836, | |
| 814 | + 0.15510204434394836, | |
| 815 | + 0.15510204434394836, | |
| 816 | + 0.15510204434394836, | |
| 817 | + 0.15510204434394836, | |
| 818 | + 0.15510204434394836, | |
| 819 | + 0.13469387590885162 | |
| 820 | + ] | |
| 821 | + ], | |
| 822 | + "logit_recovery": [ | |
| 823 | + [ | |
| 824 | + 0.0, | |
| 825 | + 0.0, | |
| 826 | + 0.0, | |
| 827 | + 0.3812299370765686, | |
| 828 | + 0.15368731319904327, | |
| 829 | + -0.08139883726835251, | |
| 830 | + 0.4371233284473419 | |
| 831 | + ], | |
| 832 | + [ | |
| 833 | + 0.0, | |
| 834 | + 0.0, | |
| 835 | + 0.0, | |
| 836 | + -0.11997843533754349, | |
| 837 | + -0.10889920592308044, | |
| 838 | + -0.15029844641685486, | |
| 839 | + 0.504331648349762 | |
| 840 | + ], | |
| 841 | + [ | |
| 842 | + 0.0, | |
| 843 | + 0.0, | |
| 844 | + 0.0, | |
| 845 | + 0.0, | |
| 846 | + 0.0, | |
| 847 | + 0.0, | |
| 848 | + 0.21160942316055298 | |
| 849 | + ] | |
| 850 | + ] | |
| 851 | + }, | |
| 852 | + "mean_flip_rate": [ | |
| 853 | + [ | |
| 854 | + 0.13163265585899353, | |
| 855 | + 0.13163265585899353, | |
| 856 | + 0.13163265585899353, | |
| 857 | + 0.1397959217429161, | |
| 858 | + 0.13163265213370323, | |
| 859 | + 0.13163265585899353, | |
| 860 | + 0.3887755125761032 | |
| 861 | + ], | |
| 862 | + [ | |
| 863 | + 0.13163265585899353, | |
| 864 | + 0.13163265585899353, | |
| 865 | + 0.13163265585899353, | |
| 866 | + 0.13163265585899353, | |
| 867 | + 0.13061224669218063, | |
| 868 | + 0.13163265585899353, | |
| 869 | + 0.1744897961616516 | |
| 870 | + ], | |
| 871 | + [ | |
| 872 | + 0.13163265585899353, | |
| 873 | + 0.13163265585899353, | |
| 874 | + 0.13163265585899353, | |
| 875 | + 0.13163265585899353, | |
| 876 | + 0.13163265585899353, | |
| 877 | + 0.13163265585899353, | |
| 878 | + 0.11632652953267097 | |
| 879 | + ] | |
| 880 | + ] | |
| 881 | + }, | |
| 882 | + "mlp_out": { | |
| 883 | + "s0": { | |
| 884 | + "flip_rate": [ | |
| 885 | + [ | |
| 886 | + 0.1081632673740387, | |
| 887 | + 0.1081632673740387, | |
| 888 | + 0.1081632673740387, | |
| 889 | + 0.12857143580913544, | |
| 890 | + 0.1081632673740387, | |
| 891 | + 0.1081632673740387, | |
| 892 | + 0.24285714328289032 | |
| 893 | + ], | |
| 894 | + [ | |
| 895 | + 0.1081632673740387, | |
| 896 | + 0.1081632673740387, | |
| 897 | + 0.1081632673740387, | |
| 898 | + 0.11224489659070969, | |
| 899 | + 0.1081632673740387, | |
| 900 | + 0.1081632673740387, | |
| 901 | + 0.2469387799501419 | |
| 902 | + ], | |
| 903 | + [ | |
| 904 | + 0.1081632673740387, | |
| 905 | + 0.1081632673740387, | |
| 906 | + 0.1081632673740387, | |
| 907 | + 0.1081632673740387, | |
| 908 | + 0.1081632673740387, | |
| 909 | + 0.1081632673740387, | |
| 910 | + 0.20000000298023224 | |
| 911 | + ] | |
| 912 | + ], | |
| 913 | + "logit_recovery": [ | |
| 914 | + [ | |
| 915 | + 0.0, | |
| 916 | + 0.0, | |
| 917 | + 0.0, | |
| 918 | + 0.676521897315979, | |
| 919 | + 0.20865347981452942, | |
| 920 | + 0.0366634726524353, | |
| 921 | + 0.1594724953174591 | |
| 922 | + ], | |
| 923 | + [ | |
| 924 | + 0.0, | |
| 925 | + 0.0, | |
| 926 | + 0.0, | |
| 927 | + 0.4173266291618347, | |
| 928 | + 0.1889232099056244, | |
| 929 | + 0.07385488599538803, | |
| 930 | + 0.49284762144088745 | |
| 931 | + ], | |
| 932 | + [ | |
| 933 | + 0.0, | |
| 934 | + 0.0, | |
| 935 | + 0.0, | |
| 936 | + 0.0, | |
| 937 | + 0.0, | |
| 938 | + 0.0, | |
| 939 | + 0.1028335839509964 | |
| 940 | + ] | |
| 941 | + ] | |
| 942 | + }, | |
| 943 | + "s1": { | |
| 944 | + "flip_rate": [ | |
| 945 | + [ | |
| 946 | + 0.15510204434394836, | |
| 947 | + 0.15510204434394836, | |
| 948 | + 0.15510204434394836, | |
| 949 | + 0.17142857611179352, | |
| 950 | + 0.15714286267757416, | |
| 951 | + 0.15510204434394836, | |
| 952 | + 0.33469387888908386 | |
| 953 | + ], | |
| 954 | + [ | |
| 955 | + 0.15510204434394836, | |
| 956 | + 0.15510204434394836, | |
| 957 | + 0.15510204434394836, | |
| 958 | + 0.15306122601032257, | |
| 959 | + 0.15510204434394836, | |
| 960 | + 0.15510204434394836, | |
| 961 | + 0.3938775658607483 | |
| 962 | + ], | |
| 963 | + [ | |
| 964 | + 0.15510204434394836, | |
| 965 | + 0.15510204434394836, | |
| 966 | + 0.15510204434394836, | |
| 967 | + 0.15510204434394836, | |
| 968 | + 0.15510204434394836, | |
| 969 | + 0.15510204434394836, | |
| 970 | + 0.23673468828201294 | |
| 971 | + ] | |
| 972 | + ], | |
| 973 | + "logit_recovery": [ | |
| 974 | + [ | |
| 975 | + 0.0, | |
| 976 | + 0.0, | |
| 977 | + 0.0, | |
| 978 | + 0.4843812882900238, | |
| 979 | + 0.14703114330768585, | |
| 980 | + -0.07759958505630493, | |
| 981 | + 0.24141383171081543 | |
| 982 | + ], | |
| 983 | + [ | |
| 984 | + 0.0, | |
| 985 | + 0.0, | |
| 986 | + 0.0, | |
| 987 | + -0.028258221223950386, | |
| 988 | + 0.021661778911948204, | |
| 989 | + 0.09376108646392822, | |
| 990 | + 0.47914665937423706 | |
| 991 | + ], | |
| 992 | + [ | |
| 993 | + 0.0, | |
| 994 | + 0.0, | |
| 995 | + 0.0, | |
| 996 | + 0.0, | |
| 997 | + 0.0, | |
| 998 | + 0.0, | |
| 999 | + 0.2513795495033264 | |
| 1000 | + ] | |
| 1001 | + ] | |
| 1002 | + }, | |
| 1003 | + "mean_flip_rate": [ | |
| 1004 | + [ | |
| 1005 | + 0.13163265585899353, | |
| 1006 | + 0.13163265585899353, | |
| 1007 | + 0.13163265585899353, | |
| 1008 | + 0.15000000596046448, | |
| 1009 | + 0.13265306502580643, | |
| 1010 | + 0.13163265585899353, | |
| 1011 | + 0.2887755110859871 | |
| 1012 | + ], | |
| 1013 | + [ | |
| 1014 | + 0.13163265585899353, | |
| 1015 | + 0.13163265585899353, | |
| 1016 | + 0.13163265585899353, | |
| 1017 | + 0.13265306130051613, | |
| 1018 | + 0.13163265585899353, | |
| 1019 | + 0.13163265585899353, | |
| 1020 | + 0.3204081729054451 | |
| 1021 | + ], | |
| 1022 | + [ | |
| 1023 | + 0.13163265585899353, | |
| 1024 | + 0.13163265585899353, | |
| 1025 | + 0.13163265585899353, | |
| 1026 | + 0.13163265585899353, | |
| 1027 | + 0.13163265585899353, | |
| 1028 | + 0.13163265585899353, | |
| 1029 | + 0.2183673456311226 | |
| 1030 | + ] | |
| 1031 | + ] | |
| 1032 | + } | |
| 1033 | + }, | |
| 1034 | + "ablation": { | |
| 1035 | + "resid_post": { | |
| 1036 | + "s0": [ | |
| 1037 | + [ | |
| 1038 | + 0.2857142984867096, | |
| 1039 | + 0.30816325545310974, | |
| 1040 | + 0.3204081654548645, | |
| 1041 | + 0.31224489212036133, | |
| 1042 | + 0.31224489212036133, | |
| 1043 | + 0.3224489688873291, | |
| 1044 | + 0.11428571492433548 | |
| 1045 | + ], | |
| 1046 | + [ | |
| 1047 | + 0.31224489212036133, | |
| 1048 | + 0.3224489688873291, | |
| 1049 | + 0.30612245202064514, | |
| 1050 | + 0.30612245202064514, | |
| 1051 | + 0.29591837525367737, | |
| 1052 | + 0.3183673322200775, | |
| 1053 | + 0.044897958636283875 | |
| 1054 | + ], | |
| 1055 | + [ | |
| 1056 | + 0.3163265287876129, | |
| 1057 | + 0.3163265287876129, | |
| 1058 | + 0.3163265287876129, | |
| 1059 | + 0.3163265287876129, | |
| 1060 | + 0.3163265287876129, | |
| 1061 | + 0.3163265287876129, | |
| 1062 | + 0.11428571492433548 | |
| 1063 | + ] | |
| 1064 | + ], | |
| 1065 | + "s1": [ | |
| 1066 | + [ | |
| 1067 | + 0.4734693765640259, | |
| 1068 | + 0.518367350101471, | |
| 1069 | + 0.5469387769699097, | |
| 1070 | + 0.48163264989852905, | |
| 1071 | + 0.5469387769699097, | |
| 1072 | + 0.5265306234359741, | |
| 1073 | + 0.06530611962080002 | |
| 1074 | + ], | |
| 1075 | + [ | |
| 1076 | + 0.559183657169342, | |
| 1077 | + 0.563265323638916, | |
| 1078 | + 0.559183657169342, | |
| 1079 | + 0.5306122303009033, | |
| 1080 | + 0.5469387769699097, | |
| 1081 | + 0.5469387769699097, | |
| 1082 | + 0.059183672070503235 | |
| 1083 | + ], | |
| 1084 | + [ | |
| 1085 | + 0.5510203838348389, | |
| 1086 | + 0.5510203838348389, | |
| 1087 | + 0.5510203838348389, | |
| 1088 | + 0.5510203838348389, | |
| 1089 | + 0.5510203838348389, | |
| 1090 | + 0.5510203838348389, | |
| 1091 | + 0.08571428805589676 | |
| 1092 | + ] | |
| 1093 | + ] | |
| 1094 | + }, | |
| 1095 | + "attn_out": { | |
| 1096 | + "s0": [ | |
| 1097 | + [ | |
| 1098 | + 0.31224489212036133, | |
| 1099 | + 0.31224489212036133, | |
| 1100 | + 0.31020408868789673, | |
| 1101 | + 0.3285714387893677, | |
| 1102 | + 0.30816325545310974, | |
| 1103 | + 0.31020408868789673, | |
| 1104 | + 0.1775510162115097 | |
| 1105 | + ], | |
| 1106 | + [ | |
| 1107 | + 0.3142857253551483, | |
| 1108 | + 0.31020408868789673, | |
| 1109 | + 0.3142857253551483, | |
| 1110 | + 0.3224489688873291, | |
| 1111 | + 0.3306122422218323, | |
| 1112 | + 0.3142857253551483, | |
| 1113 | + 0.34285715222358704 | |
| 1114 | + ], | |
| 1115 | + [ | |
| 1116 | + 0.3163265287876129, | |
| 1117 | + 0.3163265287876129, | |
| 1118 | + 0.3163265287876129, | |
| 1119 | + 0.3163265287876129, | |
| 1120 | + 0.3163265287876129, | |
| 1121 | + 0.3163265287876129, | |
| 1122 | + 0.3489795923233032 | |
| 1123 | + ] | |
| 1124 | + ], | |
| 1125 | + "s1": [ | |
| 1126 | + [ | |
| 1127 | + 0.5040816068649292, | |
| 1128 | + 0.5122448801994324, | |
| 1129 | + 0.5428571701049805, | |
| 1130 | + 0.5510203838348389, | |
| 1131 | + 0.5265306234359741, | |
| 1132 | + 0.5367347002029419, | |
| 1133 | + 0.27142858505249023 | |
| 1134 | + ], | |
| 1135 | + [ | |
| 1136 | + 0.5551020503044128, | |
| 1137 | + 0.5530612468719482, | |
| 1138 | + 0.5571428537368774, | |
| 1139 | + 0.5530612468719482, | |
| 1140 | + 0.5612244606018066, | |
| 1141 | + 0.5510203838348389, | |
| 1142 | + 0.3489795923233032 | |
| 1143 | + ], | |
| 1144 | + [ | |
| 1145 | + 0.5510203838348389, | |
| 1146 | + 0.5510203838348389, | |
| 1147 | + 0.5510203838348389, | |
| 1148 | + 0.5510203838348389, | |
| 1149 | + 0.5510203838348389, | |
| 1150 | + 0.5510203838348389, | |
| 1151 | + 0.48775508999824524 | |
| 1152 | + ] | |
| 1153 | + ] | |
| 1154 | + }, | |
| 1155 | + "mlp_out": { | |
| 1156 | + "s0": [ | |
| 1157 | + [ | |
| 1158 | + 0.30408161878585815, | |
| 1159 | + 0.30612245202064514, | |
| 1160 | + 0.30612245202064514, | |
| 1161 | + 0.3224489688873291, | |
| 1162 | + 0.3204081654548645, | |
| 1163 | + 0.3306122422218323, | |
| 1164 | + 0.29795917868614197 | |
| 1165 | + ], | |
| 1166 | + [ | |
| 1167 | + 0.3224489688873291, | |
| 1168 | + 0.3183673322200775, | |
| 1169 | + 0.3142857253551483, | |
| 1170 | + 0.3163265287876129, | |
| 1171 | + 0.30816325545310974, | |
| 1172 | + 0.3244898021221161, | |
| 1173 | + 0.2489795982837677 | |
| 1174 | + ], | |
| 1175 | + [ | |
| 1176 | + 0.3163265287876129, | |
| 1177 | + 0.3163265287876129, | |
| 1178 | + 0.3163265287876129, | |
| 1179 | + 0.3163265287876129, | |
| 1180 | + 0.3163265287876129, | |
| 1181 | + 0.3163265287876129, | |
| 1182 | + 0.27551019191741943 | |
| 1183 | + ] | |
| 1184 | + ], | |
| 1185 | + "s1": [ | |
| 1186 | + [ | |
| 1187 | + 0.48367348313331604, | |
| 1188 | + 0.5102040767669678, | |
| 1189 | + 0.5551020503044128, | |
| 1190 | + 0.5102040767669678, | |
| 1191 | + 0.5510203838348389, | |
| 1192 | + 0.5224489569664001, | |
| 1193 | + 0.26326531171798706 | |
| 1194 | + ], | |
| 1195 | + [ | |
| 1196 | + 0.559183657169342, | |
| 1197 | + 0.5510203838348389, | |
| 1198 | + 0.559183657169342, | |
| 1199 | + 0.5571428537368774, | |
| 1200 | + 0.5530612468719482, | |
| 1201 | + 0.559183657169342, | |
| 1202 | + 0.40408164262771606 | |
| 1203 | + ], | |
| 1204 | + [ | |
| 1205 | + 0.5510203838348389, | |
| 1206 | + 0.5510203838348389, | |
| 1207 | + 0.5510203838348389, | |
| 1208 | + 0.5510203838348389, | |
| 1209 | + 0.5510203838348389, | |
| 1210 | + 0.5510203838348389, | |
| 1211 | + 0.4897959232330322 | |
| 1212 | + ] | |
| 1213 | + ] | |
| 1214 | + } | |
| 1215 | + }, | |
| 1216 | + "heads": { | |
| 1217 | + "omega_token": { | |
| 1218 | + "s0": [ | |
| 1219 | + [ | |
| 1220 | + 0.1081632673740387, | |
| 1221 | + 0.11428571492433548 | |
| 1222 | + ], | |
| 1223 | + [ | |
| 1224 | + 0.1081632673740387, | |
| 1225 | + 0.1081632673740387 | |
| 1226 | + ], | |
| 1227 | + [ | |
| 1228 | + 0.1081632673740387, | |
| 1229 | + 0.1081632673740387 | |
| 1230 | + ] | |
| 1231 | + ], | |
| 1232 | + "s1": [ | |
| 1233 | + [ | |
| 1234 | + 0.15714286267757416, | |
| 1235 | + 0.15102040767669678 | |
| 1236 | + ], | |
| 1237 | + [ | |
| 1238 | + 0.15510204434394836, | |
| 1239 | + 0.15510204434394836 | |
| 1240 | + ], | |
| 1241 | + [ | |
| 1242 | + 0.15510204434394836, | |
| 1243 | + 0.15510204434394836 | |
| 1244 | + ] | |
| 1245 | + ] | |
| 1246 | + }, | |
| 1247 | + "read_position": { | |
| 1248 | + "s0": [ | |
| 1249 | + [ | |
| 1250 | + 0.1755101978778839, | |
| 1251 | + 0.2102040797472 | |
| 1252 | + ], | |
| 1253 | + [ | |
| 1254 | + 0.12448979914188385, | |
| 1255 | + 0.15714286267757416 | |
| 1256 | + ], | |
| 1257 | + [ | |
| 1258 | + 0.1061224490404129, | |
| 1259 | + 0.10408163070678711 | |
| 1260 | + ] | |
| 1261 | + ], | |
| 1262 | + "s1": [ | |
| 1263 | + [ | |
| 1264 | + 0.36938774585723877, | |
| 1265 | + 0.26734694838523865 | |
| 1266 | + ], | |
| 1267 | + [ | |
| 1268 | + 0.1795918345451355, | |
| 1269 | + 0.15714286267757416 | |
| 1270 | + ], | |
| 1271 | + [ | |
| 1272 | + 0.15510204434394836, | |
| 1273 | + 0.14897958934307098 | |
| 1274 | + ] | |
| 1275 | + ] | |
| 1276 | + } | |
| 1277 | + }, | |
| 1278 | + "reproducibility": { | |
| 1279 | + "resid_post_s0_repeat_max_abs_diff": 0.0, | |
| 1280 | + "attn_out_s0_repeat_max_abs_diff": 0.0, | |
| 1281 | + "mlp_out_s0_repeat_max_abs_diff": 0.0, | |
| 1282 | + "resid_post_s1_repeat_max_abs_diff": 0.0, | |
| 1283 | + "attn_out_s1_repeat_max_abs_diff": 0.0, | |
| 1284 | + "mlp_out_s1_repeat_max_abs_diff": 0.0, | |
| 1285 | + "resid_post_across_seed_pearson_min": 0.9930306466962506, | |
| 1286 | + "attn_out_across_seed_pearson_min": 0.9706457352445615, | |
| 1287 | + "mlp_out_across_seed_pearson_min": 0.9732088508811297 | |
| 1288 | + }, | |
| 1289 | + "baselines": { | |
| 1290 | + "s0": { | |
| 1291 | + "clean_acc_on_clean_answer": 0.3163265287876129, | |
| 1292 | + "corrupt_run_acc_on_clean_answer(sham)": 0.1081632673740387 | |
| 1293 | + }, | |
| 1294 | + "s1": { | |
| 1295 | + "clean_acc_on_clean_answer": 0.5510203838348389, | |
| 1296 | + "corrupt_run_acc_on_clean_answer(sham)": 0.15510204434394836 | |
| 1297 | + } | |
| 1298 | + } | |
| 1299 | + }, | |
| 1300 | + "across_seeds": { | |
| 1301 | + "target_iid": { | |
| 1302 | + "donor": { | |
| 1303 | + "n_seeds": 2, | |
| 1304 | + "mean": 0.12, | |
| 1305 | + "sd": 0.009428090415820645, | |
| 1306 | + "min": 0.11333333333333333, | |
| 1307 | + "max": 0.12666666666666668 | |
| 1308 | + }, | |
| 1309 | + "recipient": { | |
| 1310 | + "n_seeds": 2, | |
| 1311 | + "mean": 0.09833333333333333, | |
| 1312 | + "sd": 0.0117851130197758, | |
| 1313 | + "min": 0.09, | |
| 1314 | + "max": 0.10666666666666667 | |
| 1315 | + } | |
| 1316 | + }, | |
| 1317 | + "control_iid": { | |
| 1318 | + "donor": { | |
| 1319 | + "n_seeds": 2, | |
| 1320 | + "mean": 0.155, | |
| 1321 | + "sd": 0.007071067811865481, | |
| 1322 | + "min": 0.15, | |
| 1323 | + "max": 0.16 | |
| 1324 | + }, | |
| 1325 | + "recipient": { | |
| 1326 | + "n_seeds": 2, | |
| 1327 | + "mean": 0.16166666666666668, | |
| 1328 | + "sd": 0.021213203435596427, | |
| 1329 | + "min": 0.14666666666666667, | |
| 1330 | + "max": 0.17666666666666667 | |
| 1331 | + } | |
| 1332 | + }, | |
| 1333 | + "comp_heldout": { | |
| 1334 | + "donor": { | |
| 1335 | + "n_seeds": 2, | |
| 1336 | + "mean": 0.12833333333333333, | |
| 1337 | + "sd": 0.025927248643506744, | |
| 1338 | + "min": 0.11, | |
| 1339 | + "max": 0.14666666666666667 | |
| 1340 | + }, | |
| 1341 | + "recipient": { | |
| 1342 | + "n_seeds": 2, | |
| 1343 | + "mean": 0.095, | |
| 1344 | + "sd": 0.002357022603955154, | |
| 1345 | + "min": 0.09333333333333334, | |
| 1346 | + "max": 0.09666666666666666 | |
| 1347 | + } | |
| 1348 | + }, | |
| 1349 | + "len_ood": { | |
| 1350 | + "donor": { | |
| 1351 | + "n_seeds": 2, | |
| 1352 | + "mean": 0.08249999999999999, | |
| 1353 | + "sd": 0.03181980515339464, | |
| 1354 | + "min": 0.06, | |
| 1355 | + "max": 0.105 | |
| 1356 | + }, | |
| 1357 | + "recipient": { | |
| 1358 | + "n_seeds": 2, | |
| 1359 | + "mean": 0.055, | |
| 1360 | + "sd": 0.007071067811865472, | |
| 1361 | + "min": 0.05, | |
| 1362 | + "max": 0.06 | |
| 1363 | + } | |
| 1364 | + } | |
| 1365 | + }, | |
| 1366 | + "across_seeds_omega_step": { | |
| 1367 | + "donor": { | |
| 1368 | + "n_seeds": 2, | |
| 1369 | + "mean": 0.2683333333333333, | |
| 1370 | + "sd": 0.04006938426723772, | |
| 1371 | + "min": 0.24, | |
| 1372 | + "max": 0.2966666666666667 | |
| 1373 | + }, | |
| 1374 | + "recipient": { | |
| 1375 | + "n_seeds": 2, | |
| 1376 | + "mean": 0.07, | |
| 1377 | + "sd": 0.009428090415820625, | |
| 1378 | + "min": 0.06333333333333334, | |
| 1379 | + "max": 0.07666666666666666 | |
| 1380 | + } | |
| 1381 | + }, | |
| 1382 | + "elapsed_seconds": 22.053595066070557 | |
| 1383 | +} | |
| \ No newline at end of file | ||
added
literature/arxiv_verified_2026-11-09.txt
+45 −0
@@ -0,0 +1,45 @@ | ||
| 1 | +2004.12265v2 | 2020-04-26 | Causal Mediation Analysis for Interpreting Neural NLP: The Case of Gender Bias | Jesse Vig, Sebastian Gehrmann, Yonatan Belinkov et al. | |
| 2 | +2106.07682v1 | 2021-06-14 | Revisiting Model Stitching to Compare Neural Representations | Yamini Bansal, Preetum Nakkiran, Boaz Barak | |
| 3 | +2310.01405v4 | 2023-10-02 | Representation Engineering: A Top-Down Approach to AI Transparency | Andy Zou, Long Phan, Sarah Chen et al. | |
| 4 | +2410.21276v1 | 2024-10-25 | GPT-4o System Card | OpenAI, :, Aaron Hurst et al. | |
| 5 | +2402.06660v4 | 2024-02-05 | A philosophical and ontological perspective on Artificial General Intelligence and the Metaverse | Martin Schmalzried | |
| 6 | +2306.01708v2 | 2023-06-02 | TIES-Merging: Resolving Interference When Merging Models | Prateek Yadav, Derek Tam, Leshem Choshen et al. | |
| 7 | +2608.09521v1 | 2026-08-10 | One Adapter Pair per Model: A Universal Activation Interface for Language Models | Su-Hyeon Kim, Jiwan Mun, Yo-Sub Han | |
| 8 | +2305.01610v2 | 2023-05-02 | Finding Neurons in a Haystack: Case Studies with Sparse Probing | Wes Gurnee, Neel Nanda, Matthew Pauly et al. | |
| 9 | +2305.14314v1 | 2023-05-23 | QLoRA: Efficient Finetuning of Quantized LLMs | Tim Dettmers, Artidoro Pagnoni, Ari Holtzman et al. | |
| 10 | +2310.15916v1 | 2023-10-24 | In-Context Learning Creates Task Vectors | Roee Hendel, Mor Geva, Amir Globerson | |
| 11 | +2404.14367v3 | 2024-04-22 | Preference Fine-Tuning of LLMs Should Leverage Suboptimal, On-Policy Data | Fahim Tajwar, Anikait Singh, Archit Sharma et al. | |
| 12 | +2405.07987v5 | 2024-05-13 | The Platonic Representation Hypothesis | Minyoung Huh, Brian Cheung, Tongzhou Wang et al. | |
| 13 | +2503.21073v3 | 2025-03-27 | Shared Global and Local Geometry of Language Model Embeddings | Andrew Lee, Melanie Weber, Fernanda Viégas et al. | |
| 14 | +2410.06981v4 | 2024-10-09 | Quantifying Feature Space Universality Across Large Language Models via Sparse Autoencoders | Michael Lan, Philip Torr, Austin Meek et al. | |
| 15 | +2310.15213v2 | 2023-10-23 | Function Vectors in Large Language Models | Eric Todd, Millicent L. Li, Arnab Sen Sharma et al. | |
| 16 | +2311.07320v1 | 2023-11-13 | Model structures on operads and algebras from a global perspective | Michael Batanin, Florian De Leger, David White | |
| 17 | +2601.16034v2 | 2026-01-22 | Universal Refusal Circuits Across LLMs: Cross-Model Transfer via Trajectory Replay and Concept-Basis Reconstruction | Tony Cristofano | |
| 18 | +2608.13596v1 | 2026-07-31 | Training-Free Knowledge Transfer Across Model Scales through Activation-Guided Pruning | Jiahe Fan, Si Chen, Yinghao Hou et al. | |
| 19 | +2209.04836v6 | 2022-09-11 | Git Re-Basin: Merging Models modulo Permutation Symmetries | Samuel K. Ainsworth, Jonathan Hayase, Siddhartha Srinivasa | |
| 20 | +2302.06600v2 | 2023-02-13 | Task-Specific Skill Localization in Fine-tuned Language Models | Abhishek Panigrahi, Nikunj Saunshi, Haoyu Zhao et al. | |
| 21 | +2308.09124v2 | 2023-08-17 | Linearity of Relation Decoding in Transformer Language Models | Evan Hernandez, Arnab Sen Sharma, Tal Haklay et al. | |
| 22 | +1503.00030v1 | 2015-02-27 | Parsing as Reduction | Daniel Fernández-González, André F. T. Martins | |
| 23 | +1706.05806v2 | 2017-06-19 | SVCCA: Singular Vector Canonical Correlation Analysis for Deep Learning Dynamics and Interpretability | Maithra Raghu, Justin Gilmer, Jason Yosinski et al. | |
| 24 | +2502.03714v2 | 2025-02-06 | Universal Sparse Autoencoders: Interpretable Cross-Model Concept Alignment | Harrish Thasarathan, Julian Forsyth, Thomas Fel et al. | |
| 25 | +2510.24208v2 | 2025-10-28 | Beyond Neural Incompatibility: Cross-Scale Knowledge Transfer in Language Models through Latent Semantic Alignment | Jian Gu, Aldeida Aleti, Chunyang Chen et al. | |
| 26 | +2606.03280v2 | 2026-06-02 | A Negative Result on Cross-Model Activation Transfer in a Pythia Multi-Hop Setting | Peiyan Zhang, Jason Xin | |
| 27 | +2308.10248v5 | 2023-08-20 | Steering Language Models With Activation Engineering | Alexander Matt Turner, Lisa Thiergart, Gavin Leech et al. | |
| 28 | +2509.06608v4 | 2025-09-08 | Small Vectors, Big Effects: A Mechanistic Study of RL-Induced Reasoning via Steering Vectors | Viacheslav Sinii, Nikita Balagansky, Gleb Gerasimov et al. | |
| 29 | +2507.06265v2 | 2025-07-07 | SPARC: Concept-Aligned Sparse Autoencoders for Cross-Model and Cross-Modal Interpretability | Ali Nasiri-Sarvi, Hassan Rivaz, Mahdi S. Hosseini | |
| 30 | +2608.05164v1 | 2026-05-26 | Cross-Architecture Steering Transfer in Language Models: A Systematic Empirical Study | Ayushi Agarwal | |
| 31 | +2309.08600v3 | 2023-09-15 | Sparse Autoencoders Find Highly Interpretable Features in Language Models | Hoagy Cunningham, Aidan Ewart, Logan Riggs et al. | |
| 32 | +2304.14997v4 | 2023-04-28 | Towards Automated Circuit Discovery for Mechanistic Interpretability | Arthur Conmy, Augustine N. Mavor-Parker, Aengus Lynch et al. | |
| 33 | +2211.00593v1 | 2022-11-01 | Interpretability in the Wild: a Circuit for Indirect Object Identification in GPT-2 small | Kevin Wang, Alexandre Variengien, Arthur Conmy et al. | |
| 34 | +2212.04089v3 | 2022-12-08 | Editing Models with Task Arithmetic | Gabriel Ilharco, Marco Tulio Ribeiro, Mitchell Wortsman et al. | |
| 35 | +1905.00414v4 | 2019-05-01 | Similarity of Neural Network Representations Revisited | Simon Kornblith, Mohammad Norouzi, Honglak Lee et al. | |
| 36 | +2202.05262v5 | 2022-02-10 | Locating and Editing Factual Associations in GPT | Kevin Meng, David Bau, Alex Andonian et al. | |
| 37 | +2301.04709v4 | 2023-01-11 | Causal Abstraction: A Theoretical Foundation for Mechanistic Interpretability | Atticus Geiger, Duligur Ibeling, Amir Zur et al. | |
| 38 | +2609.04344v1 | 2026-09-03 | SharedSAE: One Feature Dictionary Across Language Models | Daniil Ognev, Célian Vasson, Lijie Hu et al. | |
| 39 | +2303.02536v4 | 2023-03-05 | Finding Alignments Between Interpretable Causal Variables and Distributed Neural Representations | Atticus Geiger, Zhengxuan Wu, Christopher Potts et al. | |
| 40 | +2401.01814v1 | 2024-01-03 | Large Language Models Relearn Removed Concepts | Michelle Lo, Shay B. Cohen, Fazl Barez | |
| 41 | +2402.17762v2 | 2024-02-27 | Massive Activations in Large Language Models | Mingjie Sun, Xinlei Chen, J. Zico Kolter et al. | |
| 42 | +2306.03341v6 | 2023-06-06 | Inference-Time Intervention: Eliciting Truthful Answers from a Language Model | Kenneth Li, Oam Patel, Fernanda Viégas et al. | |
| 43 | +2506.06609v3 | 2025-06-07 | Transferring Linear Features Across Language Models With Model Stitching | Alan Chen, Jack Merullo, Alessandro Stolfo et al. | |
| 44 | +2405.07883v2 | 2024-05-13 | Zero-Shot Tokenizer Transfer | Benjamin Minixhofer, Edoardo Maria Ponti, Ivan Vulić | |
| 45 | +2602.06205v2 | 2026-02-05 | Multi-Way Representation Alignment | Akshit Achara, Tatiana Gaintseva, Mateo Mahaut et al. | |
| \ No newline at end of file | ||
added
literature/references_unverified.md
+12 −0
@@ -0,0 +1,12 @@ | ||
| 1 | +# Candidate references NOT yet verified (do not cite) | |
| 2 | + | |
| 3 | +- Lenc & Vedaldi (2015) "Understanding image representations by measuring their equivariance and equivalence" — origin of stitching layers; arXiv id to confirm. | |
| 4 | +- Hinton, Vinyals & Dean (2015) "Distilling the Knowledge in a Neural Network" (arXiv 1503.02531) — distillation baseline; id to confirm. | |
| 5 | +- Lindsey et al. (2024) "Sparse crosscoders for cross-layer features and model diffing" (transformer-circuits.pub) — no arXiv id. | |
| 6 | +- Makelov, Lange & Nanda (2023) "Is this the subspace you are looking for? An interpretability illusion for subspace activation patching" — id to confirm. | |
| 7 | +- Csiszárik et al. (2021) "Similarity and matching of neural network representations" (stitching) — id to confirm. | |
| 8 | +- Moschella et al. (2022) "Relative representations enable zero-shot latent space communication" — id to confirm. | |
| 9 | +- Wortsman et al. (2022) "Model soups" — id to confirm. | |
| 10 | +- Wan et al. (2024) "Knowledge Fusion of Large Language Models" (FuseLLM) — id to confirm. | |
| 11 | +- Transport and Merge: Cross-Architecture Merging for LLMs (2026?) — surfaced by search without id. | |
| 12 | +- Venue metadata for verified arXiv entries (e.g. 2506.06609 NeurIPS 2025 spotlight; 2302.06600 ICML 2023; 2310.15213 ICLR 2024; 2301.04709 JMLR 2025) — add only after checking the proceedings page. | |
added
literature/references_verified.bib
+471 −0
@@ -0,0 +1,471 @@ | ||
| 1 | +% WP-AI-0001 — references whose identifier, title, authors and date were verified against the arXiv API on 2026-11-09. | |
| 2 | +% primaryClass is not verified field-by-field; venue information (NeurIPS/ICML/ICLR/JMLR) is NOT included unless verified separately. | |
| 3 | +% Do not add entries to this file without verification; unverified candidates go to references_unverified.md. | |
| 4 | + | |
| 5 | +@misc{achara2026multi, | |
| 6 | + title = {{Multi-Way Representation Alignment}}, | |
| 7 | + author = {Akshit Achara and Tatiana Gaintseva and Mateo Mahaut and Pritish Chakraborty and Viktor Stenby Johansson and Melih Barsbey and Emanuele Rodolà and Donato Crisostomi}, | |
| 8 | + year = {2026}, | |
| 9 | + month = {2}, | |
| 10 | + eprint = {2602.06205}, | |
| 11 | + archivePrefix= {arXiv}, | |
| 12 | + primaryClass = {cs.LG}, | |
| 13 | + url = {https://arxiv.org/abs/2602.06205}, | |
| 14 | + note = {arXiv:2602.06205; metadata verified via arXiv API on 2026-11-09} | |
| 15 | +} | |
| 16 | + | |
| 17 | +@misc{agarwal2026cross, | |
| 18 | + title = {{Cross-Architecture Steering Transfer in Language Models: A Systematic Empirical Study}}, | |
| 19 | + author = {Ayushi Agarwal}, | |
| 20 | + year = {2026}, | |
| 21 | + month = {5}, | |
| 22 | + eprint = {2608.05164}, | |
| 23 | + archivePrefix= {arXiv}, | |
| 24 | + primaryClass = {cs.LG}, | |
| 25 | + url = {https://arxiv.org/abs/2608.05164}, | |
| 26 | + note = {arXiv:2608.05164; metadata verified via arXiv API on 2026-11-09} | |
| 27 | +} | |
| 28 | + | |
| 29 | +@misc{ainsworth2022git, | |
| 30 | + title = {{Git Re-Basin: Merging Models modulo Permutation Symmetries}}, | |
| 31 | + author = {Samuel K. Ainsworth and Jonathan Hayase and Siddhartha Srinivasa}, | |
| 32 | + year = {2022}, | |
| 33 | + month = {9}, | |
| 34 | + eprint = {2209.04836}, | |
| 35 | + archivePrefix= {arXiv}, | |
| 36 | + primaryClass = {cs.LG}, | |
| 37 | + url = {https://arxiv.org/abs/2209.04836}, | |
| 38 | + note = {arXiv:2209.04836; metadata verified via arXiv API on 2026-11-09} | |
| 39 | +} | |
| 40 | + | |
| 41 | +@misc{bansal2021revisiting, | |
| 42 | + title = {{Revisiting Model Stitching to Compare Neural Representations}}, | |
| 43 | + author = {Yamini Bansal and Preetum Nakkiran and Boaz Barak}, | |
| 44 | + year = {2021}, | |
| 45 | + month = {6}, | |
| 46 | + eprint = {2106.07682}, | |
| 47 | + archivePrefix= {arXiv}, | |
| 48 | + primaryClass = {cs.LG}, | |
| 49 | + url = {https://arxiv.org/abs/2106.07682}, | |
| 50 | + note = {arXiv:2106.07682; metadata verified via arXiv API on 2026-11-09} | |
| 51 | +} | |
| 52 | + | |
| 53 | +@misc{chen2025transferring, | |
| 54 | + title = {{Transferring Linear Features Across Language Models With Model Stitching}}, | |
| 55 | + author = {Alan Chen and Jack Merullo and Alessandro Stolfo and Ellie Pavlick}, | |
| 56 | + year = {2025}, | |
| 57 | + month = {6}, | |
| 58 | + eprint = {2506.06609}, | |
| 59 | + archivePrefix= {arXiv}, | |
| 60 | + primaryClass = {cs.LG}, | |
| 61 | + url = {https://arxiv.org/abs/2506.06609}, | |
| 62 | + note = {arXiv:2506.06609; metadata verified via arXiv API on 2026-11-09} | |
| 63 | +} | |
| 64 | + | |
| 65 | +@misc{conmy2023towards, | |
| 66 | + title = {{Towards Automated Circuit Discovery for Mechanistic Interpretability}}, | |
| 67 | + author = {Arthur Conmy and Augustine N. Mavor-Parker and Aengus Lynch and Stefan Heimersheim and Adrià Garriga-Alonso}, | |
| 68 | + year = {2023}, | |
| 69 | + month = {4}, | |
| 70 | + eprint = {2304.14997}, | |
| 71 | + archivePrefix= {arXiv}, | |
| 72 | + primaryClass = {cs.LG}, | |
| 73 | + url = {https://arxiv.org/abs/2304.14997}, | |
| 74 | + note = {arXiv:2304.14997; metadata verified via arXiv API on 2026-11-09} | |
| 75 | +} | |
| 76 | + | |
| 77 | +@misc{cristofano2026universal, | |
| 78 | + title = {{Universal Refusal Circuits Across LLMs: Cross-Model Transfer via Trajectory Replay and Concept-Basis Reconstruction}}, | |
| 79 | + author = {Tony Cristofano}, | |
| 80 | + year = {2026}, | |
| 81 | + month = {1}, | |
| 82 | + eprint = {2601.16034}, | |
| 83 | + archivePrefix= {arXiv}, | |
| 84 | + primaryClass = {cs.LG}, | |
| 85 | + url = {https://arxiv.org/abs/2601.16034}, | |
| 86 | + note = {arXiv:2601.16034; metadata verified via arXiv API on 2026-11-09} | |
| 87 | +} | |
| 88 | + | |
| 89 | +@misc{cunningham2023sparse, | |
| 90 | + title = {{Sparse Autoencoders Find Highly Interpretable Features in Language Models}}, | |
| 91 | + author = {Hoagy Cunningham and Aidan Ewart and Logan Riggs and Robert Huben and Lee Sharkey}, | |
| 92 | + year = {2023}, | |
| 93 | + month = {9}, | |
| 94 | + eprint = {2309.08600}, | |
| 95 | + archivePrefix= {arXiv}, | |
| 96 | + primaryClass = {cs.LG}, | |
| 97 | + url = {https://arxiv.org/abs/2309.08600}, | |
| 98 | + note = {arXiv:2309.08600; metadata verified via arXiv API on 2026-11-09} | |
| 99 | +} | |
| 100 | + | |
| 101 | +@misc{fan2026training, | |
| 102 | + title = {{Training-Free Knowledge Transfer Across Model Scales through Activation-Guided Pruning}}, | |
| 103 | + author = {Jiahe Fan and Si Chen and Yinghao Hou and Aiyuan Zhang and Hong Xie}, | |
| 104 | + year = {2026}, | |
| 105 | + month = {7}, | |
| 106 | + eprint = {2608.13596}, | |
| 107 | + archivePrefix= {arXiv}, | |
| 108 | + primaryClass = {cs.LG}, | |
| 109 | + url = {https://arxiv.org/abs/2608.13596}, | |
| 110 | + note = {arXiv:2608.13596; metadata verified via arXiv API on 2026-11-09} | |
| 111 | +} | |
| 112 | + | |
| 113 | +@misc{geiger2023causal, | |
| 114 | + title = {{Causal Abstraction: A Theoretical Foundation for Mechanistic Interpretability}}, | |
| 115 | + author = {Atticus Geiger and Duligur Ibeling and Amir Zur and Maheep Chaudhary and Sonakshi Chauhan and Jing Huang and Aryaman Arora and Zhengxuan Wu and Noah Goodman and Christopher Potts and Thomas Icard}, | |
| 116 | + year = {2023}, | |
| 117 | + month = {1}, | |
| 118 | + eprint = {2301.04709}, | |
| 119 | + archivePrefix= {arXiv}, | |
| 120 | + primaryClass = {cs.LG}, | |
| 121 | + url = {https://arxiv.org/abs/2301.04709}, | |
| 122 | + note = {arXiv:2301.04709; metadata verified via arXiv API on 2026-11-09} | |
| 123 | +} | |
| 124 | + | |
| 125 | +@misc{geiger2023finding, | |
| 126 | + title = {{Finding Alignments Between Interpretable Causal Variables and Distributed Neural Representations}}, | |
| 127 | + author = {Atticus Geiger and Zhengxuan Wu and Christopher Potts and Thomas Icard and Noah D. Goodman}, | |
| 128 | + year = {2023}, | |
| 129 | + month = {3}, | |
| 130 | + eprint = {2303.02536}, | |
| 131 | + archivePrefix= {arXiv}, | |
| 132 | + primaryClass = {cs.LG}, | |
| 133 | + url = {https://arxiv.org/abs/2303.02536}, | |
| 134 | + note = {arXiv:2303.02536; metadata verified via arXiv API on 2026-11-09} | |
| 135 | +} | |
| 136 | + | |
| 137 | +@misc{gu2025beyond, | |
| 138 | + title = {{Beyond Neural Incompatibility: Cross-Scale Knowledge Transfer in Language Models through Latent Semantic Alignment}}, | |
| 139 | + author = {Jian Gu and Aldeida Aleti and Chunyang Chen and Hongyu Zhang}, | |
| 140 | + year = {2025}, | |
| 141 | + month = {10}, | |
| 142 | + eprint = {2510.24208}, | |
| 143 | + archivePrefix= {arXiv}, | |
| 144 | + primaryClass = {cs.LG}, | |
| 145 | + url = {https://arxiv.org/abs/2510.24208}, | |
| 146 | + note = {arXiv:2510.24208; metadata verified via arXiv API on 2026-11-09} | |
| 147 | +} | |
| 148 | + | |
| 149 | +@misc{gurnee2023finding, | |
| 150 | + title = {{Finding Neurons in a Haystack: Case Studies with Sparse Probing}}, | |
| 151 | + author = {Wes Gurnee and Neel Nanda and Matthew Pauly and Katherine Harvey and Dmitrii Troitskii and Dimitris Bertsimas}, | |
| 152 | + year = {2023}, | |
| 153 | + month = {5}, | |
| 154 | + eprint = {2305.01610}, | |
| 155 | + archivePrefix= {arXiv}, | |
| 156 | + primaryClass = {cs.LG}, | |
| 157 | + url = {https://arxiv.org/abs/2305.01610}, | |
| 158 | + note = {arXiv:2305.01610; metadata verified via arXiv API on 2026-11-09} | |
| 159 | +} | |
| 160 | + | |
| 161 | +@misc{hendel2023context, | |
| 162 | + title = {{In-Context Learning Creates Task Vectors}}, | |
| 163 | + author = {Roee Hendel and Mor Geva and Amir Globerson}, | |
| 164 | + year = {2023}, | |
| 165 | + month = {10}, | |
| 166 | + eprint = {2310.15916}, | |
| 167 | + archivePrefix= {arXiv}, | |
| 168 | + primaryClass = {cs.LG}, | |
| 169 | + url = {https://arxiv.org/abs/2310.15916}, | |
| 170 | + note = {arXiv:2310.15916; metadata verified via arXiv API on 2026-11-09} | |
| 171 | +} | |
| 172 | + | |
| 173 | +@misc{hernandez2023linearity, | |
| 174 | + title = {{Linearity of Relation Decoding in Transformer Language Models}}, | |
| 175 | + author = {Evan Hernandez and Arnab Sen Sharma and Tal Haklay and Kevin Meng and Martin Wattenberg and Jacob Andreas and Yonatan Belinkov and David Bau}, | |
| 176 | + year = {2023}, | |
| 177 | + month = {8}, | |
| 178 | + eprint = {2308.09124}, | |
| 179 | + archivePrefix= {arXiv}, | |
| 180 | + primaryClass = {cs.LG}, | |
| 181 | + url = {https://arxiv.org/abs/2308.09124}, | |
| 182 | + note = {arXiv:2308.09124; metadata verified via arXiv API on 2026-11-09} | |
| 183 | +} | |
| 184 | + | |
| 185 | +@misc{huh2024platonic, | |
| 186 | + title = {{The Platonic Representation Hypothesis}}, | |
| 187 | + author = {Minyoung Huh and Brian Cheung and Tongzhou Wang and Phillip Isola}, | |
| 188 | + year = {2024}, | |
| 189 | + month = {5}, | |
| 190 | + eprint = {2405.07987}, | |
| 191 | + archivePrefix= {arXiv}, | |
| 192 | + primaryClass = {cs.LG}, | |
| 193 | + url = {https://arxiv.org/abs/2405.07987}, | |
| 194 | + note = {arXiv:2405.07987; metadata verified via arXiv API on 2026-11-09} | |
| 195 | +} | |
| 196 | + | |
| 197 | +@misc{ilharco2022editing, | |
| 198 | + title = {{Editing Models with Task Arithmetic}}, | |
| 199 | + author = {Gabriel Ilharco and Marco Tulio Ribeiro and Mitchell Wortsman and Suchin Gururangan and Ludwig Schmidt and Hannaneh Hajishirzi and Ali Farhadi}, | |
| 200 | + year = {2022}, | |
| 201 | + month = {12}, | |
| 202 | + eprint = {2212.04089}, | |
| 203 | + archivePrefix= {arXiv}, | |
| 204 | + primaryClass = {cs.LG}, | |
| 205 | + url = {https://arxiv.org/abs/2212.04089}, | |
| 206 | + note = {arXiv:2212.04089; metadata verified via arXiv API on 2026-11-09} | |
| 207 | +} | |
| 208 | + | |
| 209 | +@misc{kim2026one, | |
| 210 | + title = {{One Adapter Pair per Model: A Universal Activation Interface for Language Models}}, | |
| 211 | + author = {Su-Hyeon Kim and Jiwan Mun and Yo-Sub Han}, | |
| 212 | + year = {2026}, | |
| 213 | + month = {8}, | |
| 214 | + eprint = {2608.09521}, | |
| 215 | + archivePrefix= {arXiv}, | |
| 216 | + primaryClass = {cs.LG}, | |
| 217 | + url = {https://arxiv.org/abs/2608.09521}, | |
| 218 | + note = {arXiv:2608.09521; metadata verified via arXiv API on 2026-11-09} | |
| 219 | +} | |
| 220 | + | |
| 221 | +@misc{kornblith2019similarity, | |
| 222 | + title = {{Similarity of Neural Network Representations Revisited}}, | |
| 223 | + author = {Simon Kornblith and Mohammad Norouzi and Honglak Lee and Geoffrey Hinton}, | |
| 224 | + year = {2019}, | |
| 225 | + month = {5}, | |
| 226 | + eprint = {1905.00414}, | |
| 227 | + archivePrefix= {arXiv}, | |
| 228 | + primaryClass = {cs.LG}, | |
| 229 | + url = {https://arxiv.org/abs/1905.00414}, | |
| 230 | + note = {arXiv:1905.00414; metadata verified via arXiv API on 2026-11-09} | |
| 231 | +} | |
| 232 | + | |
| 233 | +@misc{lan2024quantifying, | |
| 234 | + title = {{Quantifying Feature Space Universality Across Large Language Models via Sparse Autoencoders}}, | |
| 235 | + author = {Michael Lan and Philip Torr and Austin Meek and Ashkan Khakzar and David Krueger and Fazl Barez}, | |
| 236 | + year = {2024}, | |
| 237 | + month = {10}, | |
| 238 | + eprint = {2410.06981}, | |
| 239 | + archivePrefix= {arXiv}, | |
| 240 | + primaryClass = {cs.LG}, | |
| 241 | + url = {https://arxiv.org/abs/2410.06981}, | |
| 242 | + note = {arXiv:2410.06981; metadata verified via arXiv API on 2026-11-09} | |
| 243 | +} | |
| 244 | + | |
| 245 | +@misc{lee2025shared, | |
| 246 | + title = {{Shared Global and Local Geometry of Language Model Embeddings}}, | |
| 247 | + author = {Andrew Lee and Melanie Weber and Fernanda Viégas and Martin Wattenberg}, | |
| 248 | + year = {2025}, | |
| 249 | + month = {3}, | |
| 250 | + eprint = {2503.21073}, | |
| 251 | + archivePrefix= {arXiv}, | |
| 252 | + primaryClass = {cs.LG}, | |
| 253 | + url = {https://arxiv.org/abs/2503.21073}, | |
| 254 | + note = {arXiv:2503.21073; metadata verified via arXiv API on 2026-11-09} | |
| 255 | +} | |
| 256 | + | |
| 257 | +@misc{li2023inference, | |
| 258 | + title = {{Inference-Time Intervention: Eliciting Truthful Answers from a Language Model}}, | |
| 259 | + author = {Kenneth Li and Oam Patel and Fernanda Viégas and Hanspeter Pfister and Martin Wattenberg}, | |
| 260 | + year = {2023}, | |
| 261 | + month = {6}, | |
| 262 | + eprint = {2306.03341}, | |
| 263 | + archivePrefix= {arXiv}, | |
| 264 | + primaryClass = {cs.LG}, | |
| 265 | + url = {https://arxiv.org/abs/2306.03341}, | |
| 266 | + note = {arXiv:2306.03341; metadata verified via arXiv API on 2026-11-09} | |
| 267 | +} | |
| 268 | + | |
| 269 | +@misc{lo2024large, | |
| 270 | + title = {{Large Language Models Relearn Removed Concepts}}, | |
| 271 | + author = {Michelle Lo and Shay B. Cohen and Fazl Barez}, | |
| 272 | + year = {2024}, | |
| 273 | + month = {1}, | |
| 274 | + eprint = {2401.01814}, | |
| 275 | + archivePrefix= {arXiv}, | |
| 276 | + primaryClass = {cs.LG}, | |
| 277 | + url = {https://arxiv.org/abs/2401.01814}, | |
| 278 | + note = {arXiv:2401.01814; metadata verified via arXiv API on 2026-11-09} | |
| 279 | +} | |
| 280 | + | |
| 281 | +@misc{meng2022locating, | |
| 282 | + title = {{Locating and Editing Factual Associations in GPT}}, | |
| 283 | + author = {Kevin Meng and David Bau and Alex Andonian and Yonatan Belinkov}, | |
| 284 | + year = {2022}, | |
| 285 | + month = {2}, | |
| 286 | + eprint = {2202.05262}, | |
| 287 | + archivePrefix= {arXiv}, | |
| 288 | + primaryClass = {cs.LG}, | |
| 289 | + url = {https://arxiv.org/abs/2202.05262}, | |
| 290 | + note = {arXiv:2202.05262; metadata verified via arXiv API on 2026-11-09} | |
| 291 | +} | |
| 292 | + | |
| 293 | +@misc{minixhofer2024zero, | |
| 294 | + title = {{Zero-Shot Tokenizer Transfer}}, | |
| 295 | + author = {Benjamin Minixhofer and Edoardo Maria Ponti and Ivan Vulić}, | |
| 296 | + year = {2024}, | |
| 297 | + month = {5}, | |
| 298 | + eprint = {2405.07883}, | |
| 299 | + archivePrefix= {arXiv}, | |
| 300 | + primaryClass = {cs.LG}, | |
| 301 | + url = {https://arxiv.org/abs/2405.07883}, | |
| 302 | + note = {arXiv:2405.07883; metadata verified via arXiv API on 2026-11-09} | |
| 303 | +} | |
| 304 | + | |
| 305 | +@misc{nasirisarvi2025sparc, | |
| 306 | + title = {{SPARC: Concept-Aligned Sparse Autoencoders for Cross-Model and Cross-Modal Interpretability}}, | |
| 307 | + author = {Ali Nasiri-Sarvi and Hassan Rivaz and Mahdi S. Hosseini}, | |
| 308 | + year = {2025}, | |
| 309 | + month = {7}, | |
| 310 | + eprint = {2507.06265}, | |
| 311 | + archivePrefix= {arXiv}, | |
| 312 | + primaryClass = {cs.LG}, | |
| 313 | + url = {https://arxiv.org/abs/2507.06265}, | |
| 314 | + note = {arXiv:2507.06265; metadata verified via arXiv API on 2026-11-09} | |
| 315 | +} | |
| 316 | + | |
| 317 | +@misc{ognev2026sharedsae, | |
| 318 | + title = {{SharedSAE: One Feature Dictionary Across Language Models}}, | |
| 319 | + author = {Daniil Ognev and Célian Vasson and Lijie Hu and Kentaro Inui and Benjamin Heinzerling}, | |
| 320 | + year = {2026}, | |
| 321 | + month = {9}, | |
| 322 | + eprint = {2609.04344}, | |
| 323 | + archivePrefix= {arXiv}, | |
| 324 | + primaryClass = {cs.LG}, | |
| 325 | + url = {https://arxiv.org/abs/2609.04344}, | |
| 326 | + note = {arXiv:2609.04344; metadata verified via arXiv API on 2026-11-09} | |
| 327 | +} | |
| 328 | + | |
| 329 | +@misc{panigrahi2023task, | |
| 330 | + title = {{Task-Specific Skill Localization in Fine-tuned Language Models}}, | |
| 331 | + author = {Abhishek Panigrahi and Nikunj Saunshi and Haoyu Zhao and Sanjeev Arora}, | |
| 332 | + year = {2023}, | |
| 333 | + month = {2}, | |
| 334 | + eprint = {2302.06600}, | |
| 335 | + archivePrefix= {arXiv}, | |
| 336 | + primaryClass = {cs.LG}, | |
| 337 | + url = {https://arxiv.org/abs/2302.06600}, | |
| 338 | + note = {arXiv:2302.06600; metadata verified via arXiv API on 2026-11-09} | |
| 339 | +} | |
| 340 | + | |
| 341 | +@misc{raghu2017svcca, | |
| 342 | + title = {{SVCCA: Singular Vector Canonical Correlation Analysis for Deep Learning Dynamics and Interpretability}}, | |
| 343 | + author = {Maithra Raghu and Justin Gilmer and Jason Yosinski and Jascha Sohl-Dickstein}, | |
| 344 | + year = {2017}, | |
| 345 | + month = {6}, | |
| 346 | + eprint = {1706.05806}, | |
| 347 | + archivePrefix= {arXiv}, | |
| 348 | + primaryClass = {cs.LG}, | |
| 349 | + url = {https://arxiv.org/abs/1706.05806}, | |
| 350 | + note = {arXiv:1706.05806; metadata verified via arXiv API on 2026-11-09} | |
| 351 | +} | |
| 352 | + | |
| 353 | +@misc{sinii2025small, | |
| 354 | + title = {{Small Vectors, Big Effects: A Mechanistic Study of RL-Induced Reasoning via Steering Vectors}}, | |
| 355 | + author = {Viacheslav Sinii and Nikita Balagansky and Gleb Gerasimov and Daniil Laptev and Yaroslav Aksenov and Vadim Kurochkin and Alexey Gorbatovski and Boris Shaposhnikov and Daniil Gavrilov}, | |
| 356 | + year = {2025}, | |
| 357 | + month = {9}, | |
| 358 | + eprint = {2509.06608}, | |
| 359 | + archivePrefix= {arXiv}, | |
| 360 | + primaryClass = {cs.LG}, | |
| 361 | + url = {https://arxiv.org/abs/2509.06608}, | |
| 362 | + note = {arXiv:2509.06608; metadata verified via arXiv API on 2026-11-09} | |
| 363 | +} | |
| 364 | + | |
| 365 | +@misc{sun2024massive, | |
| 366 | + title = {{Massive Activations in Large Language Models}}, | |
| 367 | + author = {Mingjie Sun and Xinlei Chen and J. Zico Kolter and Zhuang Liu}, | |
| 368 | + year = {2024}, | |
| 369 | + month = {2}, | |
| 370 | + eprint = {2402.17762}, | |
| 371 | + archivePrefix= {arXiv}, | |
| 372 | + primaryClass = {cs.LG}, | |
| 373 | + url = {https://arxiv.org/abs/2402.17762}, | |
| 374 | + note = {arXiv:2402.17762; metadata verified via arXiv API on 2026-11-09} | |
| 375 | +} | |
| 376 | + | |
| 377 | +@misc{thasarathan2025universal, | |
| 378 | + title = {{Universal Sparse Autoencoders: Interpretable Cross-Model Concept Alignment}}, | |
| 379 | + author = {Harrish Thasarathan and Julian Forsyth and Thomas Fel and Matthew Kowal and Konstantinos G. Derpanis}, | |
| 380 | + year = {2025}, | |
| 381 | + month = {2}, | |
| 382 | + eprint = {2502.03714}, | |
| 383 | + archivePrefix= {arXiv}, | |
| 384 | + primaryClass = {cs.LG}, | |
| 385 | + url = {https://arxiv.org/abs/2502.03714}, | |
| 386 | + note = {arXiv:2502.03714; metadata verified via arXiv API on 2026-11-09} | |
| 387 | +} | |
| 388 | + | |
| 389 | +@misc{todd2023function, | |
| 390 | + title = {{Function Vectors in Large Language Models}}, | |
| 391 | + author = {Eric Todd and Millicent L. Li and Arnab Sen Sharma and Aaron Mueller and Byron C. Wallace and David Bau}, | |
| 392 | + year = {2023}, | |
| 393 | + month = {10}, | |
| 394 | + eprint = {2310.15213}, | |
| 395 | + archivePrefix= {arXiv}, | |
| 396 | + primaryClass = {cs.LG}, | |
| 397 | + url = {https://arxiv.org/abs/2310.15213}, | |
| 398 | + note = {arXiv:2310.15213; metadata verified via arXiv API on 2026-11-09} | |
| 399 | +} | |
| 400 | + | |
| 401 | +@misc{turner2023steering, | |
| 402 | + title = {{Steering Language Models With Activation Engineering}}, | |
| 403 | + author = {Alexander Matt Turner and Lisa Thiergart and Gavin Leech and David Udell and Juan J. Vazquez and Ulisse Mini and Monte MacDiarmid}, | |
| 404 | + year = {2023}, | |
| 405 | + month = {8}, | |
| 406 | + eprint = {2308.10248}, | |
| 407 | + archivePrefix= {arXiv}, | |
| 408 | + primaryClass = {cs.LG}, | |
| 409 | + url = {https://arxiv.org/abs/2308.10248}, | |
| 410 | + note = {arXiv:2308.10248; metadata verified via arXiv API on 2026-11-09} | |
| 411 | +} | |
| 412 | + | |
| 413 | +@misc{vig2020causal, | |
| 414 | + title = {{Causal Mediation Analysis for Interpreting Neural NLP: The Case of Gender Bias}}, | |
| 415 | + author = {Jesse Vig and Sebastian Gehrmann and Yonatan Belinkov and Sharon Qian and Daniel Nevo and Simas Sakenis and Jason Huang and Yaron Singer and Stuart Shieber}, | |
| 416 | + year = {2020}, | |
| 417 | + month = {4}, | |
| 418 | + eprint = {2004.12265}, | |
| 419 | + archivePrefix= {arXiv}, | |
| 420 | + primaryClass = {cs.LG}, | |
| 421 | + url = {https://arxiv.org/abs/2004.12265}, | |
| 422 | + note = {arXiv:2004.12265; metadata verified via arXiv API on 2026-11-09} | |
| 423 | +} | |
| 424 | + | |
| 425 | +@misc{wang2022interpretability, | |
| 426 | + title = {{Interpretability in the Wild: a Circuit for Indirect Object Identification in GPT-2 small}}, | |
| 427 | + author = {Kevin Wang and Alexandre Variengien and Arthur Conmy and Buck Shlegeris and Jacob Steinhardt}, | |
| 428 | + year = {2022}, | |
| 429 | + month = {11}, | |
| 430 | + eprint = {2211.00593}, | |
| 431 | + archivePrefix= {arXiv}, | |
| 432 | + primaryClass = {cs.LG}, | |
| 433 | + url = {https://arxiv.org/abs/2211.00593}, | |
| 434 | + note = {arXiv:2211.00593; metadata verified via arXiv API on 2026-11-09} | |
| 435 | +} | |
| 436 | + | |
| 437 | +@misc{yadav2023ties, | |
| 438 | + title = {{TIES-Merging: Resolving Interference When Merging Models}}, | |
| 439 | + author = {Prateek Yadav and Derek Tam and Leshem Choshen and Colin Raffel and Mohit Bansal}, | |
| 440 | + year = {2023}, | |
| 441 | + month = {6}, | |
| 442 | + eprint = {2306.01708}, | |
| 443 | + archivePrefix= {arXiv}, | |
| 444 | + primaryClass = {cs.LG}, | |
| 445 | + url = {https://arxiv.org/abs/2306.01708}, | |
| 446 | + note = {arXiv:2306.01708; metadata verified via arXiv API on 2026-11-09} | |
| 447 | +} | |
| 448 | + | |
| 449 | +@misc{zhang2026negative, | |
| 450 | + title = {{A Negative Result on Cross-Model Activation Transfer in a Pythia Multi-Hop Setting}}, | |
| 451 | + author = {Peiyan Zhang and Jason Xin}, | |
| 452 | + year = {2026}, | |
| 453 | + month = {6}, | |
| 454 | + eprint = {2606.03280}, | |
| 455 | + archivePrefix= {arXiv}, | |
| 456 | + primaryClass = {cs.LG}, | |
| 457 | + url = {https://arxiv.org/abs/2606.03280}, | |
| 458 | + note = {arXiv:2606.03280; metadata verified via arXiv API on 2026-11-09} | |
| 459 | +} | |
| 460 | + | |
| 461 | +@misc{zou2023representation, | |
| 462 | + title = {{Representation Engineering: A Top-Down Approach to AI Transparency}}, | |
| 463 | + author = {Andy Zou and Long Phan and Sarah Chen and James Campbell and Phillip Guo and Richard Ren and Alexander Pan and Xuwang Yin and Mantas Mazeika and Ann-Kathrin Dombrowski and Shashwat Goel and Nathaniel Li and Michael J. Byun and Zifan Wang and Alex Mallen and Steven Basart and Sanmi Koyejo and Dawn Song and Matt Fredrikson and J. Zico Kolter and Dan Hendrycks}, | |
| 464 | + year = {2023}, | |
| 465 | + month = {10}, | |
| 466 | + eprint = {2310.01405}, | |
| 467 | + archivePrefix= {arXiv}, | |
| 468 | + primaryClass = {cs.LG}, | |
| 469 | + url = {https://arxiv.org/abs/2310.01405}, | |
| 470 | + note = {arXiv:2310.01405; metadata verified via arXiv API on 2026-11-09} | |
| 471 | +} | |
added
paper/.latexmkrc
+5 −0
@@ -0,0 +1,5 @@ | ||
| 1 | +$pdf_mode = 1; | |
| 2 | +$pdflatex = 'pdflatex -interaction=nonstopmode -halt-on-error -synctex=1 %O %S'; | |
| 3 | +$bibtex_use = 2; | |
| 4 | +$clean_ext = 'synctex.gz run.xml bbl bcf fdb_latexmk fls log aux out toc lof lot blg'; | |
| 5 | +@default_files = ('main.tex'); | |
added
paper/Makefile
+11 −0
@@ -0,0 +1,11 @@ | ||
| 1 | +.PHONY: all clean distclean | |
| 2 | + | |
| 3 | +all: | |
| 4 | + latexmk | |
| 5 | + | |
| 6 | +clean: | |
| 7 | + latexmk -c | |
| 8 | + | |
| 9 | +distclean: | |
| 10 | + latexmk -C | |
| 11 | + rm -f *.synctex.gz *.run.xml *.bbl *.bcf | |
added
paper/appendix/appendix.tex
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +\appendix | |
| 2 | +\section{Causal-abstraction statement for stitched models}\label{app:theory} | |
| 3 | +[PLACEHOLDER --- restatement with assumptions of the interchange-commutation property under exact causal | |
| 4 | +abstraction \citep{geiger2023causal}; conjectures are labelled as such.] | |
| 5 | +\section{Prompts, configurations and model cards} | |
| 6 | +[PLACEHOLDER --- generated from \texttt{configs/} and run manifests.] | |
added
paper/figures/FIGURE_PROVENANCE.md
+5 −0
@@ -0,0 +1,5 @@ | ||
| 1 | +# Figure provenance | |
| 2 | + | |
| 3 | +| run id | results sha256[:16] | built (UTC) | figures | | |
| 4 | +|---|---|---|---| | |
| 5 | +| pilot_tier0_opseq_451ef5087182 | a75c965945f8f43f | 2026-11-09T06:57:25+00:00 | fig_gap_tier0.pdf, fig_localization_ablation_tier0.pdf, fig_localization_heads_tier0.pdf, fig_localization_patching_tier0.pdf | | |
added
paper/figures/fig_gap_tier0.pdf
+0 −0
Binary file not shown.
added
paper/figures/fig_localization_ablation_tier0.pdf
+0 −0
Binary file not shown.
added
paper/figures/fig_localization_heads_tier0.pdf
+0 −0
Binary file not shown.
added
paper/figures/fig_localization_patching_tier0.pdf
+0 −0
Binary file not shown.
added
paper/main.pdf
+0 −0
Binary file not shown.
added
paper/main.tex
+147 −0
@@ -0,0 +1,147 @@ | ||
| 1 | +% ============================================================================ | |
| 2 | +% UQO Working Paper Template — Economics / Finance | |
| 3 | +% ============================================================================ | |
| 4 | +\documentclass[12pt,letterpaper]{article} | |
| 5 | + | |
| 6 | +% --- Encoding & Language --- | |
| 7 | +\usepackage[utf8]{inputenc} | |
| 8 | +\usepackage[T1]{fontenc} | |
| 9 | +\usepackage[english]{babel} | |
| 10 | + | |
| 11 | +% --- Page Layout --- | |
| 12 | +\usepackage[ | |
| 13 | + letterpaper, | |
| 14 | + top=1in, | |
| 15 | + bottom=1in, | |
| 16 | + left=1in, | |
| 17 | + right=1in | |
| 18 | +]{geometry} | |
| 19 | + | |
| 20 | +% --- Typography --- | |
| 21 | +\usepackage{mathptmx} % Times-like font (text + math) | |
| 22 | +\usepackage{microtype} % Improved typographic refinements | |
| 23 | +\usepackage{setspace} | |
| 24 | +\onehalfspacing % 1.5 line spacing | |
| 25 | + | |
| 26 | +% --- Math --- | |
| 27 | +\usepackage{amsmath,amssymb,amsthm} | |
| 28 | + | |
| 29 | +% --- Tables --- | |
| 30 | +\usepackage{booktabs} | |
| 31 | +\usepackage{tabularx} | |
| 32 | +\usepackage{multirow} | |
| 33 | +\usepackage{threeparttable} | |
| 34 | +\usepackage{siunitx} | |
| 35 | +\sisetup{ | |
| 36 | + input-symbols = {()}, | |
| 37 | + table-format = -1.3, | |
| 38 | + parse-numbers = false | |
| 39 | +} | |
| 40 | + | |
| 41 | +% --- Figures --- | |
| 42 | +\usepackage{graphicx} | |
| 43 | +\usepackage{subcaption} | |
| 44 | +\usepackage{float} | |
| 45 | + | |
| 46 | +% --- Colors & Links --- | |
| 47 | +\usepackage[dvipsnames]{xcolor} | |
| 48 | +\usepackage[ | |
| 49 | + colorlinks = true, | |
| 50 | + linkcolor = NavyBlue, | |
| 51 | + citecolor = NavyBlue, | |
| 52 | + urlcolor = NavyBlue, | |
| 53 | + breaklinks = true | |
| 54 | +]{hyperref} | |
| 55 | + | |
| 56 | +% --- Bibliography --- | |
| 57 | +\usepackage[authoryear,round,semicolon]{natbib} | |
| 58 | +\bibliographystyle{aer} | |
| 59 | + | |
| 60 | +% --- Captions --- | |
| 61 | +\usepackage[ | |
| 62 | + font = small, | |
| 63 | + labelfont = bf, | |
| 64 | + labelsep = period, | |
| 65 | + justification = justified, | |
| 66 | + singlelinecheck = false | |
| 67 | +]{caption} | |
| 68 | + | |
| 69 | +% --- Headers & Footers --- | |
| 70 | +\usepackage{fancyhdr} | |
| 71 | +\pagestyle{fancy} | |
| 72 | +\fancyhf{} | |
| 73 | +\renewcommand{\headrulewidth}{0pt} | |
| 74 | +\fancyfoot[C]{\thepage} | |
| 75 | + | |
| 76 | +% --- Section Formatting --- | |
| 77 | +\usepackage{titlesec} | |
| 78 | +\titleformat{\section}{\large\bfseries}{\thesection.}{0.5em}{} | |
| 79 | +\titleformat{\subsection}{\normalsize\bfseries}{\thesubsection.}{0.5em}{} | |
| 80 | +\titleformat{\subsubsection}{\normalsize\itshape}{\thesubsubsection.}{0.5em}{} | |
| 81 | + | |
| 82 | +% --- Appendix Support --- | |
| 83 | +\usepackage[toc,page]{appendix} | |
| 84 | + | |
| 85 | +% --- Misc --- | |
| 86 | +\usepackage{enumitem} | |
| 87 | +\setlist{nosep,leftmargin=*} | |
| 88 | + | |
| 89 | +% ============================================================================ | |
| 90 | +% METADATA — Edit these fields for each working paper | |
| 91 | +% ============================================================================ | |
| 92 | +\newcommand{\WPnumber}{AI-0001} | |
| 93 | +\newcommand{\WPtitle}{The Neural Organ Transplant Experiment} | |
| 94 | +\newcommand{\WPsubtitle}{Causal Transfer of Cognitive Capabilities Across Local Large Language Models} | |
| 95 | +\newcommand{\WPdate}{November 2026} | |
| 96 | +\newcommand{\WPversion}{0.1} | |
| 97 | +\newcommand{\WPabstract}{% | |
| 98 | +[PROTOCOL DRAFT --- NO RESULTS YET.] We ask whether a bounded, causally identified computational subsystem | |
| 99 | +responsible for a measurable capability can be transplanted from a donor open-weight language model into a | |
| 100 | +recipient that demonstrably lacks it, without conventional full-model training. This draft states the | |
| 101 | +operational definitions, estimands, preregistered hypotheses, controls and experimental design; empirical | |
| 102 | +sections contain explicit placeholders until the corresponding runs exist in the experiment registry. | |
| 103 | +} | |
| 104 | +\newcommand{\WPkeywords}{mechanistic interpretability, activation patching, model stitching, representation alignment, knowledge transfer, causal abstraction, open-weight language models} | |
| 105 | +\newcommand{\WPjel}{C45, C63, C88, O33} | |
| 106 | + | |
| 107 | +% --- Author --- | |
| 108 | +\newcommand{\WPauthor}{Simon-Pierre Boucher} | |
| 109 | +\newcommand{\WPaffiliation}{% | |
| 110 | + Département des sciences administratives\\ | |
| 111 | + Université du Québec en Outaouais% | |
| 112 | +} | |
| 113 | +\newcommand{\WPemail}{simon-pierre.boucher@uqo.ca} | |
| 114 | +\newcommand{\WPaddress}{% | |
| 115 | + Gatineau -- Pavillon Alexandre-Taché\\ | |
| 116 | + 283, boulevard Alexandre-Taché\\ | |
| 117 | + Gatineau, Québec, Canada J9A 1L8% | |
| 118 | +} | |
| 119 | + | |
| 120 | +% ============================================================================ | |
| 121 | +% DOCUMENT | |
| 122 | +% ============================================================================ | |
| 123 | +\begin{document} | |
| 124 | + | |
| 125 | +% --- Title Page --- | |
| 126 | +\input{sections/titlepage} | |
| 127 | + | |
| 128 | +% --- Main Body --- | |
| 129 | +\input{sections/introduction} | |
| 130 | +\input{sections/related_work} | |
| 131 | +\input{sections/operational_theory} | |
| 132 | +\input{sections/experimental_design} | |
| 133 | +\input{sections/results} | |
| 134 | +\input{sections/mechanistic_analysis} | |
| 135 | +\input{sections/robustness} | |
| 136 | +\input{sections/discussion} | |
| 137 | +\input{sections/limitations} | |
| 138 | +\input{sections/conclusion} | |
| 139 | + | |
| 140 | +% --- References --- | |
| 141 | +\newpage | |
| 142 | +\bibliography{references} | |
| 143 | + | |
| 144 | +% --- Appendix --- | |
| 145 | +\input{appendix/appendix} | |
| 146 | + | |
| 147 | +\end{document} | |
added
paper/references.bib
+471 −0
@@ -0,0 +1,471 @@ | ||
| 1 | +% WP-AI-0001 — references whose identifier, title, authors and date were verified against the arXiv API on 2026-11-09. | |
| 2 | +% primaryClass is not verified field-by-field; venue information (NeurIPS/ICML/ICLR/JMLR) is NOT included unless verified separately. | |
| 3 | +% Do not add entries to this file without verification; unverified candidates go to references_unverified.md. | |
| 4 | + | |
| 5 | +@misc{achara2026multi, | |
| 6 | + title = {{Multi-Way Representation Alignment}}, | |
| 7 | + author = {Akshit Achara and Tatiana Gaintseva and Mateo Mahaut and Pritish Chakraborty and Viktor Stenby Johansson and Melih Barsbey and Emanuele Rodolà and Donato Crisostomi}, | |
| 8 | + year = {2026}, | |
| 9 | + month = {2}, | |
| 10 | + eprint = {2602.06205}, | |
| 11 | + archivePrefix= {arXiv}, | |
| 12 | + primaryClass = {cs.LG}, | |
| 13 | + url = {https://arxiv.org/abs/2602.06205}, | |
| 14 | + note = {arXiv:2602.06205; metadata verified via arXiv API on 2026-11-09} | |
| 15 | +} | |
| 16 | + | |
| 17 | +@misc{agarwal2026cross, | |
| 18 | + title = {{Cross-Architecture Steering Transfer in Language Models: A Systematic Empirical Study}}, | |
| 19 | + author = {Ayushi Agarwal}, | |
| 20 | + year = {2026}, | |
| 21 | + month = {5}, | |
| 22 | + eprint = {2608.05164}, | |
| 23 | + archivePrefix= {arXiv}, | |
| 24 | + primaryClass = {cs.LG}, | |
| 25 | + url = {https://arxiv.org/abs/2608.05164}, | |
| 26 | + note = {arXiv:2608.05164; metadata verified via arXiv API on 2026-11-09} | |
| 27 | +} | |
| 28 | + | |
| 29 | +@misc{ainsworth2022git, | |
| 30 | + title = {{Git Re-Basin: Merging Models modulo Permutation Symmetries}}, | |
| 31 | + author = {Samuel K. Ainsworth and Jonathan Hayase and Siddhartha Srinivasa}, | |
| 32 | + year = {2022}, | |
| 33 | + month = {9}, | |
| 34 | + eprint = {2209.04836}, | |
| 35 | + archivePrefix= {arXiv}, | |
| 36 | + primaryClass = {cs.LG}, | |
| 37 | + url = {https://arxiv.org/abs/2209.04836}, | |
| 38 | + note = {arXiv:2209.04836; metadata verified via arXiv API on 2026-11-09} | |
| 39 | +} | |
| 40 | + | |
| 41 | +@misc{bansal2021revisiting, | |
| 42 | + title = {{Revisiting Model Stitching to Compare Neural Representations}}, | |
| 43 | + author = {Yamini Bansal and Preetum Nakkiran and Boaz Barak}, | |
| 44 | + year = {2021}, | |
| 45 | + month = {6}, | |
| 46 | + eprint = {2106.07682}, | |
| 47 | + archivePrefix= {arXiv}, | |
| 48 | + primaryClass = {cs.LG}, | |
| 49 | + url = {https://arxiv.org/abs/2106.07682}, | |
| 50 | + note = {arXiv:2106.07682; metadata verified via arXiv API on 2026-11-09} | |
| 51 | +} | |
| 52 | + | |
| 53 | +@misc{chen2025transferring, | |
| 54 | + title = {{Transferring Linear Features Across Language Models With Model Stitching}}, | |
| 55 | + author = {Alan Chen and Jack Merullo and Alessandro Stolfo and Ellie Pavlick}, | |
| 56 | + year = {2025}, | |
| 57 | + month = {6}, | |
| 58 | + eprint = {2506.06609}, | |
| 59 | + archivePrefix= {arXiv}, | |
| 60 | + primaryClass = {cs.LG}, | |
| 61 | + url = {https://arxiv.org/abs/2506.06609}, | |
| 62 | + note = {arXiv:2506.06609; metadata verified via arXiv API on 2026-11-09} | |
| 63 | +} | |
| 64 | + | |
| 65 | +@misc{conmy2023towards, | |
| 66 | + title = {{Towards Automated Circuit Discovery for Mechanistic Interpretability}}, | |
| 67 | + author = {Arthur Conmy and Augustine N. Mavor-Parker and Aengus Lynch and Stefan Heimersheim and Adrià Garriga-Alonso}, | |
| 68 | + year = {2023}, | |
| 69 | + month = {4}, | |
| 70 | + eprint = {2304.14997}, | |
| 71 | + archivePrefix= {arXiv}, | |
| 72 | + primaryClass = {cs.LG}, | |
| 73 | + url = {https://arxiv.org/abs/2304.14997}, | |
| 74 | + note = {arXiv:2304.14997; metadata verified via arXiv API on 2026-11-09} | |
| 75 | +} | |
| 76 | + | |
| 77 | +@misc{cristofano2026universal, | |
| 78 | + title = {{Universal Refusal Circuits Across LLMs: Cross-Model Transfer via Trajectory Replay and Concept-Basis Reconstruction}}, | |
| 79 | + author = {Tony Cristofano}, | |
| 80 | + year = {2026}, | |
| 81 | + month = {1}, | |
| 82 | + eprint = {2601.16034}, | |
| 83 | + archivePrefix= {arXiv}, | |
| 84 | + primaryClass = {cs.LG}, | |
| 85 | + url = {https://arxiv.org/abs/2601.16034}, | |
| 86 | + note = {arXiv:2601.16034; metadata verified via arXiv API on 2026-11-09} | |
| 87 | +} | |
| 88 | + | |
| 89 | +@misc{cunningham2023sparse, | |
| 90 | + title = {{Sparse Autoencoders Find Highly Interpretable Features in Language Models}}, | |
| 91 | + author = {Hoagy Cunningham and Aidan Ewart and Logan Riggs and Robert Huben and Lee Sharkey}, | |
| 92 | + year = {2023}, | |
| 93 | + month = {9}, | |
| 94 | + eprint = {2309.08600}, | |
| 95 | + archivePrefix= {arXiv}, | |
| 96 | + primaryClass = {cs.LG}, | |
| 97 | + url = {https://arxiv.org/abs/2309.08600}, | |
| 98 | + note = {arXiv:2309.08600; metadata verified via arXiv API on 2026-11-09} | |
| 99 | +} | |
| 100 | + | |
| 101 | +@misc{fan2026training, | |
| 102 | + title = {{Training-Free Knowledge Transfer Across Model Scales through Activation-Guided Pruning}}, | |
| 103 | + author = {Jiahe Fan and Si Chen and Yinghao Hou and Aiyuan Zhang and Hong Xie}, | |
| 104 | + year = {2026}, | |
| 105 | + month = {7}, | |
| 106 | + eprint = {2608.13596}, | |
| 107 | + archivePrefix= {arXiv}, | |
| 108 | + primaryClass = {cs.LG}, | |
| 109 | + url = {https://arxiv.org/abs/2608.13596}, | |
| 110 | + note = {arXiv:2608.13596; metadata verified via arXiv API on 2026-11-09} | |
| 111 | +} | |
| 112 | + | |
| 113 | +@misc{geiger2023causal, | |
| 114 | + title = {{Causal Abstraction: A Theoretical Foundation for Mechanistic Interpretability}}, | |
| 115 | + author = {Atticus Geiger and Duligur Ibeling and Amir Zur and Maheep Chaudhary and Sonakshi Chauhan and Jing Huang and Aryaman Arora and Zhengxuan Wu and Noah Goodman and Christopher Potts and Thomas Icard}, | |
| 116 | + year = {2023}, | |
| 117 | + month = {1}, | |
| 118 | + eprint = {2301.04709}, | |
| 119 | + archivePrefix= {arXiv}, | |
| 120 | + primaryClass = {cs.LG}, | |
| 121 | + url = {https://arxiv.org/abs/2301.04709}, | |
| 122 | + note = {arXiv:2301.04709; metadata verified via arXiv API on 2026-11-09} | |
| 123 | +} | |
| 124 | + | |
| 125 | +@misc{geiger2023finding, | |
| 126 | + title = {{Finding Alignments Between Interpretable Causal Variables and Distributed Neural Representations}}, | |
| 127 | + author = {Atticus Geiger and Zhengxuan Wu and Christopher Potts and Thomas Icard and Noah D. Goodman}, | |
| 128 | + year = {2023}, | |
| 129 | + month = {3}, | |
| 130 | + eprint = {2303.02536}, | |
| 131 | + archivePrefix= {arXiv}, | |
| 132 | + primaryClass = {cs.LG}, | |
| 133 | + url = {https://arxiv.org/abs/2303.02536}, | |
| 134 | + note = {arXiv:2303.02536; metadata verified via arXiv API on 2026-11-09} | |
| 135 | +} | |
| 136 | + | |
| 137 | +@misc{gu2025beyond, | |
| 138 | + title = {{Beyond Neural Incompatibility: Cross-Scale Knowledge Transfer in Language Models through Latent Semantic Alignment}}, | |
| 139 | + author = {Jian Gu and Aldeida Aleti and Chunyang Chen and Hongyu Zhang}, | |
| 140 | + year = {2025}, | |
| 141 | + month = {10}, | |
| 142 | + eprint = {2510.24208}, | |
| 143 | + archivePrefix= {arXiv}, | |
| 144 | + primaryClass = {cs.LG}, | |
| 145 | + url = {https://arxiv.org/abs/2510.24208}, | |
| 146 | + note = {arXiv:2510.24208; metadata verified via arXiv API on 2026-11-09} | |
| 147 | +} | |
| 148 | + | |
| 149 | +@misc{gurnee2023finding, | |
| 150 | + title = {{Finding Neurons in a Haystack: Case Studies with Sparse Probing}}, | |
| 151 | + author = {Wes Gurnee and Neel Nanda and Matthew Pauly and Katherine Harvey and Dmitrii Troitskii and Dimitris Bertsimas}, | |
| 152 | + year = {2023}, | |
| 153 | + month = {5}, | |
| 154 | + eprint = {2305.01610}, | |
| 155 | + archivePrefix= {arXiv}, | |
| 156 | + primaryClass = {cs.LG}, | |
| 157 | + url = {https://arxiv.org/abs/2305.01610}, | |
| 158 | + note = {arXiv:2305.01610; metadata verified via arXiv API on 2026-11-09} | |
| 159 | +} | |
| 160 | + | |
| 161 | +@misc{hendel2023context, | |
| 162 | + title = {{In-Context Learning Creates Task Vectors}}, | |
| 163 | + author = {Roee Hendel and Mor Geva and Amir Globerson}, | |
| 164 | + year = {2023}, | |
| 165 | + month = {10}, | |
| 166 | + eprint = {2310.15916}, | |
| 167 | + archivePrefix= {arXiv}, | |
| 168 | + primaryClass = {cs.LG}, | |
| 169 | + url = {https://arxiv.org/abs/2310.15916}, | |
| 170 | + note = {arXiv:2310.15916; metadata verified via arXiv API on 2026-11-09} | |
| 171 | +} | |
| 172 | + | |
| 173 | +@misc{hernandez2023linearity, | |
| 174 | + title = {{Linearity of Relation Decoding in Transformer Language Models}}, | |
| 175 | + author = {Evan Hernandez and Arnab Sen Sharma and Tal Haklay and Kevin Meng and Martin Wattenberg and Jacob Andreas and Yonatan Belinkov and David Bau}, | |
| 176 | + year = {2023}, | |
| 177 | + month = {8}, | |
| 178 | + eprint = {2308.09124}, | |
| 179 | + archivePrefix= {arXiv}, | |
| 180 | + primaryClass = {cs.LG}, | |
| 181 | + url = {https://arxiv.org/abs/2308.09124}, | |
| 182 | + note = {arXiv:2308.09124; metadata verified via arXiv API on 2026-11-09} | |
| 183 | +} | |
| 184 | + | |
| 185 | +@misc{huh2024platonic, | |
| 186 | + title = {{The Platonic Representation Hypothesis}}, | |
| 187 | + author = {Minyoung Huh and Brian Cheung and Tongzhou Wang and Phillip Isola}, | |
| 188 | + year = {2024}, | |
| 189 | + month = {5}, | |
| 190 | + eprint = {2405.07987}, | |
| 191 | + archivePrefix= {arXiv}, | |
| 192 | + primaryClass = {cs.LG}, | |
| 193 | + url = {https://arxiv.org/abs/2405.07987}, | |
| 194 | + note = {arXiv:2405.07987; metadata verified via arXiv API on 2026-11-09} | |
| 195 | +} | |
| 196 | + | |
| 197 | +@misc{ilharco2022editing, | |
| 198 | + title = {{Editing Models with Task Arithmetic}}, | |
| 199 | + author = {Gabriel Ilharco and Marco Tulio Ribeiro and Mitchell Wortsman and Suchin Gururangan and Ludwig Schmidt and Hannaneh Hajishirzi and Ali Farhadi}, | |
| 200 | + year = {2022}, | |
| 201 | + month = {12}, | |
| 202 | + eprint = {2212.04089}, | |
| 203 | + archivePrefix= {arXiv}, | |
| 204 | + primaryClass = {cs.LG}, | |
| 205 | + url = {https://arxiv.org/abs/2212.04089}, | |
| 206 | + note = {arXiv:2212.04089; metadata verified via arXiv API on 2026-11-09} | |
| 207 | +} | |
| 208 | + | |
| 209 | +@misc{kim2026one, | |
| 210 | + title = {{One Adapter Pair per Model: A Universal Activation Interface for Language Models}}, | |
| 211 | + author = {Su-Hyeon Kim and Jiwan Mun and Yo-Sub Han}, | |
| 212 | + year = {2026}, | |
| 213 | + month = {8}, | |
| 214 | + eprint = {2608.09521}, | |
| 215 | + archivePrefix= {arXiv}, | |
| 216 | + primaryClass = {cs.LG}, | |
| 217 | + url = {https://arxiv.org/abs/2608.09521}, | |
| 218 | + note = {arXiv:2608.09521; metadata verified via arXiv API on 2026-11-09} | |
| 219 | +} | |
| 220 | + | |
| 221 | +@misc{kornblith2019similarity, | |
| 222 | + title = {{Similarity of Neural Network Representations Revisited}}, | |
| 223 | + author = {Simon Kornblith and Mohammad Norouzi and Honglak Lee and Geoffrey Hinton}, | |
| 224 | + year = {2019}, | |
| 225 | + month = {5}, | |
| 226 | + eprint = {1905.00414}, | |
| 227 | + archivePrefix= {arXiv}, | |
| 228 | + primaryClass = {cs.LG}, | |
| 229 | + url = {https://arxiv.org/abs/1905.00414}, | |
| 230 | + note = {arXiv:1905.00414; metadata verified via arXiv API on 2026-11-09} | |
| 231 | +} | |
| 232 | + | |
| 233 | +@misc{lan2024quantifying, | |
| 234 | + title = {{Quantifying Feature Space Universality Across Large Language Models via Sparse Autoencoders}}, | |
| 235 | + author = {Michael Lan and Philip Torr and Austin Meek and Ashkan Khakzar and David Krueger and Fazl Barez}, | |
| 236 | + year = {2024}, | |
| 237 | + month = {10}, | |
| 238 | + eprint = {2410.06981}, | |
| 239 | + archivePrefix= {arXiv}, | |
| 240 | + primaryClass = {cs.LG}, | |
| 241 | + url = {https://arxiv.org/abs/2410.06981}, | |
| 242 | + note = {arXiv:2410.06981; metadata verified via arXiv API on 2026-11-09} | |
| 243 | +} | |
| 244 | + | |
| 245 | +@misc{lee2025shared, | |
| 246 | + title = {{Shared Global and Local Geometry of Language Model Embeddings}}, | |
| 247 | + author = {Andrew Lee and Melanie Weber and Fernanda Viégas and Martin Wattenberg}, | |
| 248 | + year = {2025}, | |
| 249 | + month = {3}, | |
| 250 | + eprint = {2503.21073}, | |
| 251 | + archivePrefix= {arXiv}, | |
| 252 | + primaryClass = {cs.LG}, | |
| 253 | + url = {https://arxiv.org/abs/2503.21073}, | |
| 254 | + note = {arXiv:2503.21073; metadata verified via arXiv API on 2026-11-09} | |
| 255 | +} | |
| 256 | + | |
| 257 | +@misc{li2023inference, | |
| 258 | + title = {{Inference-Time Intervention: Eliciting Truthful Answers from a Language Model}}, | |
| 259 | + author = {Kenneth Li and Oam Patel and Fernanda Viégas and Hanspeter Pfister and Martin Wattenberg}, | |
| 260 | + year = {2023}, | |
| 261 | + month = {6}, | |
| 262 | + eprint = {2306.03341}, | |
| 263 | + archivePrefix= {arXiv}, | |
| 264 | + primaryClass = {cs.LG}, | |
| 265 | + url = {https://arxiv.org/abs/2306.03341}, | |
| 266 | + note = {arXiv:2306.03341; metadata verified via arXiv API on 2026-11-09} | |
| 267 | +} | |
| 268 | + | |
| 269 | +@misc{lo2024large, | |
| 270 | + title = {{Large Language Models Relearn Removed Concepts}}, | |
| 271 | + author = {Michelle Lo and Shay B. Cohen and Fazl Barez}, | |
| 272 | + year = {2024}, | |
| 273 | + month = {1}, | |
| 274 | + eprint = {2401.01814}, | |
| 275 | + archivePrefix= {arXiv}, | |
| 276 | + primaryClass = {cs.LG}, | |
| 277 | + url = {https://arxiv.org/abs/2401.01814}, | |
| 278 | + note = {arXiv:2401.01814; metadata verified via arXiv API on 2026-11-09} | |
| 279 | +} | |
| 280 | + | |
| 281 | +@misc{meng2022locating, | |
| 282 | + title = {{Locating and Editing Factual Associations in GPT}}, | |
| 283 | + author = {Kevin Meng and David Bau and Alex Andonian and Yonatan Belinkov}, | |
| 284 | + year = {2022}, | |
| 285 | + month = {2}, | |
| 286 | + eprint = {2202.05262}, | |
| 287 | + archivePrefix= {arXiv}, | |
| 288 | + primaryClass = {cs.LG}, | |
| 289 | + url = {https://arxiv.org/abs/2202.05262}, | |
| 290 | + note = {arXiv:2202.05262; metadata verified via arXiv API on 2026-11-09} | |
| 291 | +} | |
| 292 | + | |
| 293 | +@misc{minixhofer2024zero, | |
| 294 | + title = {{Zero-Shot Tokenizer Transfer}}, | |
| 295 | + author = {Benjamin Minixhofer and Edoardo Maria Ponti and Ivan Vulić}, | |
| 296 | + year = {2024}, | |
| 297 | + month = {5}, | |
| 298 | + eprint = {2405.07883}, | |
| 299 | + archivePrefix= {arXiv}, | |
| 300 | + primaryClass = {cs.LG}, | |
| 301 | + url = {https://arxiv.org/abs/2405.07883}, | |
| 302 | + note = {arXiv:2405.07883; metadata verified via arXiv API on 2026-11-09} | |
| 303 | +} | |
| 304 | + | |
| 305 | +@misc{nasirisarvi2025sparc, | |
| 306 | + title = {{SPARC: Concept-Aligned Sparse Autoencoders for Cross-Model and Cross-Modal Interpretability}}, | |
| 307 | + author = {Ali Nasiri-Sarvi and Hassan Rivaz and Mahdi S. Hosseini}, | |
| 308 | + year = {2025}, | |
| 309 | + month = {7}, | |
| 310 | + eprint = {2507.06265}, | |
| 311 | + archivePrefix= {arXiv}, | |
| 312 | + primaryClass = {cs.LG}, | |
| 313 | + url = {https://arxiv.org/abs/2507.06265}, | |
| 314 | + note = {arXiv:2507.06265; metadata verified via arXiv API on 2026-11-09} | |
| 315 | +} | |
| 316 | + | |
| 317 | +@misc{ognev2026sharedsae, | |
| 318 | + title = {{SharedSAE: One Feature Dictionary Across Language Models}}, | |
| 319 | + author = {Daniil Ognev and Célian Vasson and Lijie Hu and Kentaro Inui and Benjamin Heinzerling}, | |
| 320 | + year = {2026}, | |
| 321 | + month = {9}, | |
| 322 | + eprint = {2609.04344}, | |
| 323 | + archivePrefix= {arXiv}, | |
| 324 | + primaryClass = {cs.LG}, | |
| 325 | + url = {https://arxiv.org/abs/2609.04344}, | |
| 326 | + note = {arXiv:2609.04344; metadata verified via arXiv API on 2026-11-09} | |
| 327 | +} | |
| 328 | + | |
| 329 | +@misc{panigrahi2023task, | |
| 330 | + title = {{Task-Specific Skill Localization in Fine-tuned Language Models}}, | |
| 331 | + author = {Abhishek Panigrahi and Nikunj Saunshi and Haoyu Zhao and Sanjeev Arora}, | |
| 332 | + year = {2023}, | |
| 333 | + month = {2}, | |
| 334 | + eprint = {2302.06600}, | |
| 335 | + archivePrefix= {arXiv}, | |
| 336 | + primaryClass = {cs.LG}, | |
| 337 | + url = {https://arxiv.org/abs/2302.06600}, | |
| 338 | + note = {arXiv:2302.06600; metadata verified via arXiv API on 2026-11-09} | |
| 339 | +} | |
| 340 | + | |
| 341 | +@misc{raghu2017svcca, | |
| 342 | + title = {{SVCCA: Singular Vector Canonical Correlation Analysis for Deep Learning Dynamics and Interpretability}}, | |
| 343 | + author = {Maithra Raghu and Justin Gilmer and Jason Yosinski and Jascha Sohl-Dickstein}, | |
| 344 | + year = {2017}, | |
| 345 | + month = {6}, | |
| 346 | + eprint = {1706.05806}, | |
| 347 | + archivePrefix= {arXiv}, | |
| 348 | + primaryClass = {cs.LG}, | |
| 349 | + url = {https://arxiv.org/abs/1706.05806}, | |
| 350 | + note = {arXiv:1706.05806; metadata verified via arXiv API on 2026-11-09} | |
| 351 | +} | |
| 352 | + | |
| 353 | +@misc{sinii2025small, | |
| 354 | + title = {{Small Vectors, Big Effects: A Mechanistic Study of RL-Induced Reasoning via Steering Vectors}}, | |
| 355 | + author = {Viacheslav Sinii and Nikita Balagansky and Gleb Gerasimov and Daniil Laptev and Yaroslav Aksenov and Vadim Kurochkin and Alexey Gorbatovski and Boris Shaposhnikov and Daniil Gavrilov}, | |
| 356 | + year = {2025}, | |
| 357 | + month = {9}, | |
| 358 | + eprint = {2509.06608}, | |
| 359 | + archivePrefix= {arXiv}, | |
| 360 | + primaryClass = {cs.LG}, | |
| 361 | + url = {https://arxiv.org/abs/2509.06608}, | |
| 362 | + note = {arXiv:2509.06608; metadata verified via arXiv API on 2026-11-09} | |
| 363 | +} | |
| 364 | + | |
| 365 | +@misc{sun2024massive, | |
| 366 | + title = {{Massive Activations in Large Language Models}}, | |
| 367 | + author = {Mingjie Sun and Xinlei Chen and J. Zico Kolter and Zhuang Liu}, | |
| 368 | + year = {2024}, | |
| 369 | + month = {2}, | |
| 370 | + eprint = {2402.17762}, | |
| 371 | + archivePrefix= {arXiv}, | |
| 372 | + primaryClass = {cs.LG}, | |
| 373 | + url = {https://arxiv.org/abs/2402.17762}, | |
| 374 | + note = {arXiv:2402.17762; metadata verified via arXiv API on 2026-11-09} | |
| 375 | +} | |
| 376 | + | |
| 377 | +@misc{thasarathan2025universal, | |
| 378 | + title = {{Universal Sparse Autoencoders: Interpretable Cross-Model Concept Alignment}}, | |
| 379 | + author = {Harrish Thasarathan and Julian Forsyth and Thomas Fel and Matthew Kowal and Konstantinos G. Derpanis}, | |
| 380 | + year = {2025}, | |
| 381 | + month = {2}, | |
| 382 | + eprint = {2502.03714}, | |
| 383 | + archivePrefix= {arXiv}, | |
| 384 | + primaryClass = {cs.LG}, | |
| 385 | + url = {https://arxiv.org/abs/2502.03714}, | |
| 386 | + note = {arXiv:2502.03714; metadata verified via arXiv API on 2026-11-09} | |
| 387 | +} | |
| 388 | + | |
| 389 | +@misc{todd2023function, | |
| 390 | + title = {{Function Vectors in Large Language Models}}, | |
| 391 | + author = {Eric Todd and Millicent L. Li and Arnab Sen Sharma and Aaron Mueller and Byron C. Wallace and David Bau}, | |
| 392 | + year = {2023}, | |
| 393 | + month = {10}, | |
| 394 | + eprint = {2310.15213}, | |
| 395 | + archivePrefix= {arXiv}, | |
| 396 | + primaryClass = {cs.LG}, | |
| 397 | + url = {https://arxiv.org/abs/2310.15213}, | |
| 398 | + note = {arXiv:2310.15213; metadata verified via arXiv API on 2026-11-09} | |
| 399 | +} | |
| 400 | + | |
| 401 | +@misc{turner2023steering, | |
| 402 | + title = {{Steering Language Models With Activation Engineering}}, | |
| 403 | + author = {Alexander Matt Turner and Lisa Thiergart and Gavin Leech and David Udell and Juan J. Vazquez and Ulisse Mini and Monte MacDiarmid}, | |
| 404 | + year = {2023}, | |
| 405 | + month = {8}, | |
| 406 | + eprint = {2308.10248}, | |
| 407 | + archivePrefix= {arXiv}, | |
| 408 | + primaryClass = {cs.LG}, | |
| 409 | + url = {https://arxiv.org/abs/2308.10248}, | |
| 410 | + note = {arXiv:2308.10248; metadata verified via arXiv API on 2026-11-09} | |
| 411 | +} | |
| 412 | + | |
| 413 | +@misc{vig2020causal, | |
| 414 | + title = {{Causal Mediation Analysis for Interpreting Neural NLP: The Case of Gender Bias}}, | |
| 415 | + author = {Jesse Vig and Sebastian Gehrmann and Yonatan Belinkov and Sharon Qian and Daniel Nevo and Simas Sakenis and Jason Huang and Yaron Singer and Stuart Shieber}, | |
| 416 | + year = {2020}, | |
| 417 | + month = {4}, | |
| 418 | + eprint = {2004.12265}, | |
| 419 | + archivePrefix= {arXiv}, | |
| 420 | + primaryClass = {cs.LG}, | |
| 421 | + url = {https://arxiv.org/abs/2004.12265}, | |
| 422 | + note = {arXiv:2004.12265; metadata verified via arXiv API on 2026-11-09} | |
| 423 | +} | |
| 424 | + | |
| 425 | +@misc{wang2022interpretability, | |
| 426 | + title = {{Interpretability in the Wild: a Circuit for Indirect Object Identification in GPT-2 small}}, | |
| 427 | + author = {Kevin Wang and Alexandre Variengien and Arthur Conmy and Buck Shlegeris and Jacob Steinhardt}, | |
| 428 | + year = {2022}, | |
| 429 | + month = {11}, | |
| 430 | + eprint = {2211.00593}, | |
| 431 | + archivePrefix= {arXiv}, | |
| 432 | + primaryClass = {cs.LG}, | |
| 433 | + url = {https://arxiv.org/abs/2211.00593}, | |
| 434 | + note = {arXiv:2211.00593; metadata verified via arXiv API on 2026-11-09} | |
| 435 | +} | |
| 436 | + | |
| 437 | +@misc{yadav2023ties, | |
| 438 | + title = {{TIES-Merging: Resolving Interference When Merging Models}}, | |
| 439 | + author = {Prateek Yadav and Derek Tam and Leshem Choshen and Colin Raffel and Mohit Bansal}, | |
| 440 | + year = {2023}, | |
| 441 | + month = {6}, | |
| 442 | + eprint = {2306.01708}, | |
| 443 | + archivePrefix= {arXiv}, | |
| 444 | + primaryClass = {cs.LG}, | |
| 445 | + url = {https://arxiv.org/abs/2306.01708}, | |
| 446 | + note = {arXiv:2306.01708; metadata verified via arXiv API on 2026-11-09} | |
| 447 | +} | |
| 448 | + | |
| 449 | +@misc{zhang2026negative, | |
| 450 | + title = {{A Negative Result on Cross-Model Activation Transfer in a Pythia Multi-Hop Setting}}, | |
| 451 | + author = {Peiyan Zhang and Jason Xin}, | |
| 452 | + year = {2026}, | |
| 453 | + month = {6}, | |
| 454 | + eprint = {2606.03280}, | |
| 455 | + archivePrefix= {arXiv}, | |
| 456 | + primaryClass = {cs.LG}, | |
| 457 | + url = {https://arxiv.org/abs/2606.03280}, | |
| 458 | + note = {arXiv:2606.03280; metadata verified via arXiv API on 2026-11-09} | |
| 459 | +} | |
| 460 | + | |
| 461 | +@misc{zou2023representation, | |
| 462 | + title = {{Representation Engineering: A Top-Down Approach to AI Transparency}}, | |
| 463 | + author = {Andy Zou and Long Phan and Sarah Chen and James Campbell and Phillip Guo and Richard Ren and Alexander Pan and Xuwang Yin and Mantas Mazeika and Ann-Kathrin Dombrowski and Shashwat Goel and Nathaniel Li and Michael J. Byun and Zifan Wang and Alex Mallen and Steven Basart and Sanmi Koyejo and Dawn Song and Matt Fredrikson and J. Zico Kolter and Dan Hendrycks}, | |
| 464 | + year = {2023}, | |
| 465 | + month = {10}, | |
| 466 | + eprint = {2310.01405}, | |
| 467 | + archivePrefix= {arXiv}, | |
| 468 | + primaryClass = {cs.LG}, | |
| 469 | + url = {https://arxiv.org/abs/2310.01405}, | |
| 470 | + note = {arXiv:2310.01405; metadata verified via arXiv API on 2026-11-09} | |
| 471 | +} | |
added
paper/sections/conclusion.tex
+2 −0
@@ -0,0 +1,2 @@ | ||
| 1 | +\section{Conclusion}\label{sec:conclusion} | |
| 2 | +[PLACEHOLDER --- written after confirmatory results.] | |
added
paper/sections/discussion.tex
+3 −0
@@ -0,0 +1,3 @@ | ||
| 1 | +\section{Discussion}\label{sec:discussion} | |
| 2 | +[PLACEHOLDER --- what the results establish, what they do not, and alternative explanations; written after | |
| 3 | +confirmatory analysis.] | |
added
paper/sections/experimental_design.tex
+41 −0
@@ -0,0 +1,41 @@ | ||
| 1 | +\section{Experimental Design}\label{sec:design} | |
| 2 | + | |
| 3 | +\subsection{Micro-world A (OPSEQ)} | |
| 4 | +Programs $\langle \mathrm{bos}\rangle\, v_0\, o_1 \dots o_k\, {=}\, r_1 \dots r_k$ apply $k\in[1,5]$ | |
| 5 | +invented operators (eight maps on $\mathbb{Z}_{11}$) to $v_0$ and emit the execution trace. The target | |
| 6 | +operator $\Omega$ is excluded from the recipient's training distribution; two adjacent operator pairs are | |
| 7 | +held out from all training distributions; length $6$--$7$ programs form a length-OOD stratum. Splits are | |
| 8 | +generated from distinct seeds, validated by exact recomputation, hashed and checked for item-level | |
| 9 | +disjointness. Design decision D2 (scratchpad instead of single-token answers) and its consequence for | |
| 10 | +difficulty (\texttt{trace\_stride}) are recorded in the decision log. | |
| 11 | + | |
| 12 | +\subsection{Micro-worlds B and C} | |
| 13 | +B: execution of a fixed random DFA over an invented alphabet (state trace). C: context-dependent suffix | |
| 14 | +selection on pseudo-word stems. [Baselines pending.] | |
| 15 | + | |
| 16 | +\subsection{Models} | |
| 17 | +Tier~0: decoder-only transformers (4 layers, $d{=}128$, 4 heads, $0.80$\,M parameters) trained from | |
| 18 | +scratch with teacher forcing on trace tokens, three seeds per role. Tier~1 (planned): Qwen2.5-1.5B/3B-Instruct | |
| 19 | +and Llama-3.2-3B-Instruct in bf16 under MLX with wrapped layers. [Tier~2 conditional.] | |
| 20 | + | |
| 21 | +\subsection{Hook semantics} | |
| 22 | +Hook points expose embeddings, per-layer residual streams (pre/mid/post), per-head attention outputs | |
| 23 | +before the output projection and MLP outputs. With no registered intervention, or when disabled, the hook | |
| 24 | +returns the input tensor object itself; bitwise equality of logits is asserted in tests and in every run | |
| 25 | +manifest (\texttt{noop}). | |
| 26 | + | |
| 27 | +\subsection{Localization} | |
| 28 | +Interchange interventions patch clean activations into a corrupted twin (same program with $\Omega$ | |
| 29 | +replaced) at every (layer, position) and family; zero-ablation and per-head patching complete the sweep. | |
| 30 | +A sham baseline (corrupted run scored on the clean answer) and repeat/seed reproducibility are reported. | |
| 31 | + | |
| 32 | +\subsection{Transplant families and controls} | |
| 33 | +[To be executed.] Activation graft, subspace graft, circuit graft, weight graft, adapter graft, persistent | |
| 34 | +graft; controls: unmodified models, sham, norm-matched random, unrelated-skill donor, shuffled-token and | |
| 35 | +shuffled-layer grafts, sham mapping, few-shot prompting, retrieval, steering, matched-size adapter | |
| 36 | +fine-tuning, distillation (budget permitting). | |
| 37 | + | |
| 38 | +\subsection{Statistics} | |
| 39 | +Items are nested in programs (clusters); CIs are cluster bootstraps over programs; seeds form a second | |
| 40 | +level; paired contrasts use identical items; Holm correction across graft families; exploratory sweeps are | |
| 41 | +separated from confirmatory contrasts (preregistration v0.1, freeze pending). | |
added
paper/sections/introduction.tex
+25 −0
@@ -0,0 +1,25 @@ | ||
| 1 | +\section{Introduction}\label{sec:intro} | |
| 2 | + | |
| 3 | +\paragraph{Status.} This is a protocol draft. No empirical claim appears in this document unless it is | |
| 4 | +accompanied by a run identifier from the experiment registry (\texttt{experiments/registry/runs.jsonl}). | |
| 5 | + | |
| 6 | +Large language models trained independently appear to converge toward similar linear representation | |
| 7 | +geometries \citep{huh2024platonic,kornblith2019similarity,raghu2017svcca}, and affine maps between the | |
| 8 | +residual streams of related models transfer probes, sparse-autoencoder dictionaries and steering vectors | |
| 9 | +\citep{chen2025transferring,kim2026one,agarwal2026cross}. Whether such maps can carry a | |
| 10 | +\emph{capability}---a reusable computation that the recipient could not perform before---is open. The one | |
| 11 | +controlled attempt we are aware of reports a null: a linear bridge between two Pythia models aligns hidden | |
| 12 | +states almost perfectly yet does not improve multi-hop answering when injected \citep{zhang2026negative}. | |
| 13 | + | |
| 14 | +We study this question with a design in which (i) the donor's capability is \emph{causally localized} | |
| 15 | +by interchange interventions before any transfer is attempted, (ii) the recipient's lack of the capability | |
| 16 | +is \emph{manufactured} (Tier~0) or repeatedly measured (Tier~$\geq$1), and (iii) every transfer is compared | |
| 17 | +with matched sham, random and unrelated-donor interventions. The word \emph{organ} is a metaphor for a | |
| 18 | +bounded, causally identified subsystem; it carries no biological or phenomenal claim. | |
| 19 | + | |
| 20 | +\paragraph{Contributions (planned; to be rewritten after results).} | |
| 21 | +(1) An operational theory of transplantable subsystems with explicit estimands | |
| 22 | +(\S\ref{sec:theory}); (2) a controlled micro-world and an open-weight experimental framework with exact | |
| 23 | +hook semantics (\S\ref{sec:design}); (3) preregistered tests of localization, sufficiency, necessity, | |
| 24 | +selectivity, persistence and portability (\S\ref{sec:results}--\S\ref{sec:robustness}); (4) a map of | |
| 25 | +failure boundaries (\S\ref{sec:discussion}). | |
added
paper/sections/limitations.tex
+7 −0
@@ -0,0 +1,7 @@ | ||
| 1 | +\section{Limitations, Ethics, and Reproducibility}\label{sec:limitations} | |
| 2 | +Known limitations of the design at protocol stage: the Tier-0 capability is a per-step map once the trace is | |
| 3 | +visible (risk R1), so Tier-0 evidence cannot by itself support claims about multi-step reasoning; Tier-1 | |
| 4 | +checkpoints are instruction-tuned and their training data are not controlled; cross-tokenizer transfer is | |
| 5 | +expected to fail without a tokenizer bridge. Ethics: synthetic data only; open-weight models under their | |
| 6 | +licenses; no derived weights are released without license verification. Reproducibility: | |
| 7 | +\texttt{docs/REPRODUCIBILITY.md}; all runs carry manifests with commit, config hash, data hashes and seeds. | |
added
paper/sections/mechanistic_analysis.tex
+2 −0
@@ -0,0 +1,2 @@ | ||
| 1 | +\section{Mechanistic Analysis}\label{sec:mechanism} | |
| 2 | +[PLACEHOLDER --- necessity, sufficiency, rescue, specificity and limits; pending Sprint 5.] | |
added
paper/sections/operational_theory.tex
+35 −0
@@ -0,0 +1,35 @@ | ||
| 1 | +\section{Operational Theory}\label{sec:theory} | |
| 2 | + | |
| 3 | +\subsection{Objects} | |
| 4 | +Let $D$ and $R$ be donor and recipient models, $\mathcal{T}$ a task distribution with a target stratum | |
| 5 | +and control strata, $S_D$ a candidate subsystem of $D$ (a set of layers, heads, MLP units, residual | |
| 6 | +subspaces or sparse features), $A$ an alignment operator mapping donor-side quantities into recipient | |
| 7 | +coordinates, and $I$ an intervention operator. The transplanted recipient is $R' = I(R, A(S_D))$. | |
| 8 | + | |
| 9 | +\subsection{Estimands} | |
| 10 | +With $Q_T(\cdot)$ the exact-match score on held-out target items and $Q_c(\cdot)$ on control stratum $c$: | |
| 11 | +\begin{align} | |
| 12 | +\Delta_T &= Q_T(R') - Q_T(R), \qquad | |
| 13 | +\Delta_T^{\mathrm{adj}} = \Delta_T - \big[Q_T(R_{\mathrm{sham}}) - Q_T(R)\big], \label{eq:adj}\\ | |
| 14 | +\rho_c &= Q_c(R')/Q_c(R) \ \text{(if } Q_c(R)\geq 0.5\text{, else report } \Delta_c), \qquad | |
| 15 | +N_D = Q_T(D) - Q_T(D \setminus S_D). \label{eq:ret} | |
| 16 | +\end{align} | |
| 17 | +$R_{\mathrm{sham}}$ is the matched sham intervention: same positions, layers, dimensionality and activation | |
| 18 | +norm, with donor content replaced by the control defined for each graft family. | |
| 19 | + | |
| 20 | +\subsection{Definitions} | |
| 21 | +\emph{Candidate organ}: a component whose perturbation produces repeatable, task-selective causal effects | |
| 22 | +in $D$ (necessity $N_D$ and restored-answer rate under interchange). \emph{Transplant}: a predeclared | |
| 23 | +intervention $I$ that injects, replaces, composes or maps $A(S_D)$ into $R$. \emph{Acquisition}: | |
| 24 | +$\Delta_T^{\mathrm{adj}}$ above the smallest effect of interest on held-out items, with retention and no | |
| 25 | +leakage. \emph{Selectivity}: target improvement relative to control strata and matched interventions. | |
| 26 | +\emph{Persistence}: single-token, within-sequence, cross-prompt, or saved-checkpoint, reported separately. | |
| 27 | +\emph{Portability}: replication across seeds, prompts, families, sizes and tokenizers. | |
| 28 | + | |
| 29 | +\subsection{What is a theorem and what is a conjecture} | |
| 30 | +A linear-stitching sufficiency statement (if $R$'s upper layers are an exact causal abstraction of $D$'s at | |
| 31 | +the stitched layer, interchange interventions commute with the map) follows from the causal-abstraction | |
| 32 | +framework of \citet{geiger2023causal}; we restate it with its assumptions in Appendix~A. Everything about | |
| 33 | +real models is empirical. \textbf{Conjecture (transfer boundary).} Transfer by affine activation grafts | |
| 34 | +fails when the recipient's downstream computation does not read the mapped subspace; this is the default | |
| 35 | +hypothesis motivated by \citet{zhang2026negative} and is tested, not assumed. | |
added
paper/sections/related_work.tex
+37 −0
@@ -0,0 +1,37 @@ | ||
| 1 | +\section{Related Work}\label{sec:related} | |
| 2 | + | |
| 3 | +\paragraph{Representation similarity and stitching.} SVCCA \citep{raghu2017svcca}, CKA | |
| 4 | +\citep{kornblith2019similarity}, the Platonic Representation Hypothesis \citep{huh2024platonic} and | |
| 5 | +multi-way alignment \citep{achara2026multi} quantify cross-model similarity; stitching | |
| 6 | +\citep{bansal2021revisiting} turns similarity into a functional test. For language models, affine | |
| 7 | +residual-stream maps transfer SAEs, probes and steering vectors across sizes within a family | |
| 8 | +\citep{chen2025transferring}, and a shared ``activation bus'' lets one model's intermediate activation be | |
| 9 | +consumed by another's upper layers \citep{kim2026one}. Shared geometry of unembeddings supports steering | |
| 10 | +transfer \citep{lee2025shared}. Our work differs in starting from a causally identified component and in | |
| 11 | +measuring acquisition against matched controls rather than representational agreement. | |
| 12 | + | |
| 13 | +\paragraph{Cross-model feature dictionaries and steering transfer.} Universal and shared SAEs | |
| 14 | +\citep{lan2024quantifying,thasarathan2025universal,nasirisarvi2025sparc,ognev2026sharedsae} build concept | |
| 15 | +spaces across models; cross-architecture steering transfer \citep{agarwal2026cross} and refusal-circuit | |
| 16 | +transfer \citep{cristofano2026universal} move \emph{behavioural directions}. RL-induced reasoning vectors | |
| 17 | +transfer only within a family \citep{sinii2025small}. These concern concept- or behaviour-level control; | |
| 18 | +we test capability acquisition on verifiable tasks. | |
| 19 | + | |
| 20 | +\paragraph{Capability transfer and merging.} Skill localization by grafting \citep{panigrahi2023task} | |
| 21 | +operates within one model. Activation-guided pruning and merging across scales \citep{fan2026training} and | |
| 22 | +latent semantic alignment with layer-wise training \citep{gu2025beyond} transfer knowledge across sizes; | |
| 23 | +task arithmetic \citep{ilharco2022editing}, TIES \citep{yadav2023ties} and re-basin \citep{ainsworth2022git} | |
| 24 | +merge weights sharing an initialization. Tokenizer transfer \citep{minixhofer2024zero} addresses the | |
| 25 | +vocabulary boundary. | |
| 26 | + | |
| 27 | +\paragraph{Causal methods.} We rely on causal mediation and tracing \citep{vig2020causal,meng2022locating}, | |
| 28 | +interchange interventions and causal abstraction \citep{geiger2023causal,geiger2023finding}, circuit | |
| 29 | +discovery \citep{wang2022interpretability,conmy2023towards}, function and task vectors | |
| 30 | +\citep{todd2023function,hendel2023context}, activation steering | |
| 31 | +\citep{turner2023steering,li2023inference,zou2023representation} and sparse dictionaries | |
| 32 | +\citep{cunningham2023sparse,gurnee2023finding}. Massive activations \citep{sun2024massive} and concept | |
| 33 | +relearning after removal \citep{lo2024large} inform our ablation and persistence tests. | |
| 34 | + | |
| 35 | +\paragraph{Closest negative result.} \citet{zhang2026negative} find that a well-fitting linear bridge does | |
| 36 | +not yield useful causal communication inside the receiver. We treat this as the default expectation and | |
| 37 | +design controls that can distinguish ``no transfer'' from ``transfer masked by misplacement''. | |
added
paper/sections/results.tex
+61 −0
@@ -0,0 +1,61 @@ | ||
| 1 | +\section{Results}\label{sec:results} | |
| 2 | + | |
| 3 | +\paragraph{Scope.} Only the exploratory Tier-0 pilot has been executed (run id | |
| 4 | +\texttt{pilot\_tier0\_opseq\_451ef5087182}, status \emph{completed}, 2026-11-09; manifest in | |
| 5 | +\texttt{experiments/manifests/}). It establishes Gates~B and~C and the within-donor localization (RQ1). | |
| 6 | +\textbf{No transplant has been performed; nothing below is a transfer result.} Numbers are copied from | |
| 7 | +\texttt{experiments/summaries/pilot\_tier0\_opseq\_451ef5087182/results.json}; figures are regenerated by | |
| 8 | +\texttt{scripts/build\_figures.py}. | |
| 9 | + | |
| 10 | +\subsection{Gate B: a manufactured, reproducible capability gap} | |
| 11 | +Three donor seeds trained on all eight operators and three recipient seeds trained with $\Omega$ excluded | |
| 12 | +(3\,000 steps, $0.80$\,M parameters each) reach dev accuracy $1.000$. On the held-out target stratum | |
| 13 | +(programs containing $\Omega$; $n{=}1\,000$ items in $\approx 900$ programs) final-answer exact match is | |
| 14 | +$1.000$ (sd $0.000$) for donors and $0.092$ (sd $0.053$) for recipients, against a majority-class chance of | |
| 15 | +$0.105$; the accuracy of the token emitted at the first $\Omega$ step is $1.000$ versus $0.062$. On the | |
| 16 | +control stratum (no $\Omega$) both roles score $1.000$. The paired gap on identical items (seed~0) is | |
| 17 | +$+0.847$ with cluster-bootstrap 95\% interval $[+0.825,\,+0.870]$ (2\,000 draws over programs). Both roles | |
| 18 | +fail the length-OOD stratum ($0.086$ vs $0.091$), a known limitation of absolute position embeddings that | |
| 19 | +we treat as a stratum, not a target (Figure~\ref{fig:gap}). | |
| 20 | + | |
| 21 | +\begin{figure}[t]\centering | |
| 22 | +\includegraphics[width=0.62\textwidth]{figures/fig_gap_tier0.pdf} | |
| 23 | +\caption{Tier-0 pilot: final-answer exact match by evaluation stratum for donor (all operators) and | |
| 24 | +recipient ($\Omega$ excluded), mean over three seeds (bars) with per-seed values (open markers) and the | |
| 25 | +majority-class chance level (grey dashes). Run \texttt{pilot\_tier0\_opseq\_451ef5087182}.} | |
| 26 | +\label{fig:gap}\end{figure} | |
| 27 | + | |
| 28 | +\subsection{Gate C: hooks are exact} | |
| 29 | +For all six trained models, logits computed with (i) no hooks, (ii) capture hooks on all 27 hook points, | |
| 30 | +and (iii) a modifying hook registered but disabled are bitwise identical on 256 items, and repeated runs | |
| 31 | +are bitwise identical on MPS; the same modifying hook, when enabled, changes the output. | |
| 32 | + | |
| 33 | +\subsection{RQ1: where the donor executes $\Omega$} | |
| 34 | +On 490 clean/corrupted pairs (length-3 programs with $\Omega$ at index~1; corrupted twin replaces $\Omega$ | |
| 35 | +by another operator so that $r_2$ differs; identical teacher-forced prefix up to $r_1$), the clean run | |
| 36 | +scores $1.000$ and the sham (corrupted run scored on the clean answer) $0.000$ in every seed. Patching the | |
| 37 | +clean activation into the corrupted run restores the clean answer at rate $1.00$ when the residual stream | |
| 38 | +at the \emph{read position} $r_1$ is patched at any layer, and $0.00$ at every other position including the | |
| 39 | +$\Omega$ token itself (Figure~\ref{fig:loc}). Within the read position, the layer-0 attention output is | |
| 40 | +sufficient ($1.00$; layers 1--3: $0.00$) and layer-0--2 MLP outputs are partially sufficient ($1.00$, | |
| 41 | +$0.90$, $0.83$; layer 3: $0.17$). Zero-ablation at $r_1$ reduces accuracy to $0.04$--$0.09$ for the residual | |
| 42 | +stream, to $0.13$ for layer-0 attention and $0.21$ for the layer-0 MLP, with no effect elsewhere. Head-level | |
| 43 | +patching at $r_1$ attributes most of the effect to layer-0 head~0 ($0.62$; heads 1--2: $0.16$, $0.04$). | |
| 44 | +Repeating a sweep changes no entry ($\max|\Delta|{=}0$) and the flip-rate heatmaps correlate across seeds | |
| 45 | +at $r \geq 0.96$ (minimum pair; $1.00$ for residual and attention families). | |
| 46 | + | |
| 47 | +\begin{figure}[t]\centering | |
| 48 | +\includegraphics[width=\textwidth]{figures/fig_localization_patching_tier0.pdf} | |
| 49 | +\caption{Within-donor interchange interventions (mean of three seeds): restored-answer rate when the | |
| 50 | +clean activation at (layer, position) is patched into the corrupted run, for the post-block residual | |
| 51 | +stream, the attention output and the MLP output. Columns are token positions of the length-3 program; the | |
| 52 | +read position $r_1$ predicts $r_2$, the $\Omega$ step. Sham rate $0.00$.} | |
| 53 | +\label{fig:loc}\end{figure} | |
| 54 | + | |
| 55 | +\paragraph{Observed versus interpreted.} Observed: the $\Omega$ computation is executed at the read | |
| 56 | +position by layer-0 attention (moving the operator identity from the $\Omega$ token) and layer-0--2 MLPs. | |
| 57 | +Interpretation, to be tested in Sprint~3: the candidate organ for an activation graft is the layer-0 | |
| 58 | +output at the read position, whose content is the (operator, value) pair; a transplant must convey the | |
| 59 | +$\Omega$-specific part of that content without disturbing the value part. Patching the $\Omega$ token | |
| 60 | +restored nothing because the sweep did not include the embedding/pre-layer-0 stream read by layer-0 | |
| 61 | +attention (decision D6). | |
added
paper/sections/robustness.tex
+3 −0
@@ -0,0 +1,3 @@ | ||
| 1 | +\section{Robustness and Failure Modes}\label{sec:robustness} | |
| 2 | +[PLACEHOLDER --- sweeps over strength, layer, position, dimensionality, pair, prompt format, context | |
| 3 | +length, temperature, difficulty and quantization; pending Sprint 5--6.] | |
added
paper/sections/titlepage.tex
+77 −0
@@ -0,0 +1,77 @@ | ||
| 1 | +% ============================================================================ | |
| 2 | +% Title Page | |
| 3 | +% ============================================================================ | |
| 4 | +\thispagestyle{empty} | |
| 5 | + | |
| 6 | +\begin{center} | |
| 7 | + | |
| 8 | +% --- Logo --- | |
| 9 | +\includegraphics[width=3.5cm]{uq_logo.jpg} | |
| 10 | + | |
| 11 | +\vspace{0.6cm} | |
| 12 | + | |
| 13 | +{\footnotesize\textsc{Université du Québec en Outaouais}}\\[0.15cm] | |
| 14 | +{\footnotesize\textsc{Département des sciences administratives}} | |
| 15 | + | |
| 16 | +\vspace{0.8cm} | |
| 17 | + | |
| 18 | +{\footnotesize\textsc{Working Paper No.~\WPnumber}} | |
| 19 | + | |
| 20 | +\vspace{1.2cm} | |
| 21 | + | |
| 22 | +% --- Title --- | |
| 23 | +{\LARGE\bfseries \WPtitle\par} | |
| 24 | + | |
| 25 | +\ifx\WPsubtitle\empty\else | |
| 26 | + \vspace{0.3cm} | |
| 27 | + {\large\itshape \WPsubtitle\par} | |
| 28 | +\fi | |
| 29 | + | |
| 30 | +\vspace{1.2cm} | |
| 31 | + | |
| 32 | +% --- Author --- | |
| 33 | +{\large \WPauthor}\\[0.3cm] | |
| 34 | +{\normalsize \WPaffiliation}\\[0.15cm] | |
| 35 | +{\normalsize \href{mailto:\WPemail}{\WPemail}}\\[0.15cm] | |
| 36 | +{\small \WPaddress} | |
| 37 | + | |
| 38 | +\vspace{0.8cm} | |
| 39 | + | |
| 40 | +% --- Date & Version --- | |
| 41 | +{\normalsize \WPdate}\\[0.1cm] | |
| 42 | +{\small Version~\WPversion} | |
| 43 | + | |
| 44 | +\end{center} | |
| 45 | + | |
| 46 | +\vfill | |
| 47 | + | |
| 48 | +\newpage | |
| 49 | + | |
| 50 | +% ============================================================================ | |
| 51 | +% Abstract Page | |
| 52 | +% ============================================================================ | |
| 53 | +\thispagestyle{empty} | |
| 54 | + | |
| 55 | +\vspace*{1cm} | |
| 56 | + | |
| 57 | +\noindent\rule{\textwidth}{0.4pt} | |
| 58 | +\vspace{0.3cm} | |
| 59 | + | |
| 60 | +\noindent\textbf{Abstract} | |
| 61 | + | |
| 62 | +\vspace{0.15cm} | |
| 63 | + | |
| 64 | +\noindent\WPabstract | |
| 65 | + | |
| 66 | +\vspace{0.4cm} | |
| 67 | + | |
| 68 | +\noindent\textbf{Keywords:} \WPkeywords | |
| 69 | + | |
| 70 | +\vspace{0.15cm} | |
| 71 | + | |
| 72 | +\noindent\textbf{JEL Classification:} \WPjel | |
| 73 | + | |
| 74 | +\vspace{0.3cm} | |
| 75 | +\noindent\rule{\textwidth}{0.4pt} | |
| 76 | + | |
| 77 | +\newpage | |
added
paper/submission/.gitkeep
+0 −0
added
paper/tables/.gitkeep
+0 −0
added
paper/uq_logo.jpg
+0 −0
Binary file not shown.
added
pyproject.toml
+29 −0
@@ -0,0 +1,29 @@ | ||
| 1 | +[project] | |
| 2 | +name = "wp_ai_0001" | |
| 3 | +version = "0.1.0" | |
| 4 | +description = "WP-AI-0001 - The Neural Organ Transplant Experiment: causal transfer of cognitive capabilities across local LLMs (experiment harness)" | |
| 5 | +requires-python = ">=3.12" | |
| 6 | +dependencies = [ | |
| 7 | + "numpy>=2.0", | |
| 8 | + "torch>=2.4", | |
| 9 | + "pydantic>=2.6", | |
| 10 | + "scipy>=1.13", | |
| 11 | + "matplotlib>=3.9", | |
| 12 | +] | |
| 13 | + | |
| 14 | +[project.optional-dependencies] | |
| 15 | +mlx = ["mlx>=0.30", "mlx-lm>=0.28"] | |
| 16 | +hf = ["transformers>=4.45", "safetensors>=0.4", "huggingface_hub>=0.25"] | |
| 17 | +dev = ["pytest>=8"] | |
| 18 | + | |
| 19 | +[build-system] | |
| 20 | +requires = ["setuptools>=68"] | |
| 21 | +build-backend = "setuptools.build_meta" | |
| 22 | + | |
| 23 | +[tool.setuptools.packages.find] | |
| 24 | +where = ["src"] | |
| 25 | + | |
| 26 | +[tool.pytest.ini_options] | |
| 27 | +testpaths = ["tests"] | |
| 28 | +pythonpath = ["src"] | |
| 29 | +addopts = "-q" | |
added
scripts/audit_environment.py
+91 −0
@@ -0,0 +1,91 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Environment audit: hardware, Python stack, backends, cached open-weight checkpoints, cluster nodes. | |
| 3 | + | |
| 4 | +Writes docs/ENVIRONMENT_AUDIT.json (and prints a short report). Cluster probing is optional | |
| 5 | +(``--cluster``) and uses the user's existing SSH aliases; nodes that do not answer are reported as | |
| 6 | +unreachable rather than assumed online. No secrets are read or written. | |
| 7 | +""" | |
| 8 | +from __future__ import annotations | |
| 9 | + | |
| 10 | +import argparse | |
| 11 | +import json | |
| 12 | +import os | |
| 13 | +import subprocess | |
| 14 | +import sys | |
| 15 | +from pathlib import Path | |
| 16 | + | |
| 17 | +ROOT = Path(__file__).resolve().parents[1] | |
| 18 | +sys.path.insert(0, str(ROOT / "src")) | |
| 19 | +from wp_ai_0001.instrumentation.provenance import hardware, library_versions, utc_now # noqa: E402 | |
| 20 | + | |
| 21 | +NODES = ["M3U96a", "M3U96b", "M2U64", "M4M64a", "M4M64b", "M4M64c", "M5M36", "M4M36", "M4BP48", "m4mm", "m4mn"] | |
| 22 | +REMOTE_CMD = ( | |
| 23 | + 'echo "$(sysctl -n machdep.cpu.brand_string)|$(( $(sysctl -n hw.memsize)/1073741824 ))|' | |
| 24 | + '$(df -k ~ | tail -1 | awk \'{print int($4/1048576)}\')|$(python3 --version 2>&1 | cut -d" " -f2)|' | |
| 25 | + '$(python3 -c "import mlx_lm;print(mlx_lm.__version__)" 2>/dev/null || echo none)|' | |
| 26 | + '$(python3 -c "import torch;print(torch.__version__)" 2>/dev/null || echo none)|' | |
| 27 | + '$(ls ~/.cache/huggingface/hub 2>/dev/null | grep -c models--)"' | |
| 28 | +) | |
| 29 | + | |
| 30 | + | |
| 31 | +def hf_cache() -> list[dict]: | |
| 32 | + hub = Path(os.environ.get("HF_HOME", Path.home() / ".cache" / "huggingface")) / "hub" | |
| 33 | + out = [] | |
| 34 | + if hub.exists(): | |
| 35 | + for d in sorted(hub.glob("models--*")): | |
| 36 | + size = sum(f.stat().st_size for f in d.rglob("*") if f.is_file()) | |
| 37 | + out.append({"repo": d.name[len("models--"):].replace("--", "/"), "size_gb": round(size / 2**30, 2)}) | |
| 38 | + return out | |
| 39 | + | |
| 40 | + | |
| 41 | +def backends() -> dict: | |
| 42 | + b: dict = {} | |
| 43 | + try: | |
| 44 | + import mlx.core as mx | |
| 45 | + | |
| 46 | + b["mlx"] = {"version": mx.__version__, "metal": bool(mx.metal.is_available())} | |
| 47 | + except Exception as e: # noqa: BLE001 | |
| 48 | + b["mlx"] = {"error": repr(e)} | |
| 49 | + try: | |
| 50 | + import torch | |
| 51 | + | |
| 52 | + b["torch"] = {"version": torch.__version__, "mps": bool(torch.backends.mps.is_available()), "cuda": bool(torch.cuda.is_available())} | |
| 53 | + except Exception as e: # noqa: BLE001 | |
| 54 | + b["torch"] = {"error": repr(e)} | |
| 55 | + return b | |
| 56 | + | |
| 57 | + | |
| 58 | +def probe_nodes() -> dict: | |
| 59 | + res = {} | |
| 60 | + for n in NODES: | |
| 61 | + try: | |
| 62 | + out = subprocess.run(["ssh", "-o", "ConnectTimeout=6", "-o", "BatchMode=yes", n, REMOTE_CMD], capture_output=True, text=True, timeout=30) | |
| 63 | + line = out.stdout.strip().splitlines()[-1] if out.stdout.strip() else "" | |
| 64 | + if out.returncode != 0 or "|" not in line: | |
| 65 | + res[n] = {"reachable": False, "error": (out.stderr or out.stdout).strip()[:120]} | |
| 66 | + continue | |
| 67 | + chip, mem, free, py, mlxlm, torch_v, hf = line.split("|") | |
| 68 | + res[n] = {"reachable": True, "chip": chip, "memory_gb": int(mem), "free_disk_gb": int(free), "python": py, "mlx_lm": mlxlm, "torch": torch_v, "hf_models_cached": int(hf)} | |
| 69 | + except Exception as e: # noqa: BLE001 | |
| 70 | + res[n] = {"reachable": False, "error": repr(e)[:120]} | |
| 71 | + return res | |
| 72 | + | |
| 73 | + | |
| 74 | +def main() -> None: | |
| 75 | + ap = argparse.ArgumentParser() | |
| 76 | + ap.add_argument("--cluster", action="store_true") | |
| 77 | + args = ap.parse_args() | |
| 78 | + report = {"utc": utc_now(), "hardware": hardware(), "libraries": library_versions(), "backends": backends(), "hf_cache": hf_cache()} | |
| 79 | + if args.cluster: | |
| 80 | + report["cluster"] = probe_nodes() | |
| 81 | + (ROOT / "docs" / "ENVIRONMENT_AUDIT.json").write_text(json.dumps(report, indent=2, default=str)) | |
| 82 | + print(json.dumps({k: report[k] for k in ("hardware", "backends")}, indent=2, default=str)) | |
| 83 | + print("cached checkpoints:", [m["repo"] for m in report["hf_cache"]]) | |
| 84 | + if args.cluster: | |
| 85 | + for n, r in report["cluster"].items(): | |
| 86 | + print(f" {n}: {'OK ' + r['chip'] + ' ' + str(r['memory_gb']) + 'GB mlx_lm=' + r['mlx_lm'] if r['reachable'] else 'UNREACHABLE'}") | |
| 87 | + print("written docs/ENVIRONMENT_AUDIT.json") | |
| 88 | + | |
| 89 | + | |
| 90 | +if __name__ == "__main__": | |
| 91 | + main() | |
added
scripts/build_figures.py
+52 −0
@@ -0,0 +1,52 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Regenerate paper figures from registered run results (no computation, no new data). | |
| 3 | + | |
| 4 | +Usage: python scripts/build_figures.py --run <run_id> [--out paper/figures] | |
| 5 | +Every figure written is listed with the run id and results hash in paper/figures/FIGURE_PROVENANCE.md. | |
| 6 | +""" | |
| 7 | +from __future__ import annotations | |
| 8 | + | |
| 9 | +import argparse | |
| 10 | +import hashlib | |
| 11 | +import json | |
| 12 | +import sys | |
| 13 | +from pathlib import Path | |
| 14 | + | |
| 15 | +ROOT = Path(__file__).resolve().parents[1] | |
| 16 | +sys.path.insert(0, str(ROOT / "src")) | |
| 17 | +sys.path.insert(0, str(ROOT / "scripts")) | |
| 18 | + | |
| 19 | +from wp_ai_0001.config import PilotConfig # noqa: E402 | |
| 20 | +from wp_ai_0001.instrumentation.provenance import utc_now # noqa: E402 | |
| 21 | + | |
| 22 | + | |
| 23 | +def main() -> None: | |
| 24 | + ap = argparse.ArgumentParser() | |
| 25 | + ap.add_argument("--run", required=True) | |
| 26 | + ap.add_argument("--out", default=str(ROOT / "paper" / "figures")) | |
| 27 | + args = ap.parse_args() | |
| 28 | + res_path = ROOT / "experiments" / "summaries" / args.run / "results.json" | |
| 29 | + man_path = ROOT / "experiments" / "manifests" / f"{args.run}.json" | |
| 30 | + results = json.loads(res_path.read_text()) | |
| 31 | + manifest = json.loads(man_path.read_text()) | |
| 32 | + if manifest["status"] != "completed": | |
| 33 | + raise SystemExit(f"run {args.run} has status {manifest['status']}; refusing to build figures") | |
| 34 | + out = Path(args.out) | |
| 35 | + out.mkdir(parents=True, exist_ok=True) | |
| 36 | + if results["run_id"].startswith("pilot_tier0_opseq"): | |
| 37 | + from run_pilot import make_figures | |
| 38 | + | |
| 39 | + cfg = PilotConfig.model_validate(manifest["config"]) | |
| 40 | + make_figures(results, out, results["localization"]["positions"], cfg) | |
| 41 | + else: | |
| 42 | + raise SystemExit("no figure recipe for this run type") | |
| 43 | + digest = hashlib.sha256(res_path.read_bytes()).hexdigest()[:16] | |
| 44 | + prov = out / "FIGURE_PROVENANCE.md" | |
| 45 | + lines = [l for l in prov.read_text().splitlines() if not l.startswith(f"| {args.run} ")] if prov.exists() else ["# Figure provenance", "", "| run id | results sha256[:16] | built (UTC) | figures |", "|---|---|---|---|"] | |
| 46 | + lines.append(f"| {args.run} | {digest} | {utc_now()} | " + ", ".join(sorted(p.name for p in out.glob('*.pdf'))) + " |") | |
| 47 | + prov.write_text("\n".join(lines) + "\n") | |
| 48 | + print(f"figures written to {out} (provenance updated)") | |
| 49 | + | |
| 50 | + | |
| 51 | +if __name__ == "__main__": | |
| 52 | + main() | |
added
scripts/build_paper.sh
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +#!/usr/bin/env bash | |
| 2 | +# Build paper/main.pdf with the UQO template Makefile (latexmk). Figures must be built first. | |
| 3 | +set -euo pipefail | |
| 4 | +cd "$(dirname "$0")/../paper" | |
| 5 | +make | |
| 6 | +echo "built paper/main.pdf" | |
added
scripts/run_pilot.py
+356 −0
@@ -0,0 +1,356 @@ | ||
| 1 | +#!/usr/bin/env python3 | |
| 2 | +"""Sprint 1-2 pilot (Tier 0, micro-world A / OPSEQ). | |
| 3 | + | |
| 4 | +What this script establishes, with artifacts: | |
| 5 | + 1. Donor/recipient capability gap on the target operator (Gate B), repeated over seeds. | |
| 6 | + 2. Hook no-op guarantee on trained models (Gate C): instrumented == uninstrumented, bitwise. | |
| 7 | + 3. Within-model causal localization of the target operator in the donor (activation patching, | |
| 8 | + zero-ablation, head patching), with a sham baseline and reproducibility checks (RQ1). | |
| 9 | + | |
| 10 | +No transplant is performed here. Nothing in this script claims transfer. | |
| 11 | + | |
| 12 | +Usage: python scripts/run_pilot.py [--seeds 0 1 2] [--steps 3000] [--device auto] [--quick] [--dry-run] | |
| 13 | +""" | |
| 14 | +from __future__ import annotations | |
| 15 | + | |
| 16 | +import argparse | |
| 17 | +import gzip | |
| 18 | +import json | |
| 19 | +import sys | |
| 20 | +import time | |
| 21 | +from pathlib import Path | |
| 22 | + | |
| 23 | +import numpy as np | |
| 24 | +import torch | |
| 25 | + | |
| 26 | +ROOT = Path(__file__).resolve().parents[1] | |
| 27 | +sys.path.insert(0, str(ROOT / "src")) | |
| 28 | + | |
| 29 | +from wp_ai_0001.config import ModelRoleConfig, OpSeqTaskConfig, PilotConfig, ToyModelConfig, TrainConfig, config_hash # noqa: E402 | |
| 30 | +from wp_ai_0001.datasets import opseq # noqa: E402 | |
| 31 | +from wp_ai_0001.datasets.common import Split, assert_disjoint, encode_split # noqa: E402 | |
| 32 | +from wp_ai_0001.evaluation.metrics import chance_level, evaluate # noqa: E402 | |
| 33 | +from wp_ai_0001.instrumentation.provenance import Manifest, make_run_id, utc_now # noqa: E402 | |
| 34 | +from wp_ai_0001.localization.patching import ablation_sweep, head_patch_sweep, patch_sweep # noqa: E402 | |
| 35 | +from wp_ai_0001.models.hooks import Capture, Zero # noqa: E402 | |
| 36 | +from wp_ai_0001.models.toy_transformer import resolve_device # noqa: E402 | |
| 37 | +from wp_ai_0001.orchestration import registry # noqa: E402 | |
| 38 | +from wp_ai_0001.statistics.bootstrap import cluster_bootstrap_mean, cluster_bootstrap_paired_diff, seeds_summary # noqa: E402 | |
| 39 | +from wp_ai_0001.training.train_toy import load as load_model # noqa: E402 | |
| 40 | +from wp_ai_0001.training.train_toy import train # noqa: E402 | |
| 41 | + | |
| 42 | +OMEGA = "qua" | |
| 43 | +MAX_SEQ = 24 | |
| 44 | + | |
| 45 | + | |
| 46 | +def build_splits(cfg_donor: OpSeqTaskConfig, cfg_recip: OpSeqTaskConfig, n_train: int, n_dev: int, n_eval: int, base_seed: int) -> dict[str, Split]: | |
| 47 | + """All splits from distinct seeds; evaluation splits are disjoint from every training split.""" | |
| 48 | + s = base_seed | |
| 49 | + sp: dict[str, Split] = {} | |
| 50 | + sp["donor_train"] = opseq.generate(cfg_donor, n_train, s + 1, "donor_train", mode="train") | |
| 51 | + sp["recipient_train"] = opseq.generate(cfg_recip, n_train, s + 2, "recipient_train", mode="train") | |
| 52 | + used = sp["donor_train"].item_hashes() | sp["recipient_train"].item_hashes() | |
| 53 | + sp["donor_dev"] = opseq.generate(cfg_donor, n_dev, s + 3, "donor_dev", mode="train", exclude_hashes=used) | |
| 54 | + used |= sp["donor_dev"].item_hashes() | |
| 55 | + sp["recipient_dev"] = opseq.generate(cfg_recip, n_dev, s + 4, "recipient_dev", mode="train", exclude_hashes=used) | |
| 56 | + used |= sp["recipient_dev"].item_hashes() | |
| 57 | + # evaluation strata (shared by all models) | |
| 58 | + sp["target_iid"] = opseq.generate(cfg_donor, n_eval, s + 10, "target_iid", mode="train", require_operator=OMEGA, exclude_hashes=used) | |
| 59 | + used |= sp["target_iid"].item_hashes() | |
| 60 | + sp["control_iid"] = opseq.generate(cfg_donor, n_eval, s + 11, "control_iid", mode="train", forbid_operator=OMEGA, exclude_hashes=used) | |
| 61 | + used |= sp["control_iid"].item_hashes() | |
| 62 | + sp["comp_heldout"] = opseq.generate(cfg_donor, n_eval, s + 12, "comp_heldout", mode="comp", min_len=2, exclude_hashes=used) | |
| 63 | + used |= sp["comp_heldout"].item_hashes() | |
| 64 | + sp["len_ood"] = opseq.generate(cfg_donor, max(200, n_eval // 2), s + 13, "len_ood", mode="any", min_len=6, max_len=7, exclude_hashes=used) | |
| 65 | + for k in ("donor_train", "donor_dev", "target_iid", "control_iid", "comp_heldout", "len_ood"): | |
| 66 | + opseq.validate(sp[k], cfg_donor) | |
| 67 | + opseq.validate(sp["recipient_train"], cfg_recip) | |
| 68 | + opseq.validate(sp["recipient_dev"], cfg_recip) | |
| 69 | + assert_disjoint(sp["donor_train"], sp["donor_dev"], sp["target_iid"], sp["control_iid"], sp["comp_heldout"], sp["len_ood"]) | |
| 70 | + assert_disjoint(sp["recipient_train"], sp["recipient_dev"], sp["target_iid"], sp["control_iid"], sp["comp_heldout"], sp["len_ood"]) | |
| 71 | + return sp | |
| 72 | + | |
| 73 | + | |
| 74 | +def omega_step_accuracy(split: Split, predictions: list[list[str]]) -> np.ndarray: | |
| 75 | + """Per item: 1 if the scratchpad token at the first Ω step is correct (items without Ω: NaN).""" | |
| 76 | + out = np.full(len(split.examples), np.nan) | |
| 77 | + for i, (e, pred) in enumerate(zip(split.examples, predictions)): | |
| 78 | + ops = list(e.prompt[2:-1]) | |
| 79 | + if OMEGA in ops: | |
| 80 | + j = ops.index(OMEGA) | |
| 81 | + out[i] = float(j < len(pred) and pred[j] == e.answers[j]) | |
| 82 | + return out | |
| 83 | + | |
| 84 | + | |
| 85 | +def localization_set(cfg: OpSeqTaskConfig, corrupt_op: str = "zib") -> tuple[Split, Split]: | |
| 86 | + """Length-3 programs with Ω at index 1; corrupted twin replaces Ω by ``corrupt_op`` so that r_2 differs.""" | |
| 87 | + others = [o for o in cfg.operators if o != OMEGA] | |
| 88 | + clean, corrupt = [], [] | |
| 89 | + for a in others: | |
| 90 | + for b in others: | |
| 91 | + for v0 in range(cfg.modulus): | |
| 92 | + ec = opseq.make_example(v0, [a, OMEGA, b], cfg.modulus) | |
| 93 | + ex = opseq.make_example(v0, [a, corrupt_op, b], cfg.modulus) | |
| 94 | + if ec.answers[1] != ex.answers[1]: | |
| 95 | + clean.append(ec) | |
| 96 | + corrupt.append(ex) | |
| 97 | + return (Split("loc_clean", clean, "opseq", opseq.GENERATOR_VERSION, 0, cfg.model_dump()), | |
| 98 | + Split("loc_corrupt", corrupt, "opseq", opseq.GENERATOR_VERSION, 0, cfg.model_dump())) | |
| 99 | + | |
| 100 | + | |
| 101 | +def noop_check(model, enc, device) -> dict: | |
| 102 | + ids = torch.from_numpy(enc["ids"][:256]).to(device) | |
| 103 | + pos = torch.from_numpy(enc["prompt_len"][:256] - 1).to(device) | |
| 104 | + model.hooks.clear() | |
| 105 | + with torch.no_grad(): | |
| 106 | + ref = model(ids, pos) | |
| 107 | + again = model(ids, pos) | |
| 108 | + cap = Capture() | |
| 109 | + for n in model.hook_names(): | |
| 110 | + model.hooks.add(n, cap) | |
| 111 | + with_capture = model(ids, pos) | |
| 112 | + model.hooks.add("resid_post.0", Zero()) | |
| 113 | + with model.hooks.disabled(): | |
| 114 | + disabled = model(ids, pos) | |
| 115 | + enabled = model(ids, pos) | |
| 116 | + model.hooks.clear() | |
| 117 | + return {"deterministic_repeat": bool(torch.equal(ref, again)), "capture_all_bitwise_identity": bool(torch.equal(ref, with_capture)), | |
| 118 | + "disabled_modifying_hook_bitwise_identity": bool(torch.equal(ref, disabled)), | |
| 119 | + "enabled_zero_hook_changes_output": bool(not torch.equal(ref, enabled)), "n_hook_points": len(model.hook_names()), "n_items": int(ids.shape[0])} | |
| 120 | + | |
| 121 | + | |
| 122 | +def main() -> None: | |
| 123 | + ap = argparse.ArgumentParser() | |
| 124 | + ap.add_argument("--seeds", type=int, nargs="+", default=[0, 1, 2]) | |
| 125 | + ap.add_argument("--steps", type=int, default=3000) | |
| 126 | + ap.add_argument("--device", default="auto") | |
| 127 | + ap.add_argument("--quick", action="store_true", help="tiny settings for a CPU smoke test") | |
| 128 | + ap.add_argument("--dry-run", action="store_true", help="build splits and manifest only") | |
| 129 | + ap.add_argument("--n-boot", type=int, default=2000) | |
| 130 | + args = ap.parse_args() | |
| 131 | + | |
| 132 | + n_train, n_dev, n_eval, steps = (3000, 300, 300, 200) if args.quick else (40_000, 1_000, 1_000, args.steps) | |
| 133 | + task_d = OpSeqTaskConfig() | |
| 134 | + task_r = OpSeqTaskConfig(excluded_operators=[OMEGA]) | |
| 135 | + model_cfg = ToyModelConfig(max_seq_len=MAX_SEQ) if not args.quick else ToyModelConfig(d_model=64, n_layers=3, n_heads=2, d_ff=128, max_seq_len=MAX_SEQ) | |
| 136 | + cfg = PilotConfig( | |
| 137 | + experiment_id="pilot_tier0_opseq" + ("_quick" if args.quick else ""), seeds=args.seeds, target_operator=OMEGA, n_eval=n_eval, n_bootstrap=args.n_boot, | |
| 138 | + donor=ModelRoleConfig(role="donor", name="donor", model=model_cfg, task=task_d, train=TrainConfig(steps=steps, device=args.device, n_train=n_train, n_dev=n_dev)), | |
| 139 | + recipient=ModelRoleConfig(role="recipient", name="recipient", model=model_cfg, task=task_r, train=TrainConfig(steps=steps, device=args.device, n_train=n_train, n_dev=n_dev)), | |
| 140 | + ) | |
| 141 | + chash = config_hash(cfg) | |
| 142 | + run_id = make_run_id(cfg.experiment_id, chash) | |
| 143 | + out_dir = ROOT / "experiments" / "summaries" / run_id | |
| 144 | + art_dir = ROOT / "artifacts" / "runs" / run_id | |
| 145 | + models_dir = ROOT / "artifacts" / "models" / run_id | |
| 146 | + fig_dir = ROOT / "artifacts" / "figures" / run_id | |
| 147 | + for d in (out_dir, art_dir, fig_dir): | |
| 148 | + d.mkdir(parents=True, exist_ok=True) | |
| 149 | + man = Manifest(run_id, cfg.experiment_id, cfg.model_dump(), ROOT / "experiments" / "manifests") | |
| 150 | + registry.record(run_id, cfg.experiment_id, "planned", config_hash=chash) | |
| 151 | + device = resolve_device(args.device) | |
| 152 | + t_start = time.time() | |
| 153 | + print(f"[{utc_now()}] run_id={run_id} device={device}") | |
| 154 | + | |
| 155 | + # ---------------- data ---------------- | |
| 156 | + splits = build_splits(task_d, task_r, n_train, n_dev, n_eval, base_seed=20261109) | |
| 157 | + data_dir = art_dir / "data" | |
| 158 | + for name, sp in splits.items(): | |
| 159 | + sp.save(data_dir / f"{name}.json") | |
| 160 | + man.data["data_hashes"][name] = {"hash": sp.hash, "n": len(sp), "seed": sp.seed, "generator": f"{sp.generator}@{sp.generator_version}"} | |
| 161 | + man.save() | |
| 162 | + vocab = opseq.vocab_for(task_d) | |
| 163 | + chance = {k: chance_level(splits[k]) for k in ("target_iid", "control_iid", "comp_heldout", "len_ood")} | |
| 164 | + print("splits:", {k: (len(v), v.hash) for k, v in splits.items()}) | |
| 165 | + if args.dry_run: | |
| 166 | + man.set_status("planned", "dry run: splits and manifest only") | |
| 167 | + print("dry run complete") | |
| 168 | + return | |
| 169 | + | |
| 170 | + man.set_status("running") | |
| 171 | + registry.record(run_id, cfg.experiment_id, "running") | |
| 172 | + results: dict = {"run_id": run_id, "config_hash": chash, "device": str(device), "chance_level": chance, "seeds": {}, "noop": {}, "localization": {}} | |
| 173 | + try: | |
| 174 | + # ---------------- training + evaluation ---------------- | |
| 175 | + eval_names = ["target_iid", "control_iid", "comp_heldout", "len_ood"] | |
| 176 | + per_item: dict[str, dict[str, np.ndarray]] = {} | |
| 177 | + for seed in cfg.seeds: | |
| 178 | + results["seeds"][seed] = {} | |
| 179 | + for role in (cfg.donor, cfg.recipient): | |
| 180 | + tcfg = role.train.model_copy(update={"seed": seed}) | |
| 181 | + mdir = models_dir / f"{role.name}_s{seed}" | |
| 182 | + t0 = time.time() | |
| 183 | + if (mdir / "model.pt").exists(): | |
| 184 | + model, _ = load_model(mdir, device) | |
| 185 | + hist = json.loads((mdir / "history.json").read_text()) | |
| 186 | + print(f" loaded {role.name} s{seed}") | |
| 187 | + else: | |
| 188 | + hist = [] | |
| 189 | + model = train(role.model, tcfg, splits[f"{role.name}_train"], splits[f"{role.name}_dev"], vocab, mdir, hist) | |
| 190 | + print(f" trained {role.name} s{seed} in {time.time()-t0:.0f}s dev_acc={hist[-1]['dev_acc']:.3f}") | |
| 191 | + model.eval() | |
| 192 | + rec = {"n_params": model.n_params, "train_seconds": time.time() - t0, "final_dev": hist[-1], "eval": {}} | |
| 193 | + for en in eval_names: | |
| 194 | + r = evaluate(model, splits[en], vocab, device) | |
| 195 | + ci = cluster_bootstrap_mean(r.correct.astype(float), r.clusters, cfg.n_bootstrap, seed=seed) | |
| 196 | + om = omega_step_accuracy(splits[en], r.predictions) | |
| 197 | + om_ci = cluster_bootstrap_mean(om[~np.isnan(om)], [c for c, o in zip(r.clusters, om) if not np.isnan(o)], cfg.n_bootstrap, seed=seed) if (~np.isnan(om)).any() else None | |
| 198 | + rec["eval"][en] = {**r.to_summary(), "ci95": ci.to_dict(), "omega_step_acc": om_ci.to_dict() if om_ci else None, "chance": chance[en]} | |
| 199 | + per_item[f"{role.name}_s{seed}_{en}"] = {"correct": r.correct, "trace_correct": r.trace_correct, "omega": om} | |
| 200 | + with gzip.open(art_dir / f"items_{role.name}_s{seed}_{en}.json.gz", "wt") as f: | |
| 201 | + json.dump({"split_hash": r.split_hash, "predictions": r.predictions, "answers": r.answers, "clusters": r.clusters}, f) | |
| 202 | + enc_dev = encode_split(splits["donor_dev"], vocab, MAX_SEQ) | |
| 203 | + results["noop"][f"{role.name}_s{seed}"] = noop_check(model, enc_dev, device) | |
| 204 | + results["seeds"][seed][role.name] = rec | |
| 205 | + # paired donor-recipient difference on identical items | |
| 206 | + results["seeds"][seed]["gap"] = {} | |
| 207 | + for en in eval_names: | |
| 208 | + d, r_ = per_item[f"donor_s{seed}_{en}"], per_item[f"recipient_s{seed}_{en}"] | |
| 209 | + ci = cluster_bootstrap_paired_diff(d["correct"].astype(float), r_["correct"].astype(float), splits[en].examples and [e.cluster for e in splits[en].examples], cfg.n_bootstrap, seed=seed) | |
| 210 | + results["seeds"][seed]["gap"][en] = ci.to_dict() | |
| 211 | + man.save() | |
| 212 | + | |
| 213 | + results["across_seeds"] = {en: {role: seeds_summary([results["seeds"][s][role]["eval"][en]["accuracy"] for s in cfg.seeds]) for role in ("donor", "recipient")} for en in eval_names} | |
| 214 | + results["across_seeds_omega_step"] = {role: seeds_summary([results["seeds"][s][role]["eval"]["target_iid"]["omega_step_acc"]["estimate"] for s in cfg.seeds]) for role in ("donor", "recipient")} | |
| 215 | + | |
| 216 | + # ---------------- localization (donor models) ---------------- | |
| 217 | + clean, corrupt = localization_set(task_d) | |
| 218 | + enc_c, enc_x = encode_split(clean, vocab, MAX_SEQ), encode_split(corrupt, vocab, MAX_SEQ) | |
| 219 | + read_pos = int(enc_c["prompt_len"][0]) # index of r_1; predicts r_2 (the Ω step) | |
| 220 | + assert (enc_c["prompt_len"] == read_pos).all() and (enc_x["prompt_len"] == read_pos).all() | |
| 221 | + ids_c = torch.from_numpy(enc_c["ids"]).to(device) | |
| 222 | + ids_x = torch.from_numpy(enc_x["ids"]).to(device) | |
| 223 | + pos = torch.full((len(clean),), read_pos, dtype=torch.long, device=device) | |
| 224 | + ans_c = torch.from_numpy(enc_c["answers"][:, 1]).to(device) | |
| 225 | + ans_x = torch.from_numpy(enc_x["answers"][:, 1]).to(device) | |
| 226 | + positions = list(range(read_pos + 1)) | |
| 227 | + pos_labels = ["<bos>", "v0", "op1", "Ω", "op3", "=", "r1"] | |
| 228 | + loc: dict = {"n_items": len(clean), "read_position": read_pos, "positions": pos_labels, "families": {}, "ablation": {}, "heads": {}, "reproducibility": {}} | |
| 229 | + heat_by_seed: dict[str, list[np.ndarray]] = {} | |
| 230 | + for seed in cfg.seeds: | |
| 231 | + model, _ = load_model(models_dir / f"donor_s{seed}", device) | |
| 232 | + with torch.no_grad(): | |
| 233 | + base_c = (model.answer_logits(ids_c, pos).argmax(-1) == ans_c).float().mean().item() | |
| 234 | + base_x = (model.answer_logits(ids_x, pos).argmax(-1) == ans_c).float().mean().item() | |
| 235 | + loc.setdefault("baselines", {})[f"s{seed}"] = {"clean_acc_on_clean_answer": base_c, "corrupt_run_acc_on_clean_answer(sham)": base_x} | |
| 236 | + for fam in ("resid_post", "attn_out", "mlp_out"): | |
| 237 | + pr = patch_sweep(model, ids_c, ids_x, pos, ans_c, ans_x, family=fam, positions=positions) | |
| 238 | + pr2 = patch_sweep(model, ids_c, ids_x, pos, ans_c, ans_x, family=fam, positions=positions) | |
| 239 | + loc["families"].setdefault(fam, {})[f"s{seed}"] = {"flip_rate": pr.flip_rate.tolist(), "logit_recovery": pr.logit_recovery.tolist()} | |
| 240 | + loc["reproducibility"][f"{fam}_s{seed}_repeat_max_abs_diff"] = float(np.abs(pr.flip_rate - pr2.flip_rate).max()) | |
| 241 | + heat_by_seed.setdefault(fam, []).append(pr.flip_rate) | |
| 242 | + abl = ablation_sweep(model, ids_c, pos, ans_c, family=fam, positions=positions, mode="zero") | |
| 243 | + loc["ablation"].setdefault(fam, {})[f"s{seed}"] = abl.tolist() | |
| 244 | + for p_name, p_idx in (("omega_token", 3), ("read_position", read_pos)): | |
| 245 | + loc["heads"].setdefault(p_name, {})[f"s{seed}"] = head_patch_sweep(model, ids_c, ids_x, pos, ans_c, ans_x, p_idx).tolist() | |
| 246 | + print(f" localization donor s{seed} done") | |
| 247 | + for fam, mats in heat_by_seed.items(): | |
| 248 | + if len(mats) > 1: | |
| 249 | + flat = np.stack([m.ravel() for m in mats]) | |
| 250 | + cc = np.corrcoef(flat) | |
| 251 | + loc["reproducibility"][f"{fam}_across_seed_pearson_min"] = float(cc[np.triu_indices(len(mats), 1)].min()) | |
| 252 | + loc["families"][fam]["mean_flip_rate"] = np.mean(mats, axis=0).tolist() | |
| 253 | + results["localization"] = loc | |
| 254 | + | |
| 255 | + # ---------------- figures ---------------- | |
| 256 | + make_figures(results, fig_dir, pos_labels, cfg) | |
| 257 | + results["elapsed_seconds"] = time.time() - t_start | |
| 258 | + (out_dir / "results.json").write_text(json.dumps(results, indent=2, default=float)) | |
| 259 | + write_summary(results, out_dir, cfg, fig_dir) | |
| 260 | + man.data["outputs"] = {"results": str(out_dir.relative_to(ROOT) / "results.json"), "figures": str(fig_dir.relative_to(ROOT)), "models": str(models_dir.relative_to(ROOT)), "items": str(art_dir.relative_to(ROOT))} | |
| 261 | + man.set_status("completed") | |
| 262 | + registry.record(run_id, cfg.experiment_id, "completed", results=str(out_dir.relative_to(ROOT) / "results.json")) | |
| 263 | + print(f"[{utc_now()}] completed in {results['elapsed_seconds']:.0f}s -> {out_dir}") | |
| 264 | + except Exception as exc: # noqa: BLE001 | |
| 265 | + man.set_status("failed", repr(exc)) | |
| 266 | + registry.record(run_id, cfg.experiment_id, "failed", error=repr(exc)) | |
| 267 | + raise | |
| 268 | + | |
| 269 | + | |
| 270 | +def make_figures(results: dict, fig_dir: Path, pos_labels: list[str], cfg: PilotConfig) -> None: | |
| 271 | + import matplotlib.pyplot as plt | |
| 272 | + | |
| 273 | + from wp_ai_0001.visualization import DIVERGING_CMAP, ENTITY_COLORS, SEQUENTIAL_CMAP, apply_style, heatmap | |
| 274 | + from wp_ai_0001.visualization.style import DOUBLE_WIDTH_IN, TEXT_SECONDARY | |
| 275 | + | |
| 276 | + apply_style() | |
| 277 | + seeds = {str(k): v for k, v in results["seeds"].items()} # JSON round-trips keys as strings | |
| 278 | + eval_names = ["target_iid", "control_iid", "comp_heldout", "len_ood"] | |
| 279 | + # Figure 1: capability gap, per split, donor vs recipient, mean over seeds with per-seed points and CI of seed 0 | |
| 280 | + fig, ax = plt.subplots(figsize=(DOUBLE_WIDTH_IN * 0.6, 2.2)) | |
| 281 | + x = np.arange(len(eval_names)) | |
| 282 | + w = 0.36 | |
| 283 | + for k, role in enumerate(("donor", "recipient")): | |
| 284 | + means = [results["across_seeds"][en][role]["mean"] for en in eval_names] | |
| 285 | + ax.bar(x + (k - 0.5) * w, means, width=w - 0.04, color=ENTITY_COLORS[role], label=role, linewidth=0) | |
| 286 | + for s in cfg.seeds: | |
| 287 | + ax.scatter(x + (k - 0.5) * w, [seeds[str(s)][role]["eval"][en]["accuracy"] for en in eval_names], s=8, color="#ffffff", edgecolor=ENTITY_COLORS[role], linewidth=0.6, zorder=3) | |
| 288 | + ax.scatter(x, [results["chance_level"][en] for en in eval_names], marker="_", s=120, color=ENTITY_COLORS["chance"], label="majority-class chance", zorder=4) | |
| 289 | + ax.set_xticks(x) | |
| 290 | + ax.set_xticklabels(["target (Ω)", "control (no Ω)", "held-out comp.", "length OOD"]) | |
| 291 | + ax.set_ylabel("final-answer exact match") | |
| 292 | + ax.set_ylim(0, 1.02) | |
| 293 | + ax.legend(loc="upper right", ncol=1) | |
| 294 | + fig.savefig(fig_dir / "fig_gap_tier0.pdf") | |
| 295 | + plt.close(fig) | |
| 296 | + # Figure 2: localization heatmaps (mean flip rate over seeds) for three families | |
| 297 | + fams = ["resid_post", "attn_out", "mlp_out"] | |
| 298 | + fig, axes = plt.subplots(1, 3, figsize=(DOUBLE_WIDTH_IN, 2.1), sharey=True) | |
| 299 | + for ax, fam in zip(axes, fams): | |
| 300 | + m = np.array(results["localization"]["families"][fam]["mean_flip_rate"]) | |
| 301 | + heatmap(ax, m, [f"L{l}" for l in range(m.shape[0])], pos_labels, cmap=SEQUENTIAL_CMAP, vmin=0, vmax=1, cbar_label="restored-answer rate", title=fam, annotate=True) | |
| 302 | + ax.set_xlabel("patched token position") | |
| 303 | + axes[0].set_ylabel("layer") | |
| 304 | + fig.savefig(fig_dir / "fig_localization_patching_tier0.pdf") | |
| 305 | + plt.close(fig) | |
| 306 | + # Figure 3: zero-ablation (mean over seeds) accuracy | |
| 307 | + fig, axes = plt.subplots(1, 3, figsize=(DOUBLE_WIDTH_IN, 2.1), sharey=True) | |
| 308 | + for ax, fam in zip(axes, fams): | |
| 309 | + m = np.mean([np.array(v) for v in results["localization"]["ablation"][fam].values()], axis=0) | |
| 310 | + heatmap(ax, m, [f"L{l}" for l in range(m.shape[0])], pos_labels, cmap=SEQUENTIAL_CMAP, vmin=0, vmax=1, cbar_label="accuracy after zero-ablation", title=fam, annotate=True) | |
| 311 | + ax.set_xlabel("ablated token position") | |
| 312 | + axes[0].set_ylabel("layer") | |
| 313 | + fig.savefig(fig_dir / "fig_localization_ablation_tier0.pdf") | |
| 314 | + plt.close(fig) | |
| 315 | + # Figure 4: head-level patching at the Ω token and at the read position | |
| 316 | + fig, axes = plt.subplots(1, 2, figsize=(DOUBLE_WIDTH_IN * 0.75, 2.1), sharey=True) | |
| 317 | + for ax, key in zip(axes, ("omega_token", "read_position")): | |
| 318 | + m = np.mean([np.array(v) for v in results["localization"]["heads"][key].values()], axis=0) | |
| 319 | + heatmap(ax, m, [f"L{l}" for l in range(m.shape[0])], [f"h{h}" for h in range(m.shape[1])], cmap=SEQUENTIAL_CMAP, vmin=0, vmax=1, cbar_label="restored-answer rate", title=f"head patch @ {key.replace('_', ' ')}", annotate=True) | |
| 320 | + axes[0].set_ylabel("layer") | |
| 321 | + fig.savefig(fig_dir / "fig_localization_heads_tier0.pdf") | |
| 322 | + plt.close(fig) | |
| 323 | + fig.text(0, 0, "", color=TEXT_SECONDARY) | |
| 324 | + | |
| 325 | + | |
| 326 | +def write_summary(results: dict, out_dir: Path, cfg: PilotConfig, fig_dir: Path) -> None: | |
| 327 | + seeds = {str(k): v for k, v in results["seeds"].items()} | |
| 328 | + L = ["# Pilot summary — " + results["run_id"], "", f"Generated {utc_now()} on device `{results['device']}`; config hash `{results['config_hash']}`; seeds {cfg.seeds}.", "", | |
| 329 | + "## Gate B — donor/recipient gap (final-answer exact match, mean over seeds; CI = cluster bootstrap on programs)", "", | |
| 330 | + "| split | chance | donor mean (sd) | recipient mean (sd) | paired gap seed 0 [95% CI] |", "|---|---|---|---|---|"] | |
| 331 | + for en in ("target_iid", "control_iid", "comp_heldout", "len_ood"): | |
| 332 | + d, r = results["across_seeds"][en]["donor"], results["across_seeds"][en]["recipient"] | |
| 333 | + g = seeds[str(cfg.seeds[0])]["gap"][en] | |
| 334 | + L.append(f"| {en} | {results['chance_level'][en]:.3f} | {d['mean']:.3f} ({(d['sd'] or 0):.3f}) | {r['mean']:.3f} ({(r['sd'] or 0):.3f}) | {g['estimate']:+.3f} [{g['low']:+.3f}, {g['high']:+.3f}] |") | |
| 335 | + om = results["across_seeds_omega_step"] | |
| 336 | + L += ["", f"Ω-step accuracy on target_iid (token emitted at the first Ω step): donor {om['donor']['mean']:.3f}, recipient {om['recipient']['mean']:.3f}.", "", | |
| 337 | + "## Gate C — hook no-op checks (bitwise equality of logits on 256 dev items)", "", "| model | repeat | capture-all | disabled hook | enabled zero hook changes output |", "|---|---|---|---|---|"] | |
| 338 | + for k, v in results["noop"].items(): | |
| 339 | + L.append(f"| {k} | {v['deterministic_repeat']} | {v['capture_all_bitwise_identity']} | {v['disabled_modifying_hook_bitwise_identity']} | {v['enabled_zero_hook_changes_output']} |") | |
| 340 | + loc = results["localization"] | |
| 341 | + L += ["", f"## RQ1 — within-donor localization of Ω (n = {loc['n_items']} clean/corrupt pairs, read position = r1, predicting r2)", "", | |
| 342 | + "Baselines: " + "; ".join(f"s{k[1:]}: clean {v['clean_acc_on_clean_answer']:.3f}, sham (corrupt run scored on clean answer) {v['corrupt_run_acc_on_clean_answer(sham)']:.3f}" for k, v in loc["baselines"].items()), "", | |
| 343 | + "Mean restored-answer rate after patching the clean activation into the corrupted run (rows = layers, columns = positions " + ", ".join(loc["positions"]) + "):", ""] | |
| 344 | + for fam in ("resid_post", "attn_out", "mlp_out"): | |
| 345 | + m = np.array(loc["families"][fam]["mean_flip_rate"]) | |
| 346 | + L.append(f"- `{fam}`: " + " | ".join(f"L{i}: " + " ".join(f"{v:.2f}" for v in row) for i, row in enumerate(m))) | |
| 347 | + L += ["", "Reproducibility: " + "; ".join(f"{k} = {v:.4f}" for k, v in loc["reproducibility"].items()), "", | |
| 348 | + "Figures: " + ", ".join(f"`{p.name}`" for p in sorted(fig_dir.glob("*.pdf"))), "", | |
| 349 | + "## Interpretation (observed vs. speculative)", "", | |
| 350 | + "Observed: the numbers above are produced by the artifacts listed in the manifest. Any statement about *transfer* is out of scope for this run: no transplant was performed.", | |
| 351 | + "Speculative: whether the localized positions/layers constitute a transferable 'organ' is the object of the next experiment (activation graft with sham/random controls)."] | |
| 352 | + (out_dir / "SUMMARY.md").write_text("\n".join(L) + "\n") | |
| 353 | + | |
| 354 | + | |
| 355 | +if __name__ == "__main__": | |
| 356 | + main() | |
added
src/wp_ai_0001/__init__.py
+6 −0
@@ -0,0 +1,6 @@ | ||
| 1 | +"""WP-AI-0001 — The Neural Organ Transplant Experiment. | |
| 2 | + | |
| 3 | +Experiment harness for causally identified transfer of task capabilities between | |
| 4 | +open-weight language models. All code documentation is in English. | |
| 5 | +""" | |
| 6 | +__version__ = "0.1.0" | |
added
src/wp_ai_0001/alignment/__init__.py
+0 −0
added
src/wp_ai_0001/baselines/.gitkeep
+0 −0
added
src/wp_ai_0001/baselines/__init__.py
+0 −0
added
src/wp_ai_0001/config.py
+104 −0
@@ -0,0 +1,104 @@ | ||
| 1 | +"""Typed configuration objects and deterministic hashing. | |
| 2 | + | |
| 3 | +Every experiment is described by a pydantic model; ``config_hash`` is the SHA-256 of the | |
| 4 | +canonical JSON dump so that identical configurations always produce identical run IDs. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +import hashlib | |
| 9 | +import json | |
| 10 | +from typing import Any, Literal | |
| 11 | + | |
| 12 | +from pydantic import BaseModel, Field | |
| 13 | + | |
| 14 | + | |
| 15 | +def canonical_json(obj: Any) -> str: | |
| 16 | + return json.dumps(obj, sort_keys=True, separators=(",", ":"), ensure_ascii=True, default=str) | |
| 17 | + | |
| 18 | + | |
| 19 | +def config_hash(model: BaseModel, length: int = 12) -> str: | |
| 20 | + return hashlib.sha256(canonical_json(model.model_dump()).encode()).hexdigest()[:length] | |
| 21 | + | |
| 22 | + | |
| 23 | +class OpSeqTaskConfig(BaseModel): | |
| 24 | + """Micro-world A: compositional operator sequences over Z_p (see datasets/opseq.py).""" | |
| 25 | + | |
| 26 | + family: Literal["opseq"] = "opseq" | |
| 27 | + modulus: int = 11 | |
| 28 | + operators: list[str] = Field(default_factory=lambda: ["zib", "zob", "qua", "lar", "neg", "flip", "dro", "mik"]) | |
| 29 | + min_len: int = 1 | |
| 30 | + max_len: int = 5 | |
| 31 | + held_out_pairs: list[tuple[str, str]] = Field(default_factory=lambda: [("zob", "lar"), ("qua", "neg")]) | |
| 32 | + """Adjacent operator pairs never seen in training (compositional held-out).""" | |
| 33 | + excluded_operators: list[str] = Field(default_factory=list) | |
| 34 | + """Operators removed from a model's training distribution (used to create recipient weakness).""" | |
| 35 | + trace_stride: int = 1 | |
| 36 | + """Emit every ``trace_stride``-th intermediate result (plus the final one). 1 = full scratchpad; | |
| 37 | + larger values force multi-step composition inside a single prediction (difficulty knob).""" | |
| 38 | + | |
| 39 | + | |
| 40 | +class FSATaskConfig(BaseModel): | |
| 41 | + """Micro-world B: run a fixed random DFA over an invented alphabet and output the final state.""" | |
| 42 | + | |
| 43 | + family: Literal["fsa"] = "fsa" | |
| 44 | + n_states: int = 4 | |
| 45 | + alphabet: list[str] = Field(default_factory=lambda: ["ka", "mo", "ti"]) | |
| 46 | + min_len: int = 1 | |
| 47 | + max_len: int = 8 | |
| 48 | + automaton_seed: int = 7 | |
| 49 | + | |
| 50 | + | |
| 51 | +class MorphTaskConfig(BaseModel): | |
| 52 | + """Micro-world C: context-dependent morphological rule on pseudo-words.""" | |
| 53 | + | |
| 54 | + family: Literal["morph"] = "morph" | |
| 55 | + min_stem: int = 3 | |
| 56 | + max_stem: int = 6 | |
| 57 | + rules: dict[str, str] = Field(default_factory=lambda: {"vowel": "-na", "consonant": "-ek", "nasal": "-ur"}) | |
| 58 | + | |
| 59 | + | |
| 60 | +TaskConfig = OpSeqTaskConfig | FSATaskConfig | MorphTaskConfig | |
| 61 | + | |
| 62 | + | |
| 63 | +class ToyModelConfig(BaseModel): | |
| 64 | + d_model: int = 128 | |
| 65 | + n_layers: int = 4 | |
| 66 | + n_heads: int = 4 | |
| 67 | + d_ff: int = 512 | |
| 68 | + max_seq_len: int = 32 | |
| 69 | + dropout: float = 0.0 | |
| 70 | + tie_embeddings: bool = False | |
| 71 | + | |
| 72 | + | |
| 73 | +class TrainConfig(BaseModel): | |
| 74 | + seed: int = 0 | |
| 75 | + n_train: int = 40_000 | |
| 76 | + n_dev: int = 2_000 | |
| 77 | + batch_size: int = 256 | |
| 78 | + steps: int = 3_000 | |
| 79 | + lr: float = 1e-3 | |
| 80 | + weight_decay: float = 0.01 | |
| 81 | + warmup_steps: int = 100 | |
| 82 | + device: Literal["auto", "cpu", "mps", "cuda"] = "auto" | |
| 83 | + eval_every: int = 500 | |
| 84 | + | |
| 85 | + | |
| 86 | +class ModelRoleConfig(BaseModel): | |
| 87 | + """A trained toy model with a role in the donor/recipient design.""" | |
| 88 | + | |
| 89 | + role: Literal["donor", "recipient", "unrelated"] | |
| 90 | + name: str | |
| 91 | + model: ToyModelConfig = Field(default_factory=ToyModelConfig) | |
| 92 | + train: TrainConfig = Field(default_factory=TrainConfig) | |
| 93 | + task: OpSeqTaskConfig | FSATaskConfig | MorphTaskConfig = Field(default_factory=OpSeqTaskConfig) | |
| 94 | + | |
| 95 | + | |
| 96 | +class PilotConfig(BaseModel): | |
| 97 | + experiment_id: str = "pilot_tier0_opseq" | |
| 98 | + description: str = "Tier-0 pilot: donor/recipient gap, hook no-op test, within-model causal localization" | |
| 99 | + seeds: list[int] = Field(default_factory=lambda: [0, 1, 2]) | |
| 100 | + donor: ModelRoleConfig | |
| 101 | + recipient: ModelRoleConfig | |
| 102 | + target_operator: str = "qua" | |
| 103 | + n_eval: int = 1_000 | |
| 104 | + n_bootstrap: int = 2_000 | |
added
src/wp_ai_0001/datasets/__init__.py
+1 −0
@@ -0,0 +1 @@ | ||
| 1 | +from wp_ai_0001.datasets.common import Example, Split, Vocab, split_hash # noqa: F401 | |
added
src/wp_ai_0001/datasets/common.py
+166 −0
@@ -0,0 +1,166 @@ | ||
| 1 | +"""Shared dataset primitives: examples, vocabularies, split containers and hashing. | |
| 2 | + | |
| 3 | +Every example is a token sequence ``<bos> <prompt tokens> = <a_1 ... a_k>`` where the ``k`` answer | |
| 4 | +tokens form a *scratchpad* (one intermediate result per execution step; k = 1 for single-answer | |
| 5 | +tasks). The primary metric is exact match of the final answer token under greedy decoding; the | |
| 6 | +trace metric is exact match of all ``k`` answer tokens. ``cluster`` identifies the | |
| 7 | +generating template (e.g. the operator program) and is the unit of resampling in the cluster | |
| 8 | +bootstrap: items sharing a cluster are not treated as independent. | |
| 9 | +""" | |
| 10 | +from __future__ import annotations | |
| 11 | + | |
| 12 | +import hashlib | |
| 13 | +import json | |
| 14 | +from dataclasses import asdict, dataclass, field | |
| 15 | +from pathlib import Path | |
| 16 | +from typing import Iterable | |
| 17 | + | |
| 18 | +import numpy as np | |
| 19 | + | |
| 20 | +PAD, BOS, EQ = "<pad>", "<bos>", "=" | |
| 21 | + | |
| 22 | + | |
| 23 | +@dataclass(frozen=True) | |
| 24 | +class Example: | |
| 25 | + tokens: tuple[str, ...] # full sequence including the answer tokens | |
| 26 | + n_answer: int # number of answer (scratchpad) tokens at the end of ``tokens`` | |
| 27 | + cluster: str # template / program identifier (bootstrap unit) | |
| 28 | + meta: dict = field(default_factory=dict) | |
| 29 | + | |
| 30 | + @property | |
| 31 | + def prompt(self) -> tuple[str, ...]: | |
| 32 | + return self.tokens[: -self.n_answer] | |
| 33 | + | |
| 34 | + @property | |
| 35 | + def answers(self) -> tuple[str, ...]: | |
| 36 | + return self.tokens[-self.n_answer :] | |
| 37 | + | |
| 38 | + @property | |
| 39 | + def answer(self) -> str: | |
| 40 | + return self.tokens[-1] | |
| 41 | + | |
| 42 | + @property | |
| 43 | + def item_hash(self) -> str: | |
| 44 | + return hashlib.sha256(" ".join(self.tokens).encode()).hexdigest()[:16] | |
| 45 | + | |
| 46 | + | |
| 47 | +class Vocab: | |
| 48 | + def __init__(self, tokens: Iterable[str]) -> None: | |
| 49 | + base = [PAD, BOS, EQ] | |
| 50 | + extra = [t for t in dict.fromkeys(tokens) if t not in base] | |
| 51 | + self.itos: list[str] = base + extra | |
| 52 | + self.stoi: dict[str, int] = {t: i for i, t in enumerate(self.itos)} | |
| 53 | + | |
| 54 | + def __len__(self) -> int: | |
| 55 | + return len(self.itos) | |
| 56 | + | |
| 57 | + @property | |
| 58 | + def pad_id(self) -> int: | |
| 59 | + return self.stoi[PAD] | |
| 60 | + | |
| 61 | + def encode(self, tokens: Iterable[str]) -> list[int]: | |
| 62 | + return [self.stoi[t] for t in tokens] | |
| 63 | + | |
| 64 | + def decode(self, ids: Iterable[int]) -> list[str]: | |
| 65 | + return [self.itos[i] for i in ids] | |
| 66 | + | |
| 67 | + def to_json(self) -> str: | |
| 68 | + return json.dumps(self.itos) | |
| 69 | + | |
| 70 | + @classmethod | |
| 71 | + def from_json(cls, text: str) -> "Vocab": | |
| 72 | + return cls(json.loads(text)) | |
| 73 | + | |
| 74 | + | |
| 75 | +@dataclass | |
| 76 | +class Split: | |
| 77 | + name: str | |
| 78 | + examples: list[Example] | |
| 79 | + generator: str | |
| 80 | + generator_version: str | |
| 81 | + seed: int | |
| 82 | + config: dict | |
| 83 | + | |
| 84 | + def __len__(self) -> int: | |
| 85 | + return len(self.examples) | |
| 86 | + | |
| 87 | + @property | |
| 88 | + def hash(self) -> str: | |
| 89 | + return split_hash(self.examples) | |
| 90 | + | |
| 91 | + def item_hashes(self) -> set[str]: | |
| 92 | + return {e.item_hash for e in self.examples} | |
| 93 | + | |
| 94 | + def answer_distribution(self) -> dict[str, float]: | |
| 95 | + vals, counts = np.unique([e.answer for e in self.examples], return_counts=True) | |
| 96 | + return {str(v): float(c) / len(self.examples) for v, c in zip(vals, counts)} | |
| 97 | + | |
| 98 | + def save(self, path: Path) -> None: | |
| 99 | + path.parent.mkdir(parents=True, exist_ok=True) | |
| 100 | + payload = { | |
| 101 | + "name": self.name, | |
| 102 | + "generator": self.generator, | |
| 103 | + "generator_version": self.generator_version, | |
| 104 | + "seed": self.seed, | |
| 105 | + "config": self.config, | |
| 106 | + "hash": self.hash, | |
| 107 | + "n": len(self.examples), | |
| 108 | + "examples": [asdict(e) for e in self.examples], | |
| 109 | + } | |
| 110 | + path.write_text(json.dumps(payload, sort_keys=True)) | |
| 111 | + | |
| 112 | + @classmethod | |
| 113 | + def load(cls, path: Path) -> "Split": | |
| 114 | + d = json.loads(path.read_text()) | |
| 115 | + ex = [Example(tuple(e["tokens"]), int(e["n_answer"]), e["cluster"], e.get("meta", {})) for e in d["examples"]] | |
| 116 | + s = cls(d["name"], ex, d["generator"], d["generator_version"], d["seed"], d["config"]) | |
| 117 | + if s.hash != d["hash"]: | |
| 118 | + raise ValueError(f"split hash mismatch for {path}: stored {d['hash']} computed {s.hash}") | |
| 119 | + return s | |
| 120 | + | |
| 121 | + | |
| 122 | +def split_hash(examples: Iterable[Example]) -> str: | |
| 123 | + h = hashlib.sha256() | |
| 124 | + for e in examples: | |
| 125 | + h.update((" ".join(e.tokens) + "\n").encode()) | |
| 126 | + return h.hexdigest()[:16] | |
| 127 | + | |
| 128 | + | |
| 129 | +def assert_disjoint(*splits: Split) -> None: | |
| 130 | + seen: dict[str, str] = {} | |
| 131 | + for s in splits: | |
| 132 | + for e in s.examples: | |
| 133 | + if e.item_hash in seen: | |
| 134 | + raise AssertionError(f"item leakage: {e.tokens} present in {seen[e.item_hash]} and {s.name}") | |
| 135 | + seen[e.item_hash] = s.name | |
| 136 | + | |
| 137 | + | |
| 138 | +def encode_split(split: Split, vocab: Vocab, max_len: int) -> dict[str, np.ndarray]: | |
| 139 | + """Encode a split for teacher-forced training and greedy evaluation. | |
| 140 | + | |
| 141 | + Returns a dict of arrays: | |
| 142 | + ``ids`` [N,T] full sequences (prompt + answers), right-padded with ``<pad>``; | |
| 143 | + ``loss_mask`` [N,T] 1 at positions whose *next* token is an answer token; | |
| 144 | + ``prompt_len`` [N] length of the prompt (index of the first answer token); | |
| 145 | + ``n_answer`` [N] number of answer tokens; | |
| 146 | + ``answers`` [N,K] answer token ids right-padded with ``<pad>`` (K = max n_answer). | |
| 147 | + """ | |
| 148 | + n = len(split.examples) | |
| 149 | + K = max(e.n_answer for e in split.examples) | |
| 150 | + ids = np.full((n, max_len), vocab.pad_id, dtype=np.int64) | |
| 151 | + loss_mask = np.zeros((n, max_len), dtype=np.float32) | |
| 152 | + prompt_len = np.zeros(n, dtype=np.int64) | |
| 153 | + n_answer = np.zeros(n, dtype=np.int64) | |
| 154 | + answers = np.full((n, K), vocab.pad_id, dtype=np.int64) | |
| 155 | + for i, e in enumerate(split.examples): | |
| 156 | + seq = vocab.encode(e.tokens) | |
| 157 | + if len(seq) > max_len: | |
| 158 | + raise ValueError(f"sequence longer than max_len={max_len}: {e.tokens}") | |
| 159 | + ids[i, : len(seq)] = seq | |
| 160 | + pl = len(e.prompt) | |
| 161 | + assert e.prompt[-1] == EQ | |
| 162 | + prompt_len[i] = pl | |
| 163 | + n_answer[i] = e.n_answer | |
| 164 | + loss_mask[i, pl - 1 : pl - 1 + e.n_answer] = 1.0 | |
| 165 | + answers[i, : e.n_answer] = vocab.encode(e.answers) | |
| 166 | + return {"ids": ids, "loss_mask": loss_mask, "prompt_len": prompt_len, "n_answer": n_answer, "answers": answers} | |
added
src/wp_ai_0001/datasets/fsa.py
+62 −0
@@ -0,0 +1,62 @@ | ||
| 1 | +"""Micro-world B — FSA: deterministic finite automaton execution over an invented alphabet. | |
| 2 | + | |
| 3 | +``<bos> s_1 ... s_n = q_1 ... q_n`` (state after each symbol; the final answer is ``q_n``). The automaton is drawn once from ``automaton_seed``; the | |
| 4 | +transition table is part of the split config so the task is fully verifiable. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +import random | |
| 9 | + | |
| 10 | +from wp_ai_0001.config import FSATaskConfig | |
| 11 | +from wp_ai_0001.datasets.common import BOS, EQ, Example, Split, Vocab | |
| 12 | + | |
| 13 | +GENERATOR_VERSION = "fsa-1.0" | |
| 14 | + | |
| 15 | + | |
| 16 | +def transition_table(cfg: FSATaskConfig) -> dict[tuple[int, str], int]: | |
| 17 | + rng = random.Random(f"{GENERATOR_VERSION}|automaton|{cfg.automaton_seed}") | |
| 18 | + return {(q, a): rng.randrange(cfg.n_states) for q in range(cfg.n_states) for a in cfg.alphabet} | |
| 19 | + | |
| 20 | + | |
| 21 | +def run(table: dict[tuple[int, str], int], symbols: list[str]) -> list[int]: | |
| 22 | + q, out = 0, [] | |
| 23 | + for s in symbols: | |
| 24 | + q = table[(q, s)] | |
| 25 | + out.append(q) | |
| 26 | + return out | |
| 27 | + | |
| 28 | + | |
| 29 | +def vocab_for(cfg: FSATaskConfig) -> Vocab: | |
| 30 | + return Vocab(list(cfg.alphabet) + [f"q{i}" for i in range(cfg.n_states)]) | |
| 31 | + | |
| 32 | + | |
| 33 | +def generate(cfg: FSATaskConfig, n: int, seed: int, name: str, *, min_len: int | None = None, max_len: int | None = None, | |
| 34 | + exclude_hashes: set[str] | None = None) -> Split: | |
| 35 | + rng = random.Random(f"{GENERATOR_VERSION}|{name}|{seed}") | |
| 36 | + table = transition_table(cfg) | |
| 37 | + lo = cfg.min_len if min_len is None else min_len | |
| 38 | + hi = cfg.max_len if max_len is None else max_len | |
| 39 | + seen = set(exclude_hashes or set()) | |
| 40 | + out: list[Example] = [] | |
| 41 | + attempts = 0 | |
| 42 | + while len(out) < n: | |
| 43 | + attempts += 1 | |
| 44 | + if attempts > 200 * n + 10_000: | |
| 45 | + raise RuntimeError(f"could not generate {n} unique FSA examples for {name}") | |
| 46 | + k = rng.randint(lo, hi) | |
| 47 | + syms = [rng.choice(cfg.alphabet) for _ in range(k)] | |
| 48 | + states = [f"q{q}" for q in run(table, syms)] | |
| 49 | + ex = Example((BOS, *syms, EQ, *states), n_answer=k, cluster=f"len{k}", meta={"len": k}) | |
| 50 | + if ex.item_hash in seen: | |
| 51 | + continue | |
| 52 | + seen.add(ex.item_hash) | |
| 53 | + out.append(ex) | |
| 54 | + conf = cfg.model_dump() | {"table": {f"{q},{a}": v for (q, a), v in table.items()}} | |
| 55 | + return Split(name, out, "fsa", GENERATOR_VERSION, seed, conf) | |
| 56 | + | |
| 57 | + | |
| 58 | +def validate(split: Split, cfg: FSATaskConfig) -> None: | |
| 59 | + table = transition_table(cfg) | |
| 60 | + for e in split.examples: | |
| 61 | + syms = list(e.prompt[1:-1]) | |
| 62 | + assert tuple(f"q{q}" for q in run(table, syms)) == e.answers, e | |
added
src/wp_ai_0001/datasets/morph.py
+55 −0
@@ -0,0 +1,55 @@ | ||
| 1 | +"""Micro-world C — MORPH: context-dependent suffix selection on pseudo-word stems. | |
| 2 | + | |
| 3 | +``<bos> c_1 ... c_m = suffix`` where the suffix class depends on the stem-final phoneme class | |
| 4 | +(vowel / nasal / other consonant). Stems are random pseudo-words so lexical priors do not apply. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +import random | |
| 9 | + | |
| 10 | +from wp_ai_0001.config import MorphTaskConfig | |
| 11 | +from wp_ai_0001.datasets.common import BOS, EQ, Example, Split, Vocab | |
| 12 | + | |
| 13 | +GENERATOR_VERSION = "morph-1.0" | |
| 14 | +VOWELS = list("aeiou") | |
| 15 | +NASALS = list("mn") | |
| 16 | +OTHERS = list("bdgklprstv") | |
| 17 | +LETTERS = VOWELS + NASALS + OTHERS | |
| 18 | + | |
| 19 | + | |
| 20 | +def phon_class(ch: str) -> str: | |
| 21 | + if ch in VOWELS: | |
| 22 | + return "vowel" | |
| 23 | + if ch in NASALS: | |
| 24 | + return "nasal" | |
| 25 | + return "consonant" | |
| 26 | + | |
| 27 | + | |
| 28 | +def vocab_for(cfg: MorphTaskConfig) -> Vocab: | |
| 29 | + return Vocab(LETTERS + list(cfg.rules.values())) | |
| 30 | + | |
| 31 | + | |
| 32 | +def generate(cfg: MorphTaskConfig, n: int, seed: int, name: str, *, exclude_hashes: set[str] | None = None) -> Split: | |
| 33 | + rng = random.Random(f"{GENERATOR_VERSION}|{name}|{seed}") | |
| 34 | + seen = set(exclude_hashes or set()) | |
| 35 | + out: list[Example] = [] | |
| 36 | + attempts = 0 | |
| 37 | + while len(out) < n: | |
| 38 | + attempts += 1 | |
| 39 | + if attempts > 200 * n + 10_000: | |
| 40 | + raise RuntimeError(f"could not generate {n} unique MORPH examples for {name}") | |
| 41 | + m = rng.randint(cfg.min_stem, cfg.max_stem) | |
| 42 | + stem = [rng.choice(LETTERS) for _ in range(m)] | |
| 43 | + ans = cfg.rules[phon_class(stem[-1])] | |
| 44 | + ex = Example((BOS, *stem, EQ, ans), 1, cluster=f"{phon_class(stem[-1])}|len{m}", meta={"len": m}) | |
| 45 | + if ex.item_hash in seen: | |
| 46 | + continue | |
| 47 | + seen.add(ex.item_hash) | |
| 48 | + out.append(ex) | |
| 49 | + return Split(name, out, "morph", GENERATOR_VERSION, seed, cfg.model_dump()) | |
| 50 | + | |
| 51 | + | |
| 52 | +def validate(split: Split, cfg: MorphTaskConfig) -> None: | |
| 53 | + for e in split.examples: | |
| 54 | + stem = list(e.prompt[1:-1]) | |
| 55 | + assert cfg.rules[phon_class(stem[-1])] == e.answer, e | |
added
src/wp_ai_0001/datasets/opseq.py
+131 −0
@@ -0,0 +1,131 @@ | ||
| 1 | +"""Micro-world A — OPSEQ: compositional operator sequences over Z_p. | |
| 2 | + | |
| 3 | +A program is ``<bos> v0 op_1 ... op_k = r_1 ... r_k`` where each invented operator is a fixed map on | |
| 4 | +Z_p and ``r_j`` is the value after applying ``op_j`` (scratchpad execution trace; the final answer is | |
| 5 | +``r_k``). Operator names are meaningless strings so that no pre-training prior applies. | |
| 6 | +Donor competence / recipient weakness is created by *excluding* chosen operators from a model's | |
| 7 | +training distribution (``excluded_operators``). Compositional generalization is measured on | |
| 8 | +adjacent operator pairs that never co-occur in training (``held_out_pairs``), and length | |
| 9 | +generalization on programs longer than ``max_len``. | |
| 10 | + | |
| 11 | +Each split is generated from its own seed; disjointness of item hashes across splits is enforced | |
| 12 | +by the caller (``datasets.common.assert_disjoint``). | |
| 13 | +""" | |
| 14 | +from __future__ import annotations | |
| 15 | + | |
| 16 | +import random | |
| 17 | +from typing import Callable | |
| 18 | + | |
| 19 | +from wp_ai_0001.config import OpSeqTaskConfig | |
| 20 | +from wp_ai_0001.datasets.common import BOS, EQ, Example, Split, Vocab | |
| 21 | + | |
| 22 | +GENERATOR_VERSION = "opseq-1.0" | |
| 23 | + | |
| 24 | +# Invented operator semantics (affine maps x -> (a*x + b) mod p, or reflections). | |
| 25 | +OPERATOR_TABLE: dict[str, Callable[[int, int], int]] = { | |
| 26 | + "zib": lambda x, p: (x + 1) % p, | |
| 27 | + "zob": lambda x, p: (x + 3) % p, | |
| 28 | + "qua": lambda x, p: (2 * x + 1) % p, | |
| 29 | + "lar": lambda x, p: (3 * x) % p, | |
| 30 | + "neg": lambda x, p: (-x) % p, | |
| 31 | + "flip": lambda x, p: (p - 1 - x) % p, | |
| 32 | + "dro": lambda x, p: (5 * x) % p, | |
| 33 | + "mik": lambda x, p: (x * x) % p, | |
| 34 | +} | |
| 35 | + | |
| 36 | + | |
| 37 | +def trace(v0: int, ops: list[str], p: int) -> list[int]: | |
| 38 | + x, out = v0, [] | |
| 39 | + for op in ops: | |
| 40 | + x = OPERATOR_TABLE[op](x, p) | |
| 41 | + out.append(x) | |
| 42 | + return out | |
| 43 | + | |
| 44 | + | |
| 45 | +def apply_program(v0: int, ops: list[str], p: int) -> int: | |
| 46 | + return trace(v0, ops, p)[-1] if ops else v0 | |
| 47 | + | |
| 48 | + | |
| 49 | +def vocab_for(cfg: OpSeqTaskConfig) -> Vocab: | |
| 50 | + return Vocab([str(i) for i in range(cfg.modulus)] + list(cfg.operators)) | |
| 51 | + | |
| 52 | + | |
| 53 | +def _has_held_out_pair(ops: list[str], pairs: set[tuple[str, str]]) -> bool: | |
| 54 | + return any((a, b) in pairs for a, b in zip(ops, ops[1:])) | |
| 55 | + | |
| 56 | + | |
| 57 | +def visible_trace(v0: int, ops: list[str], p: int, stride: int = 1) -> list[int]: | |
| 58 | + full = trace(v0, ops, p) | |
| 59 | + idx = list(range(stride - 1, len(full), stride)) | |
| 60 | + if not idx or idx[-1] != len(full) - 1: | |
| 61 | + idx.append(len(full) - 1) | |
| 62 | + return [full[i] for i in idx] | |
| 63 | + | |
| 64 | + | |
| 65 | +def make_example(v0: int, ops: list[str], p: int, stride: int = 1) -> Example: | |
| 66 | + tr = [str(r) for r in visible_trace(v0, ops, p, stride)] | |
| 67 | + tokens = (BOS, str(v0), *ops, EQ, *tr) | |
| 68 | + return Example(tokens=tokens, n_answer=len(tr), cluster=" ".join(ops), meta={"len": len(ops), "v0": v0, "stride": stride}) | |
| 69 | + | |
| 70 | + | |
| 71 | +def generate( | |
| 72 | + cfg: OpSeqTaskConfig, | |
| 73 | + n: int, | |
| 74 | + seed: int, | |
| 75 | + name: str, | |
| 76 | + *, | |
| 77 | + mode: str = "train", | |
| 78 | + require_operator: str | None = None, | |
| 79 | + forbid_operator: str | None = None, | |
| 80 | + min_len: int | None = None, | |
| 81 | + max_len: int | None = None, | |
| 82 | + exclude_hashes: set[str] | None = None, | |
| 83 | +) -> Split: | |
| 84 | + """Generate ``n`` unique examples. | |
| 85 | + | |
| 86 | + mode="train": no held-out pairs, no excluded operators. | |
| 87 | + mode="comp": every program contains at least one held-out adjacent pair. | |
| 88 | + mode="any": unconstrained with respect to held-out pairs. | |
| 89 | + ``require_operator`` / ``forbid_operator`` restrict the operator content (target vs control). | |
| 90 | + """ | |
| 91 | + rng = random.Random(f"{GENERATOR_VERSION}|{name}|{seed}") | |
| 92 | + p = cfg.modulus | |
| 93 | + pairs = set(map(tuple, cfg.held_out_pairs)) | |
| 94 | + allowed = [o for o in cfg.operators if o not in cfg.excluded_operators] | |
| 95 | + if forbid_operator: | |
| 96 | + allowed = [o for o in allowed if o != forbid_operator] | |
| 97 | + lo = cfg.min_len if min_len is None else min_len | |
| 98 | + hi = cfg.max_len if max_len is None else max_len | |
| 99 | + seen: set[str] = set(exclude_hashes or set()) | |
| 100 | + out: list[Example] = [] | |
| 101 | + attempts = 0 | |
| 102 | + while len(out) < n: | |
| 103 | + attempts += 1 | |
| 104 | + if attempts > 200 * n + 10_000: | |
| 105 | + raise RuntimeError(f"could not generate {n} unique examples for {name} (got {len(out)})") | |
| 106 | + k = rng.randint(lo, hi) | |
| 107 | + ops = [rng.choice(allowed) for _ in range(k)] | |
| 108 | + if require_operator and require_operator not in ops: | |
| 109 | + continue | |
| 110 | + held = _has_held_out_pair(ops, pairs) | |
| 111 | + if mode == "train" and held: | |
| 112 | + continue | |
| 113 | + if mode == "comp" and not held: | |
| 114 | + continue | |
| 115 | + v0 = rng.randrange(p) | |
| 116 | + ex = make_example(v0, ops, p, cfg.trace_stride) | |
| 117 | + if ex.item_hash in seen: | |
| 118 | + continue | |
| 119 | + seen.add(ex.item_hash) | |
| 120 | + out.append(ex) | |
| 121 | + return Split(name, out, "opseq", GENERATOR_VERSION, seed, cfg.model_dump()) | |
| 122 | + | |
| 123 | + | |
| 124 | +def validate(split: Split, cfg: OpSeqTaskConfig) -> None: | |
| 125 | + """Independent recomputation of every answer (exact validator).""" | |
| 126 | + for e in split.examples: | |
| 127 | + assert e.tokens[0] == BOS and e.prompt[-1] == EQ | |
| 128 | + v0 = int(e.tokens[1]) | |
| 129 | + ops = list(e.prompt[2:-1]) | |
| 130 | + assert all(o in OPERATOR_TABLE for o in ops), e | |
| 131 | + assert tuple(str(r) for r in visible_trace(v0, ops, cfg.modulus, cfg.trace_stride)) == e.answers, e | |
added
src/wp_ai_0001/evaluation/__init__.py
+0 −0
added
src/wp_ai_0001/evaluation/metrics.py
+54 −0
@@ -0,0 +1,54 @@ | ||
| 1 | +"""Exact-match evaluation of a toy model on a Split under greedy decoding, with per-item outputs.""" | |
| 2 | +from __future__ import annotations | |
| 3 | + | |
| 4 | +from dataclasses import dataclass | |
| 5 | + | |
| 6 | +import numpy as np | |
| 7 | +import torch | |
| 8 | + | |
| 9 | +from wp_ai_0001.datasets.common import Split, Vocab, encode_split | |
| 10 | +from wp_ai_0001.models.decoding import greedy_decode | |
| 11 | +from wp_ai_0001.models.toy_transformer import ToyTransformer | |
| 12 | + | |
| 13 | + | |
| 14 | +@dataclass | |
| 15 | +class EvalResult: | |
| 16 | + split: str | |
| 17 | + split_hash: str | |
| 18 | + n: int | |
| 19 | + accuracy: float # final-answer exact match | |
| 20 | + trace_accuracy: float # all scratchpad tokens exact match | |
| 21 | + correct: np.ndarray # [N] bool (final answer) | |
| 22 | + trace_correct: np.ndarray # [N] bool | |
| 23 | + clusters: list[str] | |
| 24 | + predictions: list[list[str]] | |
| 25 | + answers: list[list[str]] | |
| 26 | + | |
| 27 | + def to_summary(self) -> dict: | |
| 28 | + return {"split": self.split, "split_hash": self.split_hash, "n": self.n, "accuracy": self.accuracy, "trace_accuracy": self.trace_accuracy} | |
| 29 | + | |
| 30 | + | |
| 31 | +@torch.no_grad() | |
| 32 | +def evaluate(model: ToyTransformer, split: Split, vocab: Vocab, device: torch.device, bs: int = 1024) -> EvalResult: | |
| 33 | + enc = encode_split(split, vocab, model.cfg.max_seq_len) | |
| 34 | + K = enc["answers"].shape[1] | |
| 35 | + preds = [] | |
| 36 | + for i in range(0, len(enc["ids"]), bs): | |
| 37 | + ids = torch.from_numpy(enc["ids"][i : i + bs]).to(device) | |
| 38 | + pl = torch.from_numpy(enc["prompt_len"][i : i + bs]).to(device) | |
| 39 | + na = torch.from_numpy(enc["n_answer"][i : i + bs]).to(device) | |
| 40 | + preds.append(greedy_decode(model, ids, pl, na, K).cpu().numpy()) | |
| 41 | + pred = np.concatenate(preds) | |
| 42 | + na = enc["n_answer"] | |
| 43 | + ar = np.arange(len(na)) | |
| 44 | + final_ok = pred[ar, na - 1] == enc["answers"][ar, na - 1] | |
| 45 | + valid = np.arange(K)[None] < na[:, None] | |
| 46 | + trace_ok = ((pred == enc["answers"]) | ~valid).all(-1) | |
| 47 | + return EvalResult(split.name, split.hash, len(na), float(final_ok.mean()), float(trace_ok.mean()), final_ok, trace_ok, | |
| 48 | + [e.cluster for e in split.examples], [vocab.decode(pred[i, : na[i]]) for i in ar], | |
| 49 | + [list(e.answers) for e in split.examples]) | |
| 50 | + | |
| 51 | + | |
| 52 | +def chance_level(split: Split) -> float: | |
| 53 | + """Majority-class rate of the answer distribution (the relevant chance baseline).""" | |
| 54 | + return max(split.answer_distribution().values()) | |
added
src/wp_ai_0001/instrumentation/__init__.py
+0 −0
added
src/wp_ai_0001/instrumentation/provenance.py
+123 −0
@@ -0,0 +1,123 @@ | ||
| 1 | +"""Run provenance: git state, environment, hardware, deterministic run IDs and manifests. | |
| 2 | + | |
| 3 | +Secrets are never read or written here; environment capture is limited to library versions and | |
| 4 | +hardware descriptors. Personal paths are stored relative to the project root. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +import datetime as _dt | |
| 9 | +import hashlib | |
| 10 | +import json | |
| 11 | +import os | |
| 12 | +import platform | |
| 13 | +import subprocess | |
| 14 | +import sys | |
| 15 | +from pathlib import Path | |
| 16 | +from typing import Any | |
| 17 | + | |
| 18 | +PROJECT_ROOT = Path(__file__).resolve().parents[3] | |
| 19 | + | |
| 20 | + | |
| 21 | +def git_state(root: Path = PROJECT_ROOT) -> dict[str, Any]: | |
| 22 | + def _run(args: list[str]) -> str | None: | |
| 23 | + try: | |
| 24 | + return subprocess.check_output(["git", *args], cwd=root, stderr=subprocess.DEVNULL, text=True).strip() | |
| 25 | + except Exception: # noqa: BLE001 - git may be absent or the directory may not be a repo | |
| 26 | + return None | |
| 27 | + | |
| 28 | + commit = _run(["rev-parse", "HEAD"]) | |
| 29 | + dirty = _run(["status", "--porcelain"]) | |
| 30 | + return {"commit": commit, "dirty": bool(dirty) if dirty is not None else None, "branch": _run(["rev-parse", "--abbrev-ref", "HEAD"])} | |
| 31 | + | |
| 32 | + | |
| 33 | +def library_versions() -> dict[str, str | None]: | |
| 34 | + out: dict[str, str | None] = {"python": sys.version.split()[0]} | |
| 35 | + for name in ["numpy", "torch", "scipy", "pydantic", "mlx", "mlx_lm", "transformers", "safetensors"]: | |
| 36 | + try: | |
| 37 | + mod = __import__(name) | |
| 38 | + out[name] = getattr(mod, "__version__", "?") | |
| 39 | + except Exception: # noqa: BLE001 | |
| 40 | + out[name] = None | |
| 41 | + return out | |
| 42 | + | |
| 43 | + | |
| 44 | +def hardware() -> dict[str, Any]: | |
| 45 | + info: dict[str, Any] = { | |
| 46 | + "platform": platform.platform(), | |
| 47 | + "machine": platform.machine(), | |
| 48 | + "hostname_hash": hashlib.sha256(platform.node().encode()).hexdigest()[:12], | |
| 49 | + "cpu_count": os.cpu_count(), | |
| 50 | + } | |
| 51 | + if sys.platform == "darwin": | |
| 52 | + try: | |
| 53 | + info["chip"] = subprocess.check_output(["sysctl", "-n", "machdep.cpu.brand_string"], text=True).strip() | |
| 54 | + info["memory_gb"] = int(subprocess.check_output(["sysctl", "-n", "hw.memsize"], text=True)) / 2**30 | |
| 55 | + except Exception: # noqa: BLE001 | |
| 56 | + pass | |
| 57 | + try: | |
| 58 | + import torch | |
| 59 | + | |
| 60 | + info["torch_mps"] = bool(torch.backends.mps.is_available()) | |
| 61 | + info["torch_cuda"] = bool(torch.cuda.is_available()) | |
| 62 | + except Exception: # noqa: BLE001 | |
| 63 | + pass | |
| 64 | + return info | |
| 65 | + | |
| 66 | + | |
| 67 | +def utc_now() -> str: | |
| 68 | + return _dt.datetime.now(_dt.timezone.utc).isoformat(timespec="seconds") | |
| 69 | + | |
| 70 | + | |
| 71 | +def sha256_file(path: Path) -> str: | |
| 72 | + h = hashlib.sha256() | |
| 73 | + with open(path, "rb") as f: | |
| 74 | + for chunk in iter(lambda: f.read(1 << 20), b""): | |
| 75 | + h.update(chunk) | |
| 76 | + return h.hexdigest() | |
| 77 | + | |
| 78 | + | |
| 79 | +def sha256_text(text: str) -> str: | |
| 80 | + return hashlib.sha256(text.encode()).hexdigest() | |
| 81 | + | |
| 82 | + | |
| 83 | +def make_run_id(experiment_id: str, cfg_hash: str, seed: int | None = None) -> str: | |
| 84 | + tail = f"_s{seed}" if seed is not None else "" | |
| 85 | + return f"{experiment_id}_{cfg_hash}{tail}" | |
| 86 | + | |
| 87 | + | |
| 88 | +class Manifest: | |
| 89 | + """Mutable run manifest persisted as JSON; status transitions are recorded with timestamps.""" | |
| 90 | + | |
| 91 | + def __init__(self, run_id: str, experiment_id: str, config: dict[str, Any], out_dir: Path) -> None: | |
| 92 | + self.path = out_dir / f"{run_id}.json" | |
| 93 | + self.data: dict[str, Any] = { | |
| 94 | + "run_id": run_id, | |
| 95 | + "experiment_id": experiment_id, | |
| 96 | + "status": "planned", | |
| 97 | + "created_utc": utc_now(), | |
| 98 | + "git": git_state(), | |
| 99 | + "libraries": library_versions(), | |
| 100 | + "hardware": hardware(), | |
| 101 | + "config": config, | |
| 102 | + "data_hashes": {}, | |
| 103 | + "seeds": {}, | |
| 104 | + "outputs": {}, | |
| 105 | + "warnings": [], | |
| 106 | + "history": [], | |
| 107 | + "interpretation": "", | |
| 108 | + } | |
| 109 | + out_dir.mkdir(parents=True, exist_ok=True) | |
| 110 | + self.save() | |
| 111 | + | |
| 112 | + def set_status(self, status: str, note: str = "") -> None: | |
| 113 | + assert status in {"planned", "running", "failed", "completed", "invalidated"} | |
| 114 | + self.data["status"] = status | |
| 115 | + self.data["history"].append({"utc": utc_now(), "status": status, "note": note}) | |
| 116 | + self.save() | |
| 117 | + | |
| 118 | + def warn(self, message: str) -> None: | |
| 119 | + self.data["warnings"].append({"utc": utc_now(), "message": message}) | |
| 120 | + self.save() | |
| 121 | + | |
| 122 | + def save(self) -> None: | |
| 123 | + self.path.write_text(json.dumps(self.data, indent=2, sort_keys=True, default=str)) | |
added
src/wp_ai_0001/localization/__init__.py
+0 −0
added
src/wp_ai_0001/localization/patching.py
+120 −0
@@ -0,0 +1,120 @@ | ||
| 1 | +"""Within-model causal localization by activation patching and ablation on toy models. | |
| 2 | + | |
| 3 | +``patch_sweep`` implements the standard clean/corrupted interchange intervention: run the model on | |
| 4 | +a *clean* sequence and on a *corrupted* sequence (same program with the target operator replaced | |
| 5 | +by a different operator, identical teacher-forced prefix), then for every (hook, layer, position) | |
| 6 | +overwrite the corrupted run's activation with the clean run's activation and measure how much of | |
| 7 | +the clean next-token answer at the read position ``pos`` is restored. | |
| 8 | +The effect is reported as the fraction of items whose argmax flips to the clean answer and as the | |
| 9 | +mean normalized logit-difference recovery. Larger = the patched location carries the information. | |
| 10 | + | |
| 11 | +``ablation_sweep`` zeroes (or noises) the activation at each location on clean prompts and reports | |
| 12 | +the accuracy drop, i.e. necessity. Both sweeps are deterministic given model and data. | |
| 13 | +""" | |
| 14 | +from __future__ import annotations | |
| 15 | + | |
| 16 | +from dataclasses import dataclass | |
| 17 | + | |
| 18 | +import numpy as np | |
| 19 | +import torch | |
| 20 | + | |
| 21 | +from wp_ai_0001.models.hooks import Capture, GaussianNoise, Replace, Zero | |
| 22 | +from wp_ai_0001.models.toy_transformer import ToyTransformer | |
| 23 | + | |
| 24 | + | |
| 25 | +@dataclass | |
| 26 | +class PatchResult: | |
| 27 | + hook_family: str | |
| 28 | + layers: list[int] | |
| 29 | + positions: list[int] | |
| 30 | + flip_rate: np.ndarray # [L, P] | |
| 31 | + logit_recovery: np.ndarray # [L, P] | |
| 32 | + n_items: int | |
| 33 | + | |
| 34 | + | |
| 35 | +def _run(model: ToyTransformer, ids: torch.Tensor, pos: torch.Tensor) -> torch.Tensor: | |
| 36 | + with torch.no_grad(): | |
| 37 | + return model.answer_logits(ids, pos) | |
| 38 | + | |
| 39 | + | |
| 40 | +def capture_all(model: ToyTransformer, ids: torch.Tensor, pos: torch.Tensor, family: str) -> dict[str, torch.Tensor]: | |
| 41 | + cap = Capture() | |
| 42 | + names = [f"{family}.{l}" for l in range(model.cfg.n_layers)] | |
| 43 | + for n in names: | |
| 44 | + model.hooks.add(n, cap) | |
| 45 | + try: | |
| 46 | + _run(model, ids, pos) | |
| 47 | + finally: | |
| 48 | + for n in names: | |
| 49 | + model.hooks.remove(n, cap) | |
| 50 | + return cap.store | |
| 51 | + | |
| 52 | + | |
| 53 | +def patch_sweep(model: ToyTransformer, clean_ids: torch.Tensor, corrupt_ids: torch.Tensor, pos: torch.Tensor, | |
| 54 | + clean_ans: torch.Tensor, corrupt_ans: torch.Tensor, family: str = "resid_post", positions: list[int] | None = None) -> PatchResult: | |
| 55 | + """Patch clean activations into the corrupted run, one (layer, position) at a time.""" | |
| 56 | + T = clean_ids.shape[1] | |
| 57 | + positions = positions if positions is not None else list(range(T)) | |
| 58 | + clean_acts = capture_all(model, clean_ids, pos, family) | |
| 59 | + base = _run(model, corrupt_ids, pos) | |
| 60 | + clean_logits = _run(model, clean_ids, pos) | |
| 61 | + ar = torch.arange(len(pos), device=clean_ids.device) | |
| 62 | + # logit difference clean-answer minus corrupt-answer, in the corrupted run (baseline) and clean run (ceiling) | |
| 63 | + ld_base = base[ar, clean_ans] - base[ar, corrupt_ans] | |
| 64 | + ld_clean = clean_logits[ar, clean_ans] - clean_logits[ar, corrupt_ans] | |
| 65 | + denom = (ld_clean - ld_base).clamp_min(1e-6) | |
| 66 | + L = model.cfg.n_layers | |
| 67 | + flip = np.zeros((L, len(positions))) | |
| 68 | + rec = np.zeros((L, len(positions))) | |
| 69 | + for l in range(L): | |
| 70 | + name = f"{family}.{l}" | |
| 71 | + for j, p in enumerate(positions): | |
| 72 | + fn = Replace(clean_acts[name], positions=[p]) | |
| 73 | + model.hooks.add(name, fn) | |
| 74 | + try: | |
| 75 | + out = _run(model, corrupt_ids, pos) | |
| 76 | + finally: | |
| 77 | + model.hooks.remove(name, fn) | |
| 78 | + ld = out[ar, clean_ans] - out[ar, corrupt_ans] | |
| 79 | + rec[l, j] = float(((ld - ld_base) / denom).clamp(-1, 2).mean()) | |
| 80 | + flip[l, j] = float((out.argmax(-1) == clean_ans).float().mean()) | |
| 81 | + return PatchResult(family, list(range(L)), positions, flip, rec, int(len(pos))) | |
| 82 | + | |
| 83 | + | |
| 84 | +def ablation_sweep(model: ToyTransformer, ids: torch.Tensor, pos: torch.Tensor, ans: torch.Tensor, family: str = "resid_post", | |
| 85 | + positions: list[int] | None = None, mode: str = "zero", noise_std: float = 1.0, seed: int = 0) -> np.ndarray: | |
| 86 | + """Accuracy after ablating (layer, position). Returns [L, P] accuracies.""" | |
| 87 | + T = ids.shape[1] | |
| 88 | + positions = positions if positions is not None else list(range(T)) | |
| 89 | + L = model.cfg.n_layers | |
| 90 | + acc = np.zeros((L, len(positions))) | |
| 91 | + for l in range(L): | |
| 92 | + name = f"{family}.{l}" | |
| 93 | + for j, p in enumerate(positions): | |
| 94 | + fn = Zero(positions=[p]) if mode == "zero" else GaussianNoise(noise_std, positions=[p], seed=seed) | |
| 95 | + model.hooks.add(name, fn) | |
| 96 | + try: | |
| 97 | + out = _run(model, ids, pos) | |
| 98 | + finally: | |
| 99 | + model.hooks.remove(name, fn) | |
| 100 | + acc[l, j] = float((out.argmax(-1) == ans).float().mean()) | |
| 101 | + return acc | |
| 102 | + | |
| 103 | + | |
| 104 | +def head_patch_sweep(model: ToyTransformer, clean_ids: torch.Tensor, corrupt_ids: torch.Tensor, pos: torch.Tensor, | |
| 105 | + clean_ans: torch.Tensor, corrupt_ans: torch.Tensor, position: int) -> np.ndarray: | |
| 106 | + """Per-(layer, head) patching of the attention head output at one token position. Returns [L, H] flip rates.""" | |
| 107 | + clean_acts = capture_all(model, clean_ids, pos, "attn_heads") | |
| 108 | + L, H = model.cfg.n_layers, model.cfg.n_heads | |
| 109 | + flip = np.zeros((L, H)) | |
| 110 | + for l in range(L): | |
| 111 | + name = f"attn_heads.{l}" | |
| 112 | + for h in range(H): | |
| 113 | + fn = Replace(clean_acts[name], positions=[position], heads=[h]) | |
| 114 | + model.hooks.add(name, fn) | |
| 115 | + try: | |
| 116 | + out = _run(model, corrupt_ids, pos) | |
| 117 | + finally: | |
| 118 | + model.hooks.remove(name, fn) | |
| 119 | + flip[l, h] = float((out.argmax(-1) == clean_ans).float().mean()) | |
| 120 | + return flip | |
added
src/wp_ai_0001/models/__init__.py
+2 −0
@@ -0,0 +1,2 @@ | ||
| 1 | +from wp_ai_0001.models.hooks import HookManager, Intervention # noqa: F401 | |
| 2 | +from wp_ai_0001.models.toy_transformer import ToyTransformer # noqa: F401 | |
added
src/wp_ai_0001/models/decoding.py
+28 −0
@@ -0,0 +1,28 @@ | ||
| 1 | +"""Greedy scratchpad decoding for toy models (batched, per-row prompt lengths).""" | |
| 2 | +from __future__ import annotations | |
| 3 | + | |
| 4 | +import torch | |
| 5 | + | |
| 6 | +from wp_ai_0001.models.toy_transformer import ToyTransformer | |
| 7 | + | |
| 8 | + | |
| 9 | +@torch.no_grad() | |
| 10 | +def greedy_decode(model: ToyTransformer, ids: torch.Tensor, prompt_len: torch.Tensor, n_answer: torch.Tensor, K: int) -> torch.Tensor: | |
| 11 | + """Fill answer positions greedily; returns predicted answer ids [B,K] (pad beyond n_answer). | |
| 12 | + | |
| 13 | + ``ids`` must contain the prompt; answer positions are overwritten step by step so the | |
| 14 | + generated prefix conditions later steps (no teacher forcing). | |
| 15 | + """ | |
| 16 | + ids = ids.clone() | |
| 17 | + B = ids.shape[0] | |
| 18 | + ar = torch.arange(B, device=ids.device) | |
| 19 | + out = torch.zeros(B, K, dtype=torch.long, device=ids.device) | |
| 20 | + for s in range(K): | |
| 21 | + read = prompt_len - 1 + s | |
| 22 | + logits = model(ids, read) # hook positions = the read position for this step | |
| 23 | + pred = logits[ar, read].argmax(-1) | |
| 24 | + write = prompt_len + s | |
| 25 | + active = s < n_answer | |
| 26 | + ids[ar[active], write[active]] = pred[active] | |
| 27 | + out[:, s] = torch.where(active, pred, torch.zeros_like(pred)) | |
| 28 | + return out | |
added
src/wp_ai_0001/models/hooks.py
+203 −0
@@ -0,0 +1,203 @@ | ||
| 1 | +"""Hook points and interventions for activation capture, patching and steering. | |
| 2 | + | |
| 3 | +Design contract (tested in tests/causal_sanity/test_hook_noop.py): | |
| 4 | + | |
| 5 | +* A ``HookManager`` with ``enabled=False`` or with no registered interventions returns the input | |
| 6 | + tensor object itself (identity, no copy), so a model instrumented with hook points produces | |
| 7 | + bit-identical outputs to the uninstrumented computation. | |
| 8 | +* Interventions are pure functions ``(tensor, ctx) -> tensor`` applied in registration order at a | |
| 9 | + named hook point. ``ctx`` carries the hook name and the batch of token positions. | |
| 10 | +* Capture interventions record (detached, cloned) activations without modifying the stream. | |
| 11 | + | |
| 12 | +Hook names used by ``ToyTransformer``: | |
| 13 | + ``embed``, ``resid_pre.{l}``, ``attn_heads.{l}`` ([B,T,H,dh] before the output projection), | |
| 14 | + ``attn_out.{l}``, ``resid_mid.{l}``, ``mlp_out.{l}``, ``resid_post.{l}``, ``final_norm``. | |
| 15 | +""" | |
| 16 | +from __future__ import annotations | |
| 17 | + | |
| 18 | +from dataclasses import dataclass, field | |
| 19 | +from typing import Callable, Protocol | |
| 20 | + | |
| 21 | +import torch | |
| 22 | + | |
| 23 | +Tensor = torch.Tensor | |
| 24 | + | |
| 25 | + | |
| 26 | +@dataclass | |
| 27 | +class HookContext: | |
| 28 | + name: str | |
| 29 | + positions: Tensor | None = None # [B] answer positions when available | |
| 30 | + extra: dict = field(default_factory=dict) | |
| 31 | + | |
| 32 | + | |
| 33 | +class Intervention(Protocol): | |
| 34 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: ... | |
| 35 | + | |
| 36 | + | |
| 37 | +class HookManager: | |
| 38 | + def __init__(self) -> None: | |
| 39 | + self.enabled: bool = True | |
| 40 | + self._hooks: dict[str, list[Intervention]] = {} | |
| 41 | + self.calls: int = 0 | |
| 42 | + | |
| 43 | + # -- registration ------------------------------------------------------------------- | |
| 44 | + def add(self, name: str, fn: Intervention) -> None: | |
| 45 | + self._hooks.setdefault(name, []).append(fn) | |
| 46 | + | |
| 47 | + def remove(self, name: str, fn: Intervention | None = None) -> None: | |
| 48 | + if fn is None: | |
| 49 | + self._hooks.pop(name, None) | |
| 50 | + elif name in self._hooks: | |
| 51 | + self._hooks[name] = [f for f in self._hooks[name] if f is not fn] | |
| 52 | + | |
| 53 | + def clear(self) -> None: | |
| 54 | + self._hooks.clear() | |
| 55 | + | |
| 56 | + def names(self) -> list[str]: | |
| 57 | + return [n for n, fns in self._hooks.items() if fns] | |
| 58 | + | |
| 59 | + # -- application -------------------------------------------------------------------- | |
| 60 | + def __call__(self, name: str, x: Tensor, ctx: HookContext | None = None) -> Tensor: | |
| 61 | + if not self.enabled: | |
| 62 | + return x | |
| 63 | + fns = self._hooks.get(name) | |
| 64 | + if not fns: | |
| 65 | + return x | |
| 66 | + self.calls += 1 | |
| 67 | + c = ctx or HookContext(name=name) | |
| 68 | + c.name = name | |
| 69 | + for fn in fns: | |
| 70 | + x = fn(x, c) | |
| 71 | + return x | |
| 72 | + | |
| 73 | + class _Disabled: | |
| 74 | + def __init__(self, mgr: "HookManager") -> None: | |
| 75 | + self.mgr, self.prev = mgr, mgr.enabled | |
| 76 | + | |
| 77 | + def __enter__(self) -> None: | |
| 78 | + self.mgr.enabled = False | |
| 79 | + | |
| 80 | + def __exit__(self, *a) -> None: | |
| 81 | + self.mgr.enabled = self.prev | |
| 82 | + | |
| 83 | + def disabled(self) -> "HookManager._Disabled": | |
| 84 | + return HookManager._Disabled(self) | |
| 85 | + | |
| 86 | + | |
| 87 | +# --------------------------------------------------------------------------------------- | |
| 88 | +# Built-in interventions | |
| 89 | +# --------------------------------------------------------------------------------------- | |
| 90 | +class Capture: | |
| 91 | + """Record activations (detached clone) without modifying the stream.""" | |
| 92 | + | |
| 93 | + def __init__(self) -> None: | |
| 94 | + self.store: dict[str, Tensor] = {} | |
| 95 | + | |
| 96 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 97 | + self.store[ctx.name] = x.detach().clone() | |
| 98 | + return x | |
| 99 | + | |
| 100 | + | |
| 101 | +def _pos_mask(x: Tensor, positions: Tensor | list[int] | slice | None) -> Tensor: | |
| 102 | + """Boolean mask [B,T] selecting token positions (per-example positions or shared slice).""" | |
| 103 | + B, T = x.shape[0], x.shape[1] | |
| 104 | + mask = torch.zeros(B, T, dtype=torch.bool, device=x.device) | |
| 105 | + if positions is None: | |
| 106 | + mask[:] = True | |
| 107 | + elif isinstance(positions, slice): | |
| 108 | + mask[:, positions] = True | |
| 109 | + elif isinstance(positions, torch.Tensor) and positions.ndim == 1 and positions.shape[0] == B: | |
| 110 | + mask[torch.arange(B, device=x.device), positions.to(x.device)] = True | |
| 111 | + else: | |
| 112 | + mask[:, list(positions)] = True # type: ignore[arg-type] | |
| 113 | + return mask | |
| 114 | + | |
| 115 | + | |
| 116 | +class Replace: | |
| 117 | + """Activation patching: overwrite selected positions with ``source`` values of the same shape.""" | |
| 118 | + | |
| 119 | + def __init__(self, source: Tensor, positions=None, heads: list[int] | None = None, dims: slice | None = None) -> None: | |
| 120 | + self.source, self.positions, self.heads, self.dims = source, positions, heads, dims | |
| 121 | + | |
| 122 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 123 | + src = self.source.to(x.device, x.dtype) | |
| 124 | + mask = _pos_mask(x, self.positions) | |
| 125 | + out = x.clone() | |
| 126 | + if self.heads is not None: # x: [B,T,H,dh] | |
| 127 | + m = mask[:, :, None, None].expand_as(x).clone() | |
| 128 | + keep = torch.zeros(x.shape[2], dtype=torch.bool, device=x.device) | |
| 129 | + keep[self.heads] = True | |
| 130 | + m &= keep[None, None, :, None] | |
| 131 | + out = torch.where(m, src, x) | |
| 132 | + elif self.dims is not None: | |
| 133 | + m = mask[:, :, None].expand_as(x).clone() | |
| 134 | + dmask = torch.zeros(x.shape[-1], dtype=torch.bool, device=x.device) | |
| 135 | + dmask[self.dims] = True | |
| 136 | + m &= dmask[None, None, :] | |
| 137 | + out = torch.where(m, src, x) | |
| 138 | + else: | |
| 139 | + m = mask.reshape(mask.shape + (1,) * (x.ndim - 2)).expand_as(x) | |
| 140 | + out = torch.where(m, src, x) | |
| 141 | + return out | |
| 142 | + | |
| 143 | + | |
| 144 | +class Add: | |
| 145 | + """Additive steering: x[positions] += scale * vector (vector broadcast over the last dim).""" | |
| 146 | + | |
| 147 | + def __init__(self, vector: Tensor, scale: float = 1.0, positions=None) -> None: | |
| 148 | + self.vector, self.scale, self.positions = vector, scale, positions | |
| 149 | + | |
| 150 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 151 | + v = self.vector.to(x.device, x.dtype) | |
| 152 | + mask = _pos_mask(x, self.positions) | |
| 153 | + m = mask.reshape(mask.shape + (1,) * (x.ndim - 2)).to(x.dtype) | |
| 154 | + return x + self.scale * m * v | |
| 155 | + | |
| 156 | + | |
| 157 | +class Zero: | |
| 158 | + def __init__(self, positions=None, heads: list[int] | None = None) -> None: | |
| 159 | + self.positions, self.heads = positions, heads | |
| 160 | + | |
| 161 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 162 | + return Replace(torch.zeros_like(x), self.positions, heads=self.heads)(x, ctx) | |
| 163 | + | |
| 164 | + | |
| 165 | +class GaussianNoise: | |
| 166 | + """Causal-tracing style corruption with a fixed generator for reproducibility.""" | |
| 167 | + | |
| 168 | + def __init__(self, std: float, positions=None, seed: int = 0) -> None: | |
| 169 | + self.std, self.positions, self.seed = std, positions, seed | |
| 170 | + | |
| 171 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 172 | + g = torch.Generator(device="cpu").manual_seed(self.seed) | |
| 173 | + noise = torch.randn(x.shape, generator=g, dtype=torch.float32).to(x.device, x.dtype) * self.std | |
| 174 | + mask = _pos_mask(x, self.positions) | |
| 175 | + m = mask.reshape(mask.shape + (1,) * (x.ndim - 2)).to(x.dtype) | |
| 176 | + return x + m * noise | |
| 177 | + | |
| 178 | + | |
| 179 | +class ProjectSubspace: | |
| 180 | + """Remove (mode='ablate') or keep only (mode='keep') the component in span(basis).""" | |
| 181 | + | |
| 182 | + def __init__(self, basis: Tensor, mode: str = "ablate", positions=None) -> None: | |
| 183 | + assert mode in {"ablate", "keep"} | |
| 184 | + q, _ = torch.linalg.qr(basis.T.float() if basis.shape[0] < basis.shape[1] else basis.float()) | |
| 185 | + self.q, self.mode, self.positions = q, mode, positions # [d, r] orthonormal columns | |
| 186 | + | |
| 187 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 188 | + q = self.q.to(x.device, x.dtype) | |
| 189 | + proj = (x @ q) @ q.T | |
| 190 | + new = x - proj if self.mode == "ablate" else proj | |
| 191 | + mask = _pos_mask(x, self.positions) | |
| 192 | + m = mask.reshape(mask.shape + (1,) * (x.ndim - 2)).expand_as(x) | |
| 193 | + return torch.where(m, new, x) | |
| 194 | + | |
| 195 | + | |
| 196 | +class Sequence: | |
| 197 | + def __init__(self, *fns: Callable[[Tensor, HookContext], Tensor]) -> None: | |
| 198 | + self.fns = fns | |
| 199 | + | |
| 200 | + def __call__(self, x: Tensor, ctx: HookContext) -> Tensor: | |
| 201 | + for f in self.fns: | |
| 202 | + x = f(x, ctx) | |
| 203 | + return x | |
added
src/wp_ai_0001/models/toy_transformer.py
+116 −0
@@ -0,0 +1,116 @@ | ||
| 1 | +"""Tier-0 toy decoder-only transformer with explicit hook points (PyTorch, CPU/MPS/CUDA). | |
| 2 | + | |
| 3 | +Pre-LN GPT-style block. Attention is written explicitly (no fused kernel) so that per-head outputs | |
| 4 | +are exposed at ``attn_heads.{l}`` before the output projection, enabling head-level patching. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +import math | |
| 9 | + | |
| 10 | +import torch | |
| 11 | +import torch.nn as nn | |
| 12 | +import torch.nn.functional as F | |
| 13 | + | |
| 14 | +from wp_ai_0001.config import ToyModelConfig | |
| 15 | +from wp_ai_0001.models.hooks import HookContext, HookManager | |
| 16 | + | |
| 17 | + | |
| 18 | +class Attention(nn.Module): | |
| 19 | + def __init__(self, cfg: ToyModelConfig, layer: int, hooks: HookManager) -> None: | |
| 20 | + super().__init__() | |
| 21 | + self.h, self.dh = cfg.n_heads, cfg.d_model // cfg.n_heads | |
| 22 | + self.qkv = nn.Linear(cfg.d_model, 3 * cfg.d_model, bias=False) | |
| 23 | + self.o = nn.Linear(cfg.d_model, cfg.d_model, bias=False) | |
| 24 | + self.layer, self.hooks = layer, hooks | |
| 25 | + | |
| 26 | + def forward(self, x: torch.Tensor, ctx: HookContext) -> torch.Tensor: | |
| 27 | + B, T, D = x.shape | |
| 28 | + q, k, v = self.qkv(x).split(D, dim=-1) | |
| 29 | + q = q.view(B, T, self.h, self.dh).transpose(1, 2) | |
| 30 | + k = k.view(B, T, self.h, self.dh).transpose(1, 2) | |
| 31 | + v = v.view(B, T, self.h, self.dh).transpose(1, 2) | |
| 32 | + att = (q @ k.transpose(-2, -1)) / math.sqrt(self.dh) | |
| 33 | + causal = torch.ones(T, T, dtype=torch.bool, device=x.device).tril() | |
| 34 | + att = att.masked_fill(~causal, float("-inf")).softmax(-1) | |
| 35 | + heads = (att @ v).transpose(1, 2) # [B,T,H,dh] | |
| 36 | + heads = self.hooks(f"attn_heads.{self.layer}", heads, ctx) | |
| 37 | + return self.o(heads.reshape(B, T, D)) | |
| 38 | + | |
| 39 | + | |
| 40 | +class Block(nn.Module): | |
| 41 | + def __init__(self, cfg: ToyModelConfig, layer: int, hooks: HookManager) -> None: | |
| 42 | + super().__init__() | |
| 43 | + self.ln1, self.ln2 = nn.LayerNorm(cfg.d_model), nn.LayerNorm(cfg.d_model) | |
| 44 | + self.attn = Attention(cfg, layer, hooks) | |
| 45 | + self.mlp = nn.Sequential(nn.Linear(cfg.d_model, cfg.d_ff), nn.GELU(), nn.Linear(cfg.d_ff, cfg.d_model)) | |
| 46 | + self.layer, self.hooks = layer, hooks | |
| 47 | + | |
| 48 | + def forward(self, x: torch.Tensor, ctx: HookContext) -> torch.Tensor: | |
| 49 | + l, hk = self.layer, self.hooks | |
| 50 | + x = hk(f"resid_pre.{l}", x, ctx) | |
| 51 | + a = hk(f"attn_out.{l}", self.attn(self.ln1(x), ctx), ctx) | |
| 52 | + x = hk(f"resid_mid.{l}", x + a, ctx) | |
| 53 | + m = hk(f"mlp_out.{l}", self.mlp(self.ln2(x)), ctx) | |
| 54 | + return hk(f"resid_post.{l}", x + m, ctx) | |
| 55 | + | |
| 56 | + | |
| 57 | +class ToyTransformer(nn.Module): | |
| 58 | + def __init__(self, cfg: ToyModelConfig, vocab_size: int) -> None: | |
| 59 | + super().__init__() | |
| 60 | + self.cfg, self.vocab_size = cfg, vocab_size | |
| 61 | + self.hooks = HookManager() | |
| 62 | + self.tok = nn.Embedding(vocab_size, cfg.d_model) | |
| 63 | + self.pos = nn.Embedding(cfg.max_seq_len, cfg.d_model) | |
| 64 | + self.blocks = nn.ModuleList([Block(cfg, i, self.hooks) for i in range(cfg.n_layers)]) | |
| 65 | + self.ln_f = nn.LayerNorm(cfg.d_model) | |
| 66 | + self.head = nn.Linear(cfg.d_model, vocab_size, bias=False) | |
| 67 | + if cfg.tie_embeddings: | |
| 68 | + self.head.weight = self.tok.weight | |
| 69 | + self.apply(self._init) | |
| 70 | + | |
| 71 | + @staticmethod | |
| 72 | + def _init(m: nn.Module) -> None: | |
| 73 | + if isinstance(m, nn.Linear): | |
| 74 | + nn.init.normal_(m.weight, std=0.02) | |
| 75 | + if m.bias is not None: | |
| 76 | + nn.init.zeros_(m.bias) | |
| 77 | + elif isinstance(m, nn.Embedding): | |
| 78 | + nn.init.normal_(m.weight, std=0.02) | |
| 79 | + | |
| 80 | + @property | |
| 81 | + def n_params(self) -> int: | |
| 82 | + return sum(p.numel() for p in self.parameters()) | |
| 83 | + | |
| 84 | + def forward(self, ids: torch.Tensor, positions: torch.Tensor | None = None) -> torch.Tensor: | |
| 85 | + B, T = ids.shape | |
| 86 | + ctx = HookContext(name="", positions=positions) | |
| 87 | + x = self.tok(ids) + self.pos(torch.arange(T, device=ids.device))[None] | |
| 88 | + x = self.hooks("embed", x, ctx) | |
| 89 | + for blk in self.blocks: | |
| 90 | + x = blk(x, ctx) | |
| 91 | + x = self.hooks("final_norm", self.ln_f(x), ctx) | |
| 92 | + return self.head(x) # [B,T,V] | |
| 93 | + | |
| 94 | + def answer_logits(self, ids: torch.Tensor, answer_pos: torch.Tensor) -> torch.Tensor: | |
| 95 | + logits = self.forward(ids, answer_pos) | |
| 96 | + return logits[torch.arange(ids.shape[0], device=ids.device), answer_pos] | |
| 97 | + | |
| 98 | + @torch.no_grad() | |
| 99 | + def predict(self, ids: torch.Tensor, answer_pos: torch.Tensor) -> torch.Tensor: | |
| 100 | + return self.answer_logits(ids, answer_pos).argmax(-1) | |
| 101 | + | |
| 102 | + def hook_names(self) -> list[str]: | |
| 103 | + names = ["embed"] | |
| 104 | + for l in range(self.cfg.n_layers): | |
| 105 | + names += [f"resid_pre.{l}", f"attn_heads.{l}", f"attn_out.{l}", f"resid_mid.{l}", f"mlp_out.{l}", f"resid_post.{l}"] | |
| 106 | + return names + ["final_norm"] | |
| 107 | + | |
| 108 | + | |
| 109 | +def resolve_device(name: str = "auto") -> torch.device: | |
| 110 | + if name != "auto": | |
| 111 | + return torch.device(name) | |
| 112 | + if torch.cuda.is_available(): | |
| 113 | + return torch.device("cuda") | |
| 114 | + if torch.backends.mps.is_available(): | |
| 115 | + return torch.device("mps") | |
| 116 | + return torch.device("cpu") | |
added
src/wp_ai_0001/orchestration/__init__.py
+0 −0
added
src/wp_ai_0001/orchestration/registry.py
+23 −0
@@ -0,0 +1,23 @@ | ||
| 1 | +"""Append-only experiment registry (JSON lines). One record per run status change.""" | |
| 2 | +from __future__ import annotations | |
| 3 | + | |
| 4 | +import json | |
| 5 | +from pathlib import Path | |
| 6 | +from typing import Any | |
| 7 | + | |
| 8 | +from wp_ai_0001.instrumentation.provenance import PROJECT_ROOT, utc_now | |
| 9 | + | |
| 10 | +REGISTRY_PATH = PROJECT_ROOT / "experiments" / "registry" / "runs.jsonl" | |
| 11 | + | |
| 12 | + | |
| 13 | +def record(run_id: str, experiment_id: str, status: str, **fields: Any) -> None: | |
| 14 | + REGISTRY_PATH.parent.mkdir(parents=True, exist_ok=True) | |
| 15 | + rec = {"utc": utc_now(), "run_id": run_id, "experiment_id": experiment_id, "status": status, **fields} | |
| 16 | + with open(REGISTRY_PATH, "a") as f: | |
| 17 | + f.write(json.dumps(rec, sort_keys=True, default=str) + "\n") | |
| 18 | + | |
| 19 | + | |
| 20 | +def load() -> list[dict[str, Any]]: | |
| 21 | + if not REGISTRY_PATH.exists(): | |
| 22 | + return [] | |
| 23 | + return [json.loads(line) for line in REGISTRY_PATH.read_text().splitlines() if line.strip()] | |
added
src/wp_ai_0001/statistics/__init__.py
+0 −0
added
src/wp_ai_0001/statistics/bootstrap.py
+54 −0
@@ -0,0 +1,54 @@ | ||
| 1 | +"""Cluster bootstrap for accuracies and paired differences. | |
| 2 | + | |
| 3 | +Items nested in generating templates (clusters) are not independent; the bootstrap resamples | |
| 4 | +clusters with replacement. Paired differences use identical items for both conditions. | |
| 5 | +""" | |
| 6 | +from __future__ import annotations | |
| 7 | + | |
| 8 | +from dataclasses import dataclass | |
| 9 | + | |
| 10 | +import numpy as np | |
| 11 | + | |
| 12 | + | |
| 13 | +@dataclass | |
| 14 | +class CI: | |
| 15 | + estimate: float | |
| 16 | + low: float | |
| 17 | + high: float | |
| 18 | + level: float | |
| 19 | + n_items: int | |
| 20 | + n_clusters: int | |
| 21 | + n_boot: int | |
| 22 | + | |
| 23 | + def to_dict(self) -> dict: | |
| 24 | + return self.__dict__.copy() | |
| 25 | + | |
| 26 | + | |
| 27 | +def _cluster_index(clusters: list[str]) -> tuple[np.ndarray, int]: | |
| 28 | + uniq = {c: i for i, c in enumerate(dict.fromkeys(clusters))} | |
| 29 | + return np.array([uniq[c] for c in clusters]), len(uniq) | |
| 30 | + | |
| 31 | + | |
| 32 | +def cluster_bootstrap_mean(values: np.ndarray, clusters: list[str], n_boot: int = 2000, level: float = 0.95, seed: int = 0) -> CI: | |
| 33 | + values = np.asarray(values, dtype=float) | |
| 34 | + cid, k = _cluster_index(clusters) | |
| 35 | + rng = np.random.default_rng(seed) | |
| 36 | + sums = np.bincount(cid, weights=values, minlength=k) | |
| 37 | + counts = np.bincount(cid, minlength=k).astype(float) | |
| 38 | + stats = np.empty(n_boot) | |
| 39 | + for b in range(n_boot): | |
| 40 | + draw = rng.integers(0, k, k) | |
| 41 | + stats[b] = sums[draw].sum() / counts[draw].sum() | |
| 42 | + a = (1 - level) / 2 | |
| 43 | + return CI(float(values.mean()), float(np.quantile(stats, a)), float(np.quantile(stats, 1 - a)), level, len(values), k, n_boot) | |
| 44 | + | |
| 45 | + | |
| 46 | +def cluster_bootstrap_paired_diff(a: np.ndarray, b: np.ndarray, clusters: list[str], n_boot: int = 2000, level: float = 0.95, seed: int = 0) -> CI: | |
| 47 | + """CI for mean(a) - mean(b) on identical items (paired), resampling clusters.""" | |
| 48 | + return cluster_bootstrap_mean(np.asarray(a, float) - np.asarray(b, float), clusters, n_boot, level, seed) | |
| 49 | + | |
| 50 | + | |
| 51 | +def seeds_summary(values: list[float]) -> dict: | |
| 52 | + v = np.asarray(values, float) | |
| 53 | + return {"n_seeds": int(len(v)), "mean": float(v.mean()), "sd": float(v.std(ddof=1)) if len(v) > 1 else None, | |
| 54 | + "min": float(v.min()), "max": float(v.max())} | |
added
src/wp_ai_0001/training/__init__.py
+0 −0
added
src/wp_ai_0001/training/train_toy.py
+102 −0
@@ -0,0 +1,102 @@ | ||
| 1 | +"""Deterministic training of a Tier-0 toy model on a single-answer-token micro-world. | |
| 2 | + | |
| 3 | +Loss is the teacher-forced cross-entropy of the answer (scratchpad) tokens only. Training is used to | |
| 4 | +*manufacture* donor competence and recipient weakness; it is documented as a separate stage and | |
| 5 | +is never part of a transplant. | |
| 6 | +""" | |
| 7 | +from __future__ import annotations | |
| 8 | + | |
| 9 | +import json | |
| 10 | +import math | |
| 11 | +import time | |
| 12 | +from pathlib import Path | |
| 13 | + | |
| 14 | +import numpy as np | |
| 15 | +import torch | |
| 16 | +import torch.nn.functional as F | |
| 17 | + | |
| 18 | +from wp_ai_0001.config import ToyModelConfig, TrainConfig | |
| 19 | +from wp_ai_0001.datasets.common import Split, Vocab, encode_split | |
| 20 | +from wp_ai_0001.models.decoding import greedy_decode | |
| 21 | +from wp_ai_0001.models.toy_transformer import ToyTransformer, resolve_device | |
| 22 | + | |
| 23 | + | |
| 24 | +def set_seed(seed: int) -> None: | |
| 25 | + torch.manual_seed(seed) | |
| 26 | + np.random.seed(seed) | |
| 27 | + | |
| 28 | + | |
| 29 | +@torch.no_grad() | |
| 30 | +def accuracy(model: ToyTransformer, enc: dict[str, np.ndarray], device: torch.device, bs: int = 1024) -> tuple[float, float, np.ndarray, np.ndarray]: | |
| 31 | + """Greedy-decoding accuracy: (final-answer acc, full-trace acc, final_correct [N], trace_correct [N]).""" | |
| 32 | + model.eval() | |
| 33 | + K = enc["answers"].shape[1] | |
| 34 | + fin, tr = [], [] | |
| 35 | + for i in range(0, len(enc["ids"]), bs): | |
| 36 | + ids = torch.from_numpy(enc["ids"][i : i + bs]).to(device) | |
| 37 | + pl = torch.from_numpy(enc["prompt_len"][i : i + bs]).to(device) | |
| 38 | + na = torch.from_numpy(enc["n_answer"][i : i + bs]).to(device) | |
| 39 | + gold = torch.from_numpy(enc["answers"][i : i + bs]).to(device) | |
| 40 | + pred = greedy_decode(model, ids, pl, na, K) | |
| 41 | + ar = torch.arange(len(pl), device=device) | |
| 42 | + fin.append((pred[ar, na - 1] == gold[ar, na - 1]).cpu().numpy()) | |
| 43 | + valid = torch.arange(K, device=device)[None] < na[:, None] | |
| 44 | + tr.append(((pred == gold) | ~valid).all(-1).cpu().numpy()) | |
| 45 | + f, t = np.concatenate(fin), np.concatenate(tr) | |
| 46 | + return float(f.mean()), float(t.mean()), f, t | |
| 47 | + | |
| 48 | + | |
| 49 | +def masked_loss(model: ToyTransformer, ids: torch.Tensor, loss_mask: torch.Tensor) -> torch.Tensor: | |
| 50 | + logits = model(ids[:, :-1]) | |
| 51 | + target = ids[:, 1:] | |
| 52 | + mask = loss_mask[:, :-1] | |
| 53 | + ce = F.cross_entropy(logits.reshape(-1, logits.shape[-1]), target.reshape(-1), reduction="none").view_as(mask) | |
| 54 | + return (ce * mask).sum() / mask.sum() | |
| 55 | + | |
| 56 | + | |
| 57 | +def train(model_cfg: ToyModelConfig, train_cfg: TrainConfig, train_split: Split, dev_split: Split, vocab: Vocab, out_dir: Path, log: list[dict] | None = None) -> ToyTransformer: | |
| 58 | + set_seed(train_cfg.seed) | |
| 59 | + device = resolve_device(train_cfg.device) | |
| 60 | + model = ToyTransformer(model_cfg, len(vocab)).to(device) | |
| 61 | + enc = encode_split(train_split, vocab, model_cfg.max_seq_len) | |
| 62 | + denc = encode_split(dev_split, vocab, model_cfg.max_seq_len) | |
| 63 | + ids, lmask = enc["ids"], enc["loss_mask"] | |
| 64 | + opt = torch.optim.AdamW(model.parameters(), lr=train_cfg.lr, weight_decay=train_cfg.weight_decay, betas=(0.9, 0.98)) | |
| 65 | + g = torch.Generator().manual_seed(train_cfg.seed) | |
| 66 | + n = len(ids) | |
| 67 | + t0 = time.time() | |
| 68 | + history = log if log is not None else [] | |
| 69 | + for step in range(1, train_cfg.steps + 1): | |
| 70 | + lr = train_cfg.lr * min(1.0, step / train_cfg.warmup_steps) * 0.5 * (1 + math.cos(math.pi * min(1.0, step / train_cfg.steps))) | |
| 71 | + for grp in opt.param_groups: | |
| 72 | + grp["lr"] = lr | |
| 73 | + idx = torch.randint(0, n, (train_cfg.batch_size,), generator=g).numpy() | |
| 74 | + x = torch.from_numpy(ids[idx]).to(device) | |
| 75 | + m = torch.from_numpy(lmask[idx]).to(device) | |
| 76 | + model.train() | |
| 77 | + loss = masked_loss(model, x, m) | |
| 78 | + opt.zero_grad(set_to_none=True) | |
| 79 | + loss.backward() | |
| 80 | + torch.nn.utils.clip_grad_norm_(model.parameters(), 1.0) | |
| 81 | + opt.step() | |
| 82 | + if step % train_cfg.eval_every == 0 or step == train_cfg.steps: | |
| 83 | + dev_acc, dev_trace, _, _ = accuracy(model, denc, device) | |
| 84 | + history.append({"step": step, "loss": float(loss.item()), "dev_acc": dev_acc, "dev_trace_acc": dev_trace, "lr": lr, "elapsed_s": time.time() - t0}) | |
| 85 | + out_dir.mkdir(parents=True, exist_ok=True) | |
| 86 | + torch.save(model.state_dict(), out_dir / "model.pt") | |
| 87 | + (out_dir / "model_config.json").write_text(model_cfg.model_dump_json(indent=2)) | |
| 88 | + (out_dir / "train_config.json").write_text(train_cfg.model_dump_json(indent=2)) | |
| 89 | + (out_dir / "vocab.json").write_text(vocab.to_json()) | |
| 90 | + (out_dir / "history.json").write_text(json.dumps(history, indent=2)) | |
| 91 | + return model | |
| 92 | + | |
| 93 | + | |
| 94 | +def load(out_dir: Path, device: torch.device | None = None) -> tuple[ToyTransformer, Vocab]: | |
| 95 | + cfg = ToyModelConfig.model_validate_json((out_dir / "model_config.json").read_text()) | |
| 96 | + vocab = Vocab.from_json((out_dir / "vocab.json").read_text()) | |
| 97 | + model = ToyTransformer(cfg, len(vocab)) | |
| 98 | + model.load_state_dict(torch.load(out_dir / "model.pt", map_location="cpu")) | |
| 99 | + model.eval() | |
| 100 | + if device is not None: | |
| 101 | + model.to(device) | |
| 102 | + return model, vocab | |
added
src/wp_ai_0001/transplantation/__init__.py
+0 −0
added
src/wp_ai_0001/visualization/__init__.py
+1 −0
@@ -0,0 +1 @@ | ||
| 1 | +from wp_ai_0001.visualization.style import CATEGORICAL, DIVERGING_CMAP, ENTITY_COLORS, SEQUENTIAL_CMAP, apply_style, heatmap # noqa: F401 | |
added
src/wp_ai_0001/visualization/style.py
+60 −0
@@ -0,0 +1,60 @@ | ||
| 1 | +"""Publication figure style: validated palette (categorical fixed order, one-hue sequential ramp, | |
| 2 | +blue-red diverging pair with neutral grey midpoint), vector output, recessive axes. | |
| 3 | + | |
| 4 | +Palette values follow the project data-visualization reference (light surface). Categorical hues | |
| 5 | +are assigned in fixed slot order to fixed entities and never cycled. | |
| 6 | +""" | |
| 7 | +from __future__ import annotations | |
| 8 | + | |
| 9 | +import matplotlib | |
| 10 | +import matplotlib.pyplot as plt | |
| 11 | +from matplotlib.colors import LinearSegmentedColormap | |
| 12 | + | |
| 13 | +CATEGORICAL = ["#2a78d6", "#eb6834", "#1baf7a", "#eda100", "#e87ba4", "#008300", "#6250d6", "#e34948"] | |
| 14 | +ENTITY_COLORS = {"donor": CATEGORICAL[0], "recipient": CATEGORICAL[1], "graft": CATEGORICAL[2], "sham": CATEGORICAL[3], | |
| 15 | + "random": CATEGORICAL[4], "chance": "#9a9892"} | |
| 16 | +SEQUENTIAL_STEPS = ["#fcfcfb", "#cde2fb", "#9ec5f4", "#6da7ec", "#3987e5", "#256abf", "#184f95", "#0d366b"] | |
| 17 | +DIVERGING_STEPS = ["#0d366b", "#3987e5", "#9ec5f4", "#f0efec", "#f2a09f", "#e34948", "#8f1d1c"] | |
| 18 | +TEXT_PRIMARY, TEXT_SECONDARY, GRID = "#0b0b0b", "#52514e", "#e2e1dd" | |
| 19 | + | |
| 20 | +SEQUENTIAL_CMAP = LinearSegmentedColormap.from_list("wp_seq_blue", SEQUENTIAL_STEPS) | |
| 21 | +DIVERGING_CMAP = LinearSegmentedColormap.from_list("wp_div_blue_red", DIVERGING_STEPS) | |
| 22 | + | |
| 23 | +COLUMN_WIDTH_IN = 3.35 # single journal column | |
| 24 | +DOUBLE_WIDTH_IN = 6.9 | |
| 25 | + | |
| 26 | + | |
| 27 | +def apply_style() -> None: | |
| 28 | + matplotlib.rcParams.update({ | |
| 29 | + "pdf.fonttype": 42, "ps.fonttype": 42, "svg.fonttype": "none", | |
| 30 | + "font.family": "sans-serif", "font.size": 8, "axes.titlesize": 8.5, "axes.labelsize": 8, | |
| 31 | + "xtick.labelsize": 7, "ytick.labelsize": 7, "legend.fontsize": 7, | |
| 32 | + "axes.edgecolor": GRID, "axes.linewidth": 0.6, "xtick.color": TEXT_SECONDARY, "ytick.color": TEXT_SECONDARY, | |
| 33 | + "axes.labelcolor": TEXT_PRIMARY, "text.color": TEXT_PRIMARY, "axes.grid": False, | |
| 34 | + "axes.spines.top": False, "axes.spines.right": False, "legend.frameon": False, | |
| 35 | + "figure.dpi": 150, "savefig.bbox": "tight", "savefig.pad_inches": 0.02, | |
| 36 | + }) | |
| 37 | + | |
| 38 | + | |
| 39 | +def heatmap(ax, data, row_labels, col_labels, *, cmap, vmin, vmax, cbar_label: str, title: str | None = None, annotate: bool = False): | |
| 40 | + im = ax.imshow(data, cmap=cmap, vmin=vmin, vmax=vmax, aspect="auto", interpolation="nearest") | |
| 41 | + ax.set_xticks(range(len(col_labels))) | |
| 42 | + ax.set_xticklabels(col_labels, rotation=90 if max(len(str(c)) for c in col_labels) > 3 else 0) | |
| 43 | + ax.set_yticks(range(len(row_labels))) | |
| 44 | + ax.set_yticklabels(row_labels) | |
| 45 | + ax.tick_params(length=0) | |
| 46 | + for s in ax.spines.values(): | |
| 47 | + s.set_visible(False) | |
| 48 | + if title: | |
| 49 | + ax.set_title(title, loc="left", color=TEXT_PRIMARY) | |
| 50 | + if annotate: | |
| 51 | + for i in range(data.shape[0]): | |
| 52 | + for j in range(data.shape[1]): | |
| 53 | + v = data[i, j] | |
| 54 | + ax.text(j, i, f"{v:.2f}", ha="center", va="center", fontsize=5.5, | |
| 55 | + color="#ffffff" if (v - vmin) / max(vmax - vmin, 1e-9) > 0.6 else TEXT_PRIMARY) | |
| 56 | + cb = plt.colorbar(im, ax=ax, fraction=0.046, pad=0.03) | |
| 57 | + cb.set_label(cbar_label, color=TEXT_SECONDARY) | |
| 58 | + cb.outline.set_visible(False) | |
| 59 | + cb.ax.tick_params(length=0, labelsize=6.5, colors=TEXT_SECONDARY) | |
| 60 | + return im | |
added
tests/causal_sanity/test_hook_noop.py
+131 −0
@@ -0,0 +1,131 @@ | ||
| 1 | +"""Gate C sanity: hooks are a true no-op when disabled/empty, and interventions have effects.""" | |
| 2 | +import torch | |
| 3 | + | |
| 4 | +from wp_ai_0001.config import OpSeqTaskConfig, ToyModelConfig | |
| 5 | +from wp_ai_0001.datasets import opseq | |
| 6 | +from wp_ai_0001.datasets.common import encode_split | |
| 7 | +from wp_ai_0001.models.hooks import Add, Capture, GaussianNoise, ProjectSubspace, Replace, Zero | |
| 8 | +from wp_ai_0001.models.toy_transformer import ToyTransformer | |
| 9 | + | |
| 10 | + | |
| 11 | +def _setup(seed=0): | |
| 12 | + torch.manual_seed(seed) | |
| 13 | + cfg = OpSeqTaskConfig() | |
| 14 | + split = opseq.generate(cfg, 64, seed=11, name="sanity") | |
| 15 | + vocab = opseq.vocab_for(cfg) | |
| 16 | + enc = encode_split(split, vocab, 24) | |
| 17 | + model = ToyTransformer(ToyModelConfig(d_model=32, n_layers=2, n_heads=2, d_ff=64, max_seq_len=24), len(vocab)).eval() | |
| 18 | + return model, torch.from_numpy(enc["ids"]), torch.from_numpy(enc["prompt_len"] - 1), torch.from_numpy(enc["answers"][:, 0]) | |
| 19 | + | |
| 20 | + | |
| 21 | +def test_no_hooks_is_bitwise_identity(): | |
| 22 | + model, ids, pos, _ = _setup() | |
| 23 | + with torch.no_grad(): | |
| 24 | + ref = model(ids, pos) | |
| 25 | + assert model.hooks.calls == 0 | |
| 26 | + out = model(ids, pos) | |
| 27 | + assert torch.equal(ref, out) | |
| 28 | + | |
| 29 | + | |
| 30 | +def test_capture_and_disabled_hooks_are_bitwise_identity(): | |
| 31 | + model, ids, pos, _ = _setup() | |
| 32 | + with torch.no_grad(): | |
| 33 | + ref = model(ids, pos) | |
| 34 | + cap = Capture() | |
| 35 | + for n in model.hook_names(): | |
| 36 | + model.hooks.add(n, cap) | |
| 37 | + out_cap = model(ids, pos) | |
| 38 | + assert set(cap.store) == set(model.hook_names()) | |
| 39 | + # a modifying hook that is disabled must also be a no-op | |
| 40 | + model.hooks.add("resid_post.0", Zero()) | |
| 41 | + with model.hooks.disabled(): | |
| 42 | + out_dis = model(ids, pos) | |
| 43 | + model.hooks.enabled = False | |
| 44 | + out_dis2 = model(ids, pos) | |
| 45 | + assert torch.equal(ref, out_cap) and torch.equal(ref, out_dis) and torch.equal(ref, out_dis2) | |
| 46 | + | |
| 47 | + | |
| 48 | +def test_identity_object_returned_when_no_hooks(): | |
| 49 | + model, ids, pos, _ = _setup() | |
| 50 | + x = torch.randn(2, 3, 32) | |
| 51 | + assert model.hooks("resid_post.0", x) is x | |
| 52 | + model.hooks.enabled = False | |
| 53 | + model.hooks.add("resid_post.0", Zero()) | |
| 54 | + assert model.hooks("resid_post.0", x) is x | |
| 55 | + | |
| 56 | + | |
| 57 | +def test_interventions_change_outputs_reproducibly(): | |
| 58 | + model, ids, pos, _ = _setup() | |
| 59 | + with torch.no_grad(): | |
| 60 | + ref = model(ids, pos) | |
| 61 | + model.hooks.add("resid_post.0", Zero(positions=pos)) | |
| 62 | + a = model(ids, pos) | |
| 63 | + b = model(ids, pos) | |
| 64 | + assert not torch.equal(ref, a) and torch.equal(a, b) | |
| 65 | + # unpatched positions are untouched up to the hooked layer: check resid_post.0 itself | |
| 66 | + model.hooks.clear() | |
| 67 | + cap = Capture() | |
| 68 | + model.hooks.add("resid_post.0", cap) | |
| 69 | + with torch.no_grad(): | |
| 70 | + model(ids, pos) | |
| 71 | + clean = cap.store["resid_post.0"] | |
| 72 | + model.hooks.clear() | |
| 73 | + cap2 = Capture() | |
| 74 | + model.hooks.add("resid_post.0", Zero(positions=pos)) | |
| 75 | + model.hooks.add("resid_post.0", cap2) | |
| 76 | + with torch.no_grad(): | |
| 77 | + model(ids, pos) | |
| 78 | + z = cap2.store["resid_post.0"] | |
| 79 | + B = ids.shape[0] | |
| 80 | + assert torch.all(z[torch.arange(B), pos] == 0) | |
| 81 | + mask = torch.ones_like(clean, dtype=torch.bool) | |
| 82 | + mask[torch.arange(B), pos] = False | |
| 83 | + assert torch.equal(z[mask], clean[mask]) | |
| 84 | + | |
| 85 | + | |
| 86 | +def test_replace_with_own_activation_is_identity(): | |
| 87 | + model, ids, pos, _ = _setup() | |
| 88 | + cap = Capture() | |
| 89 | + model.hooks.add("resid_mid.1", cap) | |
| 90 | + with torch.no_grad(): | |
| 91 | + ref = model(ids, pos) | |
| 92 | + model.hooks.clear() | |
| 93 | + model.hooks.add("resid_mid.1", Replace(cap.store["resid_mid.1"])) | |
| 94 | + with torch.no_grad(): | |
| 95 | + out = model(ids, pos) | |
| 96 | + assert torch.allclose(ref, out, atol=0, rtol=0) | |
| 97 | + | |
| 98 | + | |
| 99 | +def test_add_noise_project_have_expected_algebra(): | |
| 100 | + model, ids, pos, _ = _setup() | |
| 101 | + x = torch.randn(4, 5, 32) | |
| 102 | + v = torch.randn(32) | |
| 103 | + y = Add(v, scale=2.0)(x, model.hooks.__class__ and __import__("wp_ai_0001.models.hooks", fromlist=["HookContext"]).HookContext("h")) | |
| 104 | + assert torch.allclose(y - x, 2.0 * v.expand_as(x)) | |
| 105 | + ctx = __import__("wp_ai_0001.models.hooks", fromlist=["HookContext"]).HookContext("h") | |
| 106 | + n1, n2 = GaussianNoise(0.5, seed=3)(x, ctx), GaussianNoise(0.5, seed=3)(x, ctx) | |
| 107 | + assert torch.equal(n1, n2) and not torch.equal(n1, x) | |
| 108 | + basis = torch.randn(32, 4) | |
| 109 | + abl = ProjectSubspace(basis, "ablate")(x, ctx) | |
| 110 | + keep = ProjectSubspace(basis, "keep")(x, ctx) | |
| 111 | + assert torch.allclose(abl + keep, x, atol=1e-5) | |
| 112 | + assert torch.allclose(abl @ basis, torch.zeros(4, 5, 4), atol=1e-4) | |
| 113 | + | |
| 114 | + | |
| 115 | +def test_head_patch_touches_only_selected_head(): | |
| 116 | + model, ids, pos, _ = _setup() | |
| 117 | + cap = Capture() | |
| 118 | + model.hooks.add("attn_heads.0", cap) | |
| 119 | + with torch.no_grad(): | |
| 120 | + model(ids, pos) | |
| 121 | + src = torch.zeros_like(cap.store["attn_heads.0"]) | |
| 122 | + model.hooks.clear() | |
| 123 | + cap2 = Capture() | |
| 124 | + model.hooks.add("attn_heads.0", Replace(src, positions=[2], heads=[1])) | |
| 125 | + model.hooks.add("attn_heads.0", cap2) | |
| 126 | + with torch.no_grad(): | |
| 127 | + model(ids, pos) | |
| 128 | + out = cap2.store["attn_heads.0"] | |
| 129 | + ref = cap.store["attn_heads.0"] | |
| 130 | + assert torch.all(out[:, 2, 1] == 0) | |
| 131 | + assert torch.equal(out[:, 2, 0], ref[:, 2, 0]) and torch.equal(out[:, :2], ref[:, :2]) and torch.equal(out[:, 3:], ref[:, 3:]) | |
added
tests/integration/.gitkeep
+0 −0
added
tests/regression/.gitkeep
+0 −0
added
tests/unit/test_bootstrap.py
+18 −0
@@ -0,0 +1,18 @@ | ||
| 1 | +import numpy as np | |
| 2 | + | |
| 3 | +from wp_ai_0001.statistics.bootstrap import cluster_bootstrap_mean, cluster_bootstrap_paired_diff | |
| 4 | + | |
| 5 | + | |
| 6 | +def test_bootstrap_ci_contains_mean_and_is_deterministic(): | |
| 7 | + rng = np.random.default_rng(0) | |
| 8 | + vals = (rng.random(1000) < 0.7).astype(float) | |
| 9 | + clusters = [f"c{i % 50}" for i in range(1000)] | |
| 10 | + ci1 = cluster_bootstrap_mean(vals, clusters, n_boot=500, seed=1) | |
| 11 | + ci2 = cluster_bootstrap_mean(vals, clusters, n_boot=500, seed=1) | |
| 12 | + assert ci1.low <= ci1.estimate <= ci1.high and ci1 == ci2 and ci1.n_clusters == 50 | |
| 13 | + | |
| 14 | + | |
| 15 | +def test_paired_diff_zero_when_identical(): | |
| 16 | + vals = np.ones(100) | |
| 17 | + ci = cluster_bootstrap_paired_diff(vals, vals, [f"c{i%10}" for i in range(100)], n_boot=100) | |
| 18 | + assert ci.estimate == 0 and ci.low == 0 and ci.high == 0 | |
added
tests/unit/test_generators.py
+77 −0
@@ -0,0 +1,77 @@ | ||
| 1 | +import pytest | |
| 2 | + | |
| 3 | +from wp_ai_0001.config import FSATaskConfig, MorphTaskConfig, OpSeqTaskConfig | |
| 4 | +from wp_ai_0001.datasets import fsa, morph, opseq | |
| 5 | +from wp_ai_0001.datasets.common import assert_disjoint, encode_split | |
| 6 | + | |
| 7 | + | |
| 8 | +def test_opseq_validator_and_determinism(): | |
| 9 | + cfg = OpSeqTaskConfig() | |
| 10 | + a = opseq.generate(cfg, 500, seed=1, name="t") | |
| 11 | + b = opseq.generate(cfg, 500, seed=1, name="t") | |
| 12 | + opseq.validate(a, cfg) | |
| 13 | + assert a.hash == b.hash and len(a) == 500 | |
| 14 | + c = opseq.generate(cfg, 500, seed=2, name="t") | |
| 15 | + assert c.hash != a.hash | |
| 16 | + | |
| 17 | + | |
| 18 | +def test_opseq_train_excludes_heldout_pairs_and_operators(): | |
| 19 | + cfg = OpSeqTaskConfig(excluded_operators=["qua"]) | |
| 20 | + s = opseq.generate(cfg, 1000, seed=3, name="train", mode="train") | |
| 21 | + pairs = set(map(tuple, cfg.held_out_pairs)) | |
| 22 | + for e in s.examples: | |
| 23 | + ops = list(e.tokens[2:-2]) | |
| 24 | + assert "qua" not in ops | |
| 25 | + assert not any((x, y) in pairs for x, y in zip(ops, ops[1:])) | |
| 26 | + | |
| 27 | + | |
| 28 | +def test_opseq_comp_and_require(): | |
| 29 | + cfg = OpSeqTaskConfig() | |
| 30 | + s = opseq.generate(cfg, 300, seed=4, name="comp", mode="comp", min_len=2) | |
| 31 | + pairs = set(map(tuple, cfg.held_out_pairs)) | |
| 32 | + assert all(any((x, y) in pairs for x, y in zip(e.tokens[2:-2], e.tokens[3:-2])) for e in s.examples) | |
| 33 | + t = opseq.generate(cfg, 300, seed=5, name="target", mode="any", require_operator="qua") | |
| 34 | + assert all("qua" in e.tokens for e in t.examples) | |
| 35 | + u = opseq.generate(cfg, 300, seed=6, name="control", mode="any", forbid_operator="qua") | |
| 36 | + assert all("qua" not in e.tokens for e in u.examples) | |
| 37 | + | |
| 38 | + | |
| 39 | +def test_disjointness_enforced(): | |
| 40 | + cfg = OpSeqTaskConfig() | |
| 41 | + a = opseq.generate(cfg, 2000, seed=7, name="a") | |
| 42 | + b = opseq.generate(cfg, 2000, seed=8, name="b", exclude_hashes=a.item_hashes()) | |
| 43 | + assert_disjoint(a, b) | |
| 44 | + with pytest.raises(AssertionError): | |
| 45 | + assert_disjoint(a, a) | |
| 46 | + | |
| 47 | + | |
| 48 | +def test_encode_split_positions(): | |
| 49 | + cfg = OpSeqTaskConfig() | |
| 50 | + s = opseq.generate(cfg, 50, seed=9, name="e") | |
| 51 | + v = opseq.vocab_for(cfg) | |
| 52 | + enc = encode_split(s, v, 24) | |
| 53 | + for i, e in enumerate(s.examples): | |
| 54 | + pl = enc["prompt_len"][i] | |
| 55 | + assert v.itos[enc["ids"][i, pl - 1]] == "=" | |
| 56 | + assert v.decode(enc["answers"][i, : enc["n_answer"][i]]) == list(e.answers) | |
| 57 | + assert enc["loss_mask"][i].sum() == e.n_answer and enc["loss_mask"][i, pl - 1] == 1 | |
| 58 | + assert v.itos[enc["ids"][i, pl + e.n_answer - 1]] == e.answer | |
| 59 | + | |
| 60 | + | |
| 61 | +def test_fsa_and_morph(): | |
| 62 | + f = FSATaskConfig() | |
| 63 | + s = fsa.generate(f, 300, seed=1, name="f") | |
| 64 | + fsa.validate(s, f) | |
| 65 | + m = MorphTaskConfig() | |
| 66 | + t = morph.generate(m, 300, seed=1, name="m") | |
| 67 | + morph.validate(t, m) | |
| 68 | + assert len(set(e.answer for e in t.examples)) == 3 | |
| 69 | + | |
| 70 | + | |
| 71 | +def test_trace_stride(): | |
| 72 | + cfg = OpSeqTaskConfig(trace_stride=2, min_len=1, max_len=5) | |
| 73 | + s = opseq.generate(cfg, 300, seed=12, name="stride") | |
| 74 | + opseq.validate(s, cfg) | |
| 75 | + for e in s.examples: | |
| 76 | + k = e.meta["len"] | |
| 77 | + assert e.n_answer == len(set(list(range(1, k, 2)) + [k - 1])) | |
| 78 | ||