Stable Token-by-Token Memory Storage and Retrieval
MemT-1.0 reads accumulated memory during generation, then updates it by scanning the completed interaction token by token with a stability-oriented, symmetrized Gated DeltaNet-2 rule.
What it is
- Memory across turns A changing memory state carries information between interactions. Its learned reading and writing machinery stays fixed during online use; the state starts at zero for a new trajectory.
- Turn-triggered storage Storage processes the completed input and response token by token. Those writes produce the memory for the next turn; they are not interleaved with generating that same response.
- Reading during generation Each generated token can consult the memory accumulated before its turn, alongside ordinary attention. The write rule addresses a specific instability in how old information is erased.
Why it matters
The timing is the key distinction: token-level writing describes a scan inside a turn-level storage procedure, not a write after every generated token. Generation reads the existing state; storage incorporates the completed interaction for later turns.
The short version is that MemT-1.0 gives selected Transformer layers a memory that survives between interactions. Generation consults the memory already accumulated; a separate storage procedure processes the completed input and response to prepare memory for the next turn. “Token-level update” describes how storage scans that interaction, not an alternating generate-one-token, write-one-token loop.
-
Continuity: Suppose a user says, “My preferred airport is SFO,” and later asks for travel advice. The local memory state is a place to carry information from that earlier interaction. It starts empty for a new trajectory, not for every turn. This provides storage machinery, not a guarantee that the airport preference will be retained perfectly.
-
Timing: For that airport conversation, generation reads the state available before the current turn. Once the input and response form a completed interaction, storage processes their token representations in sequence and commits the resulting state for the next turn. I find the distinction between these two clocks essential: writes are token-granular, but storage is turn-triggered.
-
Controlled updates: Writing the airport preference means changing an existing memory, not simply appending an untouched record. Learned projections produce keys and values, while gates control erasure, writing, and forgetting. A symmetrized update addresses a particular way the erase operation can amplify a state instead of reducing it.
So what actually persists? The local state is a bank of key-by-value matrices: think of several association tables, rather than a transcript. The separate learned parameters supply the lookup and editing machinery and stay fixed during online interaction. The notebook analogy helps distinguish changing contents from fixed editing rules, but these contents are numerical mixtures, not readable sentences. How does editing such a mixture avoid damaging it?
The subtlety is that an erase can measure one direction but subtract along another. Imagine trying to remove an airport-related association while unintentionally adding a component elsewhere. Stable Gated DeltaNet-2, or SGDN-2, aligns the directions used by the erase operation. In the isolated erase analysis, the aligned component shrinks while perpendicular components stay unchanged under the stated assumptions. I would not read that as a blanket guarantee about the full memory system: writing still adds information. What does generation do with the resulting state?
At a selected layer, the same pre-attention token representation feeds ordinary attention and a separate memory read. A projected query consults the accumulated state; learned output gating processes the memory result, which is combined with the ordinary attention output. This keeps the backbone attention route rather than replacing it.
For the airport example, the current input remains available through ordinary context processing, while the memory route can supply information carried from earlier turns. The state being queried does not advance after each generated token. After the response, storage scans the completed interaction and prepares the next state. The remaining engineering question is what those additional projections, gates, and state-management steps cost relative to the information they preserve.
Read the deep dive
Why People Wanted It
A long-running assistant needs a way to carry useful information between interactions. Ordinary attention uses the context it receives; an explicit memory state provides another route for retaining and retrieving information across turns.
The problem is not just where to put that information. Updating a numerical memory can destabilize it, and reading memory during generation is a different operation from storing the current interaction. So the real question is: how can the model consult previously accumulated memory while answering, then incorporate the completed interaction without an unstable erase operation?
The timing matters throughout: storage is triggered at the turn level and scans tokens internally; utilization reads memory at the token level during generation. These are separate procedures, not alternating steps in one decoding loop.
The Core Move
MemT-1.0 adds memory blocks to selected Transformer layers: generation reads the turn's accumulated state alongside ordinary attention, while a turn-level storage procedure scans the completed input and response using Stable Gated DeltaNet-2, or SGDN-2.
Let index turns, let be the current input, and let be its response. Storage processes their concatenation , where means concatenation. Suppressing layer and channel indices, its state progression is
Here is the number of tokens in the completed interaction, is a token's pre-attention representation in the storage procedure, and denotes the SGDN-2 update with learned processing parameters . In words: start from the existing state, apply the storage update once per token, and carry the final state into the next turn.
While generating , memory utilization reads , not the intermediate storage states . The response tokens are part of the interaction that storage subsequently incorporates.
Why the State and the Learned Parameters Are Different Things
Now the version for readers who want more of the machinery: the memory that changes between interactions is a tensor state, not an online update to the learned projection weights.
At selected layer , the state has the form
Here counts memory channels, and and are the key and value dimensions. Each channel therefore holds a key-by-value matrix. These states start at zero at the beginning of a new trajectory and evolve across its interactions.
The learned parameters include query, key, and value projections; erase and write gating projections; forget-gate components; and output-gating projections. They are optimized during training and remain fixed during online interaction. A changing matrix state and fixed learned update machinery are different kinds of memory: the former contains online information, while the latter determines how information is processed.
Storage uses the pre-attention representations of the completed interaction. For each channel and token, projections form keys and values, and gating machinery supplies erase, write, and forget controls. The token scan begins from that channel's and ends at . Intermediate scan states belong to storage; they are not successive versions of the state consulted while generating the same response.
That defines what changes and when. Why can the erase part of this update need a stability fix?
Why Symmetrizing the Erase Step Matters
Here is the part that gets technical: the stability issue is a mismatch between the direction used to measure an erase and the direction along which its correction is applied.
In the GDN-2 erase analysis, the measurement uses , where is the erase-gate vector, is the key vector, and denotes elementwise multiplication. The correction acts along . Those directions need not align, making the erase operator non-symmetric.
The symmetrization instead uses
The square root is elementwise. Both sides of the rank-one subtraction now use the same vector , so is symmetric. This is the isolated erase operator, not the complete gated storage update.
To see the consequence, decompose a state vector into a component parallel to and a perpendicular component:
The erase scales the parallel component and leaves the perpendicular component unchanged. With the forget operator set to identity, no write term, and the stated assumption
this map contracts along without expanding perpendicular directions. It is non-expansive in Euclidean norm under those conditions.
Contrast this with the original erase geometry. For a unit vector orthogonal to , a mismatched correction can produce
Orthogonality removes the cross term, giving
A nonzero correction along a nonzero key increases the norm even though the operation is meant to erase. Symmetrization removes this particular coupling between perpendicular directions. It does not establish that arbitrary writes, gates, or complete trajectories can never produce large states.
Once storage has produced a state, how does that state enter the next response?
Why Memory Joins Attention Rather Than Replacing It
Now the deeper architectural point: a read of persistent memory is an additional attention path, not a replacement for the backbone's ordinary attention or an instruction to update memory during decoding.
At a selected layer, both paths receive the pre-attention hidden representation. Ordinary attention runs through the backbone path. The memory path projects a query, reads the turn's current state , and processes the result with learned output gating. Their outputs are combined before subsequent computation.
The backbone's pre-attention, attention, and post-attention operations are preserved. The additional MemoryAttention path makes previously accumulated information available during autoregressive generation.
There are two distinct uses of “parallel” here. Architecturally, memory attention runs alongside ordinary attention. Procedurally, memory utilization and storage have separate jobs. Neither means that a generated token must immediately write a new state that the next generated token reads. Within turn , utilization queries ; storage scans the completed interaction to obtain .
This leaves a practical question: how do you keep those two clocks explicit in an implementation?
Minimal Causal Code
This plain PyTorch control-flow sketch shows one selected layer's memory. The supplied callbacks stand for the backbone operations, gated memory read, and SGDN-2 arithmetic. In particular, sgdn2_step includes the projections and erase, write, and forget operations; this is a timing skeleton, not a numerical implementation of that update.
import torch
@torch.no_grad()
def run_turn(prompt, memory, max_new_tokens, *,
decode_hidden, backbone_attention, memory_attention,
combine, post_attention_and_sample, is_end,
storage_hidden_states, sgdn2_step):
# memory is M_t. Do not modify it during generation.
response = []
for _ in range(max_new_tokens):
prefix = prompt + response
hidden = decode_hidden(prefix)
ordinary = backbone_attention(hidden)
retrieved = memory_attention(hidden, memory)
token = post_attention_and_sample(combine(ordinary, retrieved))
response.append(token)
if is_end(token):
break
# Storage is triggered for the completed interaction X_t || Y_t.
# These are storage representations, not a per-token decode write.
complete_turn = prompt + response
storage_hidden = storage_hidden_states(complete_turn)
working = memory.clone() # M_t -> initial storage scan state
for hidden in storage_hidden:
working = sgdn2_step(working, hidden)
next_memory = working # Commit M_{t+1} after the full scan.
return response, next_memory
# Initialize once per new trajectory, not once per turn.
# H_kv, d_k, and d_v are the configured memory dimensions.
memory = torch.zeros(H_kv, d_k, d_v)
# For each turn: response, memory = run_turn(prompt, memory, ...)
For multiple selected layers, carry a separate state for each layer. The important invariant is unchanged: decoding reads the existing turn state without mutating it; the subsequent storage scan produces the state carried to the next turn. The sketch omits batching and execution optimizations so that this boundary stays visible.
What You Gain, and What You Lose
You gain an explicit state that evolves across interactions, a learned way to store the completed interaction, and a dedicated read path alongside ordinary attention. SGDN-2 addresses the specific non-symmetric erase mechanism described above.
You also take on projections, gates, per-layer state management, and a storage pass over the completed input and response. Token-granular storage does not mean newly generated content is immediately written into persistent memory during that response. Current-turn information remains available through the backbone's context processing; its incorporation into the persistent state serves later turns.
Finally, the erase-only non-expansion argument is narrower than a guarantee about the full memory system. The mechanism is neither an exact transcript store nor simply ordinary attention made faster: it is an additional, learned route for carrying information across turn boundaries.
Token-level storage is a scan inside a turn-triggered procedure: generation reads M_t, and storage incorporates the completed interaction to produce M_{t+1}. Symmetrization fixes a specific erase-step instability.