WideNDepth — A separation of knowledge storage from iterative reasoning

Hello, this is my first research paper that I have been working on, and I would greatly appreciate any feedback.

I’ve been working on a neural architecture that I call WND (WideNDepth). The purpose of this architecture is to separate “Reasoning” from “Knowledge.”

But why?

As we see in today’s language models, the parameters are expected to both contain knowledge and be able to reason. I consider this a waste of parameters. For example, imagine a 1M parameter Transformer:

###
###
###

This is a static multi-layer stack of parameters that is expected to both reason and store knowledge at the same time.

Now let’s look at how WND separates this idea:

#
# -> ###
#  

In other words, one part is mainly responsible for knowledge, while another part is mainly responsible for reasoning.

As for the WND architecture itself:

Input

  │
  ▼

Wide Layer

  │
  ▼

Encoder ───────────────► Feature Bank
                             ▲
  │                          │
  │                          │
  ▼                          │
                             │ 
Compressor                Attention
                             ▲
  │                          │
  ▼                          │
                             │
Depth Layer (×N iterations) ─┘
  
  │        
  ▼

Output

To explain it simply:

  • The Wide Layer is meant to hold richer information / knowledge.
  • The Encoder processes that information into a useful representation.
  • The Feature Bank stores the original wide representation.
  • The Compressor reduces that representation into a smaller state.
  • The Depth Layer then performs iterative reasoning over the compressed state, while retaining access to the Feature Bank through attention-based retrieval whenever additional information is needed.

The goal is for the Depth Layer to handle reasoning step-by-step.

From what I have tested so far, on graph reasoning tasks (long chains, medium difficulty), a ~100K parameter WND model is currently outperforming a ~600K Transformer baseline. It also trains faster, is more sample-efficient, and has a smaller footprint.

That said, I should mention that WND has not yet been tested on other tasks, so at this stage I do not know where it truly excels and where its weaknesses are.

The main issue I am facing right now is that the Wide Layer and the Encoder keep taking over most of the work, leaving the Depth Layer almost idle. I tried adding auxiliary weights, but that did not really solve the issue.

My question:

How can I encourage, constrain, or force the Wide Layer and Encoder to focus only on producing rich and useful information for the Depth Layer, while making sure that the actual reasoning is done by the Depth Layer itself?

If you are okay with my level of understanding.

Often we get information from context.
So are you attempting a finite state encoding or a dynamic context construct?

Hmm… based on what seems reasonable to say at this point:


My default answer would be: before trying to force the Depth Layer to become more active, first test whether the prediction is causally dependent on its recurrent updates.

With only a final-answer objective, the model is free to use whichever path solves the task most easily. If the Wide Layer, Encoder, Feature Bank, or Compressor can already produce an answer-ready representation, increasing an auxiliary weight may increase gradients or state movement without producing the intended division between “information storage” and “iterative reasoning.”

Structural modularity and learned functional specialization are not automatically the same thing; related work on neural module specialization makes a similar distinction.

A practical default route

I would proceed in this order:

  1. Test whether removing the recurrent update changes the answer.
  2. Separate an Encoder-side bypass from an insufficient recurrent working state.
  3. Rule out shallow shortcuts in the graph generator or split.
  4. Only after that, restrict information paths or add process-aligned supervision.

The smallest useful diagnostic set would be:

Test Intervention Main question
Full WND Normal Head(z_N) Reference
State substitution Replace Head(z_N) with Head(z_0) Do the recurrent updates affect the prediction?
Depth sweep Use 0/1/2/4/…/N iterations Do additional iterations help, saturate, or hurt?
Difficulty split Repeat the sweep by path length or graph difficulty Do harder examples need more iteration?
Encoder/context-only Predict without recurrent updates Can the earlier path already solve the task?
State-capacity sweep Change compressed width or number of state slots Is the mutable recurrent state too small?
Simple task control Node relabeling, feature-only, no-edge, or matched negatives Is there a cheaper shortcut to the label?

The first test is probably the cheapest: run the same checkpoint while feeding z_0 instead of z_N to the output head.

There is a distribution-shift caveat: the existing head was trained on z_N, not necessarily z_0. I would therefore pair that intervention with equally small readout heads trained separately on z_0 and z_N.

The two tests answer different questions:

  • the substitution test asks whether the normal prediction uses the recurrent update;
  • the separate readouts ask whether answer information is already available before recurrence.

A probe being able to decode an answer does not by itself show that the model’s normal computation uses that information, as discussed in Probing Classifiers: Promises, Shortcomings, and Advances.

How I would branch from those results

If z_0 and z_N produce almost the same result

The most useful next branches are:

  • Encoder/Compressor bypass: an early representation is already sufficient;
  • task shortcut: graph statistics or generation artifacts predict the label;
  • near-identity recurrence: Depth is present but changes little of consequence;
  • implementation path: the final recurrent state may not actually reach the head as intended.

In that case, I would prioritize an Encoder-only baseline, task controls, and a short forward-path audit before changing the objective.

If one Depth step helps, but more steps do not

Depth may be acting as one extra nonlinear layer rather than an iterative procedure.

Then the informative comparisons are:

  • accuracy versus iteration count;
  • the same curve separated by actual path length;
  • iteration counts sampled during training rather than one fixed N;
  • compressed-state size versus iteration count.

If more state capacity helps, but more iterations do not

That suggests a possible working-memory bottleneck.

More iterations provide more computation, but not automatically more mutable space for a frontier, visited set, partial path, tentative distances, or other intermediate state. A wider compressed state, multiple state slots, or a small writable workspace may be more useful than increasing N.

If harder or longer examples benefit more from additional iterations

That would be comparatively strong evidence that the recurrent block is performing useful iterative computation.

A relevant evaluation pattern appears in Can You Learn an Algorithm?, where recurrent computation can be extended to harder instances by running for more steps. For WND, a difficulty × iteration curve may therefore be more informative than attention maps or hidden-state movement alone.

If performance improves and then declines with additional iterations

That is still useful information. It may indicate convergence followed by overthinking, or specialization to the iteration range seen during training.

Logical Extrapolation Without Overthinking discusses input recall and progressive training as ways to stabilize recurrent reasoning outside the original training horizon.

I would consider adaptive stopping methods such as Adaptive Computation Time or PonderNet only after establishing that the recurrent update is useful. A stopping mechanism does not solve an unused computation path.

One distinction that may affect the interpretation

The Feature Bank seems important, but its role depends on its lifetime and update contract.

If it is rebuilt from each input and discarded after the prediction, it may be closer to input-conditioned reference memory than persistent knowledge. If it is read-only, it also differs from a mutable working memory in which Depth can store intermediate results.

This does not require changing the WND terminology. It simply gives two separate questions:

  • Where is relatively stable input information retained?
  • Where are evolving intermediate results retained during the N iterations?

If the Compressor output is the only mutable object, its capacity may be just as important as the number of Depth iterations.

So, reduced to one small next experiment, I would produce:

  1. Head(z_0) versus Head(z_N);
  2. a 0/1/2/4/N iteration sweep;
  3. the same sweep split by path length;
  4. an Encoder-only or z_0 readout baseline;
  5. one graph-shortcut control;
  6. if needed, a small recurrent-state-width sweep.

That should tell you which direction is worth pursuing before introducing more architectural constraints.

What “the Depth Layer is idle” could mean

Several different measurements can look like inactivity, but they imply different problems.

Observation Possible interpretation What it does not establish
Small Depth gradients Weak signal, local convergence, optimizer issue That Depth is irrelevant
Small parameter updates Small gradients or effective learning rate That the function is an identity
Small z_(t+1) - z_t Convergence or near-identity update That the change has no effect
Stable attention Stable retrieval pattern That no useful computation occurs
Strong probe at z_0 Answer information exists early That the normal head uses it
Removing Depth changes nothing Depth is not causally necessary under that intervention Why it became unnecessary
More iterations change nothing No test-time depth benefit in that range That the first Depth step is unused
Longer tasks do not need more steps Weak support for length-scaled iteration That recurrence cannot solve the task

I would keep three evidence levels separate:

1. Activity

Examples:

  • gradient norm;
  • parameter delta;
  • attention change;
  • hidden-state movement.

These show that something is changing.

2. Information availability

Examples:

  • a probe or small readout can recover the answer;
  • an intermediate state predicts a task variable.

These show that information is represented somewhere.

3. Causal contribution

Examples:

  • replacing z_N with z_0 changes the output;
  • masking Feature Bank access changes the result;
  • swapping a recurrent state between examples changes the answer predictably;
  • harder examples specifically benefit from additional recurrent updates.

These are closer to showing that the component participates in the computation.

I would log at least:

  • accuracy and loss after every iteration;
  • prediction agreement between iterations;
  • correct-class margin;
  • normalized state delta;
  • gradient norm;
  • parameter delta after optimizer.step();
  • performance under state substitution or removal.

A related recurrent-depth study, Scaling up Test-Time Compute with Latent Reasoning, reports that recurrence can improve reasoning performance, while also discussing configurations in which the recurrent state was not effectively exploited. That does not identify WND’s cause, but it is a useful neighboring failure mode.

A fuller ablation matrix

The most informative experiments can be organized around four questions.

1. Where does answer information first become available?

Train capacity-matched readouts on:

  • Wide Layer output;
  • Encoder output;
  • Compressor output / z_0;
  • each recurrent state z_1 ... z_N;
  • pooled Feature Bank output.

Interpretation:

  • strong early readout: information is already available;
  • improvement from z_0 to z_N: recurrence improves decodability;
  • no change in the actual head despite improved readout: information may exist but not be used.

Keep readouts deliberately small and matched. Otherwise the probe may perform part of the task itself.

2. Which path does the final answer depend on?

Possible interventions:

  • replace z_N with z_0;
  • stop at iteration t;
  • freeze the state after iteration t;
  • replace a state with one from a matched example;
  • mask Feature Bank access;
  • shuffle Feature Bank entries across nodes;
  • shuffle entries across examples;
  • remove any direct Encoder-to-head or bank-to-head route;
  • inject matched noise into early and late states.

The Feature Bank shuffles distinguish several possibilities:

  • node shuffle hurts: node alignment matters;
  • cross-example shuffle hurts: example-specific content matters;
  • neither hurts: the retrieval path may be unused;
  • masking hurts but shuffling does not: aggregate statistics may be sufficient.

3. Is the limitation computation or working-state capacity?

A small factorial sweep is more useful than changing only one dimension.

