v = 41v = 58leavesroothand-made leafhalf formula, half learned survival
Technique

NNUE evaluators

A small neural network built so that when one move changes a few cells, only the affected part of the first layer is recomputed.

Read the primer: NNUE evaluators

On this page

The problem

A look-ahead search ends at boards where the game is not over, and it needs an opinion about each one. That opinion is the leaf evaluator, and in the reference policy it is nineteen hand-tuned structural terms about height, crowding and chain readiness. Almost every learning experiment on this site has tried to replace it, and almost all of them failed the same way, which the sibling trap page explains.

building the tree…
building the tree in the browser…
MAX node the position; the search picks the column with the highest expected value.chance branches every exact outcome of a drop — the next disc, and what any cracked gray disc turns out to be — weighted by its probability.leaf the opinion of the board scorer where the look-ahead stops. Click a column to expand it; click an outcome to play that transition and continue from it.Columns are numbered 1–7 from the left. Values come from the browser solver and are a demonstration, never research evidence; seed 0x5eed1006 is the same game as /play.
The search reaches these boards and stops. Whatever it cannot see beyond them has to be priced by the number on each board, and a learned leaf replaces that number with a prediction of remaining lifetime. The tree is engine output from a scripted round.

Proposed solution

Train a small network to predict how many moves a game has left, and mix its opinion half-and-half into the hand-written scorer. This has an unusual advantage. A Drop7 Hardcore score is 94.29% the flat bonus for surviving another row rise, and a game runs at about 3,400 points per move (finding-01, 64 games), so a prediction of remaining moves multiplied by 3,400 is already a score in real points, the same unit the search's own immediate-score term carries. Mixing the two is mixing two estimates of one quantity. The design is also blind to which move was played: the same function scores every legal successor inside the existing search, so it cannot take the shortcut that sank earlier models.

The catch is how many times the leaf is called.

board scorings per decision615,090four-move search, five chance samples, counted over 30 real decisions
at seven chance samples2,271,280same measurement
the trained network costs4,122 µsper board, in the exported C++ path
so one decision would take2,535 sagainst a 0.887 s reference decision: a factor of 2,860

A three-million-parameter convolutional network cannot be the leaf of this search: one 87-move game would take 6.7 hours of the whole machine and one 64-game arm 18 days (finding-08). So the network that plays is NNUE-shaped, an "efficiently updatable" network built from sparse binary features that are gathered and summed, and it runs in about a microsecond. The prediction written down before any game was played was that the learned leaf would help more once the search handles luck exactly, with seven chance samples instead of five.

The policy reads only the visible board, the visible next disc and the moves until the next rise; at a blend weight of zero the code short-circuits to the frozen reference before the model is touched.

How it works

  1. Measure the budget first. Nothing on record said how many board evaluations a four-move decision performs, so a probe counted them over 30 real decisions before anything was trained.
  2. Train the network that was specified anyway, export it to a versioned binary that runs with no PyTorch, no BLAS and no allocation on the hot path, and gate it on 4,096 real boards at a tolerance declared before the comparison. After a surprise (under validity, below) the gate also proves that the PyTorch reference repeats bit-for-bit before anything is compared against it.
  3. Train the model that can afford to play: 8,902 binary features of which exactly 135 are active per board. They include 84 adjacent-pair features, because a disc clears when its number matches the length of the run it lands in, and a per-cell bag of features cannot see a run at all.
  4. Blend. The leaf becomes (1 − w) × hand_written + w × 3400 × predicted_lifetime. At w = 0 the comparison arm is the frozen reference bit-for-bit and costs exactly what the reference costs.
  5. Choose w on a separate 32-game cohort, freeze it, and run the comparison as a two-by-two: hand-written versus learned leaf, at five and at seven chance samples, 64 paired games each, on a cohort that tuning never touched. The output of every arm is a column per position, as in the reference.

What happened

