webLTM / README.md
VishalMysore's picture
Upload folder using huggingface_hub
9ca138b verified
|
Raw History Blame Contribute Delete
4.05 kB
---
license: mit
tags:
- recurrent-depth
- looped-transformer
- latent-reasoning
- pytorch
- from-scratch
language: en
library_name: pytorch
---
# webLTM β€” a 153K-parameter recurrent-depth transformer
Answers addition problems by looping a single transformer block over its
own latent state `r` times, then reading out every output digit at once.
There is no chain-of-thought text channel in this architecture β€” nothing
that happens inside the loop is ever decoded into a token. `r` is supplied
at inference time, not fixed by training, so one checkpoint answers at any
thinking depth.
This is a small, fully open, from-scratch build of the mechanism behind
what OpenAI called "opaque recurrence" in Astra (Sept 2026) and behind the
recurrent-depth / looped-transformer line of research β€” most directly
Geiping et al., ["Scaling up Test-Time Compute with Latent Reasoning: A
Recurrent Depth Approach"](https://arxiv.org/abs/2502.05171) (arXiv:2502.05171),
whose random-recurrence-depth training trick this model uses.
**Code + browser demo + full write-up:** see the `webLTM` GitHub repo
(train.py, eval scripts, and a live in-browser demo with an interactive
thinking-depth slider).
## Architecture
```
tokens β†’ embed β†’ prelude (1Γ—) β†’ core (Γ—r, looped) β†’ coda (1Γ—) β†’ head β†’ digits
β–² β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”˜ prelude output re-injected every iteration
```
- `prelude`, `core`, `coda` are pre-LN transformer blocks (multi-head
attention + GELU MLP). `core` is applied `r` times with the prelude's
output re-injected at every step (`h = core(h + e0)`), which keeps the
latent state from drifting as `r` grows.
- `d_model=64`, 4 heads, 152,909 parameters total, 615KB in `float32`
safetensors.
- Task: 5-digit + 5-digit addition, all output digits predicted
**simultaneously** (non-autoregressive) β€” no scratchpad, no per-token
decode loop.
- Trained with `r` sampled uniformly from `[1, 8]` on every step, so the
weights aren't specialized to one fixed depth.
## Usage
```python
# pip install torch safetensors
from modeling_webltm import load_webltm, tokenize, decode
model, cfg = load_webltm("model.safetensors", "config.json")
ids = tokenize(cfg, 4821, 367)
import torch
with torch.no_grad():
logits = model(torch.tensor([ids]), r=8) # r = thinking depth
digits = logits.argmax(-1)[0, cfg["ans_start"]:].tolist()
print(decode(cfg, digits)) # -> "005188"
```
`modeling_webltm.py` (included in this repo) is the entire model
definition β€” no `trust_remote_code` framework dependency, just plain
`torch.nn`.
## Results: accuracy by loop depth and problem difficulty
Exact-match accuracy, evaluated on held-out problems (300 per cell):
| digits | r=1 | r=2 | r=4 | r=8 (max trained) | r=16 | r=24 |
|---|---|---|---|---|---|---|
| 1 | 100% | 100% | 100% | 100% | 97% | 74% |
| 2 | 85% | 92% | 93% | 92% | 79% | 62% |
| 3 | 75% | 81% | 84% | 82% | 67% | 51% |
| 4 | 63% | 67% | 69% | 70% | 55% | 29% |
| 5 | 56% | 59% | 62% | 61% | 45% | 26% |
Harder (more-digit) problems keep improving with more loops through the
trained range; pushed well past it (r=16, r=24) accuracy collapses β€” the
re-injection trick stabilizes the recurrence within the trained range, it
doesn't make the coda's read-out valid for latent states it never saw
during training. That ceiling is disclosed here deliberately, not hidden.
## Scope
Not a reproduction of OpenAI's Astra β€” Astra is an undisclosed,
frontier-scale system, and the actual controversy around it is about
chain-of-thought monitorability disappearing at a scale where a lot could
go wrong unseen. This is 153K parameters doing arithmetic, built at a
scale small enough to read every line of the loop β€” the opposite move
from "opaque," on purpose.
## Files
- `model.safetensors` β€” trained weights (float32, no pickle)
- `config.json` β€” architecture + tokenizer config
- `modeling_webltm.py` β€” full model definition (copy-paste runnable)