A visual guide · gradients, Jacobians & one clever average

The Jacobian Lens
or: how to read a model’s inner monologue

Anthropic’s Global Workspace paper rests on a single mathematical move — differentiate the rest of the network, then average. This walkthrough rebuilds that move from first principles, at 3blue1brown pace.

after: Gurnee, Sofroniew, … Lindsey — “Verbalizable Representations Form a Global Workspace in Language Models”, Transformer Circuits, July 2026
written & built by Claude (Fable 5), with Clément Dumas
activations h transport maps J token directions v output changes
Part I

What is a layer thinking?

A transformer processes text as a sequence of token positions, and at each position it maintains one vector — the residual stream. Call it hℓ,t: the state at layer , position t, living in d with d in the thousands. Every layer reads this vector, computes something, and adds its contribution back in. By the final layer L, the stream has been shaped into something the model can act on directly: multiply by the unembedding matrix WU, apply a softmax, and you get the probability of every token in the vocabulary being the next word.

So the last layer is easy to read — it comes with its own decoder. The question is everything in between. Take the prompt the paper uses:

“The number of legs on the animal that spins webs is ___”

To answer 8, the model must first work out an unspoken intermediate: spider. That thought, if it exists, is somewhere in the residual stream around the middle layers — a direction in a d-dimensional vector that doesn’t come with labels. How do you find it?

The obvious trick, and where it breaks

The logit lens says: just pretend you’re already at the end. Take the middle-layer state h and push it straight through the final decoder:

logit-lens(h) = softmax(WU · norm(h))

This works surprisingly well in the last stretch of the network — the residual stream is additive, so late states are already close to the final one. But in early and middle layers it produces noise. The reason is subtle and important: the model’s internal coordinate system drifts across layers. The direction that means spider at layer 30 need not be the direction that means spider at the output. The logit lens assumes the two coordinate systems are identical — that the transport from layer to layer L is the identity map. Mostly, it isn’t.

The Jacobian lens is the principled correction. Instead of assuming a transport map, it measures one: for each layer, the average linear map describing how small changes at layer actually end up affecting the final layer, over a thousand different contexts. “How changes propagate” is exactly what derivatives describe — so that measured map is a Jacobian.

…the animal …spins webs is h₀ h₂₅ h₅₀ h₇₅ h₁₀₀ each layer adds Δ: h ← h + Δ(h) logit lens: assume J = I J₅₀ J-lens: measured transport W_U unembed spider ▮▮▮▮▮ web ▮▮▮ silk ▮▮ insect ▮ reading an intermediate activation, two ways
Two readouts of the same mid-layer state. The logit lens (dashed) shoves h₅₀ directly into the decoder, assuming layer-50 coordinates match final-layer coordinates. The Jacobian lens first applies J₅₀ — the measured average transport from layer 50 to the end — and only then decodes. Layer indices are rescaled 0–100, as in the paper.

To build J properly, we need the machinery of derivatives in high dimensions to be fresh. That’s Part II — and it’s where we take our time.

Part II

Derivatives, rebuilt

Forget the rules of differentiation for a moment. There is exactly one idea underneath all of it:

A derivative is the best linear stand-in for a function, near a point.

II.1 · One dimension: zoom in until it’s a line

Take a smooth function f and a point x. “Differentiable at x” means: if you zoom in on the graph around (x, f(x)), the curve becomes indistinguishable from a straight line. The slope of that line is f′(x), and the statement

f(x + ε) = f(x) + f′(x) ε + O(ε2)

is a promise about the error: the gap between curve and line dies quadratically as the nudge ε shrinks. Halve the window, quarter the error. That quadratic decay is the entire licence for everything that follows — it’s what lets us replace a horrendously complicated function (say, sixty transformer layers) by a linear map and trust the answer for small perturbations.

Interactive · linearizationdrag the point, then zoom
The curve and its tangent. “worst gap in view” is the largest vertical distance between them on screen: watch it collapse ∝ (window width)² as you zoom. That is what differentiable means.

II.2 · Many inputs, one output: the gradient

Now let f : ℝn → ℝ — many inputs, one output. A “nudge” is now a vector ε ∈ ℝn, and the best linear stand-in must eat a vector and return a number. Linear maps from ℝn to ℝ are exactly dot products with some fixed vector — and that vector is the gradient:

f(x + ε) ≈ f(x) + ⟨∇f(x), ε⟩, f = fx1fxn

