Research record

A Task Battery With Designed Headroom

Ongoing research. This is an experimental result from active work, not a settled conclusion. The numbers are what we measured and the method is described so you can judge it, but the programme is still running and later experiments may revise what it means.

A note on the language in these records. This is a working laboratory notebook for research into training AI models more cheaply and efficiently, so you will read that an approach did not work, that a result did not hold up, or that one method was worse than another. That is the research doing its job, not a verdict on the engineering we deliver to clients. Ruling an approach out is how the search narrows, and these are the pages that teach us the most: nearly every technique we now rely on came from understanding why something else fell short. Testing our own ideas at least as hard as anyone else's is the point of publishing them. More about this programme and why we run it.

Part of a bigger question: Is the task we are studying actually hard? – Often it is not. A rule from 1990 with no parameters beats the trained model on the task most of these results were measured on, and what an intervention costs is set by the task's own structure.

In plain English

What we asked. Every quality check in our experiments was passing. We got suspicious and asked whether they could ever have failed.

What we found. They could not. The test problem was so easy that models scored 96 to 99.5% on it, leaving no room to detect harm. So we designed four harder replacements and set the acceptance rule before looking at any results. Two passed. The two rejections are the interesting part: one turned out to be all-or-nothing, and the other was trivial for this kind of model.

Why it matters. A test that everything passes is not a test, it is decoration. This is a common and quiet failure in AI evaluation, because a saturated benchmark still produces a reassuring number, and the number is meaningless.

The rest of this page is the technical record: the design, every number, and the limits. It is written for a reviewer, and you do not need it to have understood the result above.

New here? How to read a research record
  • Start at the verdict. Every record states, before the experiment was run, what result would have made us abandon the idea. That is the "kill test". Then it says whether the test fired. Nothing gets reinterpreted after the fact.
  • Numbers in square brackets are uncertainty. 23.4 [18.1, 28.7] means our best estimate is 23.4 and the true value is probably somewhere in that range. If a range includes zero, we cannot claim an effect.
  • Results that rule an idea out are kept. Roughly half of what is published here says an approach did not work, including plenty of our own. Those pages are the output, not a shortfall: knowing which direction is a dead end is what lets the next experiment go somewhere better, and most of what we now rely on came out of understanding why something else fell short. Work that only publishes what worked is not measuring anything.
  • Read the Limits section. Every record ends with what it does not show. It is the most honest part of any experiment and usually the shortest.
  • Pro tip: the figures near the top are designed to carry the result on their own. If you read nothing else, read the caption under each one, which says what it shows and what to take from it.
EXPLORATORY platform qualification. Not a preregistered research study. Local CPU, 48 short training runs, no GPU, no cost. The acceptance rule below was fixed before execution and is not revisable by its outcome.

Program v2 tier 1. Decisive computation: analysis/headroom_battery.py. Output: analysis/headroom_battery.json. Reproduce with python analysis/headroom_battery.py in about eleven minutes on a throttled laptop CPU.

Why this exists

Every quality guardrail in program v1 passed. That reads as reassuring and is partly an artifact: held-out accuracy on both v1 tasks sits at 96–99.5%, so a model with 0.4 points of room cannot lose 2 points. "No quality loss" was in part a statement about the task, not about the intervention. E1 fixes that at the substrate, new tasks whose control plateau sits below ceiling for a stated structural reason, and E2 restates the guardrail in units that mean something.

Which practice tasks leave the model room to fail
Which practice tasks leave the model room to fail. Every task this project used previously was solved almost perfectly, around 97-99% accuracy. That is a problem for measurement: if an experiment damages the model slightly, there is no room for the score to drop, so the damage is invisible. These bars show where models settle on candidate replacement tasks. The shaded band is the target: hard enough to leave room, easy enough to be learnable. Tasks landing inside the green band are useful measuring instruments; tasks above it are too easy to detect anything with, and tasks below it are too hard to learn at all. Only the adopted ones will be used for future quality claims.

The acceptance rule, fixed before execution

A 5-seed width-48 GRU control must:

  1. plateau with mean held-out accuracy between 60% and 90% within 2,000 steps; and
  2. actually be plateaued: mean gain over the final 500 steps under 2 percentage points, so a task still climbing does not qualify by passing through the band on its way up.

Clause 2 was added because a task that merely passes through the band is a slow task, not a task with headroom, and it would silently saturate the moment anyone ran it longer.

