Everett Stenberg / Lab

02 / cloudChess / interactive experiment

Your move.

Play a neural network trained on human games, with Monte Carlo tree search to explore its next move.

Select a piece, then a highlighted destination. Coordinates appear on every square.

Human × neural network

Play the bootstrap.

Choose your side and start a game.

GPU inference on Modal. The first engine move may take a minute while the server wakes up. No account required.

No moves yet.

Original 12-block × 128-channel model · 10,000 training steps. This playable checkpoint predates the expanded dataset below. Search budget changes thinking time, not a measured Elo rating.

Data engineering / dataset snapshot · November 8, 2026

The dataset behind the next experiment.

The expanded corpus is converted and ready for training: human games from Lichess open database, filtered for stronger players and slower time controls. Each recorded position is an occurrence in a game; these are not 179.9 million unique boards.

2,331,246retained games
179,935,641position records
50parsed input files processed
01 / FilterBoth players ≥ 2,000 Elo. Base time ≥ 300 seconds; increment does not count. Missing filter metadata is excluded.
02 / RecordEvery pre-move FEN, played UCI move, game outcome, ply number, and game length. Repeated positions retained.
03 / ValidateReplay each game. Check every move is legal and its FEN matches before encoding board history and repetition.
04 / EncodeSharded HDF5: board tensors, action IDs, side-to-move values, game IDs, and ply numbers.

Inspect an actual game record.

Step through the opening of a retained game. Each frame is the position before the recorded move. The white player eventually won at ply 113.

Raw JSON tuple → training example

Tuple: [pre-move FEN, UCI move, white-perspective outcome, 1-based ply, game plies]. The outcome becomes +1 or −1 for the side to move. This pipeline preserves each played move as a target; it no longer aggregates move probabilities across repeated boards.

states   uint8  [N, 34, 8, 8]
actions  uint16 [N]  # square-major × 73
values   int8   [N]  # −1 / 0 / +1
game_ids uint64 [N]  # move-sequence hash
plies    uint16 [N]
Splits, duplication, and what these counts mean

A stable 64-bit hash of each game's move sequence assigns the game to a 98% / 1% / 1% train/validation/test split. Identical move sequences stay in the same split. Positions and duplicate occurrences are not deduplicated; common openings can occur across different games and splits. The terminal board after the final move is not an extra training record.

Converted source: three positions_5min_2000elo*.json files. Counts come from the completed bootstrap dataset manifest and the filtering checkpoint, not an estimate of web traffic or generated self-play.

Inside the playable model

One shared trunk. Two predictions.

A residual convolutional network produces a move prior and a position value. MCTS uses both to allocate its search. The original bootstrap has approximately 4.12 million parameters.

Board + history34 × 8 × 8 input planes
↓ 3 × 3 convolution · 34 → 128 channelsNormalization + ReLU
↓ 12 residual blocks · 128 channelsTwo 3 × 3 convolutions per block + skip connection
↓ Policy head1 × 1 convolution → 73 planes
8 × 8 × 73 = 4,672 action logits
Legal-move mask → move priors
↓ Value head1 × 1 convolution → 32 channels
2,048 → 256 → 1 · tanh
Position value in [−1, +1]
↓ Monte Carlo tree searchExplore candidate continuations → choose the most visited move
What is in the 34 input planes?

Twelve piece planes for the current board and twelve for the previous board; four castling-rights planes; en passant, halfmove clock, repetition, white-to-play, fullmove number, and a constant plane. These provide the history and rule state that a piece-only board misses.

Experimental record

Measure improvement. Don’t assume it.

The model you just played

The original bootstrap ran for 10,000 steps with batches of 2,048: 20.48 million training examples processed. Its earlier dataset contained 21,000,888 sampled positions from 1,750,074 games. Examples processed is not a count of unique examples seen.

That earlier extraction used a three-minute base-time threshold, an Elo-gap limit, and position sampling. The new five-minute corpus above is a separate, larger dataset. Its scale is not a claim that the served checkpoint has already learned from it.

Self-play is still an experiment

Early controls showed identity at 0.50, bootstrap-only near 0.49, and self-play-only near 0.30 against the baseline. That is a reason to audit targets, isolate policy and value training, and compare candidates in a controlled arena—not declare improvement from a lower loss.

The public demo serves the known bootstrap checkpoint. It does not modify the local champion, checkpoints, or distributed training state.