jlens — read a model's internal draft
rapid-mlx jlens "<prompt>" is a read-only
interpretability command. It reads what a model is disposed to
say at every layer using the Jacobian lens (J-lens),
then reports where the answer crystallizes, how much depth is left
unused, and how far ahead of the plain logit lens it can see —
locally, on your quantized MLX models, with no server and no
telemetry.
jlens is read-only —
it never mutates weights or writes anything but its report.
What this is (and isn't). jlens implements the J-lens readout — a read-only view of what each layer is disposed to say. It does not run the paper's causal experiments (swapping or ablating concepts to prove the workspace is load-bearing), and
workspace signal is a lightweight heuristic of our own,
not a metric from the paper.
What it does
The logit
lens decodes an intermediate residual-stream vector directly
with the unembedding — but at early and middle layers that often
reads as noise, because a layer's activation also matters for
future tokens, not just the next one. The Jacobian lens
corrects for that: for each layer l it estimates the
corpus-averaged transport
J_l = E[ ∂h_final / ∂h_l ]
and decodes unembed(J_l · h) with the model's own
unembedding. Because J_l accounts for an activation's
influence on the final layer, J-lens surfaces intermediate
reasoning steps and concept clusters that the logit lens misses —
and locks onto the answer several layers earlier.
Quick start
$ rapid-mlx jlens "The Eiffel Tower is located in the country of"
No model flag runs the default qwen3-1.7b. First use
pulls the weights (a few GB) after the same confirmation prompt the
other weight-loading commands use; a small model takes roughly
6–8 seconds including load. Output:
rapid-mlx jlens · qwen3-1.7b · 'The Eiffel Tower is located in the country of' model continues → 'France, and it is the' [jvp] 28 layers internal trajectory (J-lens: what the model is disposed to say, by depth) early L 0-6 · 深度 ipples 一步步 回 以上 norm mid L 7-13 · Land 土地 Green 测量 Germany (country deep L14-20 · Greece Albania Spain США Appalach República final L21-27 · France Spain Germany 法国 Belgium French answer 'France': crystallizes at L12/28 (43% depth) → early-exit headroom ~57% J-lens lead over logit lens: +10 layers (logit lens locks at L22) workspace signal 0.83 ########.. (experimental heuristic) mid-layer concept density 95% · J-lens lead 10L
Reading the output
-
internal trajectory — the top J-lens tokens grouped by
depth band. Early layers read as noise; by the middle band
generic scaffolding appears (
country,Land), the deep band narrows to a European-country cluster, and the final band commits toFrance. That mid-band cluster is exactly what the plain logit lens misses. - crystallizes at Lk — the layer where the answer token first takes and holds the lead. early-exit headroom is the fraction of depth after that point — a rough signal of how much of the network this prompt did not need.
- J-lens lead over logit lens — how many layers earlier J-lens reads the answer than the plain logit lens. This is the whole point: earlier, cleaner signal.
-
workspace signal — an experimental heuristic
(0–1) inspired by the paper's global-workspace framing. It partly
reflects answer confidence and is not a validated
capability metric — read it as a hint, not a measurement. The
line beneath it recaps the inputs it leans on:
mid-layer concept density(how much of the middle band carried nameable concepts) and theJ-lens leadfrom above.
Model size changes what you see
The default qwen3-1.7b is sized for a fast first run,
not for showing off the method. On a model that small the
intermediate bands are mostly noise and the J-lens lead is often
+0 — the answer only crystallizes near the output. The
global-workspace structure the method is built to surface is a
property of larger models; it starts to show clearly around
8B.
The same prompt on Llama-3.1-8B — watch the deep band represent the category ('city') before it commits to the instance ('Tokyo'), a genuine intermediate-reasoning trace, with a positive J-lens lead:
rapid-mlx jlens · Meta-Llama-3.1-8B-Instruct-4bit · 'The capital of Japan is' model continues → 'Tokyo. The capital of Japan' internal trajectory (J-lens: what the model is disposed to say, by depth) early L 0-7 · facts columns UGIN relation truths persons mid L 8-15 · worldwide Lv USA FOREIGN International Global deep L16-23 · city cities metropolitan Tokyo Taipei Beijing final L24-31 · Tokyo Seoul Kyoto 東京 Osaka Tok answer 'Tokyo': crystallizes at L18/32 (56% depth) → early-exit headroom ~44% J-lens lead over logit lens: +4 layers (logit lens locks at L22) workspace signal 0.42 ####...... (experimental heuristic) mid-layer concept density 58% · J-lens lead 4L
Two things hold at every size: tight lexical lookups (a chemical
symbol, say) crystallize late with little intermediate structure,
while multi-hop and conceptual prompts show the most; and the
earliest layers read as noise regardless — the workspace lives in
the middle and deep layers. For real interpretability work, reach
for a model of 8B or larger via -m; keep the
1.7B default for a quick look.
Options
| flag | effect |
|---|---|
| -m, --model <alias> | Model to inspect. Default qwen3-1.7b. Accepts any supported alias or a Hugging Face repo. |
| -v, --verbose | Fig-5-style view — full per-layer ranked readouts (J-lens vs logit lens) plus the answer token's rank trajectory across depth (e.g. Tokyo: L0→126720 … L22→0). Default is the concise summary above. |
| --step <n> | Layer stride. Default 2 (probe every 2nd layer); --step 1 reads every layer at full resolution; larger values sample more coarsely. Must be ≥ 1. |
| --json | Emit the same data machine-readably on stdout. The alias-resolution banner is routed to stderr so stdout stays pure JSON. |
How it stays cheap — and works on quantized models
-
No Jacobian is ever materialized.
J_l · his computed with a Jacobian–vector product (forward-mode autodiff), so the fulld×dmatrix never exists in memory. Cost isO(corpus_size)forward passes per layer. -
It differentiates through 4-bit / 8-bit weights. The JVP is
taken with respect to activations — the quantized weights
are constants along the way — so
jlensruns directly on your cached MLX models with no dequantization step. A finite-difference path is used as a fallback where forward-mode autodiff is unavailable.
Supported models
Standard dense decoder transformers — Qwen3, Llama, Phi, and
similar architectures (including decoder blocks that require a
cache argument, e.g. StableLM). Architecture detection
is automatic.
Linear-attention / hybrid models (e.g. Qwen3.5) and the vision towers of VLMs are detected and reported as unsupported rather than crashing — you get a clear message, not a stack trace.
Limitations
- The workspace signal is an experimental heuristic, not a validated capability metric; it partly reflects answer confidence. A rigorous version would calibrate against a J-space ablation on multi-step tasks.
- The phenomenon is scale-dependent. On small models (≈1–2B) the intermediate trajectory is largely noise and the J-lens lead collapses toward zero; meaningful workspace structure emerges around 8B and grows with size — see Model size changes what you see.
- Coverage is dense decoders today; linear-attention / hybrid architectures and VLM vision towers are out of scope and flagged as such.
Where to next
Read the method in Anthropic's
Verbalizable
Representations and Global Workspace in Language Models. For the
rest of the CLI — serve, pull,
launch — see the
engine
README and the HTTP API surface.