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. More about this programme.

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.

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.