Each partial derivative ∂f/∂xj answers one narrow question: if I nudge only coordinate j, at what rate does the output move? The gradient is the full list of these exchange rates, and the dot product ⟨∇f, ε⟩ combines them: a nudge in a general direction moves the output by the sum of its per-coordinate contributions. (That sum-of-contributions structure is linearity — it’s only true because we zoomed in.)

II.3 · Many inputs, many outputs: the Jacobian

Finally, F : ℝn → ℝm — the case we actually need, since a chunk of transformer maps a d-dimensional state to a d-dimensional state. Now the output is a vector, so we need one gradient per output coordinate. Stack those m gradients as rows and you get the Jacobian matrix:

F(x + ε) ≈ F(x) + J(x)ε, Jij = Fixj

Two ways to read this matrix, both worth having in your head:

Geometrically: a smooth map warps space, and the Jacobian at a point is the matrix that the warp looks like locally, at that point. Zoom in anywhere on a smooth map, and what you see is a plain linear transformation — a little square gets carried to a little parallelogram. Different point, different matrix.

Interactive · the Jacobian as a local matrixdrag the point on the left · shrink the square
Left: input space, a point p, and a square of nudges around it (basis nudges in green and red). Right: the whole grid pushed through a nonlinear map F. The curved red outline is the true image of the square; the green parallelogram is what the Jacobian J(p) predicts. Shrink the square: the two agree, quadratically. The matrix below updates live — its columns are the images of the two basis nudges.

II.4 · The chain rule is matrix multiplication

Compose two maps and the local pictures compose too: a nudge gets hit by the first Jacobian, and the result gets hit by the second.

Jgf(x) = Jg(f(x)) · Jf(x)

This is the whole chain rule. For a transformer it means: the end-to-end Jacobian from layer to layer L is the product of every per-layer Jacobian in between — one enormous, prompt-dependent matrix product. Nobody forms that product explicitly. Which brings us to the last piece of machinery.

How autodiff actually gets you a Jacobian

Backprop never builds J. A single backward pass computes a vector–Jacobian product: you choose a covector u at the output, and reverse-mode autodiff hands you uJ — one row-combination of the Jacobian — for the cost of roughly one forward pass. Seed u = ei (a one-hot at output coordinate i) and you get row i exactly. Want the full d×d matrix? Run d backward passes, one per row (batched in practice).

And here is reverse mode’s superpower, the reason this whole method is affordable: one backward pass produces that row with respect to every intermediate activation at once — every layer, every position. Seed the output once, and gradients rain down on the entire network. The paper exploits this: each backward pass contributes one row to J for all layers ℓ simultaneously.

Part III

Building the lens

III.1 · The function being differentiated

Fix a prompt and run the model. Pick a layer and a position t. The “rest of the network” is now a concrete function: it takes the residual state hℓ,t and (holding everything else about the run fixed) produces the final-layer states hL,t′ at that position and every later one — later positions see hℓ,t through attention. Its Jacobian,

hL,t′hℓ,t d×d,

answers: to first order, how would a small change to this activation shift what the model is about to compute — here, and at every future position? That is precisely the “causal effect” language we wanted. But a Jacobian from one prompt conflates two things: the model’s general convention for how layer- directions eventually reach the output, and the particular use this one context happens to make of them. On this prompt, nudging toward spider also nudges toward 8 — not because that’s what the direction means, but because of what this context does with it.

III.2 · The clever average

The fix is to average the Jacobian over source positions t, over target positions t′t, and over a corpus of a thousand pretraining-like prompts:

J = 𝔼t, t′t, prompt [ hL,t′hℓ,t ]

Think about what survives this average. The context-specific pathways — the ones that route spider to 8 on this prompt but to Charlotte’s Web on another — point in different directions on different prompts, and they wash out. What remains is the transport that is consistent across contexts: the model’s stable, reusable convention for how a layer- direction gets turned into words. The paper’s term for representations picked out this way is verbalizable — poised to be said in many possible futures, rather than said in this one.

same nudge ε at layer ℓ rest of network, per prompt J⁽¹⁾ε (prompt 1) J⁽²⁾ε (prompt 2) J⁽³⁾ε (prompt 3) 𝔼[J] ε — the part they agree on why average: circumstance cancels, convention survives
One nudge, many prompts. Each context propagates the same layer- nudge to a different final-layer effect (red). Averaging keeps only the component those effects share (green): the context-independent way this direction tends to reach the model’s output.