The learned leaf helped modestly, and it helped most where the prediction said it would help least. With the reference's five chance samples it added +39,105 points per game on 64 paired development games, with a one-sided bootstrap lower bound of +1,138, so above zero by very little (finding-08, run valid, development tier). With the exact seven-sample chance estimator its gain did not clear its bound and is unresolved. The preregistered prediction was that the gain would be materially larger at seven samples; the measured difference between the two gains was −21,824, the wrong sign, and by the rule fixed in advance that is a fail. The finding reports it as one.

What we learned

The refutation has a mechanism. An exact chance estimator and a learned leaf are both ways of knowing more about what happens after the current move, and having bought that knowledge once, buying it again returns less. Seen from the other axis: making the chance estimator exact is worth +101,171 points with the hand-written leaf and +79,347 with the learned one, the same substitution, 22% smaller (64 paired games per arm, finding-08). Extra look-ahead is processed through the chance average, so a biased average corrupts it; a leaf value is terminal, so it inherits the bias of the path that reached it but does not compound it.

The binding constraint is arity. 615,090 board evaluations per decision is a hard budget, and the 0.008 of held-out correlation between the deployed student and the network five times its size says a bigger survival model has little accuracy to offer anyway (finding-08). At equal compute, fixing the chance estimator is the better purchase: the seven-sample arm costs 3.42× the reference's CPU per decision and buys +101,171 points, while the learned leaf roughly doubles the cost of a decision for a gain that clears zero by 1,138.

The move-blind, state-only design is a positive result on its own terms: this evaluator never sees a move identity and it cleared a paired 64-game lower bound, which the family's earlier models did not. But every learned arm also pushed the board away from the 19 to 20 occupied cells where the flow ceiling measurement puts the crossing between achievable clear rate and survival requirement (24.29 to 24.68 cells at five samples, finding-08). A model that predicts remaining lifetime under the current policy does not steer toward the operating point where lifetime becomes cheap. Whether aiming the leaf directly at occupancy or at the clear rate would do so is the open question, and it has not been tested.

Agent contextRecords and provenance

Source: finding-08-learned-leaf, a retained exploratory finding measured in this checkout on 2026-08-20; evidence tier development for the gameplay arms and CHECK for the export, parity and feasibility gates. The prediction and pass/fail rule are in PREREGISTRATION.md in this directory, written before any cohort was run. There is no row in the experiment index and no entry in the ledger.

Verdict as recorded: run validity valid; preregistered prediction fail (refuted); learned leaf at five chance samples pass; at seven chance samples inconclusive; evidence tier development.

The two-by-two: 64 paired whole games per arm, seeds 0xa51d10000xa51d103f, four-move search, 2,000-move cap; learned arms at w = 0.50 with the lifetime head, frozen on a separate 32-game tuning cohort.

Agent contextFull results table
armmeanmedianQ25maxmovesgames ≥ 1M
5 samples, hand-written leaf297,327260,415192,352836,42787.160
5 samples, learned leaf336,432313,730209,914948,58698.280
7 samples, hand-written leaf398,498344,630212,8641,341,287114.662
7 samples, learned leaf415,779349,034194,0401,344,732120.753

Paired deltas, one-sided 95% lower bounds, 20,000 percentile-bootstrap resamples over whole games: learned − hand-written at 5 samples +39,105 [+1,138] points and +11.13 moves, wins–ties–losses 37–0–27; at 7 samples +17,281 [−55,892], 34–0–30; the difference between those two gains −21,824 [−105,254]; 7 samples − 5 samples with the hand-written leaf +101,171 [+46,730]; with the learned leaf +79,347 [+17,053].

Flow: at five chance samples the learned leaf raises numbered clears by 0.0342 and reveals by 0.0212 per move, consistent with its +11.13 moves of extra lifetime, and every reported quantile of the score improves. At seven samples the paired per-game flow changes are slightly negative, an independent reason to treat the seven-sample gain as unresolved rather than as a smaller real effect.

