// ============================================================================ // Project : modelmap // File : site/server.js // Purpose : modelmap.io platform — routes and pages (English, light theme) // Author : Simon-Pierre Boucher // Contact : contact@spboucher.ai // Website : https://modelmap.io // Created : 2026-08-12 // Modified : 2026-08-12 // Platform : macOS / Apple Silicon (arm64) — Node.js (deployed on MacLustr) // License : All rights reserved (research code) // ============================================================================ "use strict"; const path = require("path"); const express = require("express"); const C = require("./lib/content"); const R = require("./lib/render"); const Comments = require("./lib/comments"); const Charts = require("./lib/charts"); // ------------------------------------------------------------ chart builders /** Layer-profile charts for a probes atlas entry (real A/B + twin null). */ function probeMapCharts(onlyProp, mapRel) { const m = C.readJson(mapRel || "atlas/qwen3-0.6b-4bit/probes/v1/map.json"); if (!m || !m.properties) return ""; const props = onlyProp ? [onlyProp] : Object.keys(m.properties); return props.map((prop) => { const p = m.properties[prop]; if (!p) return ""; const sel = (rows) => rows.map((r) => r.selectivity_mean); const caption = p.verdict ? `Verdict: ${R.esc(p.verdict)}. Differential (real−twin) claims only; Level 1, ` + "5 seeds, shuffled-label controls inside every probe, token-balanced classes." : "The twin (dashed) matches the trained model — the registered validity gate " + "failed and this map is published as a NEGATIVE result: on these promptsets, probes " + "read the tokenizer + architecture prior, not learned computation. Level 1, 5 seeds, " + "shuffled-label controls inside every probe."; return Charts.layerLineSvg({ title: `${prop} — probe selectivity by layer (trained vs random-init twin)`, yLabel: "selectivity", yMin: 0, yMax: 1, series: [ { label: "trained · set A", color: Charts.S1, values: sel(p.per_layer.A) }, { label: "trained · set B", color: Charts.S2, values: sel(p.per_layer.B) }, { label: "random-init twin", color: Charts.REF, dash: true, ref: true, values: p.twin_null_per_layer_A.map((r) => r.selectivity_mean) }, ], caption, }); }).join(""); } const MAP_V2 = "atlas/qwen3-0.6b-4bit/probes/v2/map.json"; const MAP_INT = "atlas/qwen3-0.6b-4bit/interventions/v1/map.json"; /** Causal direction-erasure BAND map chart (interventions map, run #4 format). */ function interventionsMapCharts(mapRel) { const m = C.readJson(mapRel || MAP_INT); if (!m || !m.per_layer || !m.per_layer.mean) return ""; const all = [...m.per_layer.mean, ...m.per_layer.min, ...m.per_layer.random_direction_damage]; const yMin = Math.floor(Math.min(...all, 0) * 2) / 2 - 0.5; const yMax = Math.ceil(Math.max(...all) * 2) / 2 + 0.5; const band = m.band || {}; return Charts.layerLineSvg({ title: "agreement — causal direction-erasure BAND map (specific damage by layer)", yLabel: "specific margin damage", yMin, yMax, series: [ { label: "mean of 6 fresh sources", color: Charts.S1, values: m.per_layer.mean }, { label: "worst source (min)", color: Charts.S2, values: m.per_layer.min }, { label: "random-direction damage", color: Charts.REF, dash: true, ref: true, values: m.per_layer.random_direction_damage }, ], caption: `The published claim is the BAND (layers ${band.early_layers ? band.early_layers.join("–") : "2–15"}): ` + "erasing the diff-of-means agreement direction at any single early-band layer destroys most of " + "the grammatical margin (baseline " + (m.baseline_margin ? m.baseline_margin.toFixed(2) : "—") + "), replicated across six fresh direction estimates on a fresh behavioral bank (Level 2). " + "The late band is displayed but carries no claim — run #3's per-layer version was refused by " + "the publication gate as estimator-unstable. Anti-correlates with the probes/v2 decodability " + "ranking (survival ledger 0/2): decodability peaks ≠ causal joints.", }); } /** expH charts: warm/cold storage panels + capture-overhead grouped bars. */ function storageChart() { const d = C.expHData(); let html = ""; if (d.warm && d.cold) { const rnd = (rows) => rows.filter((r) => r.op === "random-batch") .map((r) => ({ label: r.format.replace("zarr-", "zarr‑"), value: r.gb_per_s_mean })); html += Charts.barPanelsSvg({ title: "Activation-store random-batch read throughput — the ordering inverts cold", yLabel: "GB/s", unit: "GB/s", panels: [ { title: "warm cache · M5 Max (run #1)", bars: rnd(d.warm) }, { title: "cold cache · M3 Ultra (run #2)", bars: rnd(d.cold) }, ], caption: "Run #2 falsified the registered hypothesis: raw mmap wins warm (memory speed) " + "but collapses cold to page-fault IO (~8–16 KiB, QD 1) while chunked zarr reads 32 MiB " + "blocks. The rule is IO granularity, not the container.", }); } return html; } function captureChart() { const d = C.expHData(); let html = ""; if (d.compute.length) { const key = (c) => `${c.backend}·${c.source}`; const groupsMap = new Map(); for (const c of d.compute) { const ms = 1000 * c.s_per_forward.reduce((a, b) => a + b, 0) / c.s_per_forward.length; if (!groupsMap.has(key(c))) groupsMap.set(key(c), { backend: c.backend, source: c.source, values: {} }); groupsMap.get(key(c)).values[c.mode] = ms; } const label = (g) => g.backend === "torch-mps" ? "torch-MPS (synthetic)" : g.source === "synthetic" ? "MLX (synthetic)" : "MLX (Qwen3-0.6B-4bit)"; html += Charts.groupedBarSvg({ title: "Capture overhead per forward pass — retention is nearly free under MLX", yLabel: "ms / forward", unit: "ms", groups: [...groupsMap.values()].map((g) => ({ label: label(g), values: g.values })), modes: [ { key: "plain", label: "plain", color: Charts.S1 }, { key: "retain", label: "retain", color: Charts.S2 }, { key: "retain+copy+write", label: "retain+copy+write", color: Charts.S3 }, ], caption: "Runs #1 and #3: per-layer retention costs 1.02× (MLX synthetic) and 1.004× " + "(real 4-bit checkpoint) vs 1.22× on torch-MPS; copy+write stays ≤1.5× everywhere. " + "3 repeats per cell; manifests embedded in the raw JSON.", }); } return html; } function expHCharts() { return storageChart() + captureChart(); } const app = express(); const PORT = process.env.PORT || 8140; app.set("trust proxy", true); // behind ngrok — X-Forwarded-For carries the real IP app.use("/static", express.static(path.join(__dirname, "public"), { maxAge: "1h" })); app.use(express.urlencoded({ extended: false, limit: "16kb" })); function page(res, opts) { res.send(R.layout({ ...opts, buildInfo: C.buildInfo() })); } function metaChips(data) { if (!data || !Object.keys(data).length) return ""; const fields = ["document", "author", "created", "modified", "status"]; const chips = fields .filter((f) => data[f]) .map((f) => `${f}${R.esc(data[f])}`) .join(""); return chips ? `
Independent interpretability research · Apple Silicon
Given an already-trained open-weight model, what can actually be known, measured, localized, and mapped about its internal organization — where knowledge lives, how computation is distributed, which structures are stable across inputs, layers, scales, and model families — using only a consumer-grade Mac? Every map published here is versioned, provenanced, confidence-labeled, and regenerable.
what a probe reports ≠ what the model computes ≠ what is stable across methods ≠ what survives intervention
A claim enters the atlas only at the confidence level its evidence supports. Correlational maps and causally-verified maps are never conflated — visually or textually. The two metrics tracked for every map are its replication rate (does it reproduce under resampling of seeds and data?) and its causal confirmation rate (what fraction of localized claims survive intervention?).
${R.confidenceLadder()}Negative results — techniques whose maps do not replicate — are first-class, publishable findings here.
Every figure below is regenerated from committed code + versioned results — raw JSON with hardware manifests under Results. Full per-property maps live in the Atlas.
${causal}${probe2}${probe1}${exph}No log entries yet.
"}${desc}
${ok ? "" : 'not yet written'}`; }) .join(""); const notes = (C.listDir("research/notes") || []) .filter((f) => f.name.endsWith(".md") && f.name !== "README.md") .map((f) => { const md = C.readMarkdown(f.rel); const doc = md && md.data.document ? md.data.document : f.name; return `${R.esc(doc)}
`; }) .join(""); const body = `No literature notes yet — Phase 1 has not started.
'}The project charter itself is public: read the full research charter.
`; page(res, { title: "Research", active: "Research", body }); }); // ---------------------------------------------------------------- markdown viewer app.get(/^\/doc\/(.+)$/, (req, res) => { const rel = req.params[0]; const md = rel.endsWith(".md") ? C.readMarkdown(rel) : null; if (!md) return notFound(res); const body = `Research / ${R.esc(rel)}
${metaChips(md.data)}${R.esc(e.purpose)}
${e.status} ${e.runs ? `${e.runs} result run${e.runs > 1 ? "s" : ""}` : ""}` ) .join(""); const body = `Every experiment carries a registered hypothesis with an explicit falsification criterion (seven-field scientific block), mandatory controls and nulls, raw results, and an analysis. Negative results are kept. Micro-experiments A–H establish the noise floor, the correlational→causal survival rate, and the capture cost frontier before any large model is mapped.
View benchmark implementation (benchmark.py) →
` : ""; let charts = ""; if (exp.id === "expH_capture_cost_frontier") charts = expHCharts(); if (exp.id === "expA_probe_reliability") { charts = probeMapCharts(null, MAP_V2) + probeMapCharts(); } if (exp.id === "expC_causal_verification") charts = interventionsMapCharts(); if (charts) charts = `Experiments / ${R.esc(exp.id)}
${R.esc(exp.purpose)}
${codeLink}${charts}${sections.join("")}${runsHtml}`; page(res, { title: exp.id, active: "Experiments", body }); }); // ---------------------------------------------------------------- atlas app.get("/atlas", (req, res) => { const entries = C.listAtlasEntries(); const byModel = {}; for (const e of entries) (byModel[e.model] ||= []).push(e); const groups = Object.keys(byModel).sort().map((model) => { const cards = byModel[model] .map( (e) => `${e.provenance && e.provenance.created ? "created " + R.esc(e.provenance.created) : ""}
${R.levelBadge(e.level)}` ) .join(""); return `The atlas fills only after the mapping methodology exists (Phase 9) and each map clears its
evidence bar. Every entry will carry a completed provenance.json (commit, config,
model hash, hardware, dates) and a confidence.md stating its evidence level.
Nothing is published that cannot be regenerated from committed code and versioned data.
Versioned map artifacts: atlas/<model>/<map type>/<version>.
Only open-weight models are mapped, and no claim appears here above its evidence level.
${R.highlightFile(JSON.stringify(entry.provenance, null, 2), "provenance.json")}`
: "provenance.json missing — this entry is not publishable.
"; const files = entry.files .map((f) => `Atlas / ${R.esc(entry.rel)}
${R.levelBadge(entry.level)}
${mapCharts ? `Every result is reproducible from commit hash + config + model hash + seed + hardware manifest, and each JSON embeds the manifest of the exact machine that produced it.
| Experiment | Run (UTC) | Files |
|---|---|---|
| No result runs yet. | ||
${R.highlightFile(JSON.stringify(obj, null, 2), "x.json")}`;
} else {
bodyContent = `${R.esc(raw.slice(0, 200000))}`;
}
const body = `Results / ${R.esc(rel)}
The mapping library (src/modelmap/), tooling, benchmark harness, and experiment
implementations. Every file carries the project's author header; MLX / PyTorch-MPS / Metal is the primary compute
path — CUDA is never a core dependency.
Code / ${R.esc(rel)}
${R.highlightFile(raw.slice(0, 400000), name)}modelmap is an independent research project by Simon-Pierre Boucher (contact@spboucher.ai) building a systematic methodology — and the tooling behind it — to discover, measure, and map the internal structure of pretrained open-weight LLMs running locally on consumer Apple Silicon hardware, and publishing the resulting maps as a rigorous, reproducible public atlas on this site.
The ideal outcome is not a gallery of suggestive visualizations. It is a reproducible cartographic standard for open-weight models — every map versioned, provenanced, confidence-labeled, and regenerable by anyone with a Mac — turning “we think the model does X” into “here is the map, its evidence level, and the script that rebuilds it.”
Every mapping technique runs with controls: shuffled labels for probes, random-direction baselines for steering, randomly-initialized-model baselines where meaningful, resample vs zero ablations. Structure is never claimed without showing the null. Replication across ≥3 seeds and ≥2 prompt sets, bootstrap confidence intervals, effect sizes, and multiple-comparison correction are mandatory for every published number.
Apple Silicon Mac (M1–M4 family), 16–64 GB unified memory, internal NVMe SSD, Metal GPU sharing memory with the CPU. Local interpretability on consumer hardware is itself an under-served niche: most tooling assumes CUDA clusters. Making rigorous mapping feasible on a Mac is part of the contribution. The stretch target is a full, causally-verified, versioned atlas of a 7B–14B model produced end-to-end on a single 32–64 GB Mac, comparable across ≥2 quantization levels and ≥2 model sizes.
localvm-research investigates out-of-core LLM execution on the same hardware class — running models larger than memory. The projects cross-pollinate: modelmap's working-set and localization maps (Q5) feed localvm's execution decisions, and localvm's cost measurements calibrate modelmap's capture-feasibility frontier (Experiment H).
Failure is an acceptable outcome — the charter defines explicit failure criteria, and the log records why an approach died, not just what survived.
${R.esc(p.data.abstract ? String(p.data.abstract).slice(0, 300) + "…" : "")}
Read the report →`).join(""); const body = `Official technical reports of this project. Every number is regenerable from the stated commit; figures are rendered live from the same versioned results as the Atlas; negative results and publication-gate refusals are reported with the same prominence as positive findings.
${cards || 'No publications yet.
'}`; page(res, { title: "Publications", active: "Publications", body }); }); app.get("/publications/:id", (req, res) => { const rel = `publications/${req.params.id}.md`; const md = C.readMarkdown(rel); if (!md) return notFound(res); let html = R.markdownToHtml(md.content, rel); html = html.replace(/\{\{fig:([a-z0-9-]+)\}\}<\/p>/g, (_, key) =>
FIGS[key] ? FIGS[key]() : "");
const d = md.data;
const body = ` Publications / ${R.esc(d.pub_id || req.params.id)}${R.esc(d.title || req.params.id)}
${d.abstract ? `${R.esc(String(d.cite))}
No comments yet — be the first.
`; const body = `Questions, critiques, replication reports, pointers to related work — all welcome. Methodological challenges are especially valued: this project publishes its negative results, and a comment that breaks a map is a contribution.
${flash ? `That page does not exist. Back to home.