Tell a chess model how to play.
CHSM8 is a 210M-parameter chess transformer that picks its moves from a free-text description of a playing style. It plays without search, and every move is legal by construction. Weights, datasets, labels and demos are open.
UCI_Elo 2000, no searchWhat it does
Chess models trained on human games now play well without search, but none of them lets you simply say how they should play. Rating-conditioned models control strength and player-specific models control identity; CHSM8 accepts an open-ended request. It is built for sparring and fun rather than grandmaster-level play, and it stays strong without search.
Text in, move out
A frozen EmbeddingGemma-300m encodes the prompt. Gated cross-attention in the top 6 of 12 decoder layers reads every token of it.
Legal by construction
Each move is a tuple (source, destination, piece, promotion) with one output head per field. The model scores only the legal moves of the position.
No search
One forward pass per move: the model plays its highest-scoring legal move. That is fast enough to run in a browser tab.
Try it
Play against CHSM8, give each side a style prompt, and see the probabilities behind every move.
In your browser
No install. The model runs in this tab on WebGPU, or on the CPU with WebAssembly, after a one-time download of about 480 MB (8-bit weights, fp32 compute).
On your GPU
Full-precision PyTorch on CUDA, Apple MPS or CPU. Clone the code, run python server.py and choose "My server".
The move tokenizer, live
Any notation in (SAN, LAN, UCI, numbered PGN with comments and variations, mixed within one game), the exact
model input out. Each move becomes a 15-bit id (6 bits from-square, 6 bits to-square, 3 bits promotion) and a model row
(kind, src, dst, piece, promo). This box runs the Rust tokenizer compiled to WebAssembly, the same code the demos use.
Use it
The models are project-specific PyTorch checkpoints on Hugging Face; the inference code is one file,
chsm8.py, in the code repository.
Score moves from Python
# needs a Rust toolchain for the tokenizer (https://rustup.rs) git clone https://github.com/nov3o/llm_chess-demo cd llm_chess-demo && pip install -r requirements.txt hf auth login # once: the prompt encoder is gated
from chsm8 import CHSM8 model = CHSM8.from_pretrained() # LegumMagister/chsm8 moves = model.score("1. e4 e5 2. Nf3", "castle queenside and storm the enemy king with your pawns") print(moves[:3]) # legal moves with log-probabilities, best first
An empty prompt gives the model's own play. Other weights:
CHSM8.from_pretrained("LegumMagister/chsm8-sft"), or filename="full_pass/model.pt" for the full-pass DPO model.
Accept the EmbeddingGemma-300m license on Hugging Face first.
Tokenizer and data
pip install "git+https://huggingface.co/LegumMagister/chsm8-tokenizer"
import chsm8_tok
chsm8_tok.tokenize("1. e4 e5 2. Nf3") # [1804, 2356, 1350]
chsm8_tok.convert("1. e4 e5 2. Nf3", dst="lan", type="text")
# 'e2-e4 e7-e5 Ng1-f3'
from datasets import load_dataset
games = load_dataset("LegumMagister/chsm8-pre-training",
split="train", streaming=True)
labels = load_dataset("LegumMagister/chsm8-post-training",
split="validation")
Games join their style labels on (month, row_idx), the stable game id of every CHSM8 dataset.
How it is built
Standard components at every stage: a Llama-style decoder, GPT-3 style schedules, Flamingo-style gated
cross-attention, distilled labels and DPO. Design choices at each stage were made by fixed-budget automated search loops
in the style of autoresearch. Elo is without a prompt, against Stockfish at UCI_Elo 2000. Select a stage.
Key results
Greedy legal moves against Stockfish 17.1 limited to UCI_Elo 2000, colors alternating.
The Elo scale is a reproducible engine calibration, not a FIDE or Lichess rating. Style results use 2,000 games per prompt
(95% precision about ±1 to 2 points for shares and ±21 Elo).
Prompts change play, and DPO sharpens it
The targeted behavior of the model's own side with no prompt, with the matching prompt, and under the three other main prompts (6,000 games).
Main comparison
| model | queens traded by ply 40 | pawn moves per move | queenside castling | Elo, no prompt |
|---|---|---|---|---|
| chsm8-sft | 53.0% | .290 | 97.3% | 1792 |
| chsm8 | 66.5% | .319 | 99.7% | 1797 |
| chsm8, full pass | 58.7% | .317 | 99.6% | 1812 |
Each metric is measured under its own prompt; queenside castling is the share of castling. The main model is a 20-minute DPO run on 1 GPU; a full pass over the data did not improve on it. Strength without a prompt is unchanged.
The cost of following risky prompts
Told to attack at all costs and sacrifice material, chsm8 does, and without search it loses about 150 Elo against an accurate engine (SFT: about 40). Training games labeled as sacrificial were not lost more often.
Strong without search
chsm8-pt against other public models trained without preference tuning, rewards or search: 200 games each, from 100 openings with colors swapped. Elo advantage with 95% CI. It wins every match, including against a 2.8B model.
Strength during pretraining
200 games per checkpoint (±50 Elo); final model 999 games, 1837 Elo (95% CI 1817 to 1856). The pass was restarted at 60% with the remaining data reshuffled, after a loss bump tied to the 2021-09 to 2022-05 Lichess months.
Against strong public models, 1,000 games per match
Score of each CHSM8 model (wins plus half the draws), both sides playing their most likely legal move from book openings with both colors. Every opponent was also rated against Stockfish under the same protocol, where chsm8-pt rates 1837, chsm8-player-base 1890 and the Carlsen fine-tune 1903.
| opponent | its Elo | chsm8-pt | player-base | player-carlsen |
|---|---|---|---|---|
| public models trained by supervised prediction | ||||
| Maia-2 blitz | 1657 | 65.3% | 71.8% | 71.7% |
| ChessLFM | 1687 | 91.5% | 93.3% | 92.8% |
| Kempner ChessFormer 50M | 1733 | 86.5% | 90.0% | 93.9% |
| chess-gpt2-uci | 1784 | 82.2% | 88.8% | 91.0% |
| Chess-GPT (Karvonen) | 1873 | 75.1% | 83.3% | 81.1% |
| ChessGPT-base 2.8B | 1731 | 88.0% | 93.7% | 94.3% |
| strong recent models, no search | ||||
| Otter 15M | 2021 | 49.1% | 56.1% | 61.1% |
| Allie 2.0 | 2232 | 13.5% | 21.2% | 19.8% |
| Maia-3 79M | 2271 | 14.0% | 15.7% | 21.3% |
| Searchless 9M | 2403 | 14.9% | 13.0% | 16.7% |
| Searchless 136M | 2584 | 10.2% | 10.3% | 6.3% |
| with search | ||||
| Matilda (Maia-3 + Stockfish) | 3009 | 1.9% | 4.1% | 1.6% |
CHSM8 wins every match against the older public models, is about even with Otter, and loses clearly to Allie 2.0, Maia-3 and DeepMind's searchless transformers, which are trained on far more data or on engine evaluations. None of the opponents takes a text prompt.
Player prompts
On about 1,000 held-out games for each of the 20 top players with the most data, "play like {player}" with the right name makes the player's real moves more likely than the same wording with another top player's name, for all 20 players.
| chsm8, paired on 20,508 games | another name | right name |
|---|---|---|
| probability of the player's move | 47.1% | 48.7% |
| top-1 move match | 53.7% | 55.5% |
| top-3 move match | 77.4% | 78.8% |
Across all 99 players, the right name wins in cross-entropy for 94 (SFT) and 96 (DPO). The effect is modest because top players differ little in their moves.
Labels that agree with the board
Gemma-4-31B described 3.02M game sides from their moves plus a card of features measured on the board. A Gemma-3-1B student, distilled from the 2.4M teacher sets that contradict nothing on the board, labeled the rest.
| labeler | labels contradicting the board | sides per second, 4-GPU node |
|---|---|---|
| Gemma-4-31B teacher | 4.7% | 7.5 |
| Gemma-3-1B student | 0.5% | 520 |
The student carries as much signal about the game as its teacher. A second teacher, Apertus-70B, wrote vivid labels that carried 4 to 5 times less signal, so it was dropped.
Models and datasets
Everything is public on Hugging Face. You are welcome to reproduce the results, build on the models and use the data and labels in your own work. The training code and search logs will follow.
| model | what | Elo, no prompt | license |
|---|---|---|---|
| chsm8 | final style model (DPO; called chsm8-dpo in the report), full-pass variant, browser ONNX export | 1797 | MIT |
| chsm8-sft | style-conditioned SFT model, evaluation prompts | 1792 | MIT |
| chsm8-pt | pretrained model, no text input | 1837 | MIT |
| chsm8-player-base | games-only continuation, no cross-attention; recommended base for new work | 1890 | MIT |
| chsm8-player-* | 14 player models: the FIDE top 10, plus Fischer, Kasparov, Karpov and Polgar | 1850 to 1910 | MIT |
| chsm8-labeler-gemma3-1b | style labeler distilled from Gemma-4-31B | Gemma | |
| chsm8-tokenizer | Rust move tokenizer and notation converter, Python and WebAssembly | MIT |
| dataset | what | size | license |
|---|---|---|---|
| chsm8-pre-training | filtered Lichess games, 2013-01 to 2026-06, with conversion scripts | 1.07B games | CC0 |
| chsm8-post-training | game sides with five style descriptions, the SFT and DPO splits | 30.1M sides | Apache-2.0 |
| chsm8-labeler-distill | the clean Gemma-4-31B label sets the labeler was distilled from | 2.40M sets | Apache-2.0 |
| chsm8-teacher-labels | every teacher label (Gemma-4-31B, Apertus-v1.5-70B), raw and repaired | 7.77M sets | Apache-2.0 |
| chsm8-top-players | games of the 14 modeled players with their held-out splits, crawler and prompt templates | 119,618 games | see card |
Code: github.com/nov3o/llm_chess-demo (inference, ONNX export, both demos; MIT). The prompt encoder, EmbeddingGemma-300m, is downloaded at run time under the Gemma Terms of Use.
Limitations
- No search. The model can miss tactics an engine would see, and risky prompts cost strength against an accurate opponent.
- An alignment tax. Style SFT costs about 45 Elo without a prompt (1792 against 1837), because the decoder learns to fit the description as well as the move.
- No weak-play conditioning. Every described player is rated 2200 or higher, so asking for weaker or stronger play does not change strength.
- Modest player effect. Player prompts work for 94 of 99 players, but move match rises by only about one point.
- Proxy metrics. Style adherence is measured on a handful of prompts with hand-written metrics, not a validated judgment of style.
- English prompts only; standard chess only.
Cite
@techreport{badanin2026chsm8,
title = {CHSM8: A Chess Transformer that Follows Natural-Language Style Prompts},
author = {Badanin, Ilia},
year = {2026},
month = oct,
url = {https://llmchess-demo-web.vercel.app}
}