Occupancy: mean occupied cells moved 24.29 → 24.68 at five samples, 23.15 → 23.87 at seven, and 25.53 for the pure learned leaf with the hand-written one switched off entirely.

Cost: calling the model at every one of 660,481 leaves roughly doubles the cost of a decision (2.11× for the learned leaf on top of the exact estimator); the seven-sample arm costs 3.42× the reference's CPU per decision.

The two models: the convolutional teacher has 3,006,543 parameters, held-out lifetime correlation 0.8646 and costs 4,122 µs per board. The deployed NNUE-shaped student has 572,367 parameters, held-out correlation 0.8564 and costs 1.33 µs: 0.008 of correlation given up for a 3,109× speed-up. Both were exported and both passed a stated-tolerance parity gate; only the student ever played a move.

Agent contextValidity, gates and limitations

Validity gates: both hand-written-leaf arms reproduce the earlier chance-sampling study's published 64-game cohort to every digit; the w = 0 short-circuit matched the frozen reference on 50 of 50 compared moves; 0 score-identity violations in 26,934 decisions; 0 censored games in 256; the seven-sample arms ran with a raised work bound whose measured 4,956,614 work per move confirms a completed four-move search rather than a silent degradation to three.

A host defect found here and not audited generally: the parity gate passed, then the identical command failed on every output. torch.nn.Conv2d on this host's CPU is nondeterministic: two identical forward passes in eval mode, single-threaded, differ in 6.25% of output elements, and through the normalisation layer's group statistics one perturbed activation moves 100% of the model's outputs. Written up as gpu-03. Any gate in the repository that compared against a CPU PyTorch convolution may be affected; that has not been checked.

Limitations the finding states about itself: 64 paired games per arm with a score standard deviation of 51–67% of the mean, so the +1,138 lower bound clears zero by very little and wants replication on fresh seeds; the difference-in-differences interval is wide, so the data refute the predicted positive interaction but do not establish a negative one; the evaluation cohort is previously read development data and is now doubly read; the model that was specified never played a move; the blend weight was tuned only at five chance samples and the seven-sample tuning confirmation was preregistered and not run; no timing here is timing-grade; and the mean of 415,779 is far below the 1,050,000 the frozen qualification protocol requires. No protected or final seed was opened.

Open follow-ups named by the finding: a fresh-cohort replication of the +39,105, and a blend weight re-tuned at seven chance samples, which would say whether the seven-sample number is an underestimate.

RecordsTheories, experiments and results that reference this directory

Claim: On the existing 5.26M-record training corpus (runs/RUN-A51D-corpus/all.states, whole-origin split of dataset.py), the NNUE-shaped survival leaf's held-out lifetime correlation does not improve by more than 0.01 when hidden width is raised from 64 to 512, the middle layer from 32 to 64, epochs from 10 to 20, or the learning rate is changed: its accuracy is saturated by the feature space and the data, not by capacity or training length.

This theory is currently supported-as-tested at the mechanics-only (checks only, no games played) level.

Claim: A LeafNet-shaped student (approaches/lifetime-objective/learned-leaf/leaf_features.py features, EmbeddingBag(8902,64)->32, ~572k parameters, ~1.3 us per state) trained with a within-root listwise plus pairwise loss on the existing successor-closed exact D4 sibling-value labels (runs/RUN-20260821T085042Z-c5cf0e71/d4q-labels, 291,890 afterstates over 8,639 roots) reproduces fair D4's within-root ordering on whole-origin held-out roots at the frozen d4q thresholds: top-1 >= 0.60, pairwise >= 0.78, normalised regret <= 0.13, in each half-fold.

This theory is currently not-supported-as-tested at the pilot (a small run to find bugs and project cost, not a strength claim) level.