Axis Example values
Iterations 1, 2, 4, 8, N
State width small, current, 2x
State slots 1, several generic slots, node-aligned slots
Feature Bank access none, read-only, restricted write
Encoder receptive field local, limited-hop, global

Possible patterns:

  • improvement with iteration, not width: more computation is useful;
  • improvement with width, not iteration: mutable state is limiting;
  • improvement only with writable slots: intermediate results need persistent storage;
  • improvement only with global Encoder: the recurrent path may lack required communication;
  • no improvement anywhere: revisit task shortcuts, optimization, and implementation.

4. Does the iteration benefit follow actual difficulty?

Bin results by:

  • relevant path length;
  • number of necessary graph hops;
  • graph size;
  • branching factor;
  • distractor count;
  • ambiguity or number of competing paths;
  • connected-component structure.

The strongest expected pattern would be:

  • easy examples saturate early;
  • medium examples benefit from more steps;
  • longer or more ambiguous examples continue improving;
  • the best iteration count shifts with difficulty.

The curve does not have to increase forever. Saturation or eventual degradation can also be informative.

Controls for the graph task itself

A long-chain graph task can sometimes be solved using a feature that is correlated with the answer but does not require following the intended chain.

Possible shortcut variables include:

  • graph size;
  • edge density;
  • degree distribution;
  • query-node degree;
  • node IDs or generation order;
  • feature-generation rules;
  • positive and negative sampling procedures;
  • connected-component count;
  • distractor placement;
  • different generators for different labels.

I would group the controls by cost.

Cheap controls

  • feature-only;
  • no-edge;
  • graph statistics only;
  • query-node statistics only;
  • random or constant node features;
  • node relabeling;
  • edge-list reordering;
  • adjacency serialization reordering.

Stronger matched controls

Create positive and negative pairs with approximately matched:

  • numbers of nodes and edges;
  • degree distribution;
  • query-node local neighborhoods;
  • feature histograms;
  • component count and size;
  • distractor statistics.

The answer should differ because of the target graph relation, not because one class comes from an observably different generator.

OOD controls

Split by:

  • graph size;
  • path length;
  • density;
  • branching factor;
  • distractor count;
  • generator family;
  • generator seed;
  • positive/negative construction procedure.

The CLRS Algorithmic Reasoning Benchmark is useful here because it explicitly evaluates larger problem sizes and exposes optional algorithm trajectories called “hints.” The associated CLRS paper provides additional context.

WND does not need to adopt CLRS directly. Its evaluation vocabulary—input, output, intermediate hints, processor steps, and size-based OOD generalization—is simply relevant to this problem.

If an Encoder-side bypass is confirmed

If the early path can solve the task without recurrent updates, I would use a deliberately restricted architecture as an isolation experiment.

The goal would not be “make the Encoder bad.” The goal would be to make the location of multi-hop information propagation identifiable.

A diagnostic version might use the following contract:

  • the Wide Layer produces rich local features;
  • the Encoder is local or limited to one-hop processing;
  • the Feature Bank retains the encoded input as reference information;
  • the output head sees only the final Depth state;
  • the Depth Layer may retrieve from the Feature Bank each iteration;
  • global or multi-hop communication is only possible through repeated Depth updates;
  • there is no direct Encoder-to-output bypass.

This resembles the encode-process-decode structure used in neural algorithmic reasoning: encode the inputs, repeatedly apply a shared processor, then decode the final state. See Neural Execution of Graph Algorithms and the CLRS implementation.

I would treat the restricted Encoder as an experiment, not automatically as the final WND design.

If the restricted variant restores iteration-dependent behavior

The original architecture probably contained a path that made Depth unnecessary.

Possible long-term options include:

  • limited Encoder receptive field;
  • no direct Encoder/Feature-Bank access from the output head;
  • temporary Encoder freezing;
  • staged training followed by joint fine-tuning;
  • dropout on selected bypass paths;
  • random training-depth schedules.

If performance collapses and Depth does not recover

The Encoder may have been performing necessary computation rather than merely stealing the intended role.

Then useful alternatives include:

  • increasing Depth state capacity;
  • allowing better input recall at every iteration;
  • adding several mutable state slots;
  • making retrieval more structured or node-aligned;
  • keeping some Encoder computation while removing only the direct output bypass.

If only writable memory restores performance

Then the read-only Feature Bank may be sufficient as a reference store but insufficient as a workspace.

A useful comparison is Neural Turing Machines, which distinguish a controller state from an addressable read/write memory. WND need not use the same mechanism, but the distinction between reference memory and working memory is relevant.

Another neighboring case is Partially Non-Recurrent Controllers for Memory-Augmented Neural Networks, where a capable controller can learn to bypass the intended external-memory path. Again, this is an analogy rather than a diagnosis of WND.

Feature Bank: a more precise design map

The Feature Bank can be characterized along three independent axes.

Persistence

  • learned parameters persistent across examples;
  • memory persistent across examples or sessions;
  • activations rebuilt from every input;
  • temporary state retained only during one recurrent execution.

Mutability

  • read-only;
  • append-only;
  • partially writable;
  • completely rewritten by Depth.

Addressability

  • global attention;
  • content-addressed access;
  • node-aligned entries;
  • fixed generic slots;
  • local or sequential access.

These distinctions produce different interpretations.

Input-conditioned and read-only

This is closer to reference context or encoder memory.

Depth can retrieve original information, but all intermediate results must fit in its compressed mutable state.

Input-conditioned and writable

This can serve as both reference memory and working memory, but it may blur the intended separation if Depth freely overwrites the stored representation.

Persistent across examples

This is closer to an external or parameterized knowledge store, but it introduces separate questions about updates, interference, and retrieval.

Learned parameters

This remains conventional parameter storage even if arranged as a bank.

A lightweight WND-compatible option would be:

  • preserve the original Feature Bank as read-only;
  • provide Depth with a much smaller writable workspace;
  • allow Depth to read both;
  • allow the output head to read only the final Depth state.

That preserves a “wide reference / narrow process” boundary while giving iterative computation somewhere to store evolving results.

When auxiliary objectives become useful

I would place auxiliary losses after the causal and structural tests.

Losses that merely increase:

  • hidden-state distance;
  • gradient norm;
  • attention entropy;
  • iteration-to-iteration disagreement;

can make Depth visibly active without transferring the actual task computation to it.

A more useful auxiliary objective has a task-related contract.

For graph reasoning, possible intermediate targets include:

  • frontier;
  • visited or reachable set;
  • predecessor relation;
  • tentative distance;
  • active node;
  • partial path;
  • termination or convergence state.

Neural Execution of Graph Algorithms trains models around algorithmic steps, while CLRS provides optional intermediate trajectories.

However, a fixed human-written trace is not always the only valid computation. A neural processor may discover a more parallel procedure, and forcing one sequential trajectory can overconstrain it.

Less prescriptive alternatives include:

  • invariance under node relabeling;
  • invariance to irrelevant disconnected components;
  • consistency between matched counterfactual states;
  • prediction consistency after harmless representation changes;
  • supervision of only a small number of semantically necessary variables.

Neural Algorithmic Reasoning with Causal Regularisation is a relevant example of using task-derived invariances to support OOD generalization.

A reasonable order would therefore be:

  1. causal intervention;
  2. task shortcut controls;
  3. structural isolation;
  4. state-capacity test;
  5. process or invariance supervision.
Routine implementation checks if code is available

Before concluding that the objective is the problem, a short PyTorch audit can rule out ordinary failure paths.

Parameter registration

  • Depth appears in model.named_parameters();
  • the exact Depth parameter objects are included in the optimizer;
  • recurrent weights are actually shared if sharing is intended;
  • modules are not recreated inside forward();
  • parameters were not replaced after optimizer construction.

Autograd path

  • no unintended detach();
  • no unintended torch.no_grad() region;
  • no torch.tensor(existing_tensor) reconstruction that removes autograd history;
  • no disconnected recurrent-state buffer;
  • gradients reach the intended recurrent iterations.

PyTorch documents that Tensor.detach() returns a tensor detached from the current graph, and torch.tensor() constructs a copied leaf tensor without autograd history by default. The general graph behavior is covered in the autograd documentation.

Actual forward path

  • the final z_N, rather than an earlier cached tensor, reaches the output head;
  • z_0 and z_N are not unintended aliases of the same mutable storage;
  • an in-place update is not overwriting a state required later;
  • Feature Bank retrieval actually enters the next Depth state;
  • the updated state is not discarded at the end of each loop.

Measure parameter changes as well as gradients

For a short debug run:

  • record gradient norm by module;
  • record parameter norm;
  • record actual parameter delta after optimizer.step();
  • record state delta by iteration;
  • record output sensitivity to each path.

These are routine sanity checks, not an assumption that the implementation is incorrect.

Separating the claims and comparisons

The reported 100K-versus-600K result sounds useful as a preliminary result. I would keep several possible claims separate.

Architectural intent

WND is designed to separate a wide information path from a recurrent processing path.

This follows from the design.

Learned functional separation

The trained modules actually perform different causal roles.

This requires intervention and ablation evidence.

Task performance

WND performs better on the current graph benchmark.

This requires matched data, training protocol, tuning effort, and preferably multiple seeds.

Parameter efficiency

WND reaches the result with fewer unique trainable parameters.

Weight sharing can make this a meaningful benefit.

Compute efficiency

WND uses fewer operations, lower training cost, or lower inference latency.

This is separate from parameter count because recurrent iterations reuse parameters but still execute computation, and sequential iteration can affect latency.

Memory footprint

This should specify whether it means:

  • parameter storage;
  • optimizer state;
  • training activations;
  • inference working memory;
  • peak device memory.

Generalization

The same learned process transfers to:

  • longer paths;
  • larger graphs;
  • different graph densities;
  • different generator families;
  • other task families.

A compact report could include:

Quantity WND Baseline
Unique trainable parameters
Training examples / steps
Depth iterations
Training wall-clock
Inference latency
Peak memory
Mean and variance across seeds
Longer-path OOD accuracy
Larger-graph OOD accuracy

This would not weaken the current result. It would make clear which kind of efficiency and generalization WND is demonstrating.

Related references

These seem most relevant to the design and evaluation questions, rather than evidence for a specific WND root cause:

In summary, I would treat Encoder takeover as a plausible branch rather than the diagnosis. The first goal is to determine whether Depth is causally necessary; the second is to distinguish a bypass from insufficient mutable state; and the third is to verify that graph difficulty genuinely requires iterative computation.

Once that is known, the architecture choices become much clearer:

  • bypass confirmed: restrict the early information path;
  • state bottleneck confirmed: enlarge or structure the mutable workspace;
  • fixed-depth behavior: vary training depth and evaluate by difficulty;
  • task shortcut found: repair the generator or split;
  • none of the above: inspect optimization and implementation.

Hello @John6666

Sorry if my previous reply was unstructured. I ran several follow-up experiments to test whether the Wide Layer is finding a shortcut and leaving the Depth Layer with only a limited role.

Based on the logs and ablations, that seems to be what is happening. The Encoder/Wide Layer appears to produce a representation that is already close to answer-ready. The Depth Layer does provide small improvements when I increase the number of iterations, but it currently looks more like it is refining an existing answer than performing the main reasoning process.

The main evidence is:

  • An Encoder-only version of WND achieved 66.5% accuracy, which is higher than the full model’s peak of 63.0%.
  • Masking or shuffling the Feature Bank produced little or no performance drop, suggesting that the model may not be relying much on that memory path.

One interesting detail is that the Depth Layer seemed to contribute more on the harder dataset. That gives me some hope that the recurrent path becomes more useful when the problem actually requires additional computation.

This leaves me with two questions:

  1. How can I prevent the Wide Layer / Encoder from taking over the architecture without artificially forcing the model into a particular behavior?

    My intended role for the Wide Layer is to store or prepare useful knowledge and pass the relevant information to the Depth Layer. Ideally, it should learn to provide the best context for solving the problem, rather than solving the problem itself before the recurrent reasoning begins.

  2. If the Depth Layer is mostly idle on this task, how could a roughly 50K-parameter Encoder outperform a 600K-parameter Transformer baseline?

    Could this mean that the Encoder’s inductive bias fits this dataset especially well, or that the Transformer baseline is not using its additional capacity effectively under the current setup?

My current understanding from the papers is that specialization cannot simply be guaranteed. I do not want to force Depth into an artificial role, but I may need to change the information flow so that the Encoder cannot solve the whole task alone and Depth has a meaningful role. I am not yet sure what the best first intervention would be.

Hello @Ernst03

I would describe WND as a Dynamic Context Construct rather than a finite state encoding.

The Depth layer maintains a small recurrent state to keep track of what is immediately needed for the current step, while the Feature Bank preserves the original, high-dimensional vectors generated by the Wide layer. This setup allows the Depth layer to dynamically query and access the full context as it reasons, rather than trying to compress all the information into a single, static state.

Thank you.

I have some experience with finite dynamical systems that process binary information. I like understanding the dynamics people are sharing.

-Ernst03

You’re welcome! I’m happy to discuss the dynamics further if you’re interested.

Hmm… for now, taking everything so far into account, I think it comes out roughly like this:


Those new results narrow the problem down quite a bit.

The combination of:

  • Encoder-only reaching 66.5%, above the full WND model’s 63.0% peak;
  • masking or shuffling the Feature Bank causing little or no degradation;
  • Depth becoming somewhat more useful on the harder dataset;

suggests that the current model has at least two regimes:

  1. on the present easier/medium tasks, the early path appears sufficient and the recurrent retrieval path adds little;
  2. as the task becomes harder, there may be a regime in which recurrence starts to provide useful extra computation.

So I would not interpret this simply as “Depth failed.” The harder-set result may be the most useful clue in the whole experiment. The immediate goal would be to identify when recurrence becomes necessary and where the full path first loses or gains information.

1. How to prevent Encoder takeover without assigning an artificial role

I think the cleanest answer is: do not prescribe what “reasoning” must look like with an activity loss; instead, define an information-flow contract under which the intended computation is identifiable.

For example:

Component Diagnostic contract
Wide Layer / Encoder Produce rich local or limited-hop representations
Feature Bank Preserve input-conditioned reference context
Depth state Hold the evolving, mutable computation state
Depth iterations Perform repeated multi-hop integration or retrieval
Output head Read only the final Depth state

The key distinction is between:

  • forcing Depth to move, attend, or produce a particular trace; and
  • making Depth the only route capable of the computation being attributed to it.

The latter is not necessarily an artificial semantic assignment. It is an architectural capability boundary.

A useful isolation variant would therefore be:

  • keep the Wide Layer expressive;
  • restrict the Encoder to node-local or one-hop processing;
  • retain the Feature Bank as a high-dimensional reference store;
  • let Depth query the bank at every iteration;
  • remove any direct Encoder/Feature-Bank-to-output shortcut;
  • allow global or multi-hop integration only through repeated Depth updates;
  • let the output head read only z_N.

I would treat this as a positive control and isolation experiment, not automatically as the final architecture.

If Depth begins showing a clear difficulty-dependent iteration benefit in that version, the original global Encoder probably provided an avoidable bypass.

If the restricted version simply collapses and Depth does not recover, then the Encoder was doing necessary computation rather than merely taking over, or the recurrent path lacks enough state, retrieval quality, or optimization support.

Structural separation alone does not guarantee learned functional specialization. Work on specialization under resource constraints similarly finds that specialization depends on the environment, resource constraints, architecture, and timing/bandwidth of information flow—not only on drawing module boundaries.

2. Before changing the architecture, locate where 66.5% becomes 63.0%

Because Encoder-only is better than full WND, there may be more than inactivity: one of the downstream stages may currently be degrading useful information.

I would compare a small sequence of matched variants:

Variant Path Main purpose
A Encoder → Head Encoder’s direct performance
B Encoder → Compressor → Head Cost of compression
C Encoder → Compressor → Depth → Head Effect of recurrence
D Encoder → Compressor → Depth + Feature Bank → Head Added effect of retrieval
E Full WND Complete reference

Ideally, these would use the same data split, seed set, training steps, head capacity, and early-stopping rule.

This distinguishes several possibilities:

  • A > B: the Compressor is discarding useful information;
  • B > C: the recurrent update is currently harmful or difficult to optimize;
  • C > D: Feature Bank retrieval is injecting noise or distracting the state;
  • A ≈ B ≈ C ≈ D: the difference may mainly be run variance or head/training differences;
  • D > C only on hard cases: retrieval may become useful only after a difficulty threshold.

There is also an important distinction between two kinds of Encoder-only result:

  • If Encoder-only was trained as a separate model, it shows that the architecture can learn the task without Depth.
  • If the same full-model checkpoint performs similarly when Depth is skipped or z_N is replaced with z_0, it shows that the trained full model’s prediction is not dependent on the recurrent updates.

Both are useful, but the second is the more direct causal test.

3. Interpreting the Feature Bank result

The mask result could be strong evidence that the bank path is unused, but the shuffle result depends heavily on what was shuffled.

If Feature Bank attention treats its entries as a set, changing only the array order may be expected to have no effect. Attention-based architectures can be explicitly permutation-invariant over sets; Set Transformer is a clear example.

I would arrange Feature Bank interventions as a ladder:

Intervention What it disrupts
Entry-order shuffle Only sequence order
Node-entry shuffle Alignment between nodes and stored content
Key-only shuffle Retrieval addressing
Value-only shuffle Retrieved information
Independent key/value shuffle Key-to-content association
Cross-example bank swap Example-specific context
Zero or norm-matched random bank Bank content as a whole
Remove retrieval output from the Depth update Entire retrieval route

The strongest low-cost test may be a cross-example bank swap between examples with the same graph size, or directly replacing the retrieval output with zero or norm-matched noise.

It is also worth verifying that the intervention actually reaches the recurrent computation:

  • the retrieval vector changes;
  • the next Depth state changes;
  • the mask is applied to the tensor that is actually consumed;
  • a residual path is not silently preserving the unmasked value.

That is just a positive control for the ablation, not an assumption of an implementation problem.

A practical reading of the current null result

If full removal of the retrieval output still has no effect, the leading branches would be:

  • Encoder/Compressor already contains the needed answer information;
  • Depth has learned to ignore retrieval;
  • the current task does not require revisiting the bank;
  • the recurrent path is not functionally connected as intended.

If only order-shuffling was harmless, considerably less can be concluded.

A compact default experimental route

If I were reducing the next stage to a small sequence, I would use:

  1. Same-checkpoint z_0 versus z_N
  2. Encoder → Compressor → Depth → Bank stage localization
  3. Complete retrieval removal or cross-example bank swap
  4. Difficulty × iteration evaluation within one generator
  5. A strict-locality Encoder variant as a positive control
  6. A graph-structure-matched Transformer baseline

This order avoids changing several parts of the architecture before knowing which path is responsible.

Step 1: same-checkpoint state substitution

Compare:

  • normal Head(z_N);
  • Head(z_0) using the existing head;
  • small matched readouts trained separately on z_0 and z_N.

The existing-head substitution tests causal dependence, although it may introduce distribution shift. The matched readouts test where answer information is decodable.

Step 2: localize degradation

Compare A–E from the previous table.

If possible, log both accuracy and prediction margin, because a stage may reduce confidence before changing top-1 accuracy.

Step 3: stronger bank intervention

Prefer one of:

  • cross-example bank swap;
  • value shuffle while retaining key distribution;
  • complete retrieval-output removal;
  • norm-matched random replacement.

Then confirm that z_(t+1) actually changes under the intervention.

Step 4: difficulty × iteration matrix

For each difficulty bin, evaluate Depth at 0/1/2/4/…/N steps.

Useful difficulty axes include:

  • required path length;
  • number of necessary hops;
  • graph size;
  • distractor count;
  • branching factor;
  • number of competing paths.

The main quantity could be:

accuracy at N steps - accuracy at 0 steps

for each bin.

Step 5: strict-locality positive control

Construct a variant in which one recurrent iteration can propagate information only one hop.

If the task genuinely requires k hops, this creates a clear expected relationship between task complexity and iteration count.

This does not have to be the final WND design. It asks whether the Depth implementation and training procedure can learn useful recurrence under conditions where recurrence is genuinely necessary.

Step 6: structure-matched Transformer

If the goal is to test the inductive-bias explanation, compare against a Transformer that receives comparable graph information rather than only a larger plain Transformer.

4. The harder-dataset result may be the most promising clue

I would give this result more attention than the aggregate Encoder-only score.

If Depth contributes increasingly as examples become harder, that is consistent with the intended idea: easy instances can be solved from an answer-ready encoding, while difficult instances require repeated computation.

However, comparing two datasets can mix several changes:

  • path length;
  • graph size;
  • density;
  • branching factor;
  • distractor count;
  • class balance;
  • feature distribution;
  • positive/negative generation rules.

The stronger version is to hold the generator family fixed and bin examples by a measured difficulty property.

For example:

Required path length Depth 0 Depth 1 Depth 2 Depth 4 Depth N
1–2 hops
3–4 hops
5–8 hops
9+ hops

A particularly informative result would be:

  • short examples saturate at zero or one step;
  • medium examples benefit from several steps;
  • longer examples need more steps;
  • the optimal iteration count moves with required hop count.

That would be substantially stronger evidence of iterative processing than showing that the Depth state changes or receives gradients.

Recurrent models have previously demonstrated easy-to-hard generalization by increasing their test-time iteration budget in Can You Learn an Algorithm?. The CLRS Algorithmic Reasoning Benchmark and its official repository are also useful references for size-based OOD evaluation, graph algorithms, and optional intermediate-state “hints.”

How I would interpret possible difficulty × iteration patterns

Pattern A: benefit tracks required hops

Example:

  • two-hop cases need about two iterations;
  • longer paths continue benefiting from additional iterations;
  • graph size alone does not explain the result.

This would support the intended iterative-computation interpretation.

Pattern B: benefit tracks graph size but not path length

Possible interpretations:

  • recurrence helps with general capacity or denoising;
  • larger graphs produce a harder aggregation problem;
  • the model is not necessarily traversing a path step by step.

Still useful, but a weaker match to the intended mechanism.

Pattern C: benefit appears only on a separately generated “hard” dataset

Possible interpretations:

  • recurrence is useful;
  • the hard generator changes another relevant statistic;
  • a shortcut available in the easy dataset disappeared;
  • the train/test protocol differs.

This motivates within-generator bins or matched examples.

Pattern D: benefit rises and then falls

The model may have a useful recurrence range followed by overthinking or fixed-depth specialization.

Logical Extrapolation Without Overthinking studies recurrent models that must remain stable when run beyond their training horizon, using techniques such as input recall and progressive training.

Pattern E: no benefit even under strict locality

This redirects attention toward:

  • recurrent state capacity;
  • retrieval implementation;
  • gradient/optimizer path;
  • training curriculum;
  • task construction;
  • output-head path.

5. Why a 50K Encoder can outperform a 600K Transformer

Yes, the Encoder’s inductive bias is a plausible explanation.

Parameter count alone does not determine sample efficiency or task suitability. A small model that directly respects graph structure may have a much easier learning problem than a larger model that must infer that structure from a weaker representation.

Relevant factors include:

  • local message passing;
  • permutation equivariance;
  • explicit edges;
  • node or edge types;
  • graph-specific aggregation;
  • shortest-path or structural encodings;
  • the amount of data available;
  • optimization budget.

Graph Transformer research supports this general point. Graphormer emphasizes explicitly encoding graph structure into the Transformer, while GRIT reports that Graph Transformers without sufficient graph inductive bias can perform poorly on smaller datasets, where those biases matter more.

So the result is not inherently surprising. However, several explanations remain compatible with it:

  1. good Encoder inductive bias
    Its locality or graph operations match the task.

  2. insufficient structure in the Transformer input
    The Transformer may not receive comparable adjacency, edge, or positional information.

  3. data-regime advantage
    The smaller model may generalize better with the available sample size.

  4. optimization-budget difference
    The 600K model may need more steps, different regularization, or more tuning.

  5. task shortcut
    The Encoder may exploit a generator-specific statistic efficiently.

  6. single-run variance
    A few points may move across seeds.

I would therefore separate three kinds of matching:

Matching type What is held comparable
Parameter-matched Unique trainable parameter count
Compute-matched Training/inference operations or measured time
Information-matched Graph edges, node features, structural encodings and masks

The last one is especially important. If the 50K Encoder receives explicit topology while the Transformer must reconstruct topology from a serialized input, the comparison mixes architecture with information availability.

The most useful next baseline

To test the inductive-bias hypothesis, I would not necessarily add an even larger Transformer. I would add a Transformer with comparable graph structure:

  • adjacency-aware attention or masking;
  • edge information;
  • degree or centrality encoding;
  • shortest-path or relative structural encoding;
  • the same node features and pooling target.

A simple comparison ladder could be:

Baseline Main role
Statistics-only MLP Detect generator shortcuts
Small graph Encoder / MPNN Local graph inductive bias
Plain Transformer Weakly structured global attention
Transformer + adjacency mask Explicit local topology
Transformer + structural encoding Graph-relative information
Hybrid local MPNN + global attention Stronger graph-Transformer baseline

This makes the 50K-versus-600K result easier to interpret without diminishing it.

What I would report for the 50K versus 600K comparison

To preserve the value of the preliminary result, I would report each efficiency claim separately.

Quantity Encoder-only Full WND Transformer
Unique trainable parameters
Training examples
Optimizer steps
Recurrent iterations
Training wall-clock
Inference latency
Peak device memory
IID accuracy
Hard-set accuracy
Longer-path OOD
Larger-graph OOD
Mean ± variation across seeds

This distinguishes:

  • parameter efficiency;
  • sample efficiency;
  • training speed;
  • inference compute and latency;
  • memory footprint;
  • OOD generalization.

A recurrent model can use few unique parameters while still spending additional sequential compute at inference, so parameter and compute efficiency should remain separate.

6. The Dynamic Context Construct clarification helps

Your description makes the current WND experiment easier to interpret.

The Feature Bank appears to be:

  • high-dimensional;
  • generated from the current input;
  • preserved during the current example;
  • dynamically queried by Depth.

The Depth state appears to be:

  • small;
  • mutable;
  • recurrent;
  • responsible for keeping what is currently needed.

That looks like a meaningful separation between:

  • input-conditioned reference context, and
  • recurrent working state.

Whether it later supports a broader separation between persistent knowledge and reasoning may depend on how the bank is populated, retained, or updated in other tasks. But the current distinction is already technically useful and testable.

One remaining architectural question is where evolving intermediate objects are meant to live.

For a graph procedure, those might include:

  • visited nodes;
  • current frontier;
  • partial path;
  • tentative distances;
  • predecessor pointers;
  • unresolved alternatives.

If the Feature Bank is read-only and the compressed Depth state is the only mutable object, all of those intermediate results must fit in that small state.

That may be completely sufficient for the present task. If a strict-locality version makes Depth necessary but performance remains low, then state width, multiple mutable slots, or a small writable workspace become reasonable next branches.

I would not prioritize that capacity change yet, because the current Feature Bank ablations first suggest that retrieval may not be used. But it becomes important after the early bypass is removed.

A possible WND-compatible memory contract

One option that preserves the intended wide/narrow distinction would be:

  • keep the original Feature Bank read-only;
  • give Depth a much smaller writable workspace;
  • let Depth read from both at each iteration;
  • let only the final Depth state reach the output head.

This separates:

Memory type Purpose
Read-only Feature Bank Preserve rich input-conditioned context
Mutable Depth state Control the current operation
Small writable workspace Preserve evolving intermediate results

Architectures such as Neural Turing Machines make an explicit distinction between controller state and addressable read/write memory. WND does not need to reproduce that design; it is simply a useful reference for separating stable reference content from mutable computation state.

If the strict information-flow variant succeeds or fails

If it succeeds

Suppose the local Encoder version produces:

  • increasing Depth dependence;
  • path-length-dependent iteration benefits;
  • meaningful Feature Bank intervention effects.

That would support the bypass hypothesis.

Possible long-term choices:

  • retain limited Encoder receptive field;
  • gradually relax locality until the bypass returns;
  • prohibit only the direct output shortcut;
  • use path dropout during training;
  • temporarily freeze the Encoder, then jointly fine-tune;
  • randomize the number of training iterations.

The useful design boundary would be the least restrictive one that preserves Depth-dependent behavior.

If it fails but larger state helps

This supports a mutable-state bottleneck.

Options:

  • wider z_t;
  • multiple recurrent slots;
  • node-aligned scratch slots;
  • limited writable memory;
  • more structured bank retrieval.

If it fails but stronger retrieval helps

This suggests Depth lacked access to the right information.

Options:

  • input recall at every iteration;
  • node-aligned keys/values;
  • explicit query-node identity;
  • gating changes;
  • residual retrieval integration.

If accuracy collapses and none of these help

Return to:

  • graph generator controls;
  • recurrent optimization;
  • head path;
  • parameter registration;
  • gradient detachment;
  • whether the task admits the intended iterative decomposition.
Short implementation sanity checks if code is later available

These would be routine checks, not a diagnosis:

  • Depth parameters appear in model.named_parameters();
  • those exact parameters are in the optimizer;
  • shared recurrent weights are genuinely shared;
  • no accidental detach() or no_grad() interrupts the path;
  • retrieval output enters z_(t+1);
  • z_N, rather than a cached earlier state, reaches the head;
  • the retrieval gate is not permanently saturated;
  • parameter values actually change after optimizer.step().

I would also use hooks to verify that:

  • masking the Feature Bank changes the retrieval tensor;
  • the retrieval intervention changes the Depth input;
  • cross-example bank swaps propagate into later states.

My current default interpretation

At this point, I would summarize the evidence like this:

  • The early Encoder path is currently strong enough to solve much of the task.
  • The full Compressor/Depth/retrieval path has not yet shown an aggregate advantage and may currently degrade some useful information.
  • The existing Feature Bank intervention suggests low reliance, although the exact shuffle semantics matter.
  • The harder-dataset result leaves open an important and promising regime in which recurrence becomes useful.
  • The 50K-versus-600K result is compatible with a graph inductive-bias advantage, but structure-, compute-, and information-matched baselines would clarify it.
  • The /5 clarification makes the present experiment primarily a test of input-conditioned context versus recurrent working state.

So I would not try to force specialization globally.

I would:

  1. localize where the full path loses performance;
  2. validate the Feature Bank ablation more strongly;
  3. map iteration benefit against actual task difficulty;
  4. create one strict information-flow positive control;
  5. compare against a structure-matched Transformer.

Then the next design choice follows from the result:

  • bypass confirmed: restrict only the route that creates the bypass;
  • working-state limit confirmed: enlarge or structure mutable state;
  • retrieval limit confirmed: improve addressing or input recall;
  • fixed-depth behavior confirmed: vary training depth;
  • task shortcut found: repair the generator or split;
  • none of these: inspect optimization and implementation.

The fact that Depth appears more useful on harder data is the part I would preserve and investigate most carefully. It may indicate that the intended separation is not absent, but that the current benchmark spends most of its time below the difficulty threshold where recurrence becomes necessary.

Hello @John6666

Unfortunately, I cannot view your reply because it was flagged. However, I have some results from recent WND experiments that I wanted to share.

I tested WND on an MLP-based English pretraining task using roughly 500 MB of English Wikipedia data. The experiment used an English-oriented word-level tokenizer with an 8K vocabulary. The architecture was:

  • Wide layer dimension: 768
  • Depth layer dimension: 256
  • Feature bank size: 32
  • Iterations: 12

The results were very encouraging. The model appeared to specialize its components according to the task’s needs, which is one of the behaviors I hoped WND would show.

For example, in an earlier graph-reasoning experiment, as i mentioned before, a 100K-parameter WND outperformed a 600K-parameter Transformer baseline. More interestingly, a smaller ~60K-parameter WND then outperformed the 100K-parameter WND. This may suggest that WND components can specialize more effectively when their capacity is better matched to the complexity of the data.

In the English pretraining experiment, the model contained approximately 16 million parameters and used roughly 500 MB of VRAM, reaching a peak of around 700 MB during training. Each training step usually took around 100 ms. These measurements were taken on Windows using an NVIDIA GeForce RTX 3050 Mobile GPU with 4 GB VRAM, and there is still some overhead preventing maximum performance.

The best validation loss was 4.8947.

The saved model checkpoint was also only around 60 MB on disk.

I also performed ablation tests by disabling different parts of the architecture. Attention and the Feature Bank were the most important components. When attention was disabled, accuracy dropped close to zero, suggesting that the Depth Layer relies heavily on the features supplied through attention. The orthogonality-related metric also fell near 0.0.

The losses showed depth: 4.4571 | wide: 5.0283

This suggests that the Depth pathway is doing most of the task-solving, while the Wide pathway likely provides supporting features, routing, or representation capacity.

Overall, these experiments make me optimistic that WND is highly GPU-friendly and can adapt its internal specialization to a task.

However, I want to be clear: these logs do not prove that WND is generally better than Transformers. They are only early results from limited experiments, and much broader benchmarking is still needed.

Hello @John6666

First of all, thank you for the detailed and insightful feedback.

Regarding the Encoder bypass, I fully agree with the easy-versus-hard regime interpretation. The harder-dataset result is especially interesting, because it may indicate that Depth becomes useful only once the task reaches a certain complexity threshold.

Regarding the experiments you suggested, if I understood correctly, my immediate priority should be:

  • Cross-example Feature Bank swap
  • Same-checkpoint z_0 versus z_N substitution
  • Stronger Feature Bank ablations, such as complete retrieval removal or value shuffling

However, I think there may be a small misunderstanding in how we interpret the specialization problem, because I ran two core experiments: an MLP experiment and a graph-reasoning experiment.

In the MLP experiment, orthogonality fully solved the problem. The modules specialized clearly: each component learned a separate role, and the architecture behaved as intended. This makes me think that functional specialization itself is possible in WND-like systems without necessarily imposing an artificial semantic role on every module.

The graph-reasoning experiment appears different. My current interpretation is that the Encoder may simply be strong enough to solve much of the current task directly. Therefore, Depth and the Feature Bank do not become necessary on easier instances. In that sense, Encoder takeover may be less of a universal architectural failure and more of a mismatch between model capacity and dataset complexity.

So, if I understand correctly, the goal should not necessarily be to make the Encoder weak in every setting. Instead, it may be to choose the Encoder capacity, receptive field, and information-flow restrictions according to the complexity of the dataset. Orthogonality may help modules specialize, but the task must still require the recurrent path to contribute.

Regarding the writable workspace idea, I am not yet convinced that adding a separate read-only bank and writable workspace is the best direction.

My concerns are:

  • Two separate banks add memory usage and architectural complexity.
  • If the Feature Bank contains low-quality or incomplete representations, Depth may try to rewrite the same information into the writable workspace.
  • In that case, the original Feature Bank may become less useful, while both the original bank and rewritten numeric states remain in memory.
  • The model would also need to learn a more difficult control problem: when to read, when to write, what to write, and where to write it.

For these reasons, I think a simpler alternative may be to make the existing Feature Bank both readable and writable by Depth.

The idea would be that the Encoder initializes a rich, input-conditioned Feature Bank, then Depth repeatedly reads from and selectively updates that same bank while maintaining its small recurrent state. This could preserve the wide/narrow distinction while avoiding a second memory structure.

However, I also think this could create a new bypass, if the Feature Bank becomes fully writable, the Depth Layer may begin to ignore its small recurrent state and use the bank itself as the main computation workspace. That would weaken the intended wide/narrow separation, because the narrow state would no longer need to carry the evolving reasoning process.

I think this possible bypass may be reduced if the model is rewarded for solving examples through its small recurrent state whenever possible. The analogy is similar to CPU cache versus main memory: the small state should be faster, cheaper, and preferred for information that is immediately useful, while the larger Feature Bank remains available for rich reference context or information that cannot fit in the narrow state.

Of course, this introduces risks as well: writes could overwrite useful source information, become unstable across iterations, or allow Depth to use the Feature Bank as an unrestricted scratchpad. However, these risks might also be exploited in a useful way. If the Depth layer can write directly to the Feature Bank generated by the Wide layer, it may learn which information to ignore or override, which representations to refine, and which features to preserve as valuable.

My current view is therefore:

  • The MLP result suggests orthogonality can produce genuine specialization.
  • The graph result suggests the Encoder is currently too capable relative to much of the benchmark.
  • The hard-data result may show the beginning of the regime where recurrence becomes useful.
  • Before adding writable memory, I should first verify whether the current Feature Bank is actually used through cross-example swapping and z_0 versus z_N tests.
  • If mutable external memory is later needed, I would prefer first testing a controlled read-write version of the existing Feature Bank rather than immediately adding a separate writable workspace.

What do you think about making the Feature Bank selectively writable by Depth, while keeping some part of it protected or immutable?

Well. Um, taking everything so far into account…


Yes — I think making the existing Feature Bank selectively writable by Depth is a reasonable next design branch, and I agree that a second full-sized bank is not necessarily required.

My default version would not make the whole bank freely writable at first. I would keep one logically protected view — the original source representation and/or the addressing side — and let Depth update only a bounded value, delta, or scratch portion.

That can still be one physical bank. For example:

Variant Protected Writable Main question
R0: read-only Entire bank Nothing Is the current bank already causally useful?
R1: static key / dynamic value Addressing keys or source projection Values Can Depth refine content without moving the retrieval coordinate system?
R2: source + delta Exact Encoder-produced source Small bounded delta Can Depth add working state without destroying the original input representation?
R3: protected + scratch slots Source slots A small subset of slots Does the task need persistent intermediate storage?
R4: fully writable Nothing Entire bank What is the upper bound if the bank is allowed to become a full workspace?

I would probably start with R1 or R2, then keep R4 as an informative upper bound rather than the default.

Before adding writes, I also agree with your current priority: first establish what the existing read-only bank and recurrent state are already doing. The three tests you listed are the right starting point:

  1. cross-example Feature Bank swaps;
  2. same-checkpoint z_0 versus z_N;
  3. complete retrieval removal or stronger value/key shuffles.

I would add only one cheap extension: record the prediction after every iteration, not only at z_0 and z_N. That separates “gradual useful reasoning” from “one useful step,” “early convergence,” or “correct first, then overthink.”

A compact default route would therefore be:

  1. Audit the current read-only model causally.
  2. Implement one protected-write variant, preferably R1 or R2.
  3. Keep iterations, parameter count, and read bandwidth as matched as practical.
  4. Measure both task performance and what is actually being written.
  5. Use state/bank interventions to determine where the evolving computation moved.

The most important interpretive split is this:

  • If the model improves with writes and still fails when the small recurrent state is reset or swapped, the small state remains causally important.
  • If the model improves with writes but becomes almost insensitive to the small state, the bank has probably become the main workspace.

The second outcome would not necessarily be a failed architecture. It would simply be closer to:

a narrow recurrent controller operating a wide mutable memory

than:

a narrow recurrent reasoning state consulting a wide reference store

That distinction seems more useful to measure than to enforce by terminology alone.

Why I would protect an address/source side first

There are two separate reasons to protect part of the bank.

1. Preserving the original input-conditioned evidence

If Depth repeatedly overwrites the only copy of the Encoder representation, it must both preserve the original evidence and maintain intermediate reasoning state in the same values.

That can work, but it creates an avoidable burden: every update must decide not only what new result to store, but also which source information must not be forgotten.

A conservative contract is:

  • the Encoder creates an immutable source view;
  • Depth can reread that source at every iteration;
  • Depth writes only a residual or value view;
  • the reader can attend to either the source, the mutable view, or both.

This is related to the explicit input-recall idea in Logical Extrapolation Without Overthinking: the original problem instance remains directly available during recurrent computation instead of being reconstructed from an increasingly transformed hidden state. It is not the same architecture, but the failure mode is relevant.

For R2, the conceptual update could be as simple as:

bank_t = source_bank + bounded_delta_t

where source_bank is unchanged and only bounded_delta_t evolves.

The important point is not that addition is uniquely correct. It is that the immutable and mutable parts have an auditable contract.

2. Preventing writes from changing the addressing system unintentionally

If Feature Bank retrieval is content-addressed, and the same dimensions are used both as a retrieval key and as mutable content, writing a value can also change which slot will be retrieved next.

A relevant neighboring result appears in Improving Differentiable Neural Computers Through Memory Masking, De-allocation, and Link Distribution Sharpness Control. Their analysis found that the lack of key/value separation made content lookup noisy because the value influenced the similarity score even though only the key should determine the address.

That does not establish that WND has the same failure mode. It depends on how your Feature Bank is addressed:

  • If retrieval is content-based using mutable dimensions, this is a fairly direct risk.
  • If slots are node-aligned or index-addressed, the risk is smaller.
  • If keys and values already use separate projections, the main issue becomes source preservation rather than address drift.

This is why the exact read contract matters more than whether the implementation uses one tensor or two tensors.

A static-address/dynamic-content pattern has a direct precedent in Dynamic Key-Value Memory Networks, where static keys represent concepts and dynamic values hold the changing state. That paper addresses knowledge tracing rather than within-example reasoning, so I would use it as a design precedent, not as evidence that the same choice must work here.

A minimal protected update

For the first implementation, I would keep the writer deliberately boring:

candidate = writer(state_t, reads_t)

gate = sigmoid(write_gate(state_t, reads_t))

mutable_t+1 = (1 - gate) * mutable_t + gate * candidate

Then place explicit limits on at least one of:

  • writable channels;
  • writable slots;
  • number of slots written per iteration;
  • total write norm;
  • number of write-enabled iterations.

Only if this shows a clear limitation would I split the operation further into separate retain, erase, correction, and write decisions.

Fully flexible erase/add memory is possible — Neural Turing Machines and the Differentiable Neural Computer are obvious precedents — but those systems also illustrate the alternative operating regime in which the external memory itself is a major part of the recurrent state.

For an initial WND experiment, a smaller contract is easier to interpret.

How I would test whether the bank has replaced the small state

I would distinguish three roles rather than only “Wide” and “Depth”:

  1. Source/reference state
    Input-conditioned evidence produced by the Encoder.

  2. Mutable task state
    Frontiers, partial results, tentative decisions, intermediate summaries, or other evolving computation.

  3. Controller state
    Information used to decide what to read, where to write, when to stop, or which operation to apply.

The small recurrent state could contain task state, controller state, or both. A writable bank could also contain either task state or control information.

That means state reset hurts is informative, but does not by itself prove that the state contains the answer. It might instead contain routing or write-control variables.

Intervention matrix

I would run these on the same checkpoint whenever possible:

Intervention Held fixed Changed Main interpretation
z_N → z_0 Bank and input Recurrent result Do recurrent updates affect the normal prediction?
State freeze after iteration t Bank reads/writes Later state updates Is continuing state evolution necessary?
Write freeze after iteration t State updates Later bank writes Are later writes necessary?
Bank retained, state reset Bank Small state Does the state carry necessary task/control information?
State retained, bank reset State Mutable bank Does the bank carry necessary evolving information?
Cross-example state swap Bank and input State Does state content transfer source-example behavior?
Cross-example bank swap State and input Bank Does bank content transfer source-example behavior?
Source-only bank Input source Mutable portion removed Is mutable memory necessary?
Mutable-only bank Mutable state Source view removed Is the original representation still required?
No-write inference Reads intact Writes disabled Is the trained writer causally used?

For a protected bank, I would swap the components separately:

  • immutable source only;
  • keys only;
  • mutable values/delta only;
  • scratch slots only;
  • the complete bank.

Otherwise, a “bank swap” may combine several different interventions.

Pair construction matters

A random cross-example swap can be useful, but it may create an arbitrary out-of-distribution state. I would include several pair types:

  • self → self as a null test;
  • same answer, different graph structure;
  • different answer, similar graph structure;
  • similar difficulty, different answer;
  • easy → hard;
  • hard → easy;
  • same graph size but different path;
  • same local statistics but different target relation.

Then report more than accuracy:

  • task loss;
  • correct-class margin;
  • prediction agreement;
  • fraction of predictions moving toward the source example’s answer;
  • effect size relative to a matched-noise intervention.

This is closely related to interchange interventions in Causal Abstractions of Neural Networks.

There is also a practical caution from Towards Best Practices of Activation Patching: conclusions can vary substantially with the metric and the clean/corrupted input construction. A swap that causes damage proves that the model is sensitive to the intervention, but the pattern of transferred behavior is more informative than damage alone.

Probes are secondary evidence

Small readouts trained on:

  • Encoder output;
  • z_0;
  • each z_t;
  • pooled source bank;
  • mutable bank;
  • the final combined representation;

can tell you where information is decodable.

But a probe may recover information that the normal model does not use. I would therefore keep:

  • decodability as evidence that information exists;
  • same-checkpoint interventions as evidence that the normal computation depends on it.
Iteration count, task difficulty, and write policy

I think there are two changes that should initially be tested separately:

  1. changing where intermediate state can be stored;
  2. changing how much recurrent computation each example receives.

If both writable memory and adaptive stopping are introduced together, it becomes difficult to know whether a gain came from extra workspace or better computation allocation.

First log the full iteration trajectory

For each iteration t, I would record:

  • loss and accuracy;
  • correct-class margin;
  • prediction agreement with the previous iteration;
  • fraction becoming correct at t;
  • fraction becoming incorrect after previously being correct;
  • normalized state-update norm;
  • read-attention entropy;
  • write-gate statistics;
  • updated-slot fraction;
  • mutable-bank delta norm.

Then split those curves by an actual difficulty variable:

  • path length;
  • required hop count;
  • graph size;
  • branching factor;
  • distractor count;
  • ambiguity or competing paths.

Several qualitatively different mechanisms can otherwise produce the same final result:

Trajectory Possible interpretation
Most improvement occurs at step 1 Depth may be acting mainly as one extra nonlinear block
Improvement continues with task difficulty Stronger evidence for useful iterative computation
Easy examples saturate early; hard examples continue improving Difficulty-dependent compute is plausible
Performance improves then declines Overthinking or training-horizon specialization
States change but predictions do not Activity without task-relevant causal contribution
Writes grow while state updates shrink Computation may be migrating into the bank
Write gates are active but write-freeze has no effect Decorative or redundant writes

The “correct, then wrong” case deserves explicit measurement. Recurrent reasoning models can degrade when run for more iterations than they learned to use; Logical Extrapolation Without Overthinking studies this failure and uses exact input recall plus progressive training to stabilize longer computation.

Keep depth fixed during the first memory comparison

For R0–R4, I would use the same iteration schedule first.

Only after finding a variant where:

  • hard examples continue improving;
  • easy examples saturate or degrade;
  • and recurrent updates are causally useful;

would I consider adaptive stopping.

Methods such as Adaptive Computation Time or PonderNet may eventually be relevant, but they solve computation allocation, not an unused recurrent path or an unclear memory contract.

Write frequency is also an independent variable

A writable bank does not have to be written at every iteration.

Learning to Remember More with Less Memorization argues that writing external memory at every timestep can underuse the controller’s short-term state and introduce redundant writes. Their proposed methods are different from WND, but the design question transfers.

Reasonable WND comparisons include:

  • every-iteration write;
  • every k iterations;
  • top-k slots per iteration;
  • fixed total write budget;
  • novelty-triggered write;
  • writes only in early iterations;
  • write-protected final iterations.

This would make the CPU-cache analogy operational rather than only descriptive.

A small state is not automatically preferred because it is conceptually a cache. The optimization needs an actual incentive or restriction, such as:

  • cheaper state access than bank access;
  • limited write bandwidth;
  • a penalty on write volume;
  • output access primarily through the final state;
  • stochastic bank-access dropout;
  • an explicit write budget.

I would add these only as needed. The first result to obtain is whether unrestricted optimization naturally uses the protected-write contract in a meaningful way.

How I would interpret the MLP, graph, and orthogonality results

I agree with separating the MLP/English and graph experiments.

The graph result does not require the conclusion that functional specialization is impossible. A simpler interpretation is that the current Encoder and dataset permit an easier route that makes recurrent processing unnecessary on many examples.

Similarly, the positive MLP result should not be dismissed merely because the graph regime behaves differently.

A useful general framing is task-dependent specialization:

  • the task must contain meaningfully separable subproblems;
  • the modules must face constraints that make cooperation useful;
  • information-flow timing and bandwidth affect which roles emerge;
  • excess capacity can make an intended module unnecessary.

A controlled study of these factors is Dynamics of Specialization in Neural Modules under Resource Constraints. It is not a WND study, but its conclusion that structural modularity does not automatically guarantee functional specialization is relevant to the interpretation.

Orthogonality evidence has several levels

I would separate:

  1. representations or attention values becoming less correlated;
  2. different auxiliary losses or activation patterns appearing;
  3. different information becoming decodable from each module;
  4. removing a module causing a distinct category of failure;
  5. swapping a module transferring a predicted task variable;
  6. a stable semantic interpretation such as “knowledge” versus “reasoning.”

Your MLP result is positive evidence for specialization, especially if the orthogonality condition consistently changes both performance and internal behavior.

I would still use “functional specialization” most confidently when the distinction survives same-checkpoint interventions.

For example, compare orthogonality on versus off using the same causal tests:

  • source-bank swap;
  • mutable-bank swap;
  • z_0 / z_N;
  • state reset;
  • write freeze;
  • bank reset;
  • attention removal;
  • difficulty × iteration curves.

Possible outcomes:

Observation Conservative interpretation
Orthogonality changes geometry but not intervention effects Primarily decorrelation or conditioning improvement
Orthogonality makes different modules causally necessary Stronger functional-specialization evidence
Orthogonality helps only one task regime Specialization is task-dependent
Orthogonality helps training but roles vary across seeds Useful regularization without stable semantic roles
Orthogonality produces consistent, predictable failure modes Strong evidence for a reproducible division of function

I would also avoid placing too much weight on depth loss < wide loss alone until the two losses are known to have comparable:

  • targets;
  • scales;
  • reductions;
  • normalization;
  • position in the computation;
  • weighting in the total objective.

The inequality is useful context, but the ablations and interventions tell us more about which path performs which computation.

A compact result map for the writable-bank experiment

Here is the result matrix I would use when interpreting the first experiments.

Observation First hypothesis Next comparison
Current read-only bank swaps/removal have little effect Bank path is unused, redundant, or intervention is incomplete Audit output paths, test key/value separately, compare matched noise
z_0 and z_N behave similarly Encoder-side sufficiency, near-identity recurrence, or task shortcut Difficulty sweep, Encoder-only baseline, output-path audit
Protected writes improve hard examples only Writable workspace may solve a state-capacity bottleneck State/bank resets split by difficulty
Writes improve all examples immediately Writer may act as another feed-forward transformation One-step versus multi-step write comparison
Fully writable helps, protected variants do not Strong workspace flexibility may be required Check source loss, state necessity, and whether addressing drifts
Protected source + delta helps Original evidence plus mutable residual is useful Reduce delta size/write budget to find minimum sufficient workspace
State reset still hurts strongly Small state remains causally important Separate controller information from task information
State reset stops mattering after writes Bank has likely become the main workspace Reframe claim or restrict write/access bandwidth
Bank reset and state reset cause different errors Control and task state are distributed Targeted swaps of gates, reads, values, and state
Gate is almost always zero Writer collapsed closed or writes are unnecessary Initialize/open bias, easier write-required task, writer-gradient audit
Gate is almost always one Bank may be an unrestricted scratchpad Add retention bias, write budget, or protected channels
Writes are large but freeze has little effect Redundant/decorative activity Penalize writes or remove writer
Source recoverability falls with performance Model may be trading reference fidelity for workspace capacity Strengthen source protection
Retrieval degrades after writes Possible address/content interference Freeze keys or use separate read-key projection
Performance peaks then declines with iteration Overthinking or unstable writes Freeze writes late, input recall, progressive-depth training
Orthogonality changes causal dependencies Stronger evidence for actual module specialization Check seeds and task regimes

What to log for each variant

Task behavior

  • training and validation loss;
  • final accuracy;
  • per-iteration accuracy and margin;
  • difficulty-binned curves;
  • OOD graph size/path length if available;
  • several random seeds.

Memory behavior

  • average and distribution of write gates;
  • gate entropy;
  • fraction of gates near 0 and near 1;
  • number of updated slots per iteration;
  • total write norm;
  • source-to-current representation drift;
  • read/write slot overlap;
  • frequency with which written slots are later read;
  • source-feature recovery before and after writes.

Causal behavior

  • no-write inference;
  • no-read inference;
  • state reset;
  • bank reset;
  • source-only and mutable-only;
  • matched cross-example swaps;
  • self-swap null;
  • intervention effect by iteration and difficulty.

Comparison hygiene

Because the main claim concerns a wide/narrow resource division, I would report or approximately match:

  • trainable parameter count;
  • immutable-bank capacity;
  • writable capacity;
  • recurrent-state size;
  • number of reads and writes;
  • recurrent iterations;
  • training steps/examples;
  • measured latency or FLOPs if efficiency is discussed.

Exact matching may not always be possible, but making the resource difference visible prevents “more mutable capacity” from being mistaken for a specific architectural advantage.

Suggested default decision flow

A practical decision tree could be:

A. Does the current read-only bank causally matter?

  • No or barely:
    Do not add a writer yet. First audit retrieval, output paths, task shortcuts, and whether the Encoder already provides an answer-ready representation.

  • Yes:
    Continue to a protected writable comparison.

B. Do R1 or R2 improve over read-only?

  • No, with gates mostly closed:
    The writer may be hard to optimize, unnecessary, or not exposed to a task that needs writable state.

  • No, with active writes:
    The updates may be redundant, unstable, or writing the wrong representation.

  • Yes:
    Determine where computation moved.

C. After adding writes, is the small state still causally necessary?

  • Yes:
    The original wide-reference / narrow-recurrence interpretation remains plausible.

  • Partly:
    The state may be acting primarily as controller while the bank stores task state.

  • No:
    The architecture is operating as a narrow controller plus wide mutable workspace.

D. Is the original source still preserved?

  • Yes:
    The protected contract is working as intended.

  • No, and retrieval degrades:
    Protect keys/source more strongly or separate addressing from values.

  • No, but performance improves:
    The model may prefer a pure workspace. That is useful evidence, but it changes the interpretation of the bank.

E. Do hard examples need more iterations or writes?

  • Yes:
    This supports the complexity-threshold interpretation.

  • No:
    Revisit whether the benchmark requires iterative computation or whether the recurrent path mainly adds capacity.

So my practical recommendation would be:

  1. finish the current same-checkpoint causal tests;
  2. log the full iteration trajectory;
  3. implement one-bank, protected-source/static-address + bounded writable-value/delta;
  4. keep the write mechanism simple and observable;
  5. compare it with read-only and fully writable endpoints;
  6. use state/bank resets and swaps to identify the resulting operating regime.

That preserves your preference for a single Feature Bank, does not assume a second full workspace is necessary, and still gives a clean way to detect whether the design remains “wide storage plus narrow iterative reasoning” or evolves into “wide mutable computation controlled by a narrow state.”

Hello @John6666

I tested three feature-bank variants:

  1. Read-only
  2. Delta Protection
  3. Read & Write

The results are a bit confusing. In terms of memory efficiency, my ranking is:

Read-only > Delta Protection > Read & Write

However, their learning performance is mostly similar. I have not seen a major accuracy or loss difference between the three modes so far.

Current model configuration:

Wide layer:      256
Depth layer:     64
Feature-bank slots: 16
Iterations:      4
Parameters:      ~5M

Tokenizer : BRE (~8k vocab size)

One run produced:

Train
  Loss:  6.0183
  Top-1: 11.48%
  Top-5: 23.62%

Validation
  Loss:  6.3001
  Top-1: 10.74%
  Top-5: 21.95%

Test
  Loss:  6.3103
  Top-1: 10.82%
  Top-5: 21.75%

Runtime statistics:

GPU memory allocated: 127 MB
GPU memory reserved:  198 MB
Peak GPU memory:      159 MB
Speed:                924,728 tokens/sec

My current interpretation is that the read-only bank is the most memory-efficient and stable baseline. Since the writable variants have not produced a noticeable improvement in validation or test performance, it is still unclear whether the write mechanism contributes useful information, or whether the model solves the task almost entirely through the fixed source/read pathway.

An important limitation is that I have not yet performed a scaling comparison. The feature-bank capacity was fixed at 16 slots, so I do not yet know at which model size, bank size, context length, or task complexity each bank design becomes beneficial. In addition, this evaluation was limited to standard causal next-token pretraining.

I think it is necessary to compare the modes further with causal interventions, such as disabling writes, resetting mutable memory, freezing writes, and swapping mutable-bank contents. If these interventions do not reduce performance in the writable modes, that would be strong evidence that the model is not meaningfully using the write path.

Hi. I see. A null result is a result in its own right. Still, just to be safe, here are a few things I would keep in mind before deciding whether this is a genuine null result:


I think your current interpretation is reasonable:

In this reported configuration, adding writable Feature Bank variants has not produced a clear learning advantage, while Read-only remains the simplest and most memory-efficient baseline.

That is already useful. It narrows the design space and argues against adding more write machinery merely because it is available.

I would only separate four possible meanings of the apparent tie:

Kind of result What it would mean
Implementation null The mutable path is not actually surviving, reaching the output, receiving gradients, or being updated as intended.
Usage null The path works mechanically, but the trained model does not rely on it in this regime.
Aggregation null Writes help a subset such as long-context, difficult, late-token, or high-loss cases, but the aggregate metric hides it.
Practical null After matched repeated runs and causal checks, any remaining benefit is too small to justify the extra memory and complexity.

I would not infer an implementation problem merely from the similar metrics. There is no specific evidence of one in the result you reported. But a short integrity check would make the null result considerably stronger.

My preferred order would be:

  1. Verify the mutable state lifecycle and read-after-write path.
  2. Verify that the writer is trainable and actually updated.
  3. Run same-checkpoint no-write/reset/freeze interventions.
  4. Inspect write usage and conditional effects.
  5. Only then run larger scaling sweeps or redesign the writer.

The first three can be quite small.

A compact decision flow would be:

Does mutable bank_t survive and feed a later read or the output?
|
+-- No / unclear
|   +-- Check reset/carry logic, stale K/V, masking, aliasing,
|      and whether the last write has any consumer.
|
+-- Yes
    |
    +-- Does an exact write bypass or controlled perturbation change logits?
        |
        +-- No
        |   +-- Check branch execution, parameter registration,
        |      optimizer membership, detach, and checkpoint loading.
        |
        +-- Yes
            |
            +-- Does same-checkpoint no-write change normal behavior?
                |
                +-- No
                |   +-- Connected, but unused or redundant here.
                |
                +-- Yes
                    +-- The write path is causally used.
                    |
                    +-- Is the effect limited to particular subsets?
                        |
                        +-- Yes: aggregate metrics hide conditional utility.
                        +-- No: proceed toward a practical-equivalence test.
1. What the present result establishes — and what it does not

Your comparison currently supports several useful statements:

  • Read-only, Delta Protection, and Read & Write have similar reported learning performance in the tested configuration.
  • Read-only has the lowest reported memory cost.
  • The added writable mechanisms have not yet demonstrated a validation/test benefit that clearly pays for their additional state and computation.
  • Read-only is therefore the strongest default baseline for this regime so far.

I would avoid extending that yet to:

  • writable Feature Banks are generally unnecessary;
  • the three designs are statistically or practically equivalent;
  • the writer is definitely unused;
  • Read-only will remain preferable at other bank sizes, context lengths, model scales, iteration counts, or task complexities.

The wording “one run produced” is important here. One run can reveal a large benefit, a large regression, or an obviously disconnected path. It is usually not enough to establish that small differences are genuinely absent.

So I would describe the current result as:

No clear writable-memory advantage was observed in this configuration.

That is a defensible null result already. The remaining checks determine which kind of null it is.

2. Tier 0A — Does the mutable state survive and reach a consumer?

For an iterative memory architecture, this may be more important than the generic optimizer checks.

The intended lifecycle is presumably something like:

source_bank = Encoder(input)
mutable_0   = initialize(source_bank)

for t in 0 ... N-1:
    read_t      = read(source_bank, mutable_t, state_t)
    state_t+1   = update_state(state_t, read_t)
    mutable_t+1 = write(mutable_t, state_t+1, read_t)

output = head(state_N, and/or a final bank read)

A few inexpensive checks can verify that the actual computation has this lifecycle.

A. Initialize once, carry across iterations

Check that:

  • mutable memory is initialized once per example or sequence;
  • mutable_t+1 is actually passed into iteration t+1;
  • the loop does not reconstruct the mutable bank from the original source at every iteration;
  • mutable memory is reset between independent examples as intended;
  • state is not accidentally retained across batches unless that is deliberate.

A simple diagnostic log can record, for each iteration:

  • mutable-bank norm;
  • checksum or a few fixed entries;
  • delta from the preceding iteration;
  • whether the tensor/storage identity changes as expected.

It is possible for a writer and its gate to be active while every iteration silently starts again from the source bank. In that case, only a write consumed within the same iteration could matter.

B. Verify read-after-write

The most useful question is not only:

Did the model write?

but:

Did a later computation read what it wrote?

I would verify that:

  • iteration t+1 constructs its read keys/values from the updated bank;
  • K/V projections are not calculated once before the recurrent loop and then reused unchanged;
  • mutable slots are not excluded by an attention mask;
  • the written slots receive nonzero read mass later;
  • the output head consumes either the updated bank or a state that has read from it.

A particularly easy dead path is the final write:

If the last operation writes to the bank after the final read, and neither the head nor another iteration consumes that bank, the last write cannot affect the prediction.

This does not imply that earlier writes are dead, but it can reduce the effective number of useful write/read cycles from four to three, or fewer depending on the ordering.

C. Check source/mutable aliasing

If the protected source and mutable memory are created as tensor views, they may share underlying storage.

That may be intentional, but if the goal is to keep the source immutable, it is worth checking:

  • source_bank and mutable_bank do not unexpectedly share storage;
  • saved z_0, z_N, or per-iteration banks are not aliases of one tensor that is modified later;
  • a batch-expanded bank is not written in place.

PyTorch notes that tensor views can share storage, and Tensor.expand creates a view without allocating new memory; multiple logical elements may refer to the same location, making in-place writes unsafe unless the tensor is cloned first.

For the first diagnostic version, out-of-place updates are easier to audit:

mutable_next = retain * mutable + write_gate * candidate

rather than modifying the current bank in place.

Again, none of this is evidence that your implementation has an aliasing problem. It is simply a cheap branch to eliminate when several memory contracts produce unexpectedly similar behavior.

3. Tier 0B — Is the writer trainable, connected, and actually updated?

If the state lifecycle is correct, I would then check the ordinary learning path.

A. Parameter registration and optimizer membership

If the writer is dynamically constructed or stored inside a Python collection, confirm that:

  • it appears in model.named_parameters();
  • its parameter objects appear in the optimizer’s parameter groups;
  • dynamically repeated writers are held in registered containers such as nn.ModuleList, rather than an ordinary list;
  • the optimizer was created after the writer parameters were installed, or the new parameters were explicitly added.

This is not a claim that registration is broken. It is just a common silent failure mode that takes little time to rule out.

A useful one-time check is conceptually:

writer_ids = {id(p) for p in model.writer.parameters()}
optim_ids = {
    id(p)
    for group in optimizer.param_groups
    for p in group["params"]
}

assert writer_ids <= optim_ids

B. Check gradients and actual parameter movement separately

I would distinguish three things:

  1. a writer parameter receives a gradient;
  2. an intermediate mutable tensor receives a gradient;
  3. the optimizer actually changes the writer parameter.

Using optimizer.zero_grad(set_to_none=True) is useful diagnostically: according to the PyTorch optimizer documentation, parameters that receive no gradient remain None, which helps distinguish “no graph path” from an explicitly computed zero gradient.

For writer parameters, inspect:

  • .grad is None;
  • gradient norm;
  • finite/nonfinite values;
  • parameter norm before and after optimizer.step().

For an intermediate mutable-bank tensor, remember that it is usually a non-leaf tensor. Its .grad is not automatically retained. Use retain_grad() or a tensor hook if the intermediate gradient itself is needed.

Also check for accidental graph breaks:

  • .detach();
  • reconstruction through a detached copy;
  • a no_grad() region around the writer;
  • converting through NumPy or a newly constructed tensor.

Tensor.detach explicitly returns a tensor disconnected from the current autograd graph.

If mixed precision is used, actual parameter movement remains the final check. GradScaler may skip an optimizer step when nonfinite gradients are detected, so “a backward pass ran” is not always identical to “the writer was updated.”

C. Check checkpoint and variant construction

If the three variants are warm-started or derived from a shared checkpoint, record:

  • missing and unexpected state-dict keys;
  • which writer parameters are newly initialized;
  • whether the optimizer is constructed before or after loading/replacing modules;
  • trainable parameter count by variant;
  • the writer parameter names and initialization scale.

Using strict=False can be entirely appropriate for a partial warm start, but the returned missing/unexpected key lists should be inspected rather than silently discarded.

D. Wiring smoke test

Before interpreting ordinary write usage, verify that the path can affect the output at all.

For one fixed batch in deterministic evaluation mode, compare:

  1. normal write;
  2. write_scale = 0;
  3. a small finite perturbation;
  4. a matched mutable-bank replacement;
  5. only as a final wiring test, a large but finite perturbation.

Measure:

  • maximum and mean absolute logit difference;
  • loss difference;
  • changes in top predictions.

The distinction is important:

Observation Meaning
Even a large finite perturbation does not affect logits The mutable path may not reach the output, may be masked, or may not execute.
A large perturbation matters, but write_scale = 0 does not The path is connected, but normal learned writes may be negligible or redundant.
Exact no-write changes logits/loss The normal prediction depends causally on writes.

A very large perturbation is only a wiring smoke test. It is not evidence that the model normally uses the path.

4. Tier 1 — Connected does not necessarily mean used

Once the mechanical path is confirmed, your proposed same-checkpoint interventions become the most informative tests.

I would use the same trained checkpoint and change only inference-time state handling:

  1. disable all writes;
  2. force the delta to zero;
  3. reset only the mutable portion after each iteration;
  4. freeze writes starting at iteration t;
  5. disable reads from mutable slots while retaining source reads;
  6. replace only the mutable bank with a matched example’s mutable bank;
  7. include a self-swap as a null control.

This separates retraining adaptation from the normal causal role. A separately trained Read-only model can learn a substitute route; disabling writes in a writable checkpoint asks whether that checkpoint’s actual computation depends on them.

Suggested interpretation

Result Provisional interpretation
No-write does not change logits or loss Writes are unused or redundant in this regime.
No-write changes logits but not aggregate accuracy Writes affect computation, but not enough to change the coarse metric.
No-write worsens difficult/long examples only Conditional utility is hidden by aggregate results.
Reset after every iteration hurts Persistent mutable state matters.
Early write freeze hurts, late freeze does not Early updates are useful; later writes may be redundant.
Late freeze hurts Multiple write/read cycles may be contributing.
Mutable swap moves predictions toward the source example Mutable memory contains task-specific causal information.
Swap causes generic degradation without directional transfer The intervention is disruptive, but the encoded role remains unclear.

For swap tests, pair construction matters. I would include:

  • self → self;
  • same target or similar loss, different context;
  • different target, otherwise similar context;
  • similar context length;
  • easy → easy and hard → hard;
  • easy ↔ hard as a separate stress test.

Activation-patching research has shown that results can depend substantially on the corruption method, replacement source, and evaluation metric; see Towards Best Practices of Activation Patching and How to Use and Interpret Activation Patching.

For that reason, I would report not only accuracy but also:

  • loss;
  • correct-token logit;
  • correct-token margin;
  • KL divergence between normal and intervened outputs;
  • fraction of predictions moving toward the donor example.
5. Tier 2 — What is the writer doing, and where does it help?

A writer can be active without being useful, and useful without affecting the overall average much.

Useful telemetry

Per iteration, log:

  • write-gate mean, median, and histogram;
  • fraction of gates near zero and one;
  • delta norm;
  • delta norm relative to source/mutable-bank norm;
  • number or fraction of updated slots;
  • read attention placed on slots written in earlier iterations;
  • read/write slot overlap;
  • mutable-bank drift from initialization;
  • source-feature recoverability after writes;
  • writer gradient norm;
  • writer parameter-update norm;
  • loss or logit margin after each iteration.

This distinguishes several regimes:

Telemetry Possible interpretation
Gate and delta are almost zero Closed-path collapse or writes are unnecessary.
Gate is almost always open with large deltas The bank may be acting as an unrestricted scratchpad.
Writes occur but written slots are never read later Dead or decorative writes.
Written slots are read, but no-write is harmless Redundant information or an unused substitute representation.
Sparse writes correlate with difficult examples and no-write hurts those examples Plausible conditional workspace use.
Source recovery declines after writing Mutable computation may be overwriting useful reference information.
Delta grows each iteration while performance later declines Unstable accumulation or over-writing is possible.

Check for aggregation nulls before scaling the whole experiment

The overall next-token average may hide where writable memory matters.

Using the existing evaluation set, stratify by:

  • context length;
  • token position;
  • initial per-example loss;
  • rare versus frequent tokens;
  • early versus late training checkpoint;
  • examples with high versus low write activity;
  • iteration at which the prediction first stabilizes.

Some informative patterns would be:

  • writable modes learn faster initially but converge to the same final score;
  • Delta Protection helps only late tokens or long contexts;
  • Read & Write helps difficult examples but harms easy ones;
  • a small subset uses writes heavily while most examples ignore them;
  • writes affect confidence/calibration without changing top-1 accuracy.

If nothing appears in any reasonable subset, that strengthens the practical null without requiring an immediate large-scale sweep.

6. When does the tie become a practical null result?

After the integrity and causal checks, I would move from “no detected advantage” toward “practically equivalent in this regime” using matched repeated runs.

Ideally report:

  • each variant’s individual results, not only an example run;
  • the same split, training steps, batch size, context length, optimizer, schedule, precision, and stopping rule;
  • the same set of random seeds where practical;
  • mean/spread and paired differences;
  • trainable parameters;
  • peak allocated memory;
  • latency or throughput under the same measurement contract.

The key question is not only whether a difference is statistically detectable. It is also:

What improvement would be large enough to justify the extra mutable state, memory traffic, implementation complexity, and failure surface?

For example, one could decide in advance that a writable design is not practically worthwhile unless it provides at least one of:

  • a meaningful validation-loss reduction;
  • a clear long-context or hard-subset gain;
  • faster convergence to a fixed quality;
  • a capability unavailable to Read-only;
  • a memory/compute tradeoff that improves at larger scale.

If repeated matched runs keep the performance difference inside that practical margin, while Read-only remains cheaper, then the null result becomes a strong architecture decision:

Use Read-only for the current regime, and revisit writable memory only when the task or scale creates evidence of a mutable-workspace bottleneck.

That is a useful conclusion, not a negative one.

7. Runtime and memory numbers are useful, but secondary

The reported runtime numbers can help compare engineering cost, but I would make their measurement scope explicit:

  • which of the three variants they describe;
  • training step or inference;
  • forward only or forward + backward + optimizer;
  • batch size, sequence length, and precision;
  • whether padding tokens are counted;
  • warm-up procedure;
  • whether CUDA timing is synchronized.

CUDA work is asynchronous relative to the CPU, so a naive host timer may measure dispatch rather than completed GPU execution. PyTorch’s benchmark recipe and torch.cuda.Event are useful for reproducible GPU timing.

For memory comparisons, reset peak statistics immediately before the measured region with reset_peak_memory_stats, then report the same peak metric for every variant. Current allocated, reserved, and peak allocated memory describe different quantities.

I would keep this secondary to the causal question, though. A precise speed ranking does not tell us whether the write path is functionally used.

So my short interpretation would be:

  • The present tie is already a valid and useful observed null result.
  • There is no current basis for asserting a specific bug.
  • Before treating it as evidence that writable memory has no value, verify:
    1. persistent mutable-state lifecycle;
    2. read-after-write consumption;
    3. writer registration, gradients, and real parameter updates;
    4. same-checkpoint causal dependence;
    5. conditional effects hidden by averaging.
  • If those checks pass and matched repeated runs still show no practically meaningful gain, Read-only is not merely the simplest baseline — it is the justified default for this task regime.

At that point I would postpone both a more complicated writer and a broad scaling sweep until a task, context length, or difficulty range exposes a concrete need for mutable workspace.