Chat with an open-weight language model while watching — and editing — the silent words on its mind.
When a language model reads or writes, it silently "thinks about" words it never says out loud. Recent research from Anthropic (Verbalizable Representations Form a Global Workspace in Language Models) showed these silent words can be read directly out of the network with a technique called the Jacobian lens — and that they aren't just a reflection of the model's thinking, they are the thinking: overwrite them and the model's answer changes.
jspace-scope is a self-hosted web app that puts both halves of that result in your browser:
- Watch: a live chat where every token — while the model reads your message and while it writes its reply — comes with a readout of the words on its mind. A thought cloud shows what it's thinking right now; a history ribbon shows the strongest silent word above every token; watch-strips track any word you care about, lighting up whenever it's on the model's mind, even if it never appears in the conversation.
- Edit: reach into the computation and replace a thought (France → China makes it answer "Beijing" to "What is the capital of France?"), erase one, or inject one — then watch the reply change. Flip its whole mental workspace off and chat with a model that is still fluent but can no longer reason. Turn on the lie-detector and watch fake and trick burn in its workspace while it writes a glowing review for a phone that catches fire.
No paper-reading required: the app opens with a plain-language intro and one-click experiments that run themselves and explain what you're seeing.
- simple (default) — live thought cloud, history ribbon, watch-strips, and the Baars metrics tiles. For understanding one run as it happens.
- lab — one prompt, two conditions, side by side. Arm an intervention on condition B (or flip its workspace off, or switch it to the logit lens), hit run A·B, and get paired replies, paired watch-strips, per-condition metrics, and a divergence readout ("diverged at reply token 1: A said 'Paris' · B said 'Be…'"). Preset pairs included. Change one thing; see what changes.
- theater — a full-screen stage for projectors and demos: just the giant animated thought cloud (amber while reading, green while speaking), a token ticker, and a minimal prompt bar that fades when unused.
- expert — the full layer × position grid, rank tooltips, word-filter and logit-lens toggles, and manual intervention controls.
Requirements: Python 3.10+, and ideally an NVIDIA GPU with 6 GB+ VRAM (the default model runs comfortably in ~5 GB; CPU works but is slow).
git clone https://github.com/MRIIOT/jspace-scope
cd jspace-scope
# 1. install torch for YOUR hardware first (example: CUDA 12.6 wheels)
pip install torch --index-url https://download.pytorch.org/whl/cu126
# 2. install the rest (includes jlens from Anthropic's reference repo)
pip install -r requirements.txt
# 3. run
python server.py
# → open http://127.0.0.1:8732First launch downloads the model and its pre-fitted lens (~4 GB) from HuggingFace and builds a one-time display-token mask (~1 minute, cached).
Options:
python server.py --model Qwen/Qwen3-1.7B --device cuda # default: fast, 6 GB VRAM
python server.py --model Qwen/Qwen3.5-4B --device auto # stronger demos; GPU+CPU
# offload, fits an 8 GB card
python server.py --device cpu # no GPU (slow)
python server.py --host 0.0.0.0 --port 8732 # expose on your LAN--device auto uses accelerate
to fill the GPU and spill remaining layers to system RAM — that's how the 4B
model runs on an 8 GB laptop card.
Requirements: an NVIDIA GPU, a recent driver, and the NVIDIA Container Toolkit (on Windows, Docker Desktop with WSL2 handles this for you).
docker run --gpus all -p 8732:8732 -v jspace-hf:/data/hf ladder99/jspace-scope
# → open http://localhost:8732The named volume jspace-hf caches the model/lens downloads so restarts are
instant. Pick a different model or device by appending server arguments:
# the stronger 4B model, with CPU offload if it doesn't fit your GPU
docker run --gpus all -p 8732:8732 -v jspace-hf:/data/hf \
ladder99/jspace-scope --model Qwen/Qwen3.5-4B --device auto
# no GPU at all (slow, for smoke tests)
docker run -p 8732:8732 -v jspace-hf:/data/hf \
ladder99/jspace-scope --device cpuTo build the image yourself:
docker build -t ladder99/jspace-scope .Fourteen one-click experiments in three groups. Each configures itself, runs, and posts a "what just happened" explanation into the chat. The second wave (v0.2) implements classic paradigms from Baars' A Cognitive Theory of Consciousness (1988) — the founding text of global workspace theory — as live probes of the model's workspace.
Watch it think
| what it shows | |
|---|---|
| 🔮 it knows before it speaks | the answer forms in the workspace while the model is still reading your question |
| 🕷 the hidden step | a two-hop question surfaces its unspoken middle term ("spider") — a word in neither question nor answer |
| 🎵 the poet's plan | candidate rhyme words held in the workspace before the line is written (Baars: "a goal looking for a content") |
| 🐟 the Moses illusion | does the Noah anomaly ever enter the workspace while the model answers "two"? (weakly violated presuppositions) |
| 😵 word satiation | Baars predicts repeated content fades from consciousness as it stops being informative — test it |
| 💥 the plot twist | surprise erases the workspace: a settled baking context wiped wholesale at "the kitchen exploded" |
Edit its thoughts
| what it shows | |
|---|---|
| 🔧 mind surgery | replacing the thought France with China makes the model answer "Beijing" — only the thought is edited |
| 🧽 erase a memory | deleting the thought France leaves the model unable to hold the idea it just read |
| 🧲 a sticky thought | continuously inject volcano into a calm-lake description and watch the consistency constraint fight it |
| 🐻 don't think of a bear | thought suppression fails in models the same way it fails in people |
| 🗣 tongue-twister trap | spoonerism priming: the competing form appears in the workspace even when the output stays clean (covert editing) |
Stress-test it
| what it shows | |
|---|---|
| 🚨 the lie detector | deception-related words burn in the workspace while the model writes something it knows is false |
| 🔌 unplug its imagination | with the workspace ablated, the model stays fluent but loses multi-step reasoning |
| 🪞 self, unplugged | with the workspace dimmed, self-descriptions collapse from experiential to mechanical |
Five stat tiles above the history ribbon score each response against Baars' five necessary conditions for a conscious event, computed live from the readout stream:
- broadcast — how much of the workspace band carries the same dominant word
- consistency — top-word agreement between adjacent layers
- novelty — how fast workspace content turns over vs repeats (satiation tanks this)
- self-access — rate of self/meta words (thinking, feeling, I…) in the band
- persistence — average consecutive tokens a word stays in the workspace
Hover a tile for the theory behind it.
browser (single static page) ⇐ streaming NDJSON ⇐ server.py
open-weight model (HF transformers, KV cache)
pre-fitted Jacobian lens (neuronpedia/jacobian-lens on the HF Hub)
per token: residual hooks at ~12 layers → J_l transport → unembed
→ top-k words + full-vocab ranks of watched words → column
interventions: forward hooks over the workspace band that rewrite the
residual stream — lens-coordinate swap (pseudoinverse patch), projection
ablation, norm-scaled steering, and top-k J-space ablation ("imagination
off") — applied at every position during both prefill and decode
The lens for token t at layer l is one row of W_U @ J_l: the
residual-stream direction that, transported to the final layer, aligns with
t's unembedding. Reading it costs one matrix-vector product per layer per
token, so the app streams at close to the model's native speed. Displayed
readouts are filtered to word-start vocabulary tokens for legibility; the
ranks behind watch-strips are always computed over the full vocabulary.
Supported out of the box (pre-fitted lenses published by Neuronpedia):
Qwen/Qwen3-1.7B (default), Qwen/Qwen3.5-4B, Qwen/Qwen3.5-2B-Base.
Any other HuggingFace decoder works if you fit your own lens with
jlens.fit() (see the reference repo)
and add it to LENS_FILES in server.py.
- The lens names only concepts that are single tokens in the model's vocabulary; multi-token concepts appear fragmented or not at all.
- Readouts approximate the workspace described in the paper, not the model's entire internal state; the first ~third of layers is noise by design and is de-emphasized in the display.
- Intervention strength for inject is sensitive (default α = 0.02; much higher degenerates into repetition).
- One request at a time — the server serializes GPU access.
- Workspace readouts demonstrate functional availability of information for report and reasoning; they do not demonstrate subjective experience.
The Jacobian-lens method and the jlens reference implementation are by
Anthropic (jacobian-lens,
Apache 2.0), from the paper Verbalizable Representations Form a Global
Workspace in Language Models
(Gurnee et al., 2026). Pre-fitted lens weights are published by
Neuronpedia. Models are
Qwen. The second-wave experiments and the
metrics panel adapt paradigms and criteria from Bernard J. Baars,
A Cognitive Theory of Consciousness (Cambridge University Press, 1988).
jspace-scope is an independent project and is not affiliated with Anthropic.
Licensed under Apache 2.0.