Task parameters (vocabulary, lag sets, marker rates) were selected by a one-seed screen at seed 997, which is deliberately absent from the acceptance seeds (401, 409, 419, 421, 431). The screen chose settings; it could not and did not touch the rule.

Result: 2 of 4 accepted

TaskRoleGRU plateau (5 seeds)Final-500 gainTransformerVerdict
dispatch-copy-8lagqualifying0.6175 [0.592, 0.634]+0.01190.2427ACCEPTED
dispatch-copy-wide-vocabqualifying0.6696 [0.657, 0.684]+0.01190.9991ACCEPTED
modular-sumqualifying0.6486 [0.491, 0.974]+0.25570.1640rejected
running-countqualifying1.0000 [1.000, 1.000]+0.00000.9976rejected
noisy-copycalibration0.8491 [0.840, 0.855]+0.00110.8589,
delayed-copy (v1)reference0.9960 [0.995, 0.998]+0.00081.0000,

The instrument is calibrated

synthetic-noisy-copy-v1 corrupts its scored target with probability p, so its ceiling is analytically 1 - p + p/V = 0.8547 at p = 0.15, V = 32. The measured plateau came in at 0.8491, an error of -0.0056. The plateau estimator is accurate to about half a percentage point against a known answer, which is what licenses reading the other rows.

Why the two rejections are informative, not just failures

modular-sum is all-or-nothing per seed. Its 5-seed mean of 0.6486 sits inside the band, and it would have been adopted on clause 1 alone. Clause 2 caught it: the final-500 gain is +0.2557, and the per-seed plateaus span 0.491 to 0.974. Some seeds solve the task outright and some do not; the mean is an artifact of averaging two different outcomes.

The screen shows the same thing across vocabulary size, as a cliff rather than a slope:

VocabularyPlateau at 8,000 steps
400.983
441.000
460.964
480.336 (stable, gain +0.002)
640.018 (chance)

There is no setting between "solves it" and "stuck near a third". Two-term modular arithmetic at this scale is a discontinuous capability, which makes it a poor measuring instrument and a genuinely interesting object: it is a natural candidate for E5 (grokking) and D2 (is the jump one event or several?), where all-or-nothing behaviour is the phenomenon rather than a nuisance.

running-count is trivial for a recurrent model. It hit 1.0000 in every seed at every setting screened: modulus 4 to 32, marker rates 0.2 to 0.5, sequence lengths 16 to 64. A GRU has a native accumulator, so asking it to count does not create difficulty. Recorded boundary: counting is not a source of headroom for recurrent architectures at this scale.

An unplanned result worth carrying to E3

The two accepted tasks are the same generator at different settings, and the architectures disagree completely about them:

  • dispatch-copy-8lag: GRU 0.62, transformer 0.24, the transformer does far worse.
  • dispatch-copy-wide-vocab: GRU 0.67, transformer 0.9991, the transformer solves it.

A1's design requirement asked for a task a transformer cannot solve with its native primitive. dispatch-copy-8lag is a candidate: dispatching on an announced offset across eight possible lags is not one attention lookup. That should feed directly into the E3 architecture × task grid rather than being discovered there.

E2: the guardrail convention these plateaus enable

Implemented in latent_pretraining.metrics.headroom. Quality claims are now expressed as a fraction of the room that actually existed:

headroom_fraction_lost = (plateau - observed) / (plateau - chance)

chance is measured, not assumed: it is the best constant predictor's accuracy on a large sample, via chance_accuracy(). 1 / vocab_size is wrong for any task with a non-uniform target distribution, and running-count is the clear case: at the natural marker rate its constant- predictor floor is 0.7479, not 0.03. (That measurement is also what exposed the first version of the task as trivial, and the generator now injects markers at an explicit rate.)

The same half-point loss, priced on two tasks:

TaskPlateauHeadroomCost of a 0.5 pp loss
delayed-copy (v1)0.99600.96140.5% of headroom
dispatch-copy-8lag0.61750.58410.9% of headroom

Default guardrail: an arm may give up at most 5% of achievable headroom. Measured ceilings live in TASK_CEILINGS and are properties of a task at a stated width and step budget, re-measure them when adopting a new configuration.

Also delivered in tier 1

  • D0, mid-run checkpoints. trainer.checkpoint_every: k writes weights plus optimizer state to checkpoints/step-NNNNNN.pt, registered as bundle artifacts. Off by default (0), so no existing config changes behaviour. Unblocks D1, D3, D5, D9, A7, F6, F8, and answers D6's own limitation, which could only read the output head as it stood at the end of training.
  • The optimizer field now means something. optimizer.name was read into the spec and then ignored: the trainer hard-coded AdamW, so a config asking for SGD trained with AdamW silently. Every archived run names adamw, so no recorded result is affected, but D8 (does the expansion survive plain SGD?) depends on the field working. optimizer_from_config now dispatches adamw / adam / sgd, exposes weight_decay, momentum, and nesterov, and raises on an unknown name rather than substituting.
  • E5's fixed-dataset mode. data.training_examples: N draws a finite pool once and resamples from it, making a memorisation regime possible for the first time. Because per-step accuracy is then training accuracy, held-out evaluation per logged step turns on automatically (heldout_token_accuracy, appended as a new final CSV column). A 60-step smoke run already shows the gap: 43% train against 25% held-out.
  • CPU throttling that actually throttles. laptop-safe capped thread count but LocalResourceController.after_step returned early on any non-CUDA device, so a CPU run held every capped core flat out, and the standalone analysis/ pilots bypassed the policy entirely. CPU duty cycling is now implemented, PilotThrottle applies it to pilots, and the inter-op thread pool is capped alongside the intra-op one. This battery ran at ~2–3 of 16 cores.

Limits

  • One width (48), one step budget (2,000), one optimizer (AdamW), one learning rate. A plateau is a property of that whole configuration; the accepted tasks are qualified for it and nothing else.
  • The transformer arms used 3 seeds and are informational, E3 owns the architecture grid.
  • Two accepted tasks are two configurations of one generator. The battery has breadth of setting, not of task family, and a finding that replicates across both is not yet a finding that replicates across tasks.

Terms on this page

Every piece of vocabulary this record uses, in plain language. Generated from the text above, so it cannot drift out of step with it.

accuracy
The fraction of answers a model gets right on questions it was not trained on.
AdamW
A widely used training algorithm that adapts how big a step it takes for each individual parameter. The default in most modern AI training.
architecture
The blueprint of a model: what components it has and how they connect. Two models can be the same size and completely different architectures.
calibrated
A model is calibrated when its confidence matches how often it is right: answers it gives with 90% confidence should be right about 90% of the time.
calibration
Working out an instrument's settings from runs whose answer you already know, so it can be used on a run whose answer you do not.
checkpoint
A saved copy of a model partway through training, so you can come back and inspect what it looked like at that moment.
GRU
Gated Recurrent Unit. A compact design for processing sequences one item at a time, with internal switches controlling what it keeps in memory.
held-out
Data the model was never trained on, kept back specifically to test it. Scoring a model on data it has already seen measures memorisation, not learning.
learning rate
How big a step training takes each time it updates the model. Too small and nothing happens; too big and it never settles.
momentum
Keeping part of each previous training step in the next one, so training keeps moving in a consistent direction instead of zig-zagging.
optimizer
The algorithm that decides how to change the model given the gradient. AdamW and SGD are two common choices and they behave differently.
parameters
The adjustable numbers inside a model. Training is the process of setting them. Model size is usually quoted as a count of these.
plateau
A stretch of training where the model is not visibly improving. Often, though not always, followed by a sudden jump.
recurrent
A design that reads a sequence one item at a time, carrying memory forward. The main alternative is attention, which looks at everything at once.
seed
The number that fixes all the randomness in a training run. Same seed, same run. Running several seeds is how you tell a real effect from a lucky one.
SGD
Stochastic Gradient Descent. The simplest training algorithm: take a step in the direction the gradient points, every time, with no adaptation.
slope
How steeply one quantity changes as another does. A slope of one between a warning and the event it predicts means the warning shifts exactly in step with the event.
transformer
The architecture behind most modern large language models. It uses attention to look at every part of the input at once, rather than reading in order.
vocabulary
The set of distinct symbols a model can read and produce.
width
How many internal numbers a model uses at each layer. The usual way we vary model size in these experiments.

Want this measured on your data?

We build private models our clients own and run on their own infrastructure, and every engagement proves measured lift on the client's own tasks before we call it done. Start free with a readiness scorecard that tells you whether your data can support it, or book a short call.