Kibitzer is a 15.2M-parameter, attention-first chess policy/value model trained end to end on a single laptop RTX 4060 (8 GB). Wrapped in 512-simulation PUCT search it reaches an official 2581.6 ± 102.3 Elo on a Stockfish-anchored tournament. This checkpoint, tactical_repair.pt, is the strongest trained branch in the project.
A kibitzer (Yiddish, from the German kiebitzen, "to look on at a card or chess game") is the onlooker who leans over your shoulder and tells you the best move. That is exactly what this model does: it never owns a game of its own, it reads a single position and gives its opinion.
Kibitzer is a research artifact: a study of how far a small model can be pushed at chess on consumer hardware. Use it to analyze a position and get a move (as an engine wrapped in PUCT search), to reproduce the evaluations, or as a base for further chess policy/value research. It is not a drop-in UCI engine binary, though a UCI wrapper is provided in the repo (scripts/uci_engine.py).
Architecture
Kibitzer hybrid chess architecture
A position is fed as structured chess state, not pixels or a move list: each of the 64 squares becomes one of 13 piece tokens, alongside a 7-dim auxiliary vector (side-to-move, four castling rights, en passant, halfmove clock). The model can also consume up to 128 plies of history.
The board first passes through a 3-layer position encoder built on Shaw-style relative attention: every pair of squares attends through its file and rank offset, bucketed into 15x15 = 225 learned relative vectors folded into the attention bias, which makes the geometry translation-invariant (a knight-move relationship means the same thing anywhere on the board). The 64 encoded squares are mean-pooled into one dense vector per position.
Those vectors flow into a 10-layer temporal trunk over the ply history that interleaves two block types: every third block is causal self-attention (global reasoning), the rest are selective state-space blocks (SSM, Mamba-style: causal scan, input-dependent gates, depthwise convolution, cheap linear-time state). Attention is powerful but quadratic, SSM is cheap and linear, so the trunk pays full-attention cost only where it earns its keep. An RMSNorm then feeds two heads: an AlphaZero-style policy over the fixed 4,672-move action space and a tanh-bounded value head. RMSNorm and SwiGLU are used throughout.
Evaluation
Official tournament Elo, Ordo-rated over 171 clean games against a Stockfish UCI_Elo ladder, both colors, model wrapped in 512-sim PUCT, anchored SF-2500 = 2500:
player
rating
error
games
score %
SF-3100
2979.1
207.1
32
91
SF-2900
2857.7
164.3
35
83
SF-2700
2660.8
138.5
36
61
Kibitzer @ 512 sims
2581.6
102.3
171
42
SF-2500 (anchor)
2500.0
----
35
39
SF-2200
2318.0
158.8
33
18
It crushes SF-2200 and SF-2500, loses to SF-2700 and above, with the 50% crossover near SF-2600. This is the strength of the model with search: deep PUCT does real work that does not distill back into the raw weights.
Elo ladder
Search is the single largest inference-time lever. On the same checkpoint versus a fixed Leela/Maia-2700 proxy, only changing simulation count:
Search simulation sweep
sims
score vs 2700 proxy
64
0.087
128
0.287
256
0.325
512
0.825
How to use
Kibitzer is a custom architecture, so you need the kibitzer package from the GitHub repo, not transformers.
The 2581 Elo is a with-search, compute-asymmetric match statistic, not an intrinsic raw-weights rating. The Stockfish UCI_Elo ladder is an internal relative scale, not FIDE. The ±102 interval is wide (171 games across five opponents).
The value head is the weak link: 33k parameters bolted onto a 15M trunk, correct in sign but noisy and late. Enlarging it improved offline metrics and hurt play.
Strength plateaus around 2500-2600. Nine separate post-training directions (self-play, expert iteration, on-policy distillation, TD-Leaf, GRPO/DPPO RL, preference optimization, process-reward repair) were tried to break past it. All nine held or lost strength against a fixed external opponent. The ceiling, it turns out, is remarkably committed to being a ceiling.
The only lever left with a positive slope is parameter and data scale, which is a deliberate not-now: the point of the project was the ceiling of a small model on a laptop.
This checkpoint: a competition/puzzle supervised tactical repair (tactical_supervised_repair_r1_policy_only) on top of policy_regret_repair.pt, promoted as the strongest branch that survived a paired external gate.
Full decision-by-decision history, including every failed experiment, is in the project LOGBOOK.md.
Citation
bibtex
1@software{kibitzer2026,
2 author = {Pradheep},
3 title = {Kibitzer: a 15M-parameter chess policy/value model trained on a laptop},
4 year = {2026},
5 url = {https://github.com/Mantissagithub/kibitzer}
6}