Nara Institute of Science and Technology (NAIST), Japan
Scrub across Pythia's public training checkpoints and watch next-token predictions crystallize from noise into knowledge — layer by layer, with zero backend.
The logit lens is a standard mechanistic interpretability tool for inspecting a Transformer's
predictions across layers. However, existing logit lens tools are limited to analyzing a single trained
model and are not designed for interactive exploration of a model's training history. We
present LensLapse, an open-source web application for interactive exploration of a
model's training history through token-level interpretability. Users can scrub a slider across public
checkpoints from five model families and three multilingual checkpoint suites and observe how per-layer,
per-position logit lens predictions evolve from frequency bias to factual knowledge. Arbitrary user
prompts are probed live in the browser via WebGPU/WASM ONNX inference over per-checkpoint model
pairs. No server, no API key, no hosting cost, and prompts never leave the user's device. Moreover,
LensLapse supports local models. A single pip install easily launches the
application, allowing users to explore their own models and training checkpoints without any additional
web setup. LensLapse is MIT-licensed and permanently hosted at
iamtatsuki05.github.io/lenslapse.
Existing lens tools show one finished model. LensLapse scrubs 38 checkpoints of Pythia-70M (step 0 → 143k) with exact P(token) trajectories — revealing fact acquisition that is visibly non-monotone: learned, lost, and sometimes relearned.
Free-text prompts run via onnxruntime-web (WebGPU, with WASM fallback) or an optional local probe server — one click now probes every checkpoint automatically, so ▶ playback works for anything you type, just like the curated prompts. A static site plus versioned weights on the HF Hub means unlimited concurrent users at zero hosting cost — the demo cannot rot.
pip install then lenslapse server serves the app and the probe API on one
local port. Point it at any HF model or a local Trainer run — no ONNX conversion, no config files. The
recipe is architecture-generic: GPT-NeoX and GPT-2-style LayerNorm models, plus Llama-style,
Mistral-style, and Gemma-style (plus-one-weight) RMSNorm models, all pass the parity check —
shipped for MAP-Neo, Aquila, BLOOM, SmolLM2, Qwen3, OPT, and Gemma 3 alongside Pythia and GPT-2.
A layout the generic heuristic can't reach registers an explicit override in one line, with no
change to the resolver itself.
By construction, lens(hL) equals the model's logits — asserted per checkpoint at export. fp16 weight storage keeps 100% top-1 agreement with fp32 PyTorch on our evaluation suite; dynamic int8 drops to 52%, so we do not ship it.
One click plays the whole time-lapse, cells flashing as their top-1 changes. A top-10 bar race and the classic p-vs-layer profile animate at the pinned cell; an acquisition map shows when each cell first learned its final answer, a diff view shows what changed since any reference checkpoint, and a compare mode renders a second model in lockstep — falling back to a live probe of its own when the compared model has no precomputed match for the prompt.
The core actions have CLI twins — lenslapse probe/trace/models —
and the app can copy the exact CLI or cURL command that reproduces the current view. Track any token
across training, share permalinks, or embed a live grid anywhere with ?embed.
Each checkpoint is exported once into a pair of ONNX graphs: a backbone that returns the pre-layer-norm residual stream after the embedding and every block, and a small lens head (final layer norm + unembedding) applicable to any layer's hidden state. Curated prompts are precomputed with fp32 PyTorch into static JSON shards; a live prompt is tokenized once and then probed against every checkpoint in turn — one forward pass each, pushing every (layer, position) hidden state through the lens head in a single batched matmul — so the same time-lapse playback works for it too. Weights are stored fp16 and cast to fp32 at session load.
Pythia checkpoint (HF Hub, revision step{N})
├─ backbone.f16.onnx input_ids → hidden states [L+1, T, H]
├─ lens.f16.onnx hidden [N, H] → logits [N, V]
└─ precompute → static JSON shards (top-10 per cell + trajectories)
browser (static site, no backend)
├─ precomputed mode: JSON shard → canvas grid + SVG trajectories
└─ live mode: onnxruntime-web (WebGPU → WASM) + transformers.js tokenizer
@misc{okada2026lenslapse,
title = {LensLapse: An In-Browser Logit Lens for Interactive Exploration of Language Model Training Dynamics},
author = {Tatsuki Okada and Yusuke Sakai and Taro Watanabe},
year = {2026},
url = {https://github.com/iamtatsuki05/lenslapse}
}