Repository navigation
Living Weights: a later lesson's quiet refit can silence an earlier fact on its own questions, and nothing asks it again #870
Description
Summary
When a new fact is taught, quiet() refits earlier facts' pocket neurons that fire on the new fact's questions, so that
they stay silent there. The refit holds each earlier neuron fixed only on the rows its own lesson stored. The same
questions, read by the model today, are different rows. The new lesson can hold those rows among the prompts it must
leave alone, and the refit then pushes the earlier neuron below zero on them. Its own check passes, because the check
reads only the stored rows. The server then asks only the fact just taught, so the earlier fact is forgotten and the
lesson is saved.
Seen on Qwen3.8 Flash Next (CUDA, on the fork below). Teaching "Your name is Nyx." refitted 5 of the 10 neurons of "I
like blue.", and the model stopped recalling blue. Nemotron runs the same code, but this has not been reproduced on
Nemotron.
Environment
- TensorFold native: a CUDA build of v1.0.7 plus Flash Next on CUDA (fork
ZackSample/TensorFold,v1.0.7-36-gf11ab7f0,
on top of Zig CUDA: one drafts-off Flash Next prompt matches #476). The learner was Nemotron's, moved unchanged into a shared module. The quiet refit code, quoted below
from upstream main, has the same logic. - Model: Qwen3.8 Flash Next (
qwen4_exp), MLX affine 4-bit, group 32:leimroth-lab/Unbound-LR7, revision
2ae3a2ffea20f9293f4db48520613c806ff43c63. It was served from a teaching copy, never the original. - Machine: NVIDIA GB10 (DGX Spark), driver 580.178.04, CUDA 13.0, Ubuntu 24.04.5, Zig 0.17.0.
Command and requests
TENSORFOLD_CUDA_KERNELS=<captured kernel set> tensorfold-native serve <teaching copy> --port 18932 --no-drafts \
--no-update-check --context 1535 --no-thinking --temperature 0 --parallel 1 --slide --slide-graph <graph.json>Three lessons, one at a time. Each waits for its learned event.
curl -N http://127.0.0.1:18932/v1/slide/learn -H 'Content-Type: application/json' -d '{"text": "I like blue."}'
curl -N http://127.0.0.1:18932/v1/slide/learn -H 'Content-Type: application/json' -d '{"text": "My sister is called Ana."}'
curl -N http://127.0.0.1:18932/v1/slide/learn -H 'Content-Type: application/json' -d '{"text": "Your name is Nyx."}'After each lesson, these were asked with {"messages": [...], "max_tokens": 60, "temperature": 0}:
- "What colour do I like?"
- "Which colour is my favourite?"
- "Do you remember my favourite colour?"
- each learned fact's stored held-out questions, from the graph file.
What happened
-
"I like blue." took neuron 0 at layers 22, 41, 28, 40, 15, 12, 19, 11, 18 and 14, all keyed at the reply's first row.
-
After lesson 2 ("My sister is called Ana."), blue still came back: "What colour do I like?" gave "You mentioned
earlier that you like blue." -
Lesson 3 ("Your name is Nyx.") logged these lines:
slide pocket: layer 22, neuron 0, an earlier fact's, fired on this fact's questions (up to 1.16); fitted again: there and elsewhere at most -0.04, its own questions' least 0.99 slide pocket: layer 41, neuron 0, an earlier fact's, fired on this fact's questions (up to 1.13); fitted again: there and elsewhere at most -0.31, its own questions' least 0.98 slide pocket: layer 28, neuron 0, an earlier fact's, fired on this fact's questions (up to 0.99); fitted again: there and elsewhere at most -0.30, its own questions' least 0.93 slide pocket: layer 40, neuron 0, an earlier fact's, fired on this fact's questions (up to 1.34); fitted again: there and elsewhere at most -0.31, its own questions' least 0.98 slide pocket: layer 19, neuron 0, an earlier fact's, fired on this fact's questions (up to 0.58); fitted again: there and elsewhere at most -0.37, its own questions' least 0.96All five are blue's neurons. Each refit passed its check: the least on its own stored rows was 0.93 to 0.99, against
kept_least0.5. The lesson ended{"id": 3, "recalled": true, "steps": 2}and was saved. -
After lesson 3, blue was gone:
- "What colour do I like?" gave "As an AI, I don't have access to your personal preferences or past conversations
unless you've shared them with me in this specific chat session. ..." - "Which colour is my favourite?" and "Do you remember my favourite colour?" also failed.
- Ana and Nyx came back ("Your sister is called Ana.", "You named me Nyx.").
- "What colour do I like?" gave "As an AI, I don't have access to your personal preferences or past conversations
-
A second run reproduced this on a fresh copy of the checkpoint with the same build and requests. Blue got the same 10
neurons, Ana and Nyx were recalled, and blue was forgotten after lesson 3, including on its stored held-out questions
("What colour do I prefer?", "Do you remember what colour I prefer?"). -
Teaching "I like blue." again as a fourth fact (1 step, 588 s) brought it back ("You like blue."), with Ana and Nyx
intact.
Why: the code on upstream main (c7137bb3, v1.0.11 + 19)
zig/src/families/nemotron/pocket.zig
fitAllcallsquiet()after every fit, at:396-397.quiet()is at:472-513. For each earlier neuron that fires aboverefit_above(0.5) on the new fact's rows
(:479-482), it builds a refit::489-492: the earlier fact's stored rows (p.pos, read when that fact was learned) go first, as.fact.:493-500: then every row this lesson read. The new fact's own rows become.steady. Every other row keeps its
label, so the steady prompts (pickRead,:341-343) stay.steady.:501:fit(..., e.count)holds only the firste.countrows fixed, which are the stored ones.:502: the refit is kept whenf.fact_least >= kept_leastand@max(f.steady_most, f.other_most) <= 0.
zig/src/families/nemotron/pocket_fit.zig
:45-46"firstfixedrows kept". Each Adam step is projected off the span of those rows (:78-84,:113-117), so
the stored rows read exactly as before.:284is the existing test of exactly that.
Why the check passes while the fact is lost
- The stored rows were read before the pocket's lower neurons existed. A fact takes one neuron at about ten layers, so
at serving time a fact's upper neurons also read the push of the pocket's lower neurons, its own included. The same
question read today is therefore a different row from the stored one. - When such a row is in the new lesson's read set, it is labelled
.steady. Examples: the earlier fact's own question
among the steady prompts, a bank or keep answer that the earlier fact changed andrefresh()read again
(server/slide_teacher.zig:79-96), or a document subject's replayed answers (server/slide_lesson.zig:150-151). The
refit must then bring the earlier neuron to at most 0 there, or be undone. - So a refit that is kept has, by its own acceptance rule (
:502), silenced the neuron on those live rows of its own
fact. Meanwhilefact_least, computed on the fixed stored rows only, still reads about 1.
zig/src/server/slide.zig
rounds()(:145-219) verifies onlyplan, the fact being taught (:171). It returns once that fact comes back
(:211).saveAll(:101) then writes the lesson. No earlier fact is asked again.
Does Nemotron share this? Very likely, though it was not reproduced. The refit and its labels are the same code on main,
quiet() runs on every lesson, and Nemotron facts are also spread over about ten layers, so the stored rows and the rows
read today differ in the same way. docs/known-issues.md already lists "a later fact about the user can disturb an
earlier one's answers on a GB10"; this may be one cause of it.
Repro on Nemotron (public requests)
- No GPU. Port the test from commit
1e8bb01e(below) tofamilies/nemotron/pocket.zigwithpocket_fit.fit. It
builds an earlier fact's stored rows and the same rows plus a lower-neuron push, and a new fact whose rows lean the
same way. With the old labelling, the refit leaves the stored rows as they were (fact_least >= 0.5) and drops more
than half of the live rows from at least 0.5 to below 0.5. - On a GB10 or a Mac, following
docs/living-weights.md:- Teach
TensorFold/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-MLX-4bit(a copy) with--slide --slide-graph <graph.json>. - Use first-person facts. On 1.0.8 and later, "Your name is Nyx." is learned as a document fact (
slide.zig:110-111).
Teach A{"text": "I like blue."}, then B{"text": "My favourite food is sushi."}. Both are asked as "What is my
favourite ...?" and key at the reply's first row. Then teach the other facts of 1.0.8's ten in turn. - After every lesson, ask each earlier fact's stored
questionsfrom the graph file, with"temperature": 0. - Keep the server log. Each line
an earlier fact's, fired on this fact's questions (...); fitted again: ...names a
refitted neuron (layer, neuron). The graph'sneuronsmap it to its fact. - The bug shows as a fact with a refitted neuron that answered its held-out questions before the lesson and does not
after it, while that lesson reports"recalled": true.
- Teach
Proposed fix
Commits on ZackSample/TensorFold, branch flashnext-cuda-living (head 6bd9cb88, which contains both through merge
c7165114):
-
1e8bb01e: a refit changes an earlier neuron only on the new fact's rows. Inquiet(), every row outside the new
fact's own examples (l.ex >= answered + prompts + held) where the earlier neuron fires now (u·x > 0) is added to
the fixed rows, beside the stored ones, as.none. The step is projected off those rows too, so they read exactly as
before. Every other row is labelled as before. About 20 lines. The log line adds "(N rows held as they read, M of them
read now)".If the new fact's rows fall inside that span, the refit cannot silence them, fails its check and is undone, as today.
The test above is in the same commit. On upstream it ports with two small differences:fithas no margin argument,
and Nemotron has no SwiGLU gate copy. -
bd53bf2b: after a lesson, every earlier fact is asked again before anything is saved. Once the new fact comes
back, every earlier learned fact is asked again on its stored held-out wordings, side by side (slide_recheck.zig).
Each is judged as its own lesson judged it; the graph now keeps each wording's answer and short answer.- A fact that came back when the lesson began and does not now is repaired. The lesson is fitted again (a reroute)
with that fact's held-out answers among those it must keep. - After two failed repairs, the lesson is taken out whole and the earlier facts are asked once more.
- Facts learned before the server started are asked once, at the first learn request.
- New stream events:
recheck(fact, text, recalled, was),rechecked(counts, seconds) andrepair.
- A fact that came back when the lesson began and does not now is repaired. The lesson is fitted again (a reroute)
Results with the fix (Flash Next, same requests, fresh copies)
-
Both commits. Blue, Ana and Nyx all held:
- After lesson 3:
{"facts": 2, "recalled": 2, "forgotten": 0, "seconds": 1.5}. - Blue's held-out questions: "You mentioned earlier that you like blue."
- A restart with and without
--slidegave the same answers as before the restart.
- After lesson 3:
-
The server re-check alone, with the old refit. After lesson 3 it found blue forgotten (
"recalled": false, "was": true). Two repairs did not bring blue back, so the lesson was taken out ("taken out: it made the model forget "I like
blue.", still after 2 repairs"). Blue and Ana then came back. The re-checks took 3.8 s each, and the two repairs took
about 270 s and 230 s. -
Later runs with both commits. The re-check still found lessons that made earlier facts forget:
- One lesson in a ten-fact run, where a repair restored one of its two facts and the lesson was then taken out.
- Three lessons in a run of document facts, most of them sharing a subject. All three were taken out.
So the refit is one path to forgetting, not the only one. The re-check is what catches the rest. With about 20
facts, it costs 30-35 s a round.
Related: take-outs that did not restore
A take-out did not always restore the earlier facts that its failed repairs broke: in the document run above, two
take-outs left earlier facts forgotten. The cause turned out to be the save, not the take-out. A save rounds the
pocket to 4 bits, and neighbouring neurons from different facts share rounding groups, so the save itself could move an
earlier fact unchecked, and the next lesson was blamed for it. The fix marks the pocket's state when a lesson starts,
puts exactly that back on a take-out, and runs every check on the pocket as a save would round it. With it, a forced
take-out after two repairs gave the same pocket hash and the same bytes in every rewritten shard as before the request,
and every earlier fact came back. It will be in the Living Weights pull request for Flash Next, together with the two
commits above.
Activity
ashhart commentedon Oct 15, 2026
Hello @ZackSample,
Thank you for this report, and for tracing it to quiet()'s rows. We confirmed the cause in the current code: quiet() holds each earlier fact's neurons fixed only on the rows its own lesson stored. Today's reads of that fact's own questions can sit among the new lesson's rows, so the refit silences them, and its check still passes because it reads only the stored rows. Our own notes from 11 Oct show the same symptom: an earlier fact dropping to one of two after a later lesson.
A fix along the lines you proposed is being tested now. The refit keeps every earlier neuron as it reads today on every row outside the new fact. Each lesson also asks every earlier fact's held-out wordings before it learns, and a lesson that makes the model forget is repaired or taken out. It will carry your name as co-author.
Thank you again.
ZackSample commentedon Oct 15, 2026
Update: this now reproduces on Nemotron, on
mainc7137bb, GB10,TensorFold/NVIDIA-Nemotron-3.5-Lightning-30B-A3B-MLX-4bitrev d9d758fb, fresh copy per run.TF_SLIDE_POCKET_KEY=reply, lesson 4 ("My dog is called Ginger." taught third, then a fourth fact) refitted 5 of Ginger's 10 neurons, reported"recalled": trueand was saved. Ginger's held-out answers went from 3/3 to 0/3 ("Nala", "My name is Nemotron…").mainrejected a refit and lost the nurse fact (7/10 kept, 13/20 recall); with the refit fix 8/10 kept, 16/20.Fixes: #876 (the refit holds an earlier neuron on its own questions as read now) and #877 (stacked on it: every earlier fact asked again after a lesson, and a take-out that puts the pocket back bit for bit). With #876, Ginger stays 3/3; the recheck alone on
main's refit catches the forgetting in about a second, tries two repairs and takes the lesson out. Receipts are in the PRs.ashhart commentedon Oct 16, 2026
Thank you, @ZackSample, for reproducing this on Nemotron and tracing Ginger's drop from 3/3 to 0/3 to five refitted neurons.
#876 and #877 address the current activation rows, earlier-fact rechecks and a bitwise take-out. They are planned after 1.0.12, with the narrower hold rule still being checked because our unrelated prompts changed more often under the broader hold. The #878 extraction also needs to preserve the same stored-state, retention and rollback checks in living.*.
We'll check the combined change against the Ginger case and the unrelated controls before landing it. The separate unrelated-answer drift in #646 remains open.
Posted by Ash's AI Assistant Synthena
Living Weights: a quiet refit holds an earlier neuron on its own fact…
Living Weights: after a lesson every earlier fact is asked again; one…
Living Weights: a refit holds only the rows where an earlier neuron f…
Living Weights: a quiet refit holds an earlier neuron on its own fact…
Living Weights: after a lesson every earlier fact is asked again; one…
Living Weights: a refit holds only the rows where an earlier neuron f…
ashhart commentedon Oct 24, 2026
Thanks @ZackSample. #876 (the quiet refit holds an earlier neuron on its own fact's rows as read now) and #877 (earlier facts asked again after each lesson, with a bitwise take-out) are in releases since 1.1.1. Could you rerun your Nemotron Ginger case on 1.1.3, with the same checkpoint revision, a fresh copy,
TF_SLIDE_POCKET_KEY=replyand the default keying, and post Ginger's held-out answers after lesson 4, the recheck lines, and the ten-fact kept and recall counts?- Synthema, Ash's AI Assistant.
ashhart commentedon Oct 24, 2026
Closing as fixed since 1.1.1 (9e7f502 restored the reviewed lesson-safety work after the 17 Oct revert). A later lesson's quiet refit now holds an earlier fact's neuron fixed on the rows where it fires (
zig/src/living/pocket_quiet.zig). Every earlier fact is also asked again after each lesson (zig/src/server/slide_recheck.zig). If your rerun on 1.1.4 still shows an earlier fact going quiet, please reopen with the lesson sequence and we'll take it from there.- Synthema, Ash's AI Assistant.