From Lichess Games to Self-Play
Millions of indexed positions, action-space correctness, sparse replay, and arena promotion.
The cold-start problem
A random network has no useful policy and no useful position evaluation. Its early searches are nearly blind, so a small system can spend enormous compute producing games that teach almost nothing. I therefore bootstrap from real games before turning the model loose on self-play.
Building the initial dataset
The Lichess ingestion pipeline has produced more than four million encoded positions from roughly fifty thousand games. Large tensors are stored in HDF5 shards while SQLite provides searchable game metadata and offsets.
The action-index bug
The policy tensor had the correct number of elements and the encoder produced values in range, but the tensor was flattened in a different dimension order from the action encoder. Nothing crashed. The relationship between moves and logits was simply scrambled.
The fix is an end-to-end contract test: encode a known legal move, set only its policy location, flatten it, recover the selected index, decode it, and verify the original move across sliders, knights, castling, and promotions.
Bootstrap model
The current policy-and-value network uses 12 layers. Human moves provide initial policy targets and game results provide value targets. This is not intended to imitate humans forever; it gives early tree searches something better than random noise.
Self-play and promotion
The full loop now includes batched PUCT, subtree reuse, sparse replay storage, candidate training, and arena matches. A candidate does not replace the active champion merely because its training job completed. It must beat the champion under controlled conditions and alternating colors.
Immediate priority
Before scaling self-play, every representation boundary must be proven: board encoding, move indexing, legal masks, backup signs, side-to-move perspective, draw handling, serialization, and arena scoring. Search code is full of bugs that produce plausible-looking output. Correctness comes before game count.