The result is one d × d matrix per layer — computed once, offline. (The paper probes 25 evenly spaced layers, re-indexed 0–100 so layer numbers read as percentages of depth.)

III.3 · Reading through the lens

To read an activation, transport it to final-layer coordinates with J, then decode with the model’s own unembedding pipeline:

lens(h) = softmax(WU · norm(J h))

That’s a score for every token in the vocabulary; sort them and the top of the list is a human-readable description of what the activation is disposed to make the model say. Now the key structural object: because everything before the softmax is linear (up to a normalization), the score of token w is essentially an inner product,

score(w) ≈ ⟨vw, h⟩, vw = row w of (WU J)
“≈” because the norm() in between contributes a data-dependent scale factor.

These rows vw are the J-lens vectors: one direction in residual-stream space per vocabulary token, per layer. They are the paper’s central objects — usable three ways:

And notice the logit lens is the degenerate special case J = I. The two agree in the last few layers — where residual accumulation makes the transport genuinely close to identity — and diverge earlier, exactly where the logit lens stops working.

Fine print · a linearization used beyond its warranty

Strictly, a Jacobian only speaks about infinitesimal nudges around a point. The lens applies J to the whole activation h — treating it as a bundle of perturbations and asking what they would push the outputs toward, on average. That step is not licensed by calculus; it’s a modeling bet. Two things make it reasonable: under the superposition picture, activations really do behave like sparse sums of feature directions, so “a sum of nudges” is not a crazy description of h; and the bet is cashed out empirically — the causal experiments (swaps, ablations) show these directions carry the weight they’re claimed to. It is worth keeping this honest asterisk in mind whenever you see a lens readout.

And no centering, either. The reference implementation applies J to the raw residual — transport(h) = J_ℓ @ h, no mean subtraction anywhere — so the implicit baseline is h = 0: read Jh as “the average first-order effect of having this activation at all, versus nothing.” Why is any fixed baseline acceptable? Expand around an arbitrary reference h₀:  g(h) ≈ g(h₀) + J(hh₀). Every h₀-dependent piece is a constant — the same logit offset for every prompt, position, and context at a given layer. Centering by the corpus mean would subtract Jμ from all readouts equally; everything that varies with h, which is everything the lens is used for, is unchanged. The tuned-lens comparison makes the point vividly: the paper finds that in early layers the tuned lens’s advantage comes entirely from its learned bias term — an affine constant that predicts well while ignoring the input. The J-lens is deliberately bias-free: whatever it reports is a property of this activation, not of the average context. (One more subtlety: J is not the Jacobian at zero — it’s the average of local Jacobians evaluated at real activations. Applied to a finite h, it acts less like a pointwise derivative and more like a global regression slope; the Stein’s-lemma connection below makes that intuition precise, and note that Stein’s right-hand side is mean-centered — the centering you might expect is baked into what the averaged Jacobian is, since derivatives are blind to constant shifts.)

III.4 · The recipe, concretely

Here is the actual computation, condensed from the paper’s appendix. The elegant tricks are worth spelling out:

# One-time cost per model: build J_ℓ for every probed layer ℓ.
for prompt in corpus:                      # 1,000 seqs × 128 tokens
    forward pass; cache h_ℓ[t] for all ℓ, t
    for i in 1..d_model:                    # batched in practice
        seed gradient e_i at every position of the target layer z
        backward pass                       # one VJP → reaches all ℓ, all t at once
        for each layer ℓ:
            row i of J_ℓ⁽ᵖ⁾ = mean over t of ∂(Σ_t′ z[t′,i]) / ∂h_ℓ[t]
J_ℓ = mean over prompts of J_ℓ⁽ᵖ⁾            # per-element mean (or median)

# Ever after, reading any activation is one matrix multiply:
lens(h) = softmax( W_U · norm( J_ℓ · h ) )

Design choices they ablate, all with modest effects: differentiate to the penultimate layer rather than the final one (the last block is output-calibration machinery, and adds noise); optionally stop-grad through queries and keys, freezing attention patterns so gradients flow only through the value pathway — isolating “what gets moved” from “what gets attended to” (this slightly strengthens causal effects); and restricting targets to t′ = t only (closer in spirit to the logit lens) or t′ > t only (isolating what a position broadcasts to its future).

III.5 · Placing the J-lens among its relatives

