LatentReasoningNoDecode/BLOG.md at main · Oli-26/LatentReasoningNoDecode · GitHub
//blob/show" data-turbo-transient="true" />
Skip to content
Search or jump to...
Search code, repositories, users, issues, pull requests...
-->
Search
Clear
Search syntax tips
Provide feedback
--><br>We read every piece of feedback, and take your input very seriously.
Include my email address so I can be contacted
Cancel
Submit feedback
Saved searches
Use saved searches to filter your results more quickly
-->
Name
Query
To see all available qualifiers, see our documentation.
Cancel
Create saved search
Sign in
//blob/show;ref_cta:Sign up;ref_loc:header logged out"}"<br>Sign up
Appearance settings
Resetting focus
You signed in with another tab or window. Reload to refresh your session.<br>You signed out in another tab or window. Reload to refresh your session.<br>You switched accounts on another tab or window. Reload to refresh your session.
Dismiss alert
{{ message }}
Oli-26
LatentReasoningNoDecode
Public
Notifications<br>You must be signed in to change notification settings
Fork
Star
FilesExpand file tree
main
/BLOG.md
Copy path
Blame<br>More file actions
Blame<br>More file actions
Latest commit
History<br>History<br>History
58 lines (31 loc) · 7.77 KB
main
/BLOG.md
Copy path
Top
File metadata and controls<br>Preview
Code
Blame
58 lines (31 loc) · 7.77 KB
Raw<br>Copy raw file<br>Download raw file
OutlineEdit and raw actions
I tried to make an LLM think in latent space. The metrics said it worked. The model never read a single thought.
Standard LLM reasoning pays a strange tax. Every step of a chain of thought gets squeezed through the vocabulary: hidden state to logits, sample a token, embed the token, continue. Two lossy projections per step, and the whole trajectory of "thought" is constrained to hop between ~150k discrete points in a continuous space. Papers like Coconut (Meta, 2024) asked the obvious question: what if the model just kept thinking in hidden-state space and only decoded at the end?
I spent a couple of weeks and about 21 GPU-hours on a 12GB laptop GPU testing an aggressive version of this idea, and I want to write up what happened, because the interesting part isn't that it failed. It's how confidently the standard metrics told me it was working while it failed.
The architecture
The setup, on Qwen2.5-1.5B-Instruct: at moments of uncertainty during generation (next-token entropy spike), pause. Take the current hidden state, clone it into K parallel streams, add a different noise vector to each. Let each stream "think" by feeding its final-layer hidden state back in as the next input embedding, N steps, no decoding. Then compress the streams through a bottleneck, inject the result into the context as extra positions, and resume generating.
There's a whole story in the design about parallel subconscious processing and global-workspace bottlenecks, but mechanically that's it: recurrent latent rollouts, noise for diversity, inject, decode.
Day one: the frozen model has nothing to say in latent space
Before any training, I built two diagnostics that turned out to be the most valuable code in the project.
The first was a logit lens over latent states : at every latent step, project each stream's hidden state through the output head and log the top tokens. Not to generate, just to see what region of token space the state occupies.
The result was immediate. At step 0 the states decode to task-flavoured tokens ("Step", "answer", digits). Within 2 to 4 latent steps they drift to junk: whitespace, /router, Array, random CJK fragments. Task-token fraction drops from about 8% to about 1%. The trajectories cover a spectacular amount of hidden-space volume (about 1000x the convex-hull volume of a token-level CoT trajectory in top-5 PCA dims) but the volume is empty. Reach is not meaning.
Worse, the architecture had a built-in uncertainty story: streams disagreeing means the model is uncertain, streams converging means consensus, so use variance as a halt signal. The lens killed that too. Stream agreement does rise as variance falls, but they agree on junk tokens. What looks like consensus is all the streams falling into the same content-free attractor of the frozen recurrent map. If I had shipped variance-convergence as a feature without the lens, I'd have been measuring collapse and calling it agreement.
The training ladder
Fine, nobody expected the frozen model to do this. Coconut needed curriculum training. So: train it.
The second diagnostic mattered here. At every evaluation, I decoded each held-out problem three ways: (a) normally, (b) with the latent states zeroed before injection, (c) with latent states shuffled across problems, so each question gets another question's thoughts. If (a) isn't better than (b) and (c), the latent channel is decorative, whatever the other metrics say.
Then I climbed the ladder. Each rung is a thing that plausibly fixes the previous rung's...