chess-transformer

Four GPT-style transformer checkpoints trained to predict chess moves from UCI-tokenized move sequences. These are the checkpoints behind a controlled study of why chess language models produce illegal moves, and what actually fixes it.

Full writeup, training code, and evaluation scripts: github.com/JOTELLECHEA/chess-transformer

Checkpoints

Names encode corpus size and architecture: 1.2m_L12E384H6 is 1.2M games, 12 layers, 384 embedding dimensions, 6 attention heads.

Checkpoint Architecture Params Final Val Loss Legal-move rate Fully-legal games
98k_L6E256H4 6L / 256E / 4H ~5M 2.2593 97.3% 4.4%
1.2m_L6E256H4 6L / 256E / 4H ~5M 2.1035 97.7% 11.4%
98k_L12E384H6 12L / 384E / 6H ~22M 2.7826 97.8% 9.8%
1.2m_L12E384H6 12L / 384E / 6H ~22M 1.7015 99.1% 51.8%

"Fully-legal games" is the share of generated games (n=500) in which every single move was legal. Scaling data alone takes it from 4.4% to 11.4%; scaling capacity alone reaches 9.8%. Doing both reaches 51.8% — roughly 12x baseline, and 4.5-5.3x what either intervention achieves on its own. Capacity and data unlock each other rather than contributing separable gains.

1.2m_L12E384H6 is the flagship. The other three exist for the comparison.

Loading

These are not transformers-compatible. The text-generation tag describes the mechanism (autoregressive next-token prediction), not API compatibility — AutoModel and pipeline() will not work. Loading requires the GPT, GPTConfig, and MoveTokenizer classes from the GitHub repo.

from huggingface_hub import hf_hub_download
from safetensors.torch import load_model

from src.config import GPTConfig
from src.model import GPT
from src.dataset import MoveTokenizer

REPO_ID = "Jotellechea/chess-transformer"
CHECKPOINT = "1.2m_L12E384H6"

weights_path = hf_hub_download(REPO_ID, f"{CHECKPOINT}/model.safetensors")
config_path  = hf_hub_download(REPO_ID, f"{CHECKPOINT}/config.json")
vocab_path   = hf_hub_download(REPO_ID, f"{CHECKPOINT}/vocab.json")

config = GPTConfig.load(config_path)
tokenizer = MoveTokenizer.from_vocab_file(vocab_path)
config.vocab_size = tokenizer.vocab_size

model = GPT(config)
load_model(model, weights_path)
model.eval()

Use load_model() rather than load_file() — the embedding and output-projection weights are tied, and load_model() reconstructs that tie on load.

Tokenization

Word-level, where one token is one complete UCI move (g1f3), not a sequence of characters. The vocabulary is closed-form: 1,968 theoretically possible UCI moves computed from the rules of chess, plus 5 special tokens (<|SOM|> and four result tokens), for 1,973 total. It is identical across all four checkpoints, so token IDs are directly comparable between them.

Unlike a BPE tokenizer, there is no fallback for unencodable input — text that is not a legal UCI move simply cannot be tokenized.

Because UCI encodes only from-square and to-square, the model is never told which piece is moving. It has to infer that from move history alone, which is what makes "does it track board state internally" a real question rather than something handed to it for free.

Training data

Lichess open database, released under CC0. Games were kept if at least one player was GM-titled, across all time controls except correspondence, then converted from SAN to UCI.

  • 98k corpus: 2023-01, ~98k games after filtering
  • 1.2m corpus: 2023-01 plus 2025-01 through 2026-05, ~1.2M games after filtering

Both architectures were trained for 5 epochs with block_size=192, which covers 99.7% of real games in the corpus.

Interpretability

Linear probes on the flagship checkpoint's internal activations show board state is linearly decodable, peaking at layer 9 of 12 at 84.6% of the gap to perfect (measured against a random-init baseline), then declining through the final two layers. The 6-layer model is still climbing at its last layer, with layer-over-layer improvement collapsed to +0.5 points.

This follows the methodology of Li et al. (OthelloGPT), Nanda et al., and Karvonen.

Limitations

  • Legal is not strong. Against Stockfish, the flagship wins ~3.8% of games at skill 0 and effectively never at higher skill levels. High legal-move rates say nothing about playing strength.
  • The data comparison is confounded by time period. The 98k corpus is from 2023-01 while the additional 1.2m data spans 2025-2026, so that arm varies population alongside scale. The capacity comparison holds corpus fixed and is unaffected.
  • Color is uncontrolled. All evaluation had the model playing White.

License

MIT. Training data is CC0 via the Lichess open database.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Papers for Jotellechea/chess-transformer