Logit lensTuned lensJacobian lens
transport ℓ → Lassumed: identityfitted: regression onto final outputsmeasured: averaged causal Jacobian
naturestructural shortcutcorrelationalcausal, first-order
early / mid layersuninterpretablereadable, but “skips ahead” to the eventual output, papering over intermediate thoughtsreadable; surfaces unspoken intermediates
setup costnonea training rund×1,000 backprops, once

The tuned-lens comparison is the conceptually sharp one. Both fit a per-layer linear map — but the tuned lens is trained to predict the model’s output distribution, so on prompts with hidden intermediate reasoning it happily reports the conclusion (8) rather than the thought (spider). The J-lens map is built from causal derivatives, not output correlations, so intermediate content survives.

For the curious · a probe-flavored cousin, via Stein’s lemma

The appendix draws a lovely connection. Stein’s lemma says that for Gaussian x and differentiable g:  𝔼[∇g(x)] = Σ−1𝔼[g(x)(xμ)]. Take x to be residual activations and g the probability of saying word w: the left side is (approximately) the J-lens vector for w — an averaged gradient — and the right side is a whitened class-mean difference, i.e. a linear-discriminant probe direction. Averaged gradients ≈ whitened mean-difference probes. The paper uses this to build a “template lens” for multi-token words (photosynthesis, blackmail): prompt-generate contexts where w is the natural next word, average activations, whiten. Assumptions don’t hold exactly (activations aren’t Gaussian), but it motivates why the construction behaves J-lens-like.

Part IV

From lens to space

IV.1 · Too many vectors to be a basis

At each layer we now hold one direction vw per vocabulary token: nvocab vectors in d-dimensional space, with nvocabd (think ~10⁵ vectors in ~10⁴ dimensions). Such a family is wildly overcomplete: it spans everything, many times over. So the interesting object can’t be “the subspace they span” — that’s all of ℝd, and any activation whatsoever could be written as a combination of J-lens vectors. As a set of directions with more members than dimensions, this is what linear algebra calls a frame, not a basis — and decompositions against a frame are never unique.

What rescues the concept is an empirical fact: at any given moment, only a couple dozen J-lens vectors are meaningfully active in a real activation. Sparsity, not span, is the defining constraint.

IV.2 · A union of cones

So the paper defines the J-space as everything you can build from few lens vectors, with nonnegative weights. Fix a sparsity budget k (typically ≈ 25). For each choice of k tokens S, the nonnegative combinations of their vectors form a k-dimensional cone; the J-space is the union over all choices:

𝓕 = |S|=k { ΣiS aivi : ai ≥ 0 }

Not a subspace — a union of low-dimensional wedges threading through activation space, one wedge per possible “set of ~25 concurrent thoughts.” Given any activation x, its J-space component is the nearest point of 𝓕:

d𝓕(x) = miny∈𝓕xy‖, x = Πx + residual

Finding that nearest point exactly would mean searching over all (nk) cones — hopeless — so in practice it’s approximated greedily by gradient pursuit: pick vectors one at a time, each time choosing the one that most reduces the reconstruction error, until k are chosen. The chosen tokens are a discrete inventory of “what’s in the workspace right now,” and the coefficients ai are its local coordinates. (Sparse decomposition typically yields a less redundant inventory than naïvely taking the top-k inner products, because the lens vectors are far from orthogonal — spider and spiders shouldn’t both get full credit.)

v_web v_spider v_silk v_legs v_eight v_ant v_six v_insect cone{v_spider, v_silk} cone{v_ant, v_six} x — an activation Πx
The J-space: a union of sparse cones (cartoon, k = 2). Yellow rays are J-lens token directions; each shaded wedge is the cone of nonnegative combinations of one pair of them — two out of the enormous number of cones whose union makes up the J-space. An activation x generally lies off every cone. Its J-space component Πx is the nearest point of the union (in this 2-D cartoon it lands on a single ray — a 1-sparse combination), and the dashed gap x − Πx is the residual, which typically carries >90% of the vector. In the real model: k ≈ 25 in ~10⁴ dimensions, chosen from ~10⁵ directions.

IV.3 · Small in variance, large in consequence

Now the fact that makes all of this more than bookkeeping. Decompose real activations, or concept vectors extracted independently of the lens, and the J-space component is tiny: never more than ~10% of the variance, a 6–7% median for concept vectors. Over 90% of what a representation “is,” by energy, lies outside the J-space.

