ChessNano
A compact autoregressive transformer that reads chess moves in Standard Algebraic Notation and predicts the next one. No board representation and no evaluation function — the model sees notation and nothing else.
Code: github.com/Kcbir/chessnano
Files
| File | Size | Description |
|---|---|---|
chessnano_deployed.pt |
58.4 MB | Quantised artifact — INT8 weights, bit-packed sign bits, fp16 embedding |
chessnano_fp16.pt |
102 MB | fp16 checkpoint |
vocab.json |
76 KB | SAN token vocabulary |
Architecture
| Layers | 8 |
| Model dim | 768 |
| Attention | grouped-query, 12 query heads / 4 KV heads, head dim 64 |
| Positions | RoPE |
| Feedforward | SwiGLU, 2048 hidden |
| Normalisation | RMSNorm, pre-norm, no bias |
| Vocabulary | 2048 SAN tokens |
| Context | 512 tokens |
| Parameters | 51.9M |
Quantization
Weights are trained with quantization simulated in the forward pass. The TurboQuant path applies a Hadamard rotation, quantises each coordinate pair's angle to 128 levels, and stores a one-bit Johnson–Lindenstrauss residual sketch scaled by the least-squares coefficient. Training and export share one reconstruction function, so the simulated quantizer matches the exported one.
Usage
import chess
from inference.tot_inference import ChessNanoPlayer, TotConfig
player = ChessNanoPlayer("chessnano_deployed.pt", tot_cfg=TotConfig(depth=1))
board, history = chess.Board(), []
for san in ["e4", "e5", "Nf3"]:
board.push_san(san)
history.append(san)
print(player.predict_move(history, board))
Candidate moves are masked against python-chess's legal move list before
sampling, so the decoder cannot emit an illegal move.
Licence
MIT