Claim: A leaf-cost student (the existing 572k-parameter finding-08 NNUE, architecture unchanged) trained on ALL legal siblings per root, with labels that are long-horizon outcome distributions (per-rise hazard vector plus censored restricted-mean lifetime, Kaplan-Meier over K CRN-paired continuations under a fixed cheap public continuation policy) and a within-root pairwise ranking loss on the deployed scalar (KM expected lifetime), achieves within-root discrimination that played-action outcome training cannot provide (coverage) and exact-search-value distillation cannot provide (objective): offline, top-1 agreement with exact D4's argmax >= 0.55 and >= the played-action incumbent + 0.03; deployed as the existing blended leaf, it improves the paired 256-game d4s7 mean with a positive one-sided 95% lower bound without giving back the incumbent's d4s5 gain.

This theory is currently untested at the proposal (no games played) level.

Claim: With the reveal quadrature fixed at M=6, continuation-search depth is second-order for WITHIN-ROOT sibling ordering: fast d1-M6 or d2-M6 KM-lifetime orderings agree with fast d3-N7M6 at mean within-root Kendall tau LB95 >= 0.75 and top-1 agreement LB95 >= 0.80 at the corpus operating point (K=8, H=40, CRN continuations shared across siblings and engines), and labels from the certified cheap engine train the 572k NNUE leaf to the P-SOL G1/G2 gates (student top-1 vs exact D4 >= 0.55 and >= incumbent + 0.03; label-argmax vs D4 >= 0.60; fit >= 0.7x the split-half label ceiling).

This theory is currently untested at the proposal (no games played) level.

Claim: A leaf-affordable NNUE evaluator (the 8,902-feature, 135-active sparse class of approaches/lifetime-objective/learned-leaf), whose weights are (a) initialised by distilling the sibling-complete root values of a depth-5 seven-stratum fair-expectimax teacher and (b) then refined by a mutation-only genetic algorithm whose fitness is the mean score of complete paired depth-3 seven-stratum games, deployed as the leaf of that same depth-3 seven-stratum search, achieves a higher mean whole-game score on never-read paired development games than the identical search using the frozen fair leaf.

This theory is currently not-supported-as-tested at the public-development (a cohort for deciding what to try next, not confirmation) level.

It compares leafnet-capacity-grid against fair-d4 at the CHECK (mechanics checks only, no games played) level, using previously-evaluated-development data.

valid run outcome: pass The run was valid and the outcome was pass (mechanics-only (checks only, no games played)). Read the result.

It compares LeafNet h64/m32 listwise student on d4q labels against exact fair D4 ordering (d4q labels); exact D1 0.486 and D2 0.568 top-1 as calibration at the CHECK (mechanics checks only, no games played) level, using no-gameplay data.

valid run outcome: fail The run was valid and the outcome was fail (pilot (a small run to find bugs and project cost, not a strength claim)). Read the result.

It compares panel2-km-label-nnue-leaf against incumbent played-action LeafNet (finding-08) and exact D1/D2/D4 orderings at the CHECK (mechanics checks only, no games played) level, using no-gameplay data.

No result has been recorded for it.

It compares panel2-km-label-nnue-leaf-fastd3s7 against incumbent played-action LeafNet (finding-08) and exact D1/D2/D4 orderings at the CHECK (mechanics checks only, no games played) level, using no-gameplay data.

valid run outcome: fail The run was valid and the outcome was fail (pilot (a small run to find bugs and project cost, not a strength claim)). Read the result.

It compares psol3-m6-cheap-engine-corpus-nnue against incumbent played-action LeafNet and exact D1/D2/D4 orderings at the CHECK (mechanics checks only, no games played) level, using no-gameplay data.

No result has been recorded for it.

resultvalid runoutcome: passtier: mechanics-onlyRS-20260822T024228Z-94090db1

The run was valid; the outcome was pass, at the mechanics-only (checks only, no games played) level. Of 3 preregistered checks, 3 passed and 0 failed.