Yet in the paper’s causal experiments, that sliver does nearly all the talking. In the think-of-a-word swap experiments, intervening along a concept’s J-space component drives the target into the model’s top outputs on 59% of trials (pure J-lens vectors: 88%) — while the other 93% of the vector, swapped at matched magnitude, succeeds 5% of the time. Same story for internal reasoning through unspoken intermediates (61% vs 28%, the latter collapsing to 6% once you clamp the J-space so the concept can’t re-enter it). The J-space is a low-variance, high-leverage channel — which is exactly the shape you’d expect of a workspace: a small bulletin board that many circuits read, sitting atop a much larger volume of automatic machinery that never gets posted.

For the curious · comparing two candidate workspaces

Because a union-of-cones isn’t a subspace, the appendix defines geometry for it via distance functions: two candidate spaces 𝓕, 𝓖 are compared by how differently they approximate real activations, Δμ(𝓕,𝓖) = 𝔼x∼μ[(d𝓕(x) − d𝓖(x))²]1/2, with a one-sided variant for containment. The payoff: “grow the vocabulary with multi-token phrases” provably yields a strictly larger J-space, and limits of such enlargements are well-defined — a foundation for treating the J-lens as an approximation to some intrinsic workspace, rather than the thing itself.

Part V

Writing into the workspace

Reading is half the story. The lens vectors are directions in activation space, so they’re also handles you can push on.

V.1 · Steering and ablation

hh + αvw

Positive α injects a concept (this is how the paper implants “thoughts” and tests whether the model can introspectively detect them). Negative α, or projecting the component out entirely, suppresses one. Ablating the top-k J-space contents wholesale is how the paper shows the model can still parse and speak fluently without its workspace — while losing much of its capacity for deliberate internal reasoning.

V.2 · The surgical swap, and why it needs a pseudoinverse

The sharpest intervention exchanges one thought for another — spider out, ant in — while disturbing nothing else. The subtlety: J-lens vectors are not orthogonal. You cannot just read the coefficient of vspider with a dot product, because vspider overlaps vweb, vinsect, and thousands of others. Reading coordinates against a non-orthogonal pair takes a dual basis — and that is exactly what the Moore–Penrose pseudoinverse supplies.

Stack the two lens vectors as columns of V = [vs vt] ∈ ℝd×2. The pseudoinverse V = (VV)−1V solves the least-squares problem: c = Vh is the coefficient pair minimizing ‖hVc‖, which splits the activation cleanly as

h = Vc + r, r ⊥ span{vs, vt}

— the in-plane part, expressed in the skewed coordinates of the two concepts, plus an orthogonal remainder r carrying everything else the activation encodes. Now swap the two coordinates with the permutation σ(c1, c2) = (c2, c1) and write back only the difference:

hpatched = h + V(σ(c) − c)  =  Vσ(c) + r

Whatever weight sat on spider now sits on ant, and vice versa; the remainder r — untouched — still says “animal question, counting legs, mid-sentence.” The rows of V are the dual vectors s, t satisfying ⟨i, vj⟩ = δij: each one reads “its” coordinate while being blind to the other.

Interactive · coordinates in a skewed framedrag h · then swap
The plane shown is span{v_s, v_t} — a 2-D slice of activation space. The skewed gridlines are the frame coordinates that V reads; the dashed parallelogram decomposes h into c_s v_s + c_t v_t. Swapping sends h ↦ h′ = c_t v_s + c_s v_t. In the real model, the (d−2)-dimensional orthogonal remainder rides along unchanged.

V.3 · What the swap revealed

This one operation, applied at the workspace layers, carries a remarkable share of the paper’s results:

Coda

The whole method on one page

Differentiate the rest of the network; average the Jacobian over a thousand contexts; compose with the unembedding. The rows of the result are one direction per word the model could ever say — reading them ranks the model’s unspoken vocabulary; sparse-decomposing against them inventories a small “workspace” carrying <10% of activation variance; and steering or swapping them rewrites reports, plans, and multi-step inferences. Everything else in the paper — verbal report, directed modulation (“concentrate on citrus fruits”), internal reasoning, flexible generalization, selectivity — is this one mathematical object, interrogated five different ways.

Two structural facts to carry with you: the workspace has a band — readouts are noise for roughly the first third of layers, coherent through the middle, then collapse to next-token “motor” content in the last few — and it has a capacity, those ~25 meaningfully active directions. Small, late-ish, low-variance, causally decisive.

If you want to go deeper: the paper itself (Methods, plus appendices on methodological ablations, the sparse-frame formalization, and multi-token extensions), and J-lens readouts on open-source models are browsable on Neuronpedia.