Repository navigation
Kestrel 2.0
Kestrel 2.0
The first Kestrel with one large neural network instead of two small ones plus a hand-written evaluation. In the matches below it scores above Kestrel 1.1 and 1.0 at every time control tested, at the price of an exe of about 88 MB, because the network is stored inside it.
The network is the one from 2.0 beta 1. The training run was stopped after about 70 of its 106 planned hours: of the snapshots saved every 3 hours, the 10th (after about 49 hours of training) and the 13th were the best on held-out positions (equal within 0.03 %), and the later ones were slightly worse (about 1 % higher loss; the training positions had been seen dozens of times, and the Lichess database has no more to offer). A 10-hour fine-tune of the end-of-run network on 1.5 million positions from fresh Kestrel games, with the learning rate lowered to zero, did not help either: against snapshot 10 it scored -6.7 +/- 11.2 Elo in 1,600 equal-node games, so snapshot 10 stays. The beta-1 and the 2.0 programs play the same moves; only the name the engine reports differs.
What is new compared with 1.1
- One network of 39 million parameters, stored inside the exe: 24,576 inputs per side (12 piece kinds x 64 squares x 32 horizontally mirrored king buckets), 1,536 integer accumulators per side, a pairwise-product activation, then 16 -> 32 -> 1 neurons with 8 output buckets chosen by the number of pieces. The hand-written evaluation and the second network of 1.x are gone: the evaluation is the network only.
- Trained on about 238 million positions of the Lichess evaluation database (Stockfish evaluations, CC0) plus 12 million positions from Kestrel's own games labelled by Stockfish, on the CPU with Adam. Stockfish is used only as a teacher; no Stockfish code is included.
- Fast evaluation code to pay for the size: the second layer skips the zero inputs (only about 10 % are non-zero), the first layer is updated only for positions that are really evaluated (about half of the positions the search makes never are), king moves use a refresh cache, weight rows are prefetched, and a
gocopies much less data. Together 1.95 times faster than the first version of 2.0, with exactly the same moves and scores (checked: same node counts, 186,000 accumulator checks against a from-scratch rebuild, Chess960 castling, multi-threaded search). In the depth-12 bench the AVX2 build does about 830,000 nodes per second on a performance core of the test laptop (Kestrel 1.1: about 1.2 million on a busy machine, so roughly 30 % fewer nodes per second). - New UCI options:
EvalFile(load another network file of the same format) andEvalScale(percent, 50 to 200, default 100: multiplies the network's output). Everything else is as in 1.1 (Chess960, WDL, analysis mode, MultiPV, bucketed hash table, up to 8 threads, optional book and experience file, no tablebases).
Strength
fastchess, 1 thread, 32 MB hash, no book, no experience file, 300 games per entry (600 for 5 + 0.1), the same openings for both sides. Elo is the 2.0 build against the older Kestrel; the value after +/- is fastchess's 95 % interval.
| Time per game (base+increment, seconds) | against Kestrel 1.1 | against Kestrel 1.0 |
|---|---|---|
| 1 + 0.01 | +15 +/- 32 | +28 +/- 33 |
| 2 + 0.02 | +13 +/- 28 | +51 +/- 31 |
| 3 + 0.03 | +64 +/- 29 | +31 +/- 28 |
| 5 + 0.1 | +38 +/- 20 (600 games) | +64 +/- 21 (600 games) |
| 10 + 0.1 | +51 +/- 30 (240 games) | not measured |
| 20 + 0.5 | +41 +/- 36 (160 games) | not measured |
Pooled over all time controls, 2.0 is about +37 +/- 11 Elo ahead of 1.1 (1,900 games) and about +48 +/- 13 ahead of 1.0 (1,500 games). Single entries at the shortest time controls (1 + 0.01 and 2 + 0.02 against 1.1, 1 + 0.01 against 1.0) are inside their error margins: at about 20 ms per move the large network is roughly level with 1.1. The 5 + 0.1 line was played with the packaged x86-64-v3 exe of this release; the others with the same program before it was renamed. These are matches on one laptop, and no rating list has tested Kestrel.
EvalScale was checked at 60, 80, 125 and 160 against the default 100 (600 games each at 5 + 0.1): -19 +/- 17, +1 +/- 16, +9 +/- 16 and -41 +/- 16 Elo. The curve is flat between 80 and 125, so the default stays 100.
Which file do I need?
| File | For |
|---|---|
Kestrel-2.0-windows-x86-64-v3.zip |
Windows 64-bit, AVX2 + BMI2 CPUs (recommended) |
Kestrel-2.0-windows-x86-64-v2.zip |
Windows 64-bit, SSE4.2 + POPCNT CPUs |
Kestrel-2.0-windows-x86-64.zip |
Windows 64-bit, any CPU |
Kestrel-2.0-linux-x86-64-v3.tar.gz |
Linux x86-64, AVX2 + BMI2 CPUs |
Kestrel-2.0-linux-x86-64-v2.tar.gz |
Linux x86-64, SSE4.2 + POPCNT CPUs |
Kestrel-2.0-linux-x86-64.tar.gz |
Linux x86-64, any CPU |
Kestrel-2.0-linux-arm64.tar.gz |
Linux ARM64 |
Kestrel-2.0-macos-x86-64.tar.gz |
macOS, Intel Macs |
Kestrel-2.0-macos-arm64.tar.gz |
macOS, Apple Silicon (M1 and newer) |
The three Windows builds are also attached as plain .exe files (same program as in the zips; a plain exe has no opening book: put claude_book.txt next to it, or turn OwnBook off). kestrel_net_2_0.bin is the network alone (needed only to build from source or to load with EvalFile).
Only the x86-64-v3 builds have the AVX2 evaluation code (CPU with AVX2 and BMI2: most PCs since 2015). The v2 and generic builds work on older CPUs but are about 37 % slower in the depth-12 bench (522,000 against 832,000 nodes per second).
Status of each build
- Windows: all three builds were run here; each gives the same depth-12 bench (934,326 nodes), so the plain code and the AVX2 code agree exactly. On the x86-64-v3 exe the two black-box audits of 1.1 were repeated: 83 of 83 protocol and robustness cases and 31 of 31 rule checks against python-chess pass. The longer test suite of 1.1 was re-run on the 2.0 source as well: a GCC build and a clang AddressSanitizer + UBSan build (each also with 4 threads by default) pass 27 of 27 checks (accumulator self-test over 186,000 positions, perft, perft against python-chess, evaluation mirror symmetry, PV legality, UCI fuzzers,
go infinite/stopraces, MultiPV and ponder checks, bench), and a fuzz campaign (about 8,900 random UCI command sequences on four builds, 550 random FEN positions, perft against python-chess on 450 positions to depth 4 and 4,500 to depth 3) found no problem. The logs are inlogs/of the repository. - Linux and macOS: compiled with Zig and the file format checked, but not run (no such machine was available). Please open an issue if one does not start.
- The exe is about 88 MB and is not code-signed; some virus scanners are suspicious of big unsigned programs (1.0 had a false positive, see
docs/BUILDING.md).
Building from source
src/kestrel_2_0.cpp embeds the network with .incbin "kestrel_net.bin", which the assembler looks up in the current directory: download kestrel_net_2_0.bin from this release, save it as kestrel_net.bin in the folder where you run the compiler, then for example
g++ -std=c++17 -O3 -march=x86-64-v3 -static -pthread -DNDEBUG -o kestrel.exe path/to/src/kestrel_2_0.cpp
The network is not stored in the git history (76 MB per version); see docs/BUILDING.md for the other targets.