chess-gpt-pgn-char (A)
A 50.9M-parameter GPT that plays chess by predicting the next move token. There is no search and no evaluation function: one forward pass per move. It is model A of three models trained the same way and differing only in their tokenizer:
| Model | Tokenizer | A token is | Vocab |
|---|---|---|---|
| A | pgn-char |
one character of 1.e4 e5 2.Nf3 |
34 |
| B | uci-move |
one move, g1f3 |
1971 |
| C | uci-square |
one square (+ promotion piece), g1 f3 |
71 |
Write-up: blog.wezn.dev/chess-gpt ยท Code: github.com/wezn/chess-gpt
This model
- Architecture: decoder-only transformer, 16 layers, 8 heads, width 512, context 1024 tokens, tied embeddings
- Training data: 35M Lichess games (rapid and slower, all ratings), each seen once
- Training: 206,934 steps on one NVIDIA GB10
- Validation loss per move: 1.564
Mean over the final 11 snapshots, from the write-up:
| A | B | C | |
|---|---|---|---|
| Elo (Lichess scale, estimated from self-play scored by Stockfish) | 1,940 | 1,908 | 1,792 |
| Legal moves on held-out human games | 99.75% | 99.45% | 99.71% |
| Average centipawn loss | 56 | 58 | 61 |
The Elo figures are estimates, not results from rated play. The write-up describes how they were measured.
Usage
git clone https://github.com/wezn/chess-gpt && cd chess-gpt && uv sync
uv run hf download ftaz/chess-gpt-pgn-char --local-dir models/chess-gpt-pgn-char
import chess
from chessgpt.eval.player import ModelPlayer
player = ModelPlayer("models/chess-gpt-pgn-char", device="cpu")
board = chess.Board()
for san in ["e4", "e5", "Nf3", "Nc6", "Bb5", "a6"]:
board.push_san(san)
print(player.choose_moves([board])[0].move) # the model's move
print([(board.san(m), round(p, 3)) for m, p in player.rank_legal_moves(board)[:3]])
config.json holds the architecture and tokenizer. model.safetensors holds the weights only.
- Downloads last month
- -