Searchless chess transformers, ONNX
ONNX conversions of the action-value transformers from Grandmaster-Level Chess Without Search (Ruoss et al., 2024) by Google DeepMind: google-deepmind/searchless_chess.
Licence and attribution. The model weights are © 2024 DeepMind Technologies Limited and licensed under CC BY 4.0. The original code is Apache-2.0. Changes made here: the JAX (Haiku) checkpoints were re-expressed as an equivalent PyTorch module and exported to ONNX (the attention einsums written as matrix products, the same computation); the 136M and 270M weights are stored in fp16 and cast to fp32 at load. No retraining, no change to the weights' values beyond fp16 rounding.
Used by CrispChess, which runs them on-device (native ONNX Runtime, ONNX Runtime Web, or a pure-Dart interpreter).
| File | Model | Size |
|---|---|---|
9M/model.onnx |
9M (8 layers, width 256) | 36 MB |
136M/model_fp16.onnx |
136M (8 layers, width 1024) | 273 MB |
270M/model_fp16.onnx |
270M (16 layers, width 1024) | 542 MB |
The paper reports a Lichess blitz Elo of about 2895 against humans for the 270M model; the smaller models are weaker (see the paper for their figures).
Graph
tokens int64 [b, 79] → log_probs float32 [b, 128].
Each row is one legal move of the position: the 77 FEN tokens of the original
tokenizer.py (the FEN as python-chess writes it: an en-passant square only when an
en-passant capture is legal), then the move's index in actions.json (1968 UCI moves,
the repository's utils.ACTION_TO_MOVE order), then a 0. The output is the
log-distribution over 128 uniform win-probability buckets (bucket_values.json); the
move's win probability is sum(exp(log_probs) * bucket_values). Play the legal move
with the highest win probability; the original engine also scores a move allowing a
threefold repetition as 0.5.
Verification
Against the original JAX engine on five positions (start, Italian, a mate in one, a back-rank mate, a legal en passant): same move chosen in 5/5 for every model; max log-probability difference 3e-5 (9M), 0.012 (136M, fp16), 0.008 (270M, fp16). Exported by export_searchless.py.