I wanted to see if a tiny language model could follow a graph one step at a time, then keep going for much longer than it had practiced. I looped the middle layers of Qwen2.5-0.5B-Instruct and trained each loop to predict the next node. After several revisions, the executor follows every step correctly on 96.89% of 1,350 unseen graphs at 256 steps, after training on at most twelve.
A separate learned timer stops it at exactly the requested loop for every tested count from 1–256, with 97.78% correct final answers at 256. I gave the timer a counting structure and numerical training labels through 63. The result is specific to fixed-format graphs with 26 states, so longer paths revisit nodes. The experiments below show what failed along the way and how I separated execution from stopping.
It is no secret that Large Language Models have gotten really good. Throughout the last few years, the capabilities of models
in complex reasoning tasks such as coding and mathematics have improved significantly, coming along with leaps in pre-training and post-training techniques.
And innovations are not just at the frontier, smaller models can now also be trained to perform comparably when trained on specific, specialized tasks.
One of the recent advances in this area has been the introduction of the Recurrent Looped Transformer architecture. The idea is that we can get
more reasoning performance out of a language model by allowing it to loop over some selected layers multiple times before providing the outputs.
I found this idea quite interesting and wanted to investigate if this technique could be used to train a smaller language model to perform a specific, repetitive, procedural
task where each loop of the recurrent layers can represent a single step towards solving the overall problem.
The Task
I wanted a task built from simple steps that a tiny language model could learn to repeat.
The problem should also be something that can be programmatically solved to make it easier to benchmark and evaluate the model's performance later.
After some thought, I settled on a pointer-following task, which ends up being somewhat similar to traversing a cyclical directed graph when solved programmatically.
Let's define a node in this graph as a point that is assigned a letter of the alphabet - say (A) represents node A.
Nodes in this graph are connected by edges, with each one pointing to just one other node for simplicity's sake.
Let (A, B) denote the edge going from node A to node B.
To add complexity to this task, we use repetitions. Given a set of rules (which represent a graph), we define N to be a number of steps to take from a designated starting node. In future, I may refer to N as "depth" or "task depth".
The model is expected to follow the edges of the graph for N steps and return the node that it ends up at.
For example, given the following rules:
(A, B)
(B, C)
(C, A)
and a starting node of A with N = 4, the model should follow the transitions A → B → C → A → B and return B as the final node.
This task has some limitations. For starters, since I used single-lettered nodes, the number of unique nodes (and subsequently, rules) is limited to 26.
Secondly, having just one edge per node makes the task quite straightforward, that is another layer of complexity that can be added later. Some ideas
to add complexities to those can be to use double-lettered nodes, or to add another parameter such as a color to each edge to make the task more challenging.
However, my selected task serves as a good starting point to test the Recurrent Looped Transformer architecture and see if a tiny model can learn to reason through this task.
Data
Given the simple, structured nature of this task, I could generate a large amount of synthetic data rather easily.
I previously described the structure of the data required for this task.
For the initial experiments, I sample N+1 distinct letters and connect them into a path of N transitions, using its first letter as the starting node.
I then assign random destinations to all remaining nodes and shuffle the order of the rules. Each graph contains all 26 nodes, but its requested path never repeats a node.
Requested depths are balanced across the chosen range (which can be varied).
The fixed format also lets me determine the correct outputs (including traces to the final node) programmatically.
For reproducibility, I set seeds for all random number generators and generate multiple seeded datasets to evaluate generalizability to unseen graphs and depths.
Note that in later experiments, I change the generator to sample graphs independently of the requested depth, allowing repeated states and cycles. I will describe that change alongside the corresponding model.
Metrics
This task has a few different things that can go wrong. Just knowing that the final answer is wrong does not tell us whether the model followed the wrong edge, lost track after several steps, or stopped too early.
I designed the benchmark to help separate these problems. Some measurements only become relevant in later architectures, but I describe them together here.
The full benchmark uses 1,350 graphs across three generation seeds, with requested depths from 1 to 256. That gives us 345,600 graph/count queries per model. The graphs include random functions, permutations, and full 26-state cycles. In random functions, each node's destination is chosen independently. Permutations give every node exactly one incoming edge, while full cycles connect all 26 nodes into a single cycle.
This full benchmark suite was introduced later but I have retroactively applied it to the earlier models for comparison. I describe the smaller evaluations used during training alongside each run.
Since there are still only 26 nodes, longer runs necessarily revisit nodes.
Does the model get the answer right?
First, I check the answer after exactly N loops, regardless of whether the model wanted to stop earlier.
This is forced final accuracy, and it lets us evaluate graph execution separately from stopping.
I also check the answer at each intermediate loop, which gives us per-loop accuracy.
Did it take the correct steps to get there?
Getting the final answer right is not enough here.
The model could take a wrong step and still end up at the correct node later, especially when the graph has cycles.
So I also check whether every intermediate step was correct.
This is complete trajectory accuracy: here, just one wrong step makes the whole trajectory a failure.
Where does it start going wrong?
A model that fails immediately has a different problem from one that works for twenty steps before losing track.
I record the first incorrect loop and plot how many examples remain correct through each step, called survival.
I also measure the fraction of previously correct examples that fail at the next loop—the conditional first-error rate—and the average number of correct steps before failure.
These comparisons keep the requested count fixed, since changing the Steps field can also change the model’s behavior.
Does the requested count change the execution?
The correct state at a given loop should depend on the rules and starting node, even if I ask the model to keep going for longer afterward. I compare the same graphs at the same intermediate loop while changing only the requested count. This checks whether the number of steps in the prompt is affecting execution before it should need to stop.
Can it recover after a mistake?
After a wrong prediction, the model might stay wrong or return to the correct path.
I track how often predictions are wrong, how long those stretches last, and how often a wrong prediction is followed by a correct one.
The correct answer keeps moving through the graph, so recovery means matching the reference at the current step.
It does not erase the earlier mistake, and wrong stretches still continuing at the end are marked as unfinished.
What kind of mistake is it making?
At the first error, I check whether the model repeated the previous state, returned to another earlier state, predicted a reachable state it had not visited yet, or predicted a state outside the start node’s reachable path.
I assign these categories in that order to avoid counting an error twice.
I also check whether its predictions still follow valid graph edges after it loses track.
This is decoded transition consistency: the model can follow valid edges while being on the wrong part of the graph.
Is the problem in the recurrent block or in the final readout?
A later architecture lets us predict a letter directly from the recurrent block as well as through the final readout.
Comparing these predictions, especially at the first error, tells us whether the two readouts disagree.
For example, the direct prediction might be correct while the final readout is wrong. This helps locate a discrepancy, although it does not tell us exactly what the hidden state represents. Earlier architectures do not have this additional readout.
Does it know when to stop?
A model might execute the graph correctly but stop after six steps when we asked for ten.
Exact-stop accuracy checks whether its first stop signal occurs at exactly the requested loop.
I also separate early, late, and missing stops, and measure how far the signaled stops are from the requested count.
The benchmark uses a stop threshold of 0.5 and a safety cap of 272 loops (relevant to later architectures).
Reaching that cap without signaling counts as a missing stop.
Is it reading and updating the count correctly?
For the later controllers, I also check the initial count estimate and how the predicted remaining work changes over the loops. The GRU uses an auxiliary numerical readout for this diagnostic; the final timer has a scalar memory that we can inspect directly. I keep these smaller development and controller-only tests separate from the graph benchmark, and compare the numerical estimate with the actual stop signal.
Does the whole system work?
I check the letter returned when execution stops, but the right letter at the wrong time can be a coincidence on a cyclic graph.
End-to-end success therefore requires both the correct answer and exact stopping.
Strict autonomous success additionally requires every intermediate step to be correct.
Breaking outcomes down by answer correctness and stopping correctness helps show which part failed, and missing stops and correct letters reached only at the safety cap remain explicitly marked.
Which problems are harder?
I compare performance across requested depths and graph properties, including graph type, cycle length, the number of steps before entering a cycle, and the number of reachable states.
I separate familiar requested counts, held-out counts within the training range, and depths beyond training.
Seeing a number in a training prompt is different from being trained to execute that many steps.
Each comparison includes example counts as well as success rates.
How much confidence can we have in the comparison?
Testing the same graph at 256 requested depths does not give us 256 independent graphs.
To estimate uncertainty, I resample whole graphs within the seed and graph-type groups, keeping their queries together and using the same samples when comparing models.
This measures variation across graphs, not across training runs or untested numbers.
The later controller-only test through 8,192 steps is reported separately, since it tests stopping without executing the graph.
Baselines
Before changing the architecture, I wanted to see how well the original model could handle this task on its own.
This gives me a starting point to compare against when training the recurrent models.
Experiments
I ran three experiments on the same 1,350 graphs at requested counts 1–256, giving us 345,600 queries per experiment.
Just asking Qwen
I used the original Qwen2.5-0.5B-Instruct checkpoint, without any additional training.
I gave it three examples at depths 1, 2 and 3, each with its own rule table and final answer, followed by the graph to solve.
The prompt asks for just the final letter, without intermediate steps or an explanation.
I used Qwen's chat template and greedy decoding, with a maximum of eight output tokens.
I evaluated it on the same full benchmark described above. A response counts as correct only if it is the expected uppercase letter after removing surrounding whitespace.
The model can generate any token; answers that do not follow the requested format still count as failures.
Since it only returns a final answer, we cannot measure its intermediate trajectory or assign it a recurrent stopping time.
Letting it show its work
Asking for just the answer does not give the model room to write out the steps.
So, I gave the unchanged checkpoint three examples that show the intermediate states, and asked it to return every letter along the path, excluding the starting node.
The last letter in this sequence is its answer. The model has to generate the steps and decide when to stop on its own.
I kept greedy decoding and allowed up to 272 new tokens, enough to write out the longest requested trace.
Training the ordinary model
Next, I fine-tuned all 494 million parameters of the original model to generate these traces, keeping ordinary autoregressive generation.
I used the same 36,000 training examples used by the later recurrent executor, with requested counts 1–6, 8, 10 and 12.
Counts 7, 9 and 11 are left out as requested lengths, though those positions can still occur inside a longer training trace.
Training ran for one epoch, or 2,250 updates, with an effective batch size of 16.
The loss covers every response token, including the end-of-sequence token, but excludes the prompt.
During training, the model receives the correct preceding states. During evaluation, it has to continue from its own predictions.
I selected update 2,250 using validation loss on the trained counts.
Both trace experiments use the same prompt and generation settings. The direct-answer experiment uses FP32 and an eight-token budget,
while the trace experiments use BF16 and 272 tokens. So this is not an isolated test of changing the prompt alone.
Results
Just asking the instruct-tuned model for the final answer gets 6.25% of questions right. Asking for intermediate steps marginally helps, increasing this to 7.73%, while full SFT reaches 23.99%.
These averages cover all requested counts from 1 to 256. For the trace models, a correct last letter can still come from the wrong path or a trace of the wrong length and still count as correct in this metric.
Qwen · direct answer
6.25%
21,614 / 345,600 queries
Qwen · intermediate steps
7.73%
26,698 / 345,600 queries
Full SFT · intermediate steps
23.99%
82,894 / 345,600 queries
What happens as we ask for more steps?
All three baselines · choose a quality measure · higher is better
Larger = smoother
All graph types · 1,350 graphs at each requested count.
Loading chart. Summary measurements are available below.
Hover or tap for counts and 95% intervals · drag to zoom
Returned final-answer accuracy checks the last letter against the N-step answer, including wrong-length traces; invalid responses fail. Each point is a separate free-generation request. Shaded columns mark counts 7, 9 and 11, excluded from SFT training; the dotted line marks its maximum training count of 12. Lines average five neighboring requested counts; Raw shows the individual measurements. Hover reports the raw measurements and their pointwise 95% Wilson intervals, not uncertainty on the smoothed line.
Fine-tuning makes a huge difference on the trained counts - every transition is correct and the model stops at the right length on all 12,150 queries.
This does not carry over to unseen counts. Across 7, 9 and 11, only 6 of 4,050 queries succeed strictly, and none do beyond 12.
The plot above separates getting the answer right, following the path correctly, and stopping at the right time.
Without fine-tuning, only 45 responses have every transition correct and stop at exactly the requested length, so strict success is just 0.013%.
Giving the original model room to show its work is not enough to reliably solve this task.
Looking at the generated lengths helps explain the failures. When asked for 7 steps, the SFT model usually returns 6, while for 9, it always returns 8.
At 11, it gets every transition through step 11 right, but always emits a twelfth state before stopping.
It has learned to follow the graph at the trained lengths, but does not reliably apply the stopping rule to unfamiliar counts.
Where does it stop?
Both trace baselines · all 1,350 graphs at the selected requested count
Direct-answer Qwen returns one letter, so trace termination is not applicable.
Loading chart. The SFT model emits 12 states on every 11-step request.
Early, exact and late refer to the number of emitted states when EOS is produced. A well-formed response without EOS before the token cap is a budget failure; malformed responses are counted separately first. These five categories cover every query for each model. Exact termination alone does not require correct transitions. The length view counts parsed states, not tokens, and marks the requested count. It shows exact lengths near N and groups more distant lengths into wider bins; hover for their observed lengths and counts.
I also compared the models across graph types, cycle lengths, steps before entering a cycle and the number of reachable states.
The plot below keeps the same graph groups for all three models, so we can see where each one succeeds or struggles.
Which graph structures are harder?
All three baselines · returned final-answer accuracy across the selected counts
450 graphs per type · 115,200 queries per type in this range.
Loading chart. Full-range values are given above.
Structure views compare graphs within one graph type, since all full cycles have length 26. Reachable states include the starting node; steps before cycle counts transitions before first entering the cycle. Hover for graph and query counts. Error bars show 95% intervals from resampling whole graphs within each seed/type/bin; small groups have less evidence, and empty bins are marked N/A. These are associations, not isolated effects of each property.
The direct-answer prompt returns Z on 45.02% of questions, even though Z is only correct on 3.77% of them.
So, returning a valid letter almost every time does not mean it is choosing among the letters well.
Here we can compare that behavior with the last letters returned by both trace models on the same questions.
Which letters do they keep choosing?
All three baselines · returned letters compared with the actual answer distribution
345,600 queries per model · invalid responses remain in every denominator.
Loading chart. The largest difference is described above.
Every series uses all queries in the selected range as their denominator. The dashed reference line shows the actual correct letters, rather than assuming a uniform distribution. Invalid responses are not letter bars, but remain in the denominator. This shows which answers are overrepresented; it does not reveal the model's internal reasoning.
Finally, these are the SFT training curves. Validation uses the correct preceding tokens, so its low loss does not tell us whether the model can generate and stop correctly on its own.
Only the SFT experiment has a training curve; the other two use the unchanged checkpoint.
Learning to write out the steps
Full ordinary-model SFT · response-token loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available below.
Hover or tap for values · drag to zoom · switch to logarithmic to see the smaller losses
Full-vocabulary cross-entropy, averaged over response tokens within each example, then across examples. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 576 fixed examples at the nine trained counts, measured every 250 updates. Both losses use correct preceding tokens; free-generation results are shown above.Training details and validation measurements
All 494,032,768 parameters are trainable, including the embeddings, all 24 transformer layers, final norm and tied output head. AdamW uses a peak learning rate of 2 × 10−5, 100 warmup updates, cosine decay to 10% of the peak, weight decay 0.01 and gradient clipping at 1. The objective includes the generated states and EOS, with no loss on prompt tokens.
Teacher-forced validation · trained counts only · response cross-entropy (nats)
Original Qwen · all graph types · final-answer accuracy
Requested steps
Correct / queries
Accuracy
95% interval
1–6
625 / 8,100
7.72%
6.96–8.52%
7–12
466 / 8,100
5.75%
5.10–6.46%
13–32
1,790 / 27,000
6.63%
6.01–7.29%
33–64
2,780 / 43,200
6.44%
5.78–7.13%
65–128
5,167 / 86,400
5.98%
5.38–6.65%
129–256
10,786 / 172,800
6.24%
5.64–6.93%
All · 1–256
21,614 / 345,600
6.25%
5.65–6.92%
Range averages weight requested counts equally. These intervals resample whole graphs within seed and graph-type groups, keeping their requests together. They measure variation across graphs, not across prompts or training runs.
Trace-baseline measurements and evaluation details
All graph types · free generation · count groups defined by the SFT training set
Model
Requested counts
Correct last letter
Strict successes / queries
Strict success
Original · traces
Trained · 1–6, 8, 10, 12
6.54%
45 / 12,150
0.370%
Full SFT · traces
Trained · 1–6, 8, 10, 12
100%
12,150 / 12,150
100%
Original · traces
Held out · 7, 9, 11
5.01%
0 / 4,050
0%
Full SFT · traces
Held out · 7, 9, 11
9.23%
6 / 4,050
0.148%
Original · traces
Beyond training · 13–256
7.80%
0 / 329,400
0%
Full SFT · traces
Beyond training · 13–256
21.36%
0 / 329,400
0%
Original · traces
All · 1–256
7.73%
45 / 345,600
0.013%
Full SFT · traces
All · 1–256
23.99%
12,156 / 345,600
3.517%
Both trace baselines use greedy, unrestricted-vocabulary generation with BF16/SDPA and a 272-token cap, on the same 1,350 graphs at each N from 1 to 256. No correct intermediate states are supplied at evaluation. The original checkpoint receives three trace demonstrations. Compared with the direct-answer baseline above, the prompt, output budget and precision differ; this is not an isolated test of one prompting change.
Both completed runs passed independent artifact audits. A separate 54-query check against native generation agreed on all scored outcomes, though not every token continuation. The downloadable data includes pointwise intervals, whole-graph bootstrap intervals for count groups, and source hashes.
Full SFT clearly teaches the model something useful: it can generate the entire path and stop correctly at every trained count on this benchmark. The problem is carrying that behavior to unfamiliar requested lengths. The eleven-step example makes this particularly clear, since it follows all eleven transitions correctly and then generates one more. Low training loss and a correct final letter would each miss part of that failure.
This gives us a baseline of what the instruction-tuned model can do, and also what vanilla SFT can bring to the table. It does not show that ordinary transformers cannot solve the task with another recipe. Full SFT also updates many more parameters than the recurrent models, and a generated token is not equivalent to one recurrent loop in compute cost. The recurrent readouts choose among 26 letters, while ordinary generation uses the full vocabulary. The final timer also receives separate numerical supervision through 63, whereas trace SFT uses requested lengths through twelve. These differences mean the comparison cannot isolate the benefit of recurrence alone.
The First Attempt
Model Architecture
For all training experiments, I start with the Qwen2.5-0.5B-Instruct checkpoint; model specs can be found here.
Let us call layers 0-5 P, layers 6-17 R, and layers 18-23 C. For this first attempt, I freeze the P and C blocks and only train the LoRA adapters within R, the recurrent block.
I take ht at the end of R and feed it back into the input of R for the next step, then ht+1 = R(ht).
The output of C is used to generate the final output.
The complete [batch, sequence, 896] P output initializes h0.
With R being reapplied to all positions at every loop, representations of rules, start, steps and the answer position are all allowed to evolve together.
The original causal mask and RoPE positions are reused. Rank-8 q/v LoRA in R supplies 270,336 trainable parameters.
This model must learn to loop over the graph, following the correct path at each step. For this initial experiment, I supply the correct loop count during training and evaluation.
Inside the first architecture
Encode, Loop, Decode.
3 loops supplied externally
Rules A → B · B → C · C → D · …Start ASteps 3
01
Start with the whole prompt
Rules, Start and Steps are embedded together. P prepares the initial hidden state once.
Loop
Conceptual inference flow: the hidden state loops through R, and C reads the final answer when the supplied loop budget is reached. In the actual implementation, I also decode through C at every loop to supervise intermediate steps during training and measure them during evaluation. These readouts do not feed back into R. This is an ideal three-step example, not a recorded model trace; grid colors are schematic.Diagram notes & visual references
The prompt above is an excerpt; actual tasks contain all 26 rules. Embeddings, original transformer weights, final normalization and the language-model head are frozen. The answer-position readout is restricted to the 26 letter tokens. The full state recurs with the same causal mask and RoPE positions, and gradients pass through C and all preceding loops during training.
Visual inspiration: the tensor blocks in Jay Alammar’s The Illustrated Transformer and the inspectable flow in Georgia Tech’s Transformer Explainer. This diagram is drawn specifically for this architecture.
Training
I trained the LoRA adapters on 30,000 synthetic examples, with 5,000 examples at each requested depth ranging from 1 to 6.
Each example used a different rule table, with a nonrepeating path through its requested depth.
I used an AdamW optimizer with a learning rate of 2e-4 (10 warmup updates, then constant), weight decay was 0.
I set the batch size to 4, accumulating gradients over 2 batches (effective batch size of 8). I also clipped gradients to a maximum norm of 1.0. I trained for 1 epoch (3,750 steps).
The training objective was cross-entropy over the 26 possible letter outputs, targeting the correct symbol after exactly t transitions at loop t.
I averaged the losses across the requested transitions within each example, then across examples so that each example contributed equally, so a six-step problem did not contribute six times as much loss as a one-step problem.
Loss masks remove loops after an example's requested N. Earlier hidden states remain in the autograd graph so that earlier loops can be trained from later losses.
Note that while the trainer knows t, N and reference states for labels, it does not feed those labels back into the model.
There was no stopping loss in this first attempt.
Every 250 steps, I ran a validation set of 32 examples each at depths 1-8 (256 examples total).
This is to measure performance on unseen graphs, and also on unseen depths to see whether the model can generalize to longer paths with just a small set of training depths.
Depths 1-6 measured in-distribution performance, while depths 7-8 measured extrapolation.
Learning the next transition
Training and validation loss · lower is better
Larger = smoother
Loading interactive chart. Validation measurements are also available in the table below.
Hover or tap for values · drag to zoom · use Reset view to restore the axes
Training shows a trailing 50-update, example-weighted mean; initial windows use available updates.
Each raw update uses 8 examples. Validation is unsmoothed and uses 192 fixed examples at depths 1–6, measured every 250 updates, including initialization at update 0.
Both losses average transitions within each example, then examples. Validation measures a fixed cohort; training batches change at every update.
Does learning extend beyond six steps?
Complete trajectories on unseen validation graphs · higher is better
Loading interactive chart. Validation measurements are also available in the table below.
Hover or tap for counts · toggle curves to compare · drag to zoom
A trajectory counts as correct only when every intermediate letter through the requested depth is correct.
Depths 1–6 contain 192 examples; depths 7 and 8 contain 32 each. All are fixed validation cohorts, with no smoothing.
Lines connect measured checkpoints; there are no validation measurements between the markers.
These small development cohorts are separate from the later full evaluations and population benchmark.
The dotted vertical lines mark updates 2,500 and 3,250; I explain the checkpoint choice below.
View all 16 validation measurements and source data
Mean cross-entropy on the fixed 192-example validation cohort at depths 1–6.
The export includes all 3,750 raw training losses, cohort counts, run configuration, metric definitions and source-file SHA-256 hashes.
Validation aggregates were checked against all 16 saved prediction CSVs. No new model inference was used.
Results
For the full benchmark, I used the checkpoint at 2,500 updates, which I had retained for its stronger depth-extension results on the earlier development evaluations.
This is different from update 3,250, which had the lowest validation loss at trained depths. The checkpoint was chosen before running this benchmark.
I use the full suite described above, and unlike the training paths, these graphs can revisit nodes even within the first six steps.
Since this version has no stopping head, I supply the requested number of loops and read the answer through C.
The results below measure execution with that loop budget supplied, not whether the model knows when to stop.
Complete trajectory · N = 6
94.81%
1,280 / 1,350 graphs
Complete trajectory · N = 12
1.11%
15 / 1,350 graphs
Complete trajectory · N = 256
0%
0 / 1,350 graphs
Over requested counts 1–6, the model gets 97.53% of final answers right. It also completes 91.78% of trajectories at seven steps and 87.11% at eight.
But this drops sharply as we ask it to go further. At twelve steps, just 81/1,350 graphs end on the correct letter, while only 15 have every step correct.
So I plot both measurements together to keep that difference visible.
How far does it keep working?
Checkpoint 2,500 · 1,350 graphs at each requested count
Loading chart. Summary measurements are available below.
Each N is a separately prompted rollout. The dotted line marks the six-step training limit. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. Optional bands are pointwise 95% Wilson intervals.
To see where it starts going wrong, I keep the requested count fixed and follow the predictions within that rollout.
With Steps = 32, the average correct prefix is 8.83 steps, and only two of the 1,350 graphs remain correct throughout.
Most first errors fall between loops 9 and 12, a few loops beyond the training limit. The histogram counts successful trajectories separately.
When does it first lose the path?
First-error distribution · one fixed request per graph
Steps = 32 throughout · mean correct prefix: 8.83 loops · 2 / 1,350 complete trajectories.
Loading chart. Summary measurements are available below.
Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
I also checked what happens after a mistake. For the 32-step requests, 1,238 of the 28,546 transitions following a wrong prediction return to the correct reference state, or 4.34%.
The views below separate this from continuing along a valid edge on the wrong path, and show what the first mistakes and later wrong stretches look like.
What happens when it loses track?
First errors, recovery, decoded edges and wrong-stretch lengths
1,348 failed graphs; each contributes exactly one first error. Two graphs have no error.
Loading chart. Summary measurements are available below.
First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
Finally, I break the results down by graph structure. At six steps, complete trajectory accuracy is 92.22% on random functions, 95.11% on permutations, and 97.11% on full cycles.
We can then compare shorter and longer cycles within each graph type, rather than mixing all three types together.
Which graphs does it struggle with?
Compare graph properties at a fixed requested depth
Fixed Steps = 6 · all 1,350 graphs · one query per graph.
Loading chart. Summary measurements are available below.
Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.View key measurements and evaluation data
Checkpoint 2,500 · each row uses 1,350 graphs
Requested steps
Final answer correct
Complete trajectory
1
1,344 / 1,350 · 99.56%
1,344 / 1,350 · 99.56%
6
1,289 / 1,350 · 95.48%
1,280 / 1,350 · 94.81%
7
1,249 / 1,350 · 92.52%
1,239 / 1,350 · 91.78%
8
1,186 / 1,350 · 87.85%
1,176 / 1,350 · 87.11%
12
81 / 1,350 · 6.00%
15 / 1,350 · 1.11%
32
52 / 1,350 · 3.85%
2 / 1,350 · 0.15%
256
60 / 1,350 · 4.44%
0 / 1,350 · 0.00%
Within fixed requests · the same 1,350 graphs at each N
Request
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.82 loops
2.54%
9 / 145 · 6.21%
12
8.65 loops
26.01%
199 / 2,945 · 6.76%
32
8.83 loops
69.08%
1,238 / 28,546 · 4.34%
256
8.81 loops
92.73%
11,903 / 319,189 · 3.73%
Correct-prefix length includes complete successes at their full requested length. Wrong loops use all graph/loop observations; recovery uses transitions following a wrong prediction, excluding a final wrong state with no observed next step.
The main result is that the model learns to follow a path through the training lengths, performing very well on lengths 1-6 on unseen graphs.
It also generalizes to lengths 7-8 (though not as well), but performance drops sharply after that.
Looking into what the first-error actually is can be informative for understanding the model's behavior.
The first errors are fairly evenly spread between the failure modes of repeated state, another earlier state, a later reachable state, or a state outside the reachable path from the starting node.
This seems like the model is simply learning to output any letter past the training depth rather than learning to follow the graph structure. The error categories alone do not prove that the choices are random, but the sharp loss of complete trajectories shows that the execution is no longer reliable.
My analysis of the type of graphs the model struggles with shows that out of the graph structures, the model gets some answers right on random functions.
However, complete trajectory accuracy is low across all three families at 12 steps, and by 32 steps only random functions retain any complete successes.
No family retains a complete trajectory at length 256. With so few complete successes at the longer depths, I do not think there is a reliable graph-specific behavior to build on here.
There is also a part of the task this first version never had to learn: when to finish. I supplied the loop budget myself, so before revising the recurrence I wanted to see what happened when the model had to make that decision too.
The First Revision
Model Architecture
For this version, I wanted the model to decide when to stop by using the requested steps already present in the prompt.
I kept the same P, R and C split, with the original Qwen weights frozen and rank-8 q/v LoRA adapters in R.
The first change was to add a small stopping head that reads the answer-position hidden state after each R loop.
It uses LayerNorm, a 896-to-128 linear layer, GELU, and a final scalar output converted to a stop probability by a sigmoid.
It has no separate memory or external counter, so it has to learn progress from the hidden state.
During inference, the model stops at the first probability of at least 0.5 and returns the letter decoded through C, with a fixed safety cap if no stop is predicted.
In this version, the entire sequence still changes on every loop. I train the stopping head jointly with the adapters, bringing the total to 387,073 trainable parameters.
This means learning when to stop can also change how R learns to follow the graph. Neither the stop prediction nor the decoded letter is fed back into R.
Training
I used the same data, optimizer settings, training budget and validation schedule as the first attempt.
The new part of training was the stopping loss. I kept the letter cross-entropy at every requested step and added binary cross-entropy with a weight of 0.1: continue before N, stop at N.
To keep the single stop label from being outweighed by the continue labels, I gave the mean continue loss and final stop loss equal weight. For one-step examples, the stopping objective only contains the stop term, since there are no preceding continue steps.
Training still runs through the requested depth even if the head predicts an early stop, with no supervision after that depth.
Learning the next transition
Letter-prediction loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Cross-entropy over the 26 letters, averaged over requested transitions within each example, then across examples. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 192 fixed examples at depths 1–6, measured every 250 updates.
Learning when to stop
Continue/stop loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Balanced binary cross-entropy, shown before multiplying by its training weight of 0.1. Each example gives equal weight to its mean continue loss and final stop loss; a one-step example has no continue term in its stopping loss. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 192 fixed examples at depths 1–6, measured every 250 updates.
The dotted line marks update 3,250, selected by the lowest letter-prediction validation loss at depths 1–6. Stopping loss did not select the checkpoint. These are the original development curves; the full benchmark is separate.
View validation measurements and source data
192 fixed validation examples at depths 1–6. Stop BCE is balanced and unscaled.
The shared export contains both architecture 2 and 3a histories. This section shows this run’s 3,750 training updates and 16 saved validation checkpoints, checked against their per-loop prediction CSVs. Configurations and source hashes are included.
Results
I evaluated update 3,250 on the same 1,350 graphs at requested counts 1–256.
There are now two things to check: whether it can follow the path when I supply the loop budget, and whether it can return the right answer when it decides when to stop.
Complete trajectory · N = 6
92.89%
1,254 / 1,350 graphs · forced depth
Complete trajectory · N = 7
70.30%
949 / 1,350 graphs · forced depth
Complete trajectory · N = 12
0.37%
5 / 1,350 graphs · forced depth
With the stopping head ignored, final-answer accuracy over counts 1–6 is 97.85%.
But execution still breaks down beyond training. Complete trajectory accuracy falls to 70.30% at seven steps, 27.56% at eight, and 0.37% at twelve.
At eight steps, the first attempt still completed 87.11% of paths. So this version loses the path sooner, even when an early stop cannot cut the rollout short.
Can it still follow the path?
Stopping head ignored · 1,350 graphs at each requested count
Loading chart. Summary measurements are available below.
Each N is a separately prompted rollout, forced through N loops. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. The dotted line marks the six-step training limit. Lines are unsmoothed; hover for graph counts and pointwise 95% Wilson intervals, also available as optional bands.
To see where execution goes wrong, I kept Steps = 32 and ignored the stopping head throughout.
The average correct prefix is now 6.34 steps, compared with 8.83 in the first attempt, and none of the 1,350 graphs stays correct through all 32.
Most first errors occur at loops 7–8: 1,052 graphs fail there, rather than the concentration at loops 9–12 we saw before.
When does it first lose the path?
Stopping ignored · first error within a fixed request
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
The first errors are still spread across the same four categories, but their proportions have changed.
Repeating the previous state now accounts for 27.19% of first errors, compared with 19.44% before. Returning to another earlier state falls from 24.18% to 14.44%.
So the broad failure modes are similar, but this is not exactly the same pattern.
Recovery remains uncommon. Of the 31,995 transitions following a wrong prediction, 1,276 return to the correct reference state, or 3.99%, compared with 4.34% before.
Only 3.20% of transitions after a wrong prediction follow a valid edge from the previous decoded letter, whether or not they recover.
I also counted 2,569 wrong stretches, with 1,293 still ongoing at loop 32. The views below retain the same error, recovery, edge and wrong-stretch breakdowns as the first attempt.
What happens when it loses track?
Forced rollouts · first errors, recovery, decoded edges and wrong stretches
Stopping ignored · all 1,350 graphs have a first error.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
The graph-type ordering at six steps is similar too: complete trajectory accuracy is 89.56% on random functions, 92.22% on permutations, and 96.89% on full cycles.
The structure views below also keep the cycle-length, steps-before-cycle, reachable-state and generation-seed breakdowns.
At 32 steps, no graph type has a complete trajectory, so the later failure is not confined to one of these groups.
Which graphs does it struggle with?
Stopping ignored · compare graph properties at a fixed requested depth
Fixed Steps = 6 · all 1,350 graphs · one query per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.
When I let the head decide, it stops at the right loop on 98.49% of requests within counts 1–6, and gets both the answer and stopping time right on 96.47%.
Beyond depth 6, this disappears completely - every single one of the remaining 337,500 requests stops early.
The next plot separates getting the stopping time right from getting both the answer and stopping time right.
Does it know when to stop?
First stop probability ≥ 0.5 · fixed cap of 272 loops
Loading chart. Summary measurements are available below.
Exact stop requires the first threshold crossing to occur at N. Correct answer + exact stop additionally requires C’s returned letter to match the N-step answer; it does not require every earlier letter to be correct. A correct letter at the wrong loop is not a success. The cap is independent of N, and reaching it without a stop would count as a stopping failure. Lines are unsmoothed; hover for counts and pointwise 95% Wilson intervals.
Asking for more steps does not make it run for longer. For seven-step requests, it stops at five or six; for eight, it always stops at five.
At twelve, 1,314 graphs stop at loop three and the remaining 36 at loop four. At 256, it stops at loop two or three.
The plot below shows those four requests together: the stopping time moves earlier in these examples as the requested count grows.
Across the full benchmark, it never chooses to run beyond six loops.
What does it do with a larger request?
Rows: requested steps · columns: actual stopping loop · 1,350 graphs per row
Loading chart. Summary measurements are available below.
Each row is a separate requested count on the same 1,350 graphs. Columns show the first loop where the stop probability reaches 0.5. Cell percentages use that row’s 1,350 graphs; a dash means no graph stops there. All observed stops are within loops 1–6, so no later stops are omitted. These are stopping times, not first-error locations or answer accuracy.View key measurements and evaluation data
Across the 8,100 requests at counts 1–6, exact stopping succeeds on 7,978 and correct answer + exact stop on 7,814. Neither succeeds on any of the 337,500 requests beyond six. All observed stops occur before the cap.
Forced execution within fixed requests · 1,350 graphs at each N
Requested steps
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.86 loops
2.19%
8 / 88 · 9.09%
12
6.85 loops
40.88%
295 / 5,327 · 5.54%
32
6.34 loops
77.06%
1,276 / 31,995 · 3.99%
256
6.68 loops
93.76%
11,523 / 322,729 · 3.57%
Correct-prefix length includes complete successes at their full requested length. Wrong loops use all graph/loop observations; recovery uses transitions following a wrong prediction, excluding a final wrong state with no observed next step. These diagnostics continue past the learned stop to measure execution.
The stopping head learns the familiar lengths quite well, but it does not extend that behavior when I ask for more steps. The forced rollouts also get worse, so early stopping is not the only reason this version fails. I am asking the same evolving state to support both following the graph and deciding when the work is done.
One possibility is that these objectives interfere with one another. The comparison does not establish that, especially since the two versions use different selected updates, but it gave me a reason to separate the problems more carefully. Another thing that stood out was that the representations of the rules were being transformed on every loop, even though the graph never changes. I wanted to start by keeping that information fixed.
Architecture 3a
A Fixed Prompt
Model Architecture
In the previous versions, the entire hidden state changes each time we loop through R, including the representations of the rules, start and requested steps.
I wanted to keep that prompt information fixed and let only the answer position change as the model follows the graph.
P still encodes the full prompt once. At each R layer, I keep the prompt representations from the first pass and reuse them on later loops.
Only the 896-dimensional vector at the answer position is allowed to change and feed back into R. C also reuses its own layer-specific prompt representations when reading the answer.
This memory is fixed within a rollout, but it is recomputed for each forward pass and remains in the autograd graph during training.
I kept the same adapters and stopping head as the previous version. The requested steps are still present in the prompt.
I changed where the model can write, without adding a separate counter or controller memory.
Inside architecture 3a
Keep the prompt fixed.
Prompt representations stay fixed at each layer. Only the 896-dimensional answer-position vector evolves.
Rules A → B · B → C · C → D · …Start ASteps 3
01
Encode the prompt once
P prepares the full sequence. The requested count is present as text, with no separate numeric counter.
Loop
Conceptual inference flow: H decides whether to continue, and C reads the final answer once recurrence stops. In the actual implementation, I also decode through C at every loop to supervise intermediate steps during training and measure them during evaluation. Training runs the requested rollout regardless of H. This is an ideal example, not checkpoint predictions. In 3a, the gray prefix stays fixed and only the teal answer-position vector recurs; colors are schematic.What is fixed in architecture 3a?
Every R and C layer reuses its own prompt-prefix representations from the first pass. Only the final answer position changes between loops. This memory is recomputed for each forward pass and remains differentiable during training. The original Steps text stays in the prompt; no parsed count, loop index, predicted letter or stop decision is inserted into the recurrent state.
I trained this version from fresh adapters, using the same data, optimizer settings, training budget, losses and validation procedure as the previous version.
The change was the fixed prompt memory described above.
Learning the next transition
Letter-prediction loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Cross-entropy over the 26 letters, averaged over requested transitions within each example, then across examples. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 192 fixed examples at depths 1–6, measured every 250 updates.
Learning when to stop
Continue/stop loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Balanced binary cross-entropy, shown before multiplying by its training weight of 0.1. Each example gives equal weight to its mean continue loss and final stop loss; a one-step example has no continue term in its stopping loss. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 192 fixed examples at depths 1–6, measured every 250 updates.
The dotted line marks update 3,250, selected by the lowest letter-prediction validation loss at depths 1–6. Stopping loss did not select the checkpoint. These are the original development curves; the full benchmark is separate.
View validation measurements and source data
192 fixed validation examples at depths 1–6. Stop BCE is balanced and unscaled.
The shared export contains both architecture 2 and 3a histories. This section shows this run’s 3,750 training updates and 16 saved validation checkpoints, checked against their per-loop prediction CSVs. Configurations and source hashes are included.
Results
I evaluated update 3,250 on the same graphs and requested counts as before. Keeping the prompt fixed does help execution past the training depth, but it still does not solve stopping.
Complete trajectory · N = 6
93.85%
1,267 / 1,350 graphs · forced depth
Complete trajectory · N = 8
85.93%
1,160 / 1,350 graphs · forced depth
Complete trajectory · N = 12
2.15%
29 / 1,350 graphs · forced depth
With the stopping head ignored, complete trajectory accuracy is 92.00% at seven steps and 85.93% at eight, up from 70.30% and 27.56% in the previous version.
At nine it falls to 57.41%, then 8.30% at ten. So we get a few more useful steps, but the sharp drop is still there. At eight steps, this is also still slightly below the first attempt’s 87.11%.
Can it still follow the path?
Stopping head ignored · 1,350 graphs at each requested count
Loading chart. Summary measurements are available below.
Each N is a separately prompted rollout, forced through N loops. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. The dotted line marks the six-step training limit. Lines are unsmoothed; hover for graph counts and pointwise 95% Wilson intervals, also available as optional bands.
For the same Steps = 32 diagnostic, the average correct prefix increases from 6.34 to 7.77 loops.
There are now four complete trajectories out of 1,350. Most first errors have moved to loops 9–12, where 880 graphs first lose the path.
When does it first lose the path?
Stopping ignored · first error within a fixed request
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
The timing of those errors is worth looking at more closely. Among paths that are still correct, the chance of making the first error rises from 5.27% at loop seven to 23.61% at eight, 69.98% at nine and 81.25% at ten.
This is a sharp increase in failure risk, rather than just the same small chance of an error accumulating at every step. There are only 272 correct paths left entering loop ten, so the later percentages also need to be read with their denominators.
Does each extra step carry the same risk?
Stopping ignored · first errors among paths correct through the previous loop
Loading chart. Summary measurements are available below.
Each point divides new first errors by graphs correct at every earlier loop within the same requested rollout. Hover shows both counts; bars are pointwise 95% Wilson intervals. The denominator shrinks after failures, so later points can represent very few graphs. No eligible graphs means N/A, not zero risk. The dotted line marks the six-step training limit.
The failure modes are familiar, but repeating the previous state is now the largest group: 564 of the 1,346 failed graphs, or 41.90%, compared with 27.19% before.
The remaining first errors return to another earlier state (15.45%), predict a later reachable state (17.83%), or leave the start’s reachable states (24.81%). Repeating a decoded letter does not tell us whether the hidden state has stopped changing.
Recovery is still uncommon: 1,273 of 30,032 transitions after a wrong prediction return to the reference state, or 4.24%, compared with 3.99% before.
Only 2.55% follow a valid edge from the previous decoded letter. There are 2,560 wrong stretches, with 1,287 still ongoing at loop 32. The different views below show the same breakdowns as before.
What happens when it loses track?
Forced rollouts · first errors, recovery, decoded edges and wrong stretches
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
At six steps, complete trajectory accuracy is 89.56% on random functions, 96.22% on permutations and 95.78% on full cycles.
Random functions are still the hardest group here, but fixing the prompt has not improved every group: full cycles are slightly below the previous version’s 96.89%.
The other views keep the breakdowns by cycle length, steps before the cycle, reachable states and generation seed.
Which graphs does it struggle with?
Stopping ignored · compare graph properties at a fixed requested depth
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.
Fixing the prompt also does not make execution independent of the requested count. On the same graphs, the correct letter at loop nine should be identical whether I ask for nine steps or 32.
But loop-nine accuracy falls from 58.37% to 22.52% when I change that request. Of the 788 graphs correct with Steps = 9, 495 become wrong with Steps = 32, while only eleven change from wrong to correct.
The plot below holds the readout at loop nine and changes only the requested count. The effect is not a steady decline as N grows; the executor is sensitive to the request even though the rules and start are unchanged.
Does asking for more steps change the same intermediate answer?
Same 1,350 graphs · always read at loop nine · stopping ignored
Loading chart. Summary measurements are available below.
Every point reads C at executed loop nine from a separate prompt with the displayed requested N. This is intermediate-letter accuracy, not final-answer or complete-trajectory accuracy. Lines are unsmoothed. Hover includes counts, pointwise 95% Wilson intervals, changed letters and paired gains/losses against Steps = 9. This shows sensitivity to the Steps text, including its tokenization and positions; it does not identify the internal cause.
Within counts 1–6, exact stopping improves to 99.72%, and correct answer plus exact stop to 97.70%.
Beyond six, only eight of the 337,500 requests get both right, all at Steps = 7. Every other request stops early. The execution improvement has not carried over to learning when to stop.
Does it know when to stop?
First stop probability ≥ 0.5 · fixed cap of 272 loops
Loading chart. Summary measurements are available below.
Exact stop requires the first threshold crossing to occur at N. Correct answer + exact stop additionally requires C’s returned letter to match the N-step answer; it does not require every earlier letter to be correct. A correct letter at the wrong loop is not a success. The cap is independent of N, and reaching it without a stop would count as a stopping failure. Lines are unsmoothed; hover for counts and pointwise 95% Wilson intervals.
For seven-step requests, 1,334 graphs stop at loop six, eight at five and eight at seven. For eight-step requests, 1,324 stop at six, nine at five and seventeen at seven.
At twelve, the stops split between loops five and six; at 256, 1,304 of the 1,350 graphs stop at five. These are the four requests shown together below. Across the full benchmark, no stop occurs beyond loop seven.
What does it do with a larger request?
Rows: requested steps · columns: actual stopping loop · 1,350 graphs per row
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
Each row is a separate requested count on the same 1,350 graphs. Columns show the first loop where the stop probability reaches 0.5. Cell percentages use that row’s 1,350 graphs; a dash means no graph stops there. All observed stops are within loops 1–7, so no later stops are omitted. These are stopping times, not first-error locations or answer accuracy.View key measurements and evaluation data
Across counts 1–6, forced final answers are correct on 7,927/8,100 requests, exact stopping on 8,077 and correct answer + exact stop on 7,914. There are 19 early and four late stops. Beyond six, eight requests stop exactly and 337,492 stop early. No request reaches the cap without a stop.
Forced execution within fixed requests · 1,350 graphs at each N
Requested steps
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.84 loops
2.49%
8 / 126 · 6.35%
12
8.11 loops
31.10%
198 / 3,790 · 5.22%
32
7.77 loops
72.50%
1,273 / 30,032 · 4.24%
256
7.78 loops
93.16%
12,440 / 320,656 · 3.88%
Correct-prefix length includes complete successes at their full requested length. Wrong loops use all graph/loop observations; recovery uses transitions following a wrong prediction, excluding a final wrong state with no observed next step. These diagnostics continue past the learned stop to measure execution.
One graph has a complete forced trajectory at Steps = 256. This benchmark permits cycles on 26 states; it does not require 256 distinct states, and the model stops early on that request.
Keeping the prompt fixed recovers much of the execution that the previous revision lost, but it still only buys a few extra steps. The sharp increase in first-error risk is more informative than the occasional correct final answer: paths that were working tend to break around the same part of the rollout. Fixed prompt memory and a smaller writable state changed together here, so I cannot say which part helped most.
The count comparison also shows that fixed does not mean irrelevant. The requested steps still enter the prompt, and changing that number changes the answer at the same intermediate loop. That should not be necessary to execute the graph. Before changing the architecture again, though, there was a simpler limitation to address: the model had never practiced continuing beyond six loops, and every six-loop training example ended with a stop label.
Architecture 3b
A Small Training Change
Changing up the data
Until now, every training example ended within six steps. At loop 6, the stopping head only ever received a stop label, and there was no supervision beyond that loop.
I wanted to give the model practice continuing further, while also exposing it to two-digit step counts. I kept the architecture from 3a and changed the training data.
I generated a fresh set of 30,000 examples, this time with requested depths of 1–6, 8, 10 and 12.
I left out requested counts 7, 9 and 11 to see whether the model could fill in gaps within the training range, separately from extending beyond 12.
Those intermediate steps still receive supervision inside longer examples while the requested counts are held out.
Training
I trained fresh adapters with the same losses and learning-rate schedule as before. For the longer rollouts, I switched to BF16 with PyTorch’s scaled dot-product attention and grouped examples by depth.
The batch size stayed at 4, but I removed gradient accumulation, so the effective batch size dropped from 8 to 4. One epoch now took 7,500 updates.
These changes were made for speed and memory. The number of training examples and the one-epoch budget stayed the same, but the smaller effective batch doubled the number of optimizer updates.
I validated every 500 updates on 32 examples at each depth from 1 to 12. Checkpoint selection still used letter-prediction loss, restricted to the requested counts used in training.
Counts 7, 9 and 11 were monitored but excluded from selection. This selected update 5,000.
Learning the next transition
Letter-prediction loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Cross-entropy over the 26 letters, averaged over requested transitions within each example, then across examples. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 288 fixed examples at requested counts 1–6, 8, 10 and 12, measured every 500 updates. Counts 7, 9 and 11 are excluded from these curves.
Learning when to stop
Continue/stop loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Balanced binary cross-entropy, shown before multiplying by its training weight of 0.1. Each example gives equal weight to its mean continue loss and final stop loss; a one-step example has no continue term in its stopping loss. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 288 fixed examples at requested counts 1–6, 8, 10 and 12, measured every 500 updates. Counts 7, 9 and 11 are excluded from these curves.
The dotted line marks update 5,000, selected by letter-prediction validation loss at trained counts. These are the original development curves.
View validation measurements and source data
288 fixed validation examples at requested counts 1–6, 8, 10 and 12. Stop BCE is balanced and unscaled.
The export contains all 7,500 updates and 16 validation checkpoints, checked against their per-loop CSVs. The 96 examples at held-out requested counts 7, 9 and 11 are exported separately. Run configuration and source hashes are included.
Results
I evaluated update 5,000 on the same 1,350 graphs and requested counts 1–256. This time, the model can follow the path much further.
The held-out requests 7, 9 and 11 let us check whether it can fill in the gaps, while counts above 12 still test execution beyond the training depth.
Complete trajectory · N = 12
93.33%
1,260 / 1,350 graphs · forced depth
Complete trajectory · N = 13
88.89%
1,200 / 1,350 graphs · forced depth
Complete trajectory · N = 16
6.07%
82 / 1,350 graphs · forced depth
With stopping ignored, complete trajectory accuracy at twelve steps increases from 2.15% in 3a to 93.33%.
At the held-out requests 7, 9 and 11, it completes 96.67%, 95.70% and 94.96% of paths. These requested counts were absent from training, but the intermediate transitions were still supervised inside longer examples.
Beyond twelve, it completes 88.89% at thirteen and 62.59% at fourteen, before falling to 16.89% at fifteen and 6.07% at sixteen. The drop has moved further out, but it has not disappeared.
Can it still follow the path?
Stopping head ignored · open markers: held-out requests 7, 9 and 11
Loading chart. Summary measurements are available below.
Each N is a separately prompted rollout, forced through N loops. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. The dotted line marks the 12-step training limit. Open markers identify held-out requested counts 7, 9 and 11; their intermediate transitions were supervised inside longer training examples. Lines are unsmoothed; hover for graph counts and pointwise 95% Wilson intervals, also available as optional bands.
For the same Steps = 32 diagnostic, the average correct prefix is now 12.54 loops, compared with 7.77 in 3a.
Most first errors occur at loops 13–16, where 1,126 graphs first lose the path. Only one graph stays correct through all 32 steps, and none does at Steps = 256.
When does it first lose the path?
Stopping ignored · first error within a fixed request
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
The first-error risk shows the same sharp rise, just later. Among paths still correct, 5.97% first fail at loop twelve, 26.84% at thirteen, 62.72% at fourteen and 75.16% at fifteen.
By loop fifteen, only 318 of the original 1,350 paths are still correct. The later percentages describe those remaining paths, not the full benchmark.
Does each extra step carry the same risk?
Stopping ignored · first errors among paths correct through the previous loop
Loading chart. Summary measurements are available below.
Each point divides new first errors by graphs correct at every earlier loop within the same requested rollout. Hover shows both counts; bars are pointwise 95% Wilson intervals. The denominator shrinks after failures, so later points can represent very few graphs. No eligible graphs means N/A, not zero risk. The dotted line marks the 12-step training limit.
Repeating the previous state is still the largest first-error category, now accounting for 750 of the 1,349 failed graphs, or 55.60%, compared with 41.90% in 3a.
The remaining errors return to another earlier state (16.46%), predict a later reachable state (8.67%), or leave the start’s reachable states (19.27%). The failure modes are similar, with a stronger tendency to repeat the previous letter.
Recovery remains low: 1,192 of 23,642 transitions after a wrong prediction return to the reference state, or 5.04%, up from 4.24%.
Only 4.31% follow a valid edge from the previous decoded letter. I counted 2,481 wrong stretches, with 1,289 still ongoing at loop 32. The views below keep the same error, recovery, edge and wrong-stretch breakdowns.
What happens when it loses track?
Forced rollouts · first errors, recovery, decoded edges and wrong stretches
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
At twelve steps, complete trajectory accuracy is 91.56% on random functions, 93.33% on permutations and 95.11% on full cycles.
So performance near the new training limit is strong across all three graph types, with random functions still the hardest group.
The other views show the same cycle-length, steps-before-cycle, reachable-state and generation-seed breakdowns as before.
Which graphs does it struggle with?
Stopping ignored · compare graph properties at a fixed requested depth
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.
The requested count still changes execution on the same graph. To look just beyond the new training limit, I fixed the readout at loop fourteen.
With Steps = 14, 858 graphs produce the correct letter there, or 63.56%. Changing only the request to Steps = 20 reduces this to 313, or 23.19%: 557 correct answers become wrong, while twelve change from wrong to correct.
Both requests have two digits. The curve is not monotonic, but the intermediate answer is still sensitive to how many steps we ask for.
Does asking for more steps change the same intermediate answer?
Same 1,350 graphs · always read at loop fourteen · stopping ignored
Loading chart. Summary measurements are available below.
Every point reads C at executed loop fourteen from a separate prompt with the displayed requested N. This is intermediate-letter accuracy, not final-answer or complete-trajectory accuracy. Lines are unsmoothed. Hover includes counts, pointwise 95% Wilson intervals, changed letters and paired gains/losses against Steps = 14. This shows sensitivity to the Steps text, including its tokenization and positions; it does not identify the internal cause.
Stopping improves on unfamiliar counts inside the training range, but not equally. Exact stopping is 98.81% at seven, 83.33% at nine and 88.59% at eleven; correct answer plus exact stop is 96.30%, 81.63% and 85.11%.
Across the nine trained requested counts, exact stopping is 96.65% and correct answer plus exact stop is 94.70%.
At twelve itself, these fall to 79.33% and 76.44%. Beyond twelve, every one of the 329,400 requests stops early, even at thirteen where forced execution is still strong.
Does it know when to stop?
First stop probability ≥ 0.5 · open markers: held-out requests 7, 9 and 11
Loading chart. Summary measurements are available below.
Exact stop requires the first threshold crossing to occur at N. Correct answer + exact stop additionally requires C’s returned letter to match the N-step answer; it does not require every earlier letter to be correct. A correct letter at the wrong loop is not a success. The dotted line marks the 12-step training limit. The fixed cap of 272 loops is independent of N, and reaching it without a stop would count as a stopping failure. Open markers identify held-out requested counts 7, 9 and 11; their intermediate transitions were supervised inside longer training examples. Lines are unsmoothed; hover for counts and pointwise 95% Wilson intervals.
For twelve-step requests, 1,071 graphs stop at loop twelve; 272 stop early and seven stop at thirteen.
Asking for thirteen steps mostly makes it stop at eleven instead: 1,153 graphs do so. At 32, 1,131 graphs stop at ten.
At 256, 593 stop at ten and 715 at eleven, with the remaining 42 at eight, nine or twelve. The four rows below show those requests together.
What does it do with a larger request?
Rows: requested steps · columns: actual stopping loop · 1,350 graphs per row
First threshold crossing · one stopping time per graph.
Loading chart. Summary measurements are available below.
Each row is a separate requested count on the same 1,350 graphs. Columns show the first loop where the stop probability reaches 0.5. Cell percentages use that row’s 1,350 graphs; a dash means no graph stops there. Only stop loops observed in at least one displayed row are shown, with their actual loop numbers on the axis. No stops from these rows are omitted. These are stopping times, not first-error locations or answer accuracy.View key measurements and evaluation data
Separate requested-count groups · all graph/count pairs included
Requested counts
Queries
Complete trajectory
Exact stop
Correct answer + exact stop
Trained: 1–6, 8, 10, 12
12,150
11,807 · 97.18%
11,743 · 96.65%
11,506 · 94.70%
Held out: 7, 9, 11
4,050
3,879 · 95.78%
3,655 · 90.25%
3,551 · 87.68%
Beyond training: 13–256
329,400
2,641 · 0.80%
0 · 0.00%
0 · 0.00%
The trained-count group has 373 early and 34 late stops; held-out requests have 292 early and 103 late stops. All 329,400 requests above twelve stop early. No request reaches the cap without a stop. Aggregated percentages pool graph/count queries; the plots’ Wilson intervals are pointwise across graphs at each N.
Forced execution within fixed requests · 1,350 graphs at each N
Requested steps
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.91 loops
1.28%
6 / 63 · 9.52%
12
11.63 loops
2.75%
17 / 368 · 4.62%
32
12.54 loops
57.71%
1,192 / 23,642 · 5.04%
256
13.02 loops
90.99%
11,748 / 313,138 · 3.75%
Correct-prefix length includes complete successes at their full requested length. Wrong loops use all graph/loop observations; recovery uses transitions following a wrong prediction, excluding a final wrong state with no observed next step. These diagnostics continue past the learned stop to measure execution.
This is a useful improvement. The model can now handle requested counts that were left out inside the training range, and it follows the graph correctly for much longer than 3a. But the sharp drop has mostly moved with the training limit. Going from six trained loops to twelve still leaves execution unreliable much beyond the new limit, and the stopping head still cuts every longer request short.
I also do not think this is only a problem with reading a new number of digits. Changing a two-digit request from fourteen to twenty changes the loop-fourteen answer on the same graph. The requested count is still influencing a transition that should depend on the current state and rules. The new data and training recipe changed together, so this run cannot isolate the effect of longer paths, but it makes the remaining problem clearer.
At this point, I wanted to give the executor a more specific job: follow one edge, then do the same thing again. Tracking how many of those operations we need would become a separate job. That meant revisiting both what each part of the model could see and how the recurrent state was passed between loops.
A Whole New Architecture
Model Architecture
So far, the models have learned to step through the graphs and stop at the right time for training depths, but execution accuracy drops sharply on longer unseen rollouts.
This seems to be a mix of a data problem and also a model problem - something about the architecture itself does not lend itself to generalization.
This calls for a revision of the whole architecture itself, and a new data recipe.
The old architecture was possibly doing too much - both the evaluation of the next step, and the stopping decision were being jointly trained and possibly interfering with one another.
I thought it would be best to separate the two tasks.
On one side, let's have a part of the model that is solely responsible for evaluating the next step. And on the other side, let's also have another part of the model that takes up the task of deciding when to stop.
I call these the executor and the controller respectively.
To separate these jobs, I also changed what each part gets to see. I remove the Steps line from the executor's prompt, leaving it with the rules and starting node.
The controller gets P's representation of the full prompt, including Steps, and can observe the executor's hidden state at each loop.
Both versions of the prompt pass through the same frozen P before looping.
The controller still has to learn to read the requested count from the prompt; it is not given a separate numerical count or loop index.
The Executor
The executor is equivalent to what was previously just the R block. It takes in the hidden state from P or from itself at the previous step, and outputs the next hidden state.
One subtle problem with the previous architecture was that R’s output was fed directly back into its input, without a separate learned mapping between the two.
This could cause the hidden state to drift in scale as we loop, making each new input less like the output from P that R was originally trained to receive.
To address this possibility, I added a re-entry bridge that normalizes the output hidden state to the initial P state’s scale, then applies a learned gain and projection before feeding it back into R.
The first loop skips this bridge.
The Controller
The controller is a separate GRU with its own 128-dimensional memory.
The controller's memory is initialized from the output of P through a learned projection.
Then at each loop, it takes the output from the executor as its input and updates its own memory to make a continue/stop decision.
As in 3a, the prompt memory stays fixed and only the answer-position state changes across loops.
Architecture 4 · the complete flow
An executor, with its own stopping controller.
Overview
Rules A → B · B → C · C → D · …Start ASteps 3
1 / 12
Two states, with separate jobs
R updates the working state hₜ. The controller updates its own memory mₜ and chooses when to stop. Only hₜ returns to R.
Swipe horizontally to inspect the full diagram.
Keep in mind
The same P weights encode two prompt views before recurrence. Read each row from left to right. Teal carries the executor state; rust carries private controller memory. The dashed decision arrow selects a path without adding a state input to R.
Conceptual inference flow. The animation follows an ideal three-step path, not a measured controller trace. P is run on two prompt views before recurrence, using the same weights. The named h₀ and m₀ outputs initialize the two rows below. C is shown at the final exit; in the implementation, I also decode through C at every loop for supervision and evaluation, and use a direct R readout. Neither prediction feeds back into R.Implementation & visual references
The single P block represents shared weights used on two prompt views. Its full-prompt feature initializes the GRU through a learned projection. R’s per-layer prompt memory is formed on its first pass and reused thereafter. All R weights, the bridge and the direct readout train in the executor stage; the later controller stage freezes them. Controller observations are detached, so its loss cannot change R. Final C readout includes normalization and the language-model head. The auxiliary remaining-work readout supplies training supervision only.
For this version, I also figured that another part of the problem could be that LoRA adapters were not expressive enough to learn the transition function, so I also allowed all the weights in R to train.
P, C, the embeddings and the language model head remain frozen.
I generated 36,000 new training examples at the same requested depths as 3b.
This time, the rule tables were sampled independently of the requested depth, using a mixture of random functions, permutations and full 26-state cycles.
Paths could revisit states within the requested steps, unlike the earlier nonrepeating training paths.
I kept the intermediate letter loss through C and added a separate 26-letter readout directly from R, with a loss weight of 0.25.
This gives R direct supervision on the current state as well as supervision through C. Neither readout is fed back into the next loop.
The controller was trained alongside the executor with the stopping loss, but that loss now updates only the controller.
With the full R block trainable, I lowered the learning rate to 2e-5, used 100 warmup updates followed by cosine decay, and set weight decay to 0.01.
Batch size stayed at 4, with gradient accumulation over 4 batches for an effective batch size of 16. One epoch took 2,250 updates.
Validation letter loss at the trained counts selected the final update.
Learning the transition through C
Executor training · letter-prediction loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Cross-entropy over the 26 letters, averaged over requested transitions within each example, then across examples. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation is unsmoothed: 576 queries at trained counts 1–6, 8, 10 and 12 (64 per count), measured every 250 updates. Queries share graph/start pairs across counts.
Reading the state directly from R
Executor training · direct R readout loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
The new direct 26-letter readout, using the same per-example averaging as the C readout. Shown before its training weight of 0.25. Training shows a trailing 50-update, example-weighted mean; initial windows use available updates. Validation uses the same 576 queries at trained counts and is unsmoothed. Both curves use the same reduction; validation is recomputed from per-loop readout losses.
The dotted line marks executor update 2,250, selected by validation letter loss through C. Both plots use the original executor run; the later controller training leaves these weights frozen.
When running evals, I noticed that the controller was not learning to stop at the right time, so I decided to continue training it separately while keeping the executor frozen.
Trained for another 6,000 updates, using a batch size of 256 and learning rate of 3e-4.
I used 256 training graphs with requested counts from 1 to 63, leaving out 9, 17, 29, 41 and 53.
Each training rollout still covered at most 12 loops. Alongside the stop labels, an auxiliary readout learned to predict the remaining steps, including the initial count. These numbers were training targets, never inputs to the controller’s memory.
Requests longer than 12 received only continue labels over their observed prefix; reaching the training limit was not treated as completion.
Checkpoint selection used exact stopping on seen validation counts up to 12, with stopping loss as the tie-breaker. This selected controller update 5,800.
Training the separate controller
Frozen executor · continue/stop loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Balanced binary cross-entropy over the observed continue/stop classes in each example, excluding the auxiliary numerical losses. Training shows a trailing 50-update, example-weighted mean of available logged batches; initial windows use available records. Training logs one 256-example batch at update 1 and every tenth update, sampled from 58 requested counts through 63 with rollouts capped at 12. Validation is unsmoothed: 1,408 queries on 128 graphs at seen counts 1–12 excluding 9, measured every 100 updates. Training and validation therefore cover different requested-count ranges.
The dotted line marks controller update 5,800, selected by exact stopping on the short seen-count validation cohort, with BCE as the tie-breaker. It is not the minimum-loss checkpoint. These are development learning curves, not the full benchmark results.
For this comparison, I used the executor from update 2,250 with the separately trained GRU controller selected at update 5,800.
The benchmark is unchanged: 1,350 graphs and requested counts 1–256. This version finally separates the two problems clearly. The executor can keep following the graph, while the controller still struggles to stop at the right time.
Forced final answer · N = 256
97.78%
1,320 / 1,350 graphs
Forced complete trajectory · N = 256
96.89%
1,308 / 1,350 graphs
Answer + exact stop · N = 256
0.00%
0 / 1,350 graphs
With stopping ignored, complete trajectory accuracy is 98.00% at twelve steps and 96.89% at 256. In 3b, no graph stayed correct through 256.
Final-answer accuracy at 256 is 97.78%, so some paths that made an earlier mistake still return the correct final letter. These are cyclic graphs on 26 states, so this does not mean executing 256 distinct states.
Can it still follow the path?
Forced executor · same 1,350 graphs through 256 loops
Loading chart. Summary measurements are available below.
Stopping is ignored. Each N reads the same count-independent executor trajectory through loop N; reuse was checked against native inference. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. The dotted line marks twelve trained loops. Open markers identify counts 7, 9 and 11 omitted from executor training prompts, whose intermediate transitions were supervised inside longer examples. Hover for graph counts and pointwise 95% Wilson intervals, also available as bands.
At Steps = 256, only 42 graphs make an error at any point. All of those first errors occur by loop 30; the other 1,308 graphs stay correct for the entire rollout.
The average correct prefix is 248.37 loops, compared with 13.02 in 3b. That average includes the successful graphs at their full 256-loop length.
When does it first lose the path?
Stopping ignored · first error within a fixed request
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
The first-error risk also looks different. It stays below 0.4% at every observed loop, rather than rising sharply just beyond training.
There are no new first errors after loop 30, with 1,308 still-correct paths remaining. This says those paths keep working on this benchmark; it does not say the 42 failed paths recover or stop making mistakes.
Does each extra step carry the same risk?
Stopping ignored · first errors among paths correct through the previous loop
Loading chart. Summary measurements are available below.
Each point divides new first errors by graphs correct at every earlier loop. Hover shows both counts; bars are pointwise 95% Wilson intervals. The vertical axis is zoomed to 0–1% because first errors are rare. Zero eligible graphs would mean N/A. The dotted line marks twelve trained loops. The default shows the first 32 loops of the 256-loop rollout; switch to the full range to inspect the remainder.
None of the 42 first errors repeats the previous state. Sixteen return to another earlier state, seventeen predict a later reachable state, and nine leave the start’s reachable states.
That is a different mix from 3b, where repeating the previous state dominated. The percentages below are now based on just 42 failed graphs.
Recovery itself remains uncommon: 234 of 7,544 transitions after a wrong prediction return to the reference state, or 3.10%.
But 92.44% of those transitions follow a valid edge from the previous decoded letter, compared with 2.51% in 3b at the same 256-loop cutoff. So most decoded transitions remain valid even when the model is off the reference path.
There are 264 wrong stretches, with thirty still ongoing at loop 256.
What happens when it loses track?
Forced rollouts · first errors, recovery, decoded edges and wrong stretches
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
Complete trajectory accuracy through 256 is 97.33% on random functions, 97.33% on permutations and 96.00% on full cycles.
The improvement is present across all three graph types. The other views keep the same breakdowns by cycle length, steps before the cycle, reachable states and generation seed.
Which graphs does it struggle with?
Stopping ignored · compare graph properties at a fixed requested depth
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.
The count-sensitivity plot is now flat: the loop-fourteen readout is correct on 1,329 graphs, or 98.44%, for every requested count shown.
This follows from the routing change: R no longer sees the requested steps, and the controller cannot alter its state. The evaluator reuses that shared executor trace after native checks, so these are not independent reruns demonstrating that it learned to ignore the count.
Does asking for more steps change the same intermediate answer?
Loading chart. Summary measurements are available below.
The executor receives no Steps text or count-dependent token positions. These points therefore reuse the same audited loop-fourteen predictions for every N, with no paired letter changes. The extraction’s native-inference checks support that reuse; this is not 243 independently rerun count variants or evidence that the model learned to ignore a visible count. Hover shows graph counts and pointwise Wilson intervals.
There is also a second way to read the state now, directly from R. Through 256, that readout keeps every step correct on 1,295 graphs, or 95.93%, compared with 1,308 through C.
At the final loop both give the correct letter on 1,320 graphs. The two readouts are close, but matching final answers can hide different earlier mistakes. Neither prediction is fed back into R.
Do the two readouts agree about execution?
Same executor states · direct R readout versus C · stopping ignored
Loading chart. Summary measurements are available below.
Both readouts score the same reference states on the same 1,350 graphs. Complete trajectory requires every earlier prediction from that readout to be correct; current-letter accuracy does not. The vertical axis is zoomed to 94–100%. Hover for counts, pointwise 95% Wilson intervals and the number of differing R/C letters at each loop. Across the full rollout, 55 graphs have a direct-R error and 42 a C error; forty have both, and 36 first fail at the same loop.
Looking specifically at C’s first mistake, the direct R prediction is still correct on five of the 42 failed graphs. On the other 37, both readouts give the same wrong letter.
So there are a few cases where the readouts disagree about the correct state, but most first errors are shared. This does not tell us exactly what went wrong inside R or C.
When C first fails, what does R predict?
Stopping ignored · compare both readouts at the first C error
Loading chart. Measurements are available in the downloadable evaluation data.
Each graph with a C error contributes once at its first incorrect C loop within N. Bars divide by the number of failed graphs, not all 1,350. “R correct” means its direct letter matches the reference at that loop, regardless of its earlier predictions. Zero bars are retained; graphs without a C error are excluded.
The controller is now the main limitation. On the familiar counts 1–12 excluding nine, exact stopping is only 59.15%, and correct answer plus exact stop is 58.88%.
For the seen requested values 13–63, excluding the held-out counts, those fall to 7.50% and 7.34%. These larger numbers appeared during controller training, but their rollouts ended at twelve loops.
At 256, every graph stops early despite the strong forced-execution result.
Does it know when to stop?
First stop probability ≥ 0.5 · open markers: controller-held-out counts 9, 17, 29, 41 and 53
Loading chart. Summary measurements are available below.
Exact stop requires the first probability ≥0.5 at N. Correct answer + exact stop also requires the returned C letter to match the N-step answer, without requiring every earlier letter to be correct. The optional strict-success curve additionally requires every intermediate C prediction to be correct. The dotted line marks the twelve-loop training horizon. The controller saw 58 requested values through 63, but no training rollout exceeded twelve loops. Open markers identify its five held-out values. The fixed cap is 272; reaching it without a stop would fail. Hover for counts and pointwise Wilson intervals; bands are optional.
The stopping distributions show why a single average is not enough. For a twelve-step request, the median stop is twelve, but the 10th–90th percentile range is ten to fourteen; only 344 graphs stop exactly at twelve.
At 32, the median is 31 with a range of 26–36. At 63, it overshoots to a median of 77, with a range of 69–87. At 256, the median is only 74, with a range of 66–84.
The plot below shows those four requests together, with the requested stopping loop marked separately.
How long does the controller actually run?
Rows: requested steps · columns: actual stopping loop · 1,350 graphs per row
First threshold crossing · one stopping time per graph.
Loading chart. Summary measurements are available below.
Each row uses the same 1,350 graphs. The filled dot is the median first stopping loop, with whiskers spanning the 10th–90th percentiles; the open diamond is the requested loop. These are distribution percentiles, not confidence intervals or a range containing every stop. Hover for the full minimum/maximum. No graph is missing a stop. A median at the requested loop does not imply every graph stops correctly.
Across requested counts, the controller switches between stopping too early and too late. At 63, 1,332 of the 1,350 graphs stop late; at 256, all of them stop early.
The full range makes that shift clearer. The error view measures how far away those stops are, keeping early stops negative and late stops positive.
Does it stop early or late?
Full benchmark · first stop relative to the requested count
Loading chart. Measurements are available in the downloadable evaluation data.
Each column partitions the same 1,350 graphs by the first stop signal. Switch views for mean signed and absolute stopping error, in loops. Every graph signaled a stop within the 272-loop cap. The dotted line marks twelve training loops, not the largest numeric value seen.
Returning the correct letter does not fix the timing problem. At 256, 313 graphs return the requested final letter, but every one stops too early.
That is 23.19% correct returned letters and zero exact completions. On a cyclic graph, reaching the same letter at another loop is possible, which is why I keep these outcomes separate.
Right answer, right time, or both?
Full benchmark · returned C letter compared with the requested N-step answer
Loading chart. Measurements are available in the downloadable evaluation data.
Each column sums to 100%. “Exact + correct” is end-to-end success. “Wrong time” includes observed early and late stops; correctness always refers to the requested final letter, not the state at the stopping loop. Every graph signaled a stop, so these four categories cover all queries. These outcomes allow earlier execution errors. Strict success is available in the stopping-accuracy figure.
I also checked the controller’s numerical readout to see whether its estimate of the remaining work was going wrong before or during the loops.
On the smaller development panel, its initial estimate for a nine-step request is already off by 1.91 steps on average, before any recurrence. Its average decrement error is 0.73 steps.
The other view compares when this readout reaches zero with when the stop head fires. These are separate signals; the numerical prediction is not fed back into the controller or used to stop it.
Is the controller actually counting down?
Development replay · 128 graphs per count · 1–16 requested steps · 16-loop cap
Loading chart. Measurements are available in the downloadable evaluation data.
Saved development diagnostics for the same selected GRU checkpoint, using its auxiliary numerical readout. These panels differ from the 1,350-graph benchmark above and from each other; their caps are 16 and 64 loops. Numerical errors are measured against N−t only through the requested loop, averaging within each query before averaging queries. Decrement error measures |prediction(t) − prediction(t−1) + 1|. In the agreement view, a diagnostic zero is the first readout ≤0.5 from loop one. Matching the stop signal does not necessarily mean either occurs at N. The numerical readout diagnoses memory; it does not prove a literal counter is implemented.View key measurements and evaluation data
Controller exposure · all training rollouts capped at twelve
Requested counts
Queries
Exact stop
Correct answer + exact stop
Seen: 1–12 except 9
14,850
8,784 · 59.15%
8,744 · 58.88%
Seen: 13–63 except 17, 29, 41, 53
63,450
4,756 · 7.50%
4,656 · 7.34%
Held out: 9, 17, 29, 41, 53
6,750
797 · 11.81%
785 · 11.63%
Unseen numeric range: 64–256
260,550
1,468 · 0.56%
1,426 · 0.55%
Executor training used requested counts 1–6, 8, 10 and 12. The controller’s later training exposed 58 numeric values through 63, including seven and eleven, but still used at most twelve recurrent loops. Numeric exposure and rollout-depth exposure are different. These pooled percentages do not treat repeated queries on one graph as independent confidence-interval observations.
Forced execution within fixed requests · 1,350 graphs at each N
Requested steps
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.97 loops
0.38%
4 / 19 · 21.05%
12
11.86 loops
0.87%
8 / 121 · 6.61%
32
31.33 loops
1.58%
25 / 651 · 3.84%
256
248.37 loops
2.19%
234 / 7,544 · 3.10%
Correct-prefix length includes complete successes at their full requested length. Wrong loops use all graph/loop observations; recovery uses transitions following a wrong prediction, excluding a final wrong state with no observed next step. These diagnostics continue past the learned stop to measure execution. All graphs have an observed first stop before the cap; no missing-stop cases are excluded from the distributions.
This is the first version where more loops continue to produce useful execution across the full benchmark. The failure pattern has changed too. Most paths stay correct all the way through, and when the model is wrong, its decoded transitions usually still follow valid edges. That is different from the earlier versions losing the path near the training limit and rarely making valid transitions afterward. It does not tell us exactly what the hidden state represents, but the behavior is much closer to the repeated operation I wanted.
Several things changed together: the count-free prompt, the bridge, full training of R, direct supervision and cyclic training graphs. I cannot give one of them all the credit from this run. What we can separate clearly now is the remaining stopping failure, since the controller cannot change the executor’s state and the stopping loss no longer updates the executor.
The numerical diagnostic also shows that errors can start before the first loop, when the GRU’s initial memory is read as the requested count. Later updates and the stop decision add their own errors, so more accurate initialization alone is not guaranteed to fix it. For this task, though, the controller has a very specific job: count the requested transitions. That made me want to try a simpler memory and update rule instead of asking the GRU to learn everything at once.
The Missing Piece
Model Architecture
At this point, I had an executor that could keep stepping through the graph correctly (most of the time), but the controller was still struggling to decide when to stop on longer requests.
I thought the GRU might be doing more than this task needed. We already know what completion means here - just take the requested number of steps.
So I kept the executor frozen and replaced the controller with a much simpler learned timer.
A simpler memory
Instead of a 128-dimensional GRU memory, the controller now keeps a single number representing how much work is left.
At each loop, a small learned update multiplies this number by a scalar and adds a bias: mt = a · mt-1 + b.
A separate learned readout uses the updated value to decide whether to continue or stop. The same update is reused at every loop.
I do not set the update to subtract one; the coefficients have to be learned from the remaining-work targets.
Reading the requested count
The timer also needs a starting value. I take the raw digit tokens from the Steps field and use their frozen token embeddings directly instead of passing the full prompt through P for the controller.
One shared learned projection maps each digit embedding to a scalar, and a learned accumulation gain combines these values from left to right.
Using the same weights at every position gives the reader a way to compose longer numbers from the digits it has already seen.
The code extracts the digit tokens, but does not convert the text into an integer and hand that value to the controller.
The executor still sees only the rules and starting node. The timer now reads only the requested count, and no longer uses the executor's hidden state.
This means it can learn when the requested work should end, but cannot tell whether the executor has made a mistake.
I am giving the controller a specific counting structure here, rather than asking it to discover a general stopping strategy.
Architecture 5 · the final controller
Read once. Update. Decide.
Before looping
Read the request into one scalar
The reader turns the Steps digit embeddings into the initial memory m₀. The connected path carries that value into the repeating update below.
Swipe horizontally to inspect the full diagram.
Controller only. Each memory update happens after one executor loop. The reader gain, digit projection, update coefficients and stop readout are learned. The animation shows an ideal countdown with rounded values, not recorded checkpoint activations. The timer does not receive the executor’s hidden state or check whether its answer is correct.Diagram notes
The reader starts its accumulation at zero and applies the same learned projection and gain to every valid digit token. The resulting scalar initializes the timer once; subsequent loops use the timer’s own previous output. The stop readout applies a learned affine map and sigmoid, with a stop threshold of 0.5. It is not a programmed comparison of memory against zero. The implementation accepts at most eight digit tokens, accumulates the reader in float64, and runs the countdown in float32.
Training
I kept the same graph/count panel and 12-loop training limit as the previous controller run. All of the executor weights stayed frozen.
The remaining-work targets now supervise the scalar memory directly, while the stopping loss trains only the stop readout.
The timer runs on its own predictions during training; the correct remaining count is used as a target, never fed back into its memory.
I first trained this scalar controller with a linear reader of the final eight frozen token embeddings in the prompt.
I fitted that reader to the training-count labels with least squares and froze it, then trained the countdown and stop readout for 3,000 updates.
I used AdamW with a learning rate of 0.01, with the countdown's multiplicative coefficient learning 100 times more slowly.
The schedule used 100 warmup updates followed by cosine decay to one tenth of the starting rate.
Batch size and validation frequency stayed the same. The same short-count stopping criterion selected update 3,000.
Learning the stopping decision
Initial scalar controller · continue/stop loss · lower is better
Larger = smoother
Loading chart. Validation measurements are available in the table below.
Hover or tap for values · drag to zoom
Balanced binary cross-entropy over the observed continue/stop classes in each example, excluding numerical losses. This is the initial controller with the suffix reader, before the shared-reader and precision repairs. Training shows a trailing 50-update, example-weighted mean of available logged batches; initial windows use available records. Training logs one 256-example batch at update 1 and every tenth update, sampled from 58 requested counts through 63 with rollouts capped at 12. Validation is unsmoothed: 1,408 queries on 128 graphs at seen counts 1–12 excluding 9, measured every 100 updates. Training and validation therefore cover different requested-count ranges.
The dotted line marks that selected update. These curves describe the initial scalar-controller run; the two later fits below produce the final checkpoint.
View validation measurements and source data
Initial scalar-controller validation · 1,408 short seen-count queries
The first reader had separate weights for each token position, which became a problem when digits appeared in positions it had not learned to read.
I replaced it with the shared reader described above and fitted its gain and projection using the same 58 training-count labels.
This was another least-squares fit, with no new counts or longer training rollouts. The countdown and stopping readout stayed unchanged at this stage.
Small errors in the countdown coefficients could also accumulate over long rollouts.
For the final checkpoint, I refitted just those two coefficients using float64 L-BFGS on the same short remaining work targets, then exported them for float32 inference.
The reader and stop readout stayed fixed. This changed the precision and convergence of the fit, without adding longer examples.
Final fits on the original training labels
Fit
Saved measurement
Shared number reader
Maximum count error: 3.815 × 10−6
Countdown before precision fit
Training MSE: 4.163 × 10−9
Countdown after float32 export
Training MSE: 6.308 × 10−12
These are training-fit measurements, not benchmark accuracy. Countdown MSE uses squared-step units, averages each observed prefix with denominator min(N, 12) + 1, then averages the 58 counts; the fixed initial-state error is omitted. The saved fits do not contain per-update validation curves.
Results
For the final comparison, I used the shared-reader controller after the numerical precision fit, with the same executor from update 2,250.
The benchmark is still the same 1,350 graphs and every requested count from 1–256. This time, the controller stops at exactly the requested loop on every query. The remaining failures are in execution.
Exact stop · N = 256
100%
1,350 / 1,350 graphs
Answer + exact stop · N = 256
97.78%
1,320 / 1,350 graphs
Every step + exact stop · N = 256
96.89%
1,308 / 1,350 graphs
The executor’s predictions are identical to Architecture 4, including the intermediate steps. At 256, final-answer accuracy is still 97.78% and complete trajectory accuracy is 96.89%.
The executor plots below are unchanged from Architecture 4. The controller repair lets the model stop at the requested loop; it does not improve execution.
Can it still follow the path?
Forced executor · same 1,350 graphs through 256 loops
Loading chart. Summary measurements are available below.
Stopping is ignored. Each N reads the same count-independent executor trajectory through loop N; reuse was checked against native inference. Final-answer accuracy allows earlier mistakes; complete trajectory accuracy does not. The dotted line marks twelve trained loops. Open markers identify counts 7, 9 and 11 omitted from executor training prompts, whose intermediate transitions were supervised inside longer examples. Hover for graph counts and pointwise 95% Wilson intervals, also available as bands.
When does it first lose the path?
Stopping ignored · first error within a fixed request
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Each graph contributes once: to the range containing its first incorrect loop, or to “No error” if every prediction is correct through the requested cutoff. Bars use all 1,350 graphs as the denominator. Bins have different widths; hover for graph counts. Later recovery does not erase the first error.
Does each extra step carry the same risk?
Stopping ignored · first errors among paths correct through the previous loop
Loading chart. Summary measurements are available below.
Each point divides new first errors by graphs correct at every earlier loop. Hover shows both counts; bars are pointwise 95% Wilson intervals. The vertical axis is zoomed to 0–1% because first errors are rare. Zero eligible graphs would mean N/A. The dotted line marks twelve trained loops. The default shows the first 32 loops of the 256-loop rollout; switch to the full range to inspect the remainder.
What happens when it loses track?
Forced rollouts · first errors, recovery, decoded edges and wrong stretches
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. First-error categories use the priority defined in the metrics section. Each failed graph contributes once; percentages are among failed graphs. The other views use different denominators, shown with the chart and on hover.
Which graphs does it struggle with?
Stopping ignored · compare graph properties at a fixed requested depth
Stopping ignored · one fixed request per graph.
Loading chart. Summary measurements are available below.
The stopping head is ignored and execution continues through N. Every graph contributes one query at the selected N. Bars show success rates with pointwise 95% Wilson intervals and graph counts, including groups with no successes. Empty bins are N/A. Cycle, transient and reachable-state comparisons stay within one graph type; reachable states include Start. These properties overlap, so this does not isolate the cause of a failure.
Does asking for more steps change the same intermediate answer?
Loading chart. Summary measurements are available below.
The executor receives no Steps text or count-dependent token positions. These points therefore reuse the same audited loop-fourteen predictions for every N, with no paired letter changes. The extraction’s native-inference checks support that reuse; this is not 243 independently rerun count variants or evidence that the model learned to ignore a visible count. Hover shows graph counts and pointwise Wilson intervals.
Do the two readouts agree about execution?
Same executor states · direct R readout versus C · stopping ignored
Loading chart. Summary measurements are available below.
Both readouts score the same reference states on the same 1,350 graphs. Complete trajectory requires every earlier prediction from that readout to be correct; current-letter accuracy does not. The vertical axis is zoomed to 94–100%. Hover for counts, pointwise 95% Wilson intervals and the number of differing R/C letters at each loop. Across the full rollout, 55 graphs have a direct-R error and 42 a C error; forty have both, and 36 first fail at the same loop.
When C first fails, what does R predict?
Stopping ignored · compare both readouts at the first C error
Loading chart. Measurements are available in the downloadable evaluation data.
Each graph with a C error contributes once at its first incorrect C loop within N. Bars divide by the number of failed graphs, not all 1,350. “R correct” means its direct letter matches the reference at that loop, regardless of its earlier predictions. Zero bars are retained; graphs without a C error are excluded.
Stopping is where the result changes. Every count from 1–256 stops exactly, including the five held-out values and all counts above 63.
At 256, correct answer plus exact stop rises from zero to 97.78%. Requiring every intermediate letter to be correct brings that to 96.89%; twelve graphs return the right final letter despite an earlier error.
Does it know when to stop?
First stop probability ≥ 0.5 · open markers: controller-held-out counts 9, 17, 29, 41 and 53
Loading chart. Summary measurements are available below.
Exact stopping is 100% at every tested count. Correct answer + exact stop allows earlier errors; strict success requires every intermediate C prediction to be correct as well. Both success curves now equal their forced-execution counterparts. The dotted line marks twelve training loops; open markers identify controller-held-out counts 9, 17, 29, 41 and 53. Numeric training exposure ended at 63. Optional pointwise 95% Wilson bands apply to answer and trajectory success only: the count-only controller has one effective timing outcome per integer, not 1,350 independent trials. These results do not establish stopping at untested counts.
For requests of twelve, 32, 63 and 256, the actual stopping loop is now exactly twelve, 32, 63 and 256 on every graph.
The markers overlap and the percentile ranges collapse to a point because there is no graph-dependent variation left in stopping.
How long does the controller actually run?
Rows: requested steps · columns: actual stopping loop · 1,350 graphs per row
First threshold crossing · one stopping time per graph.
Loading chart. Summary measurements are available below.
The same 1,350 graphs are used at each request. The filled median-stop marker overlaps the open requested-loop diamond: minimum, maximum, median and both percentiles all equal N. There is no variation across graphs because this controller reads only the requested number. The default shows twelve, 32, 63 and 256; other counts are available in the selector.
Across the full range there are no early or late stops. Every graph signals a stop, and both the signed and absolute stopping errors are zero.
This covers every integer through 256, rather than just the four examples above.
Does it stop early or late?
Full benchmark · first stop relative to the requested count
Loading chart. Measurements are available in the downloadable evaluation data.
Every graph stops exactly at N throughout the benchmark, so the early and late categories are zero. Every graph signaled a stop within the 272-loop cap. In the distance view, signed and absolute errors overlap at zero. Repeated graphs do not provide independent evidence about this count-only controller; the coverage here is all 256 requested integers.
There are also no correct letters returned at the wrong time anymore. At 256, 1,320 graphs stop on time with the correct letter and thirty stop on time with the wrong one.
Those thirty are execution errors. The controller counts the requested loops; it does not check whether the answer is right.
Right answer, right time, or both?
Full benchmark · returned C letter compared with the requested N-step answer
Loading chart. Measurements are available in the downloadable evaluation data.
Only two categories are nonzero: exact stop with a correct answer, and exact stop with a wrong answer. The wrong-time categories remain zero. Each column uses all 1,350 graphs. Correctness refers to the requested final letter and can include an earlier error followed by recovery; strict success is shown separately in the stopping-accuracy figure.
I checked the number reader and timer separately at larger counts too. The largest initial reading error through 10,000 is 0.001953125 steps.
Switching to the stopping view shows exact first stops for all 8,192 tested requests. No executor runs in this diagnostic, so it does not mean the model follows a graph correctly for 8,192 steps.
Does the new controller count correctly?
Controller only · number reading through 10,000 · no executor loops
Loading chart. Measurements are available below.
This separate saved diagnostic reads every integer from 1–10,000 and runs the controller for every requested count from 1–8,192. No R transitions or pointer answers are evaluated. Reading error is |initial memory − N|; stopping error is first stop − N. Each integer contributes once, without graph-based confidence intervals. The stopping view uses the learned stop head at threshold 0.5, with a diagnostic cap of 8,208 loops. It is not the GRU’s auxiliary zero-crossing test. Training still used the same 58 numbers through 63 and at most twelve recurrent loops; these finite-range results do not establish arbitrary-depth counting.
Across all 345,600 graph/count queries, correct answer plus exact stop is 97.81%, and strict success is 97.02%.
With exact stopping at every requested count, these are also the corresponding forced-execution scores.
View key measurements and evaluation data
Same 1,350 graphs per count · final shared-reader controller · executor update 2,250
Requested steps
Exact stop
Correct answer + exact stop
Every step correct + exact stop
6
1,350 / 1,350 · 100.00%
1,338 / 1,350 · 99.11%
1,334 / 1,350 · 98.81%
9
1,350 / 1,350 · 100.00%
1,332 / 1,350 · 98.67%
1,327 / 1,350 · 98.30%
12
1,350 / 1,350 · 100.00%
1,330 / 1,350 · 98.52%
1,323 / 1,350 · 98.00%
13
1,350 / 1,350 · 100.00%
1,330 / 1,350 · 98.52%
1,322 / 1,350 · 97.93%
16
1,350 / 1,350 · 100.00%
1,325 / 1,350 · 98.15%
1,318 / 1,350 · 97.63%
17
1,350 / 1,350 · 100.00%
1,323 / 1,350 · 98.00%
1,317 / 1,350 · 97.56%
29
1,350 / 1,350 · 100.00%
1,319 / 1,350 · 97.70%
1,309 / 1,350 · 96.96%
32
1,350 / 1,350 · 100.00%
1,320 / 1,350 · 97.78%
1,308 / 1,350 · 96.89%
41
1,350 / 1,350 · 100.00%
1,319 / 1,350 · 97.70%
1,308 / 1,350 · 96.89%
53
1,350 / 1,350 · 100.00%
1,318 / 1,350 · 97.63%
1,308 / 1,350 · 96.89%
63
1,350 / 1,350 · 100.00%
1,319 / 1,350 · 97.70%
1,308 / 1,350 · 96.89%
64
1,350 / 1,350 · 100.00%
1,319 / 1,350 · 97.70%
1,308 / 1,350 · 96.89%
128
1,350 / 1,350 · 100.00%
1,320 / 1,350 · 97.78%
1,308 / 1,350 · 96.89%
256
1,350 / 1,350 · 100.00%
1,320 / 1,350 · 97.78%
1,308 / 1,350 · 96.89%
Numeric exposure is separate from the twelve-loop training horizon
Requested counts
Queries
Exact stop
Correct answer + exact stop
Strict success
Seen: 1–12 except 9
14,850
14,850 · 100.00%
14,727 · 99.17%
14,688 · 98.91%
Seen: 13–63 except 17, 29, 41, 53
63,450
63,450 · 100.00%
62,074 · 97.83%
61,592 · 97.07%
Held out: 9, 17, 29, 41, 53
6,750
6,750 · 100.00%
6,611 · 97.94%
6,569 · 97.32%
Unseen numeric range: 64–256
260,550
260,550 · 100.00%
254,614 · 97.72%
252,444 · 96.89%
Exact-stop outcomes are identical across graphs at each count. The 345,600 repeated graph/count queries do not represent that many independent numerical tests. Forced final-answer and complete-trajectory scores equal joint and strict success respectively because every stop is exact.
Forced execution within fixed requests · 1,350 graphs at each N
Requested steps
Mean correct prefix
Wrong loops
Recovery after a wrong prediction
6
5.97 loops
0.38%
4 / 19 · 21.05%
12
11.86 loops
0.87%
8 / 121 · 6.61%
32
31.33 loops
1.58%
25 / 651 · 3.84%
256
248.37 loops
2.19%
234 / 7,544 · 3.10%
The executor, both readouts and all forced diagnostics match Architecture 4 exactly. The separate numerical diagnostic checks the final checkpoint’s reader through 10,000 and first stops through 8,192; it does not extend pointer quality beyond 256. These are saved measurements, with no new fitting or checkpoint selection on this benchmark.
The main result here is that I could fix stopping without changing the executor at all. Its intermediate predictions and remaining mistakes are identical to the GRU version, but the final model now returns its answer at the requested loop. That makes the distinction between executing correctly and knowing when to stop much more concrete than it was in the earlier attempts.
The simpler controller also comes with a lot of structure supplied by me. I chose a digit-by-digit reader, a scalar memory and an affine update, then supervised the remaining work directly. It learned the coefficients, but I gave it a form suited to counting. This is a useful solution to a task with a known completion rule. A general way to judge whether reasoning is complete would need more than that. It will stop on time even when the executor is wrong.
So I think the original experiment worked within a fairly specific scope: a small model trained on short graph paths can keep executing them for much longer, with one loop corresponding to one graph transition on the successful trajectories. The 26-state cycles, fixed prompt format and separate timer all matter to that conclusion. The successful executor was trained with one seed; testing graphs from three generation seeds does not tell me how reliably another training run would reproduce it. The next question is how much of this carries over once those conveniences are removed.
What Next?
There are a few things I would like to try next. These are follow-up experiments, rather than things this benchmark already answers.
Find out which changes mattered
Several changes went into the successful executor at once. I would start by comparing runs with and without the requested count in the executor’s prompt, keeping the rest of the recipe the same. Similar comparisons could test the bridge, full training of R, direct supervision and cyclic training data. That would help explain which changes were needed to keep execution working beyond the training horizon.
Make the graph task harder
Two-letter node names would let us go beyond 26 states and test much longer paths without necessarily revisiting a node. Another option is to give each node multiple outgoing edges and use an extra instruction, such as an edge color, to choose the transition. I would also vary the prompt format and rule order to check how much the current result depends on the exact presentation. These would test more than just how long the timer can count.
See whether mistakes can actually be repaired
Right now, another loop means another graph transition, so simply running for longer after an error does not necessarily repair the answer we wanted. I would like to test a version with a clear terminal state, where the target stops changing once the task is complete. Then we could ask whether extra loops fix wrong answers while preserving correct ones. That would be a better starting point for a controller that decides how much computation is useful, instead of only counting a supplied number of steps.
Try another procedure, and measure the cost
Finally, I would like to see whether the recurrent executor can help with another small algorithmic task, such as running a finite-state machine or applying a sequence of symbolic updates. I would test transfer separately from training a new model from scratch. Alongside that, I would measure latency and memory at matched task quality, including the readouts and controller. A shared set of weights is useful, but it does not by itself tell us whether the full system is cheaper to run.