Offline capacity/training sweep of the NNUE-shaped survival leaf on runs/RUN-A51D-corpus/all.states (13 runs, same whole-origin test split, 486,819 held-out examples). Baseline h64/m32/e10/lr3e-3 held-out lifetime Pearson 0.8546 (finding-08 recorded 0.8564 on an earlier torch build); seed-to-seed spread 0.0023 over three seeds. Best configuration h64-m64-e10-lr3e3-s0 at 0.8568, delta +0.0022 <= max(0.005, 2 x spread): gate verdict supported-as-tested. Width hurts: Pearson by width (params, Pearson, final train loss) h32-m32-e10-lr3e3-s0 (286,447 params: 0.855, loss 0.5238); h64-m32-e10-lr3e3-s0 (572,367 params: 0.8546, loss 0.511); h128-m32-e10-lr3e3-s0 (1,144,207 params: 0.8543, loss 0.5006); h256-m32-e10-lr3e3-s0 (2,287,887 params: 0.8515, loss 0.4857); h256-m64-e20-lr3e3-s0 (2,296,591 params: 0.8446, loss 0.4596); h512-m64-e20-lr3e3-s0 (4,592,143 params: 0.8378, loss 0.4197). Training loss falls monotonically with width while held-out accuracy falls, i.e. larger students overfit this corpus; 20 epochs change nothing at h64 and hurt at h128/h256; lr 1e-3 and mid 16/64 are within spread. The accuracy of this feature space on this corpus is saturated near 0.855-0.857; it is not limited by hidden width, middle width, epochs or learning rate.

Technical recordLimitations recorded with the resultRS-20260822T024228Z-94090db1
  • Offline diagnostic on teacher labels from already-played games; says nothing about playing strength (finding-08: a 0.008 Pearson gap did not separate two models in play).
  • Single corpus (5.26M records, whole-origin split); a corpus several times larger could move the saturation point and is the natural follow-up, since the wider models overfit rather than underfit.
  • Per-board inference cost was not measured; irrelevant to the verdict because no wider model won.
  • GPU ran concurrently with a 30-thread CPU evolution; wall times are not timing-grade; metrics are unaffected.
  • The baseline reproduction differs from finding-08's 0.8564 by 0.0018 on a newer torch build; within the measured seed spread.

Full record →

resultvalid runoutcome: failtier: pilotRS-20260823T194142Z-946e3cd1

The run was valid; the outcome was fail, at the pilot (a small run to find bugs and project cost, not a strength claim) level. Of 5 preregistered checks, 2 passed and 3 failed.

The leaf-affordable NNUE-class student does not reproduce fair D4's within-root ordering from the existing successor-closed labels. Five initialisation seeds of the LeafNet h64/m32 student (571,905 parameters; features from learned-leaf/leaf_features.py) were trained for 30 epochs on the 6,551 training roots of runs/RUN-20260821T085042Z-c5cf0e71/d4q-labels with the preregistered listwise + gap-weighted pairwise + 0.1 MSE loss; the seed with the best calibration-fold top-1 (0xA52E02, 0.3281) was then read once on the 3,030-root held-out panel of that experiment. Held-out top-1 was 0.296 / 0.3011 in the two origin-seed half-folds (gate >= 0.60), pairwise 0.6266 / 0.6259 (>= 0.78), normalised regret 0.3354 / 0.3379 (<= 0.13): every criterion fails in both half-folds. The other four seeds lie between 0.2987 and 0.3135 pooled top-1, all below the 3.4M-parameter afterstate CNN of RS-20260821T104500Z-77d21e90 (0.375) and below exact D1 (0.486). The student is leaf-affordable as claimed (1.27 us per state through the existing d7leaf export and leaf-check), but at this size it holds less of D4's ordering than the CNN did. Per the preregistered failure action: no leaf-affordable NNUE-class student of this size reproduces D4's ordering from these labels; the self-play loop TH-20260821-...-299ed02f stays blocked in its leaf form and its redesign is routed to the larger-student question. Diagnostic tier: the held-out panel had already been read once by the d4q experiment, so this is a diagnostic read on existing data, not new evidence about fresh roots.

Technical recordLimitations recorded with the resultRS-20260823T194142Z-946e3cd1
  • Diagnostic-tier read: the 3,030-root held-out panel (d4q-labels-gate) was already opened once by EX-20260821-afterstate-d4q-stage1; no fresh roots were labelled. The result schema has no diagnostic tier, so it is recorded at the lowest tier (pilot); it is not development-tier evidence.
  • The preregistration names only the d4q-labels file, which carries folds train and calibration but no held-out fold; the held-out panel and its origin-seed half-folds were taken from the same run's d4q-labels-gate/d4q-labels.tsv and corpus-gate/roots.tsv, exactly as d4q.py consumed them, which is the reading the protocol's 'train/validation/held-out origins are reused unchanged' clause intends.
  • Epoch count was fixed at 30 by the protocol and the final-epoch model was used. Calibration-fold top-1 peaked at 0.352-0.359 between epochs 5 and 10 for every seed and then declined as the training listwise loss kept falling (overfitting); even the best epoch is far below the 0.60 gate, so early stopping would not change the verdict, but the reported held-out numbers are for the overfitted final epoch.
  • Loss coefficients not fixed by the hypothesis text were set to 1.0 for the pairwise term (d4-q-clone used 0.35) and the prediction-side softmax temperature was 1 in standardised value units; only the listed configuration is rejected.
  • CPU training with 8 torch threads; the EmbeddingBag backward is not bit-deterministic across thread counts, so a re-run reproduces the numbers only approximately.
  • Inference cost is from leaf-check on the RUN-A51D-corpus mix-d3 states on a shared host; informational only.

Full record →

resultvalid runoutcome: failtier: pilotRS-20260823T225753Z-0fbd48c3

The run was valid; the outcome was fail, at the pilot (a small run to find bugs and project cost, not a strength claim) level. Of 3 preregistered checks, 1 passed and 2 failed.

P-SOL-2 stage G0 fails per the frozen failureAction, with no leased seed opened. Re-gates 7/7 pass, including fast-vs-native d3s7 parity (240 decisions, 0 action/work mismatches). Rung 1 S1-halted on measured cost: fast-d3s7 continuations run at 54.6 ms/move, ~13x the design's 4 ms estimate, projecting 47.9 CPU-h against the 6.76 ceiling; no tau was computed and the 1,200-root seed-free pool is retained. Rung 2 executed within envelope and the guardrail KILLED the proxy: on 6 CRN-matched C0 roots (exact replay verified), fast-d3s7 vs native D3 N7M6 within-root KM-lifetime orderings agree at mean tau 0.370 (LB95 0.283, min 0.053), top-1 4/6 - both kill conditions trigger, worst at late-game roots. Scientific consequence: the M=6 reveal quadrature genuinely changes within-root orderings, so an M=1 continuation corpus cannot carry D3 N7M6 label semantics; the fast-engine M=6 port (E-FAST-M6) is the required reopening route for any cheap-continuation label programme. Total ~7.5 CPU-h of the 35 cap; training lease still reserved and unopened.

Technical recordLimitations recorded with the resultRS-20260823T225753Z-0fbd48c3
  • Rung 2 is a 6-root guardrail: it detects gross misalignment (kill power ~0.89 at true agreement 0.5) and its kill here is decisive for the proxy, but the tau point estimates carry wide intervals.
  • Rung 1's powered comparison never ran, so D1/D2 fidelity to fast-d3s7 is unmeasured.
  • The 20-minute wall overage over the subagent's 2.5 h cap was spent in the single-threaded determinism gate and is disclosed.

Full record →

Agent contextSource files, operational notes and how to reproduce