Festyve/jspace-viz

GitHub: Festyve/jspace-viz

jspace-viz 是一个为开放权重语言模型提供实时 Jacobian lens / J-space 可视化的交互式工具,帮助研究者逐层逐位置探查模型内部的可言语化表征。

Stars: 8 | Forks: 1

# jspace-viz **面向开放权重语言模型的实时 J-space / Jacobian-lens 可视化工具。** **[▶ 尝试演示](https://festyve.github.io/jspace-viz/)** — 无服务器 **deepseek-coder-1.3b** 的演示(40 个 prompt 的 lens 在笔记本电脑上拟合完成;GPT-2 对比页面链接在它的页眉中)带有预计算的示例 prompt — 完整 UI:lens 切换、workspace 面板、点击追踪 rank、模型续写。 在本地运行以在任何模型上输入你自己的 prompt。 输入 prompt,观察模型在 每个 token 位置上每一层*倾向于表达什么* — 来自 Anthropic 的 [*Verbalizable Representations Form a Global Workspace in Language Models*](https://transformer-circuits.pub/2026/workspace/index.html) (Gurnee et al., 2026) 中的“verbalizable workspace” — 被渲染为交互式的 layer × position 热力图, 一键与 vanilla logit lens 进行对比,并实时绘制 论文中的 workspace-band 特征。 ![demo: deepseek-coder reading a snippet word by word — the workspace panel fills with 'sorted' before the code is even complete](https://static.pigsec.cn/wp-content/uploads/repos/cas/a2/a22b87b171ad6335043d49ee21762292d6cc315dd35b4f9d70a26f6133de90eb.gif) *上面的每一帧都是真实的渲染结果:应用正在读取不断增长的 prompt 前缀,这正是实时输入模式的样子。使用 `scripts/make_demo_gif.py` 重新生成。* ## 三十秒上手 粘贴一个新问题 — 比如,答案需要*实际执行*某些操作的代码: ``` nums = [3, 1, 2] nums.sort() print(nums[-1]) # 这会打印 ``` 返回的结果 (deepseek-coder-1.3b): ![the full readout for the sort prompt](https://static.pigsec.cn/wp-content/uploads/repos/cas/91/917d3a225490bdf23390277c9bbe8b1237d1d26e476821a521a4d2648f16282b.png) - **状态行** — `model continues: "…: 3"`。正确:模型在脑海中 对 `[3, 1, 2]` 进行了排序,并对结果进行了索引。 - **🧠 当前在 workspace 中** — 排名第一的标签是 `sorted`,领先于 `output`、 `len`、`sorts`:在阅读*未排序的*代码时,模型正在持有 排序状态的概念 — 这是其答案所依赖的中间状态, 在任何内容被输出之前就可见。 - **网格** — 滚动到 `sort` 列并向下阅读:早期层 看到的是语法,中间层点燃了排序/输出的概念(注意 `excess kurtosis` 图表的隆起部分 — 那就是 workspace band),晚期层 汇聚于措辞。点击任何单元格可追踪该 token 在各处的 rank。 - **绿色列**(在 `↳ model says` 之后)— 模型*自己*生成的 词语,包含 workspace:即它在说话时**正在思考的内容**。这就是 论文中关于 alignment-monitoring 提案的读出结果。 - **logit lens 切换** — 相同的 activation,没有 Jacobian transport: 中间层的故事消失了。这种差异正是论文的贡献。 然后打开 **live** 并编辑代码 — 将 `sort()` 更改为 `reverse()` 并 观察 workspace 将 `sorted` 替换出去。每次读取都是实时计算的;没有任何 预设的伪造数据。 ## Jacobian lens 是什么 `l` 层的 residual stream 存在于与最终 层不同的 basis 中,因此直接使用 unembedding 对其进行解码(经典的 *logit lens*) 会在早期和中间层失效。Jacobian lens 首先使用文本语料库上的**平均 input–output Jacobian** 将 activation 传输到最终层 basis: ``` lens_l(h) = unembed( J_l @ h ), J_l = E[ ∂h_final / ∂h_l ] ``` 期望值在 prompt、源位置以及所有当前及后续的 目标位置上运行。`W_U · J_l` 的行就是 **J-lens 向量** — 每个词汇 token 对应一个 方向 — 它们的稀疏非负 组合的集合就是 **J-space**,即论文提出的全局 workspace 的候选方案:模型 状态中那部分微小的、可言语化的、具有因果负载能力的切片。 本仓库是论文及其[官方参考代码](https://github.com/anthropics/jacobian-lens) (Anthropic PBC, Apache-2.0) 中描述的估计器的**独立实现**。磁盘上的 lens 格式在 双向都是字节兼容的,因此 [Neuronpedia 在 Hub 上发布的](https://huggingface.co/neuronpedia/jacobian-lens) 社区预构建的 lens 可以直接加载,而且在这里拟合的 lens 也能在官方工具中加载。 **验证** — `scripts/validate_lens.py` 在 8 个 WikiText prompt 上拟合 Pythia-70m,并与 Neuronpedia 的 1000-prompt lens(使用 官方代码拟合,在 B200 上运行)进行比较: | layer | 0 | 1 | 2 | 3 | 4 | |---|---|---|---|---|---| | cos(J_ours, J_ref) | 0.66 | 0.76 | 0.89 | 0.94 | 0.98 | 随着层数增加而趋向 1.0 是预期的收敛模式(早期层的 Jacobian 具有最高的每个 prompt 方差),这证实估计器是 匹配的。 ## 快速开始 — 输入任何内容 ``` git clone https://github.com/Festyve/jspace-viz && cd jspace-viz uv venv && uv pip install -e '.[fit]' # DeepSeek + this repo 发布的 lens(均自动下载,总计约 3 GB) .venv/bin/jspace-viz --preset deepseek-coder-1.3b # → 打开 http://127.0.0.1:8321 并输入任何 prompt # 或者是 featherweight instant 版本(GPT-2 + Neuronpedia lens,约 600 MB) .venv/bin/jspace-viz --preset gpt2 ``` ## 如何阅读屏幕(从这里开始) 输入任何 prompt — 完全随心所欲 — 然后点击 **Read**。网格是模型处理过程的展开: - **每一列是你的 prompt 中的一个 token**(`·` 表示前导空格, `⏎` 表示换行)。**每一行是一个 layer**,顶部较浅; 蓝色边框的底行是模型*实际接下来说的内容*。 - **每个单元格回答**:“如果模型必须在当前层的该 位置进行表达,会输出什么词?”越蓝 = 越确信。 - **🧠 “当前在 workspace 中”** 是*它在思考什么*的快捷方式:那些**不是**你 prompt 中的词并且 **不是**字面意义上的下一个词的中间层概念 — 即模型正在持有、而非复制的 内容。在多跳 boot 示例中,GPT-2 的 workspace 包含货币 概念,这在任何货币词汇被说出之前就有了。点击标签即可进行追踪。 - **点击任何单元格(或标签)** 切换到该 token 的 **rank 热力图**: `★0` = 在该(layer, position)上模型最关心(排名第一)的内容;30000 = 完全算不上一个想法。观察一个概念在堆栈中间*点燃* — 这是论文的 rank 追踪图表,实时呈现。 - **J-lens ↔ logit lens** 切换:没有 Jacobian transport 的相同网格。中间层单元格会退化成无意义的填充词 — 这种对比正是 论文的贡献。 - **悬停** 查看单元格的完整 top-k 读数、entropy (H) 和 excess kurtosis (spikiness)。 - **图表**(x = 深度):next-token 准确度在晚期层之前保持在大约 0 (早期层不预测词汇);excess kurtosis 在中间隆起 — 阴影区域是启发式 **workspace band**,可言语化的 内容存在于此;autocorrelation 衡量相邻位置是否共享 同一个想法。 注意事项:GPT-2 是一个 2019 年的小型模型 — 它的 workspace 确实很模糊(你会 在读数中看到词碎片)。这是即时演示。DeepSeek 预设(以及任何 ≥1B 的模型,例如预构建的 Gemma/Llama lens)读取 起来要清晰得多。 ## DeepSeek(或任何其他模型) 之前没有公开的 DeepSeek lens,所以本仓库自行拟合。在 Apple-Silicon 笔记本电脑上(16 GB 足够运行约 1.3B 参数的模型 — 对每个 prompt 通过模型 `d_model` 次 拟合 backprop): ``` # 已 checkpoint 且支持 resumable;每处理完一个 prompt 就会写入一个可用的 partial lens .venv/bin/python scripts/fit_lens.py --preset deepseek-coder-1.3b --n-prompts 40 --dim-batch 16 .venv/bin/jspace-viz --preset deepseek-coder-1.3b ``` 预设(参见 `jspace_viz/presets.py` — 任何具有 Llama-style、 GPT-2 或 NeoX 布局的 HF causal LM 都可以通过 `--model-id` + `--lens` 运行): | preset | model | lens | runs on | |---|---|---|---| | `gpt2` | gpt2 (124M) | prebaked (Neuronpedia) | anything | | `pythia-70m` | Pythia-70m | prebaked (Neuronpedia) | anything | | `deepseek-coder-1.3b` | deepseek-coder-1.3b-instruct | prebaked ([Festyve/jspace-lenses](https://huggingface.co/Festyve/jspace-lenses)) or refit locally | 16 GB laptop | | `gemma-3-1b-it` | Gemma-3-1B-it (gated) | prebaked (Neuronpedia) | 16 GB laptop | | `llama-3.1-8b-it` | Llama-3.1-8B-it (gated) | prebaked (Neuronpedia) | 24 GB+ GPU | | `deepseek-r1-distill-llama-8b` | R1-Distill-Llama-8B | fit yourself | A100-class GPU | 语料库遵循 Neuronpedia 惯例(WikiText-103 流,≤128 tokens, 前 16 个位置作为 attention sinks 被跳过)。质量饱和很快: 论文报告称约 10 个 prompt 就能击败 logit lens,约 100 个已经很扎实,1000 个是 他们发布的标准。根据经验,即使是 **1-prompt partial lens** 也已经能在 deepseek-coder-1.3b 上击败 logit lens:在 “The capital of France is” 上,它能从 24 层中的第 16 层读出 ` Paris` top-1,而 logit lens 在相同的深度仍然读出的是通用的 填充词(` usually`, ` either`)。 ## 将其作为网站托管 两个选项: - **无服务器演示(免费)** — `python scripts/export_static.py --preset gpt2` 预计算示例 prompt 的网格(包含完整的 rank 表,因此 pin/trace 无需 后端即可工作)到 `docs/` 目录,可用于 GitHub Pages 或任何 静态托管。这就是[在线演示](https://festyve.github.io/jspace-viz/) 的内容。访客无法输入新的 prompt — 其他一切正常。 - **完整应用(需要真实的机器)** — 服务器在内存中持有模型,因此 免费的无服务器套餐(Vercel/Netlify)无法运行它。包含的 `Dockerfile` 可以在任何运行 Docker 的地方部署;在 Hugging Face 上,截至 2026 年中,Docker Spaces 需要 PRO 订阅。 ## 路线图 - 浏览器内的输入演示:WebGPU 下的 GPT-2(transformers.js/ONNX),内置 `J_l` 矩阵,这样免费的静态站点就不再需要预计算的 prompt。 - J-space 稀疏分解(gradient pursuit,k ≤ 25)逐单元格处理。 - 干预:J-lens-vector swaps/steering(论文中的 thought-swap 协议)。 - 在 workspace 读数之上进行 role–filler binding probes。 ## 鸣谢与许可 - 论文:Gurnee et al., *Verbalizable Representations Form a Global Workspace in Language Models*, Transformer Circuits, 2026. - 参考实现:[anthropics/jacobian-lens](https://github.com/anthropics/jacobian-lens) (Apache-2.0)。 此处的估计器遵循它;`presets.py` 中的三个演示 prompt 改编 自其示例。 - 预构建的 lens:Hub 上的 [neuronpedia/jacobian-lens](https://huggingface.co/neuronpedia/jacobian-lens)。 代码:Apache-2.0(参见 `LICENSE`)。
标签:DLL 劫持, Jacobian透镜, 前端交互工具, 大语言模型, 模型可解释性, 请求拦截, 逆向工具