chess-gpt-uci-square (C)

A 50.6M-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 C 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 384 tokens, tied embeddings
  • Training data: 35M Lichess games (rapid and slower, all ratings), each seen once
  • Training: 76,110 steps on one NVIDIA GB10
  • Validation loss per move: 1.604

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.74% 99.77% 99.84%
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-uci-square --local-dir models/chess-gpt-uci-square
import chess
from chessgpt.eval.player import ModelPlayer

player = ModelPlayer("models/chess-gpt-uci-square", 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
220
Safetensors
Model size
50.6M params
Tensor type
F32
ยท
Inference Providers NEW
This model isn't deployed by any Inference Provider. ๐Ÿ™‹ Ask for provider support