Skip to main content

Official implementation of Maia-2, a unified human-like chess model across skill levels.

Project description

Maia-2: A Unified Model for Human-AI Alignment in Chess

CI PyPI Python License

[!IMPORTANT] Maia-3 is recommended for new projects. See its pre-trained models, paper, and website.

Maia-2 is a unified, skill-aware chess model for predicting human moves and outcomes across Elo levels. This repository is the official implementation of the NeurIPS 2024 paper Maia-2: A Unified Model for Human-AI Alignment in Chess, led by CSSLab at the University of Toronto.

Installation

Maia-2 supports Python 3.10–3.12 and runs on CUDA, Apple MPS, or CPU.

pip install maia2

For development or the validated dependency baseline, use a fresh Python 3.12 environment:

conda create -n maia2 python=3.12 -y
conda activate maia2
git clone https://github.com/CSSLab/maia2.git
cd maia2
python -m pip install -r maia2/requirements.txt
python -m pip install -e . --no-deps

Install contributor tools with:

python -m pip install -e ".[dev]"

The main branch may contain changes not yet published on PyPI. Use a source checkout when validating an exact commit.

Inference

Batch inference

Load a released Rapid or Blitz model and run it on the example dataset:

from maia2 import dataset, inference, model

maia2_model = model.from_pretrained(type="rapid", device="auto")
data = dataset.load_example_test_dataset()

data, accuracy = inference.inference_batch(
    data,
    maia2_model,
    verbose=1,
    batch_size=1024,
    num_workers=0,
)
print(accuracy)

"auto" selects CUDA first, then MPS, then CPU. Set device to "cuda", "mps", or "cpu" to choose explicitly. Adjust batch_size and num_workers for the available memory.

Position-wise inference

Prepare the move and Elo mappings once, then reuse them:

prepared = inference.prepare()
columns = ["board", "move", "active_elo", "opponent_elo"]

for fen, move, elo_self, elo_oppo in data.loc[:, columns].head(10).itertuples(
    index=False, name=None
):
    move_probs, white_expected_score = inference.inference_each(
        maia2_model,
        prepared,
        fen,
        elo_self,
        elo_oppo,
    )
    predicted_move = max(move_probs, key=move_probs.get)
    print(
        f"Move: {move}; predicted: {predicted_move}; "
        f"White expected score: {white_expected_score}"
    )

The second return value is a White-perspective expected score, not a calibrated win probability or the active player's score. Values 0, 0.5, and 1 represent a White loss, draw, and win.

Training

Data

Maia-2 trains on monthly .pgn.zst archives from the Lichess standard-rated database. A game's PGN Event must contain the exact, case-sensitive Rated marker and the selected Rapid or Blitz marker. Arena, tournament, and casual Event names without Rated are excluded. Games involving a player titled BOT or missing per-move clock annotations are also excluded.

Download one month for a local test:

./maia2/fetch_data.sh /path/to/lichess_data 2023-01 2023-01

Download the released training range:

./maia2/fetch_data.sh /path/to/lichess_data 2018-05 2023-11

December 2019 is skipped to match the original training pipeline.

Configurations

Choose one of the maintained presets:

The presets use separate checkpoint roots. Keep Rapid and Blitz outputs separate when overriding save_root. Older configurations without game_type default to Rapid.

maia2-training.yaml is the preserved legacy configuration matching the released checkpoint architecture. Use an explicit Rapid or Blitz preset for new training runs.

Run training from a Python script:

from importlib.resources import as_file, files

from maia2 import train, utils


def main():
    game_type = "rapid"  # Use "blitz" for rated Blitz training.
    config_resource = files("maia2.configs").joinpath(
        f"maia2-training-{game_type}.yaml"
    )
    with as_file(config_resource) as config_path:
        cfg = utils.parse_args(config_path)

    cfg.data_root = "/path/to/lichess_data"
    cfg.save_root = f"/path/to/checkpoints/{game_type}"
    train.run(cfg, device="auto")


if __name__ == "__main__":
    main()

Keep the __main__ guard: training uses spawned preprocessing workers. Checkpoints are written below <save_root>/<lr>_<batch_size>_<weight_decay>/.

The default configuration covers May 2018 through November 2023, trains for three epochs, and uses a batch size of 8192. Reduce the date range, batch_size, num_workers, and chunk_size for a short or laptop run. Unindexed "cuda" uses all visible CUDA devices through DataParallel; "cuda:N" selects one device.

The packaged configuration matches the released architecture and training settings, but does not guarantee bit-for-bit weight reproduction. Data filtering, dependency versions, hardware, and parallel execution can affect the result.

Resume and reproducibility

train.run starts a new model unless checkpoint restoration is enabled; a model returned by model.from_pretrained is not used automatically. To resume, set from_checkpoint, checkpoint_epoch, checkpoint_year, and checkpoint_month, while keeping the original full date range in the configuration.

Maia-2 records data provenance and rejects incompatible checkpoints. Use a separate save_root for different configurations. Legacy checkpoints without training metadata can only be resumed with Rapid configurations.

Interpretability

The Maia-2 skill-adaptation repository contains tools for extracting intermediate activations and training Elo-conditioned probes over 172 chess concepts. It extends the paper's concept analysis rather than exactly reproducing every result in Figure 4.

Citation

@inproceedings{
tang2024maia,
title={Maia-2: A Unified Model for Human-{AI} Alignment in Chess},
author={Zhenwei Tang and Difan Jiao and Reid McIlroy-Young and Jon Kleinberg and Siddhartha Sen and Ashton Anderson},
booktitle={The Thirty-eighth Annual Conference on Neural Information Processing Systems},
year={2024},
url={https://openreview.net/forum?id=XWlkhRn14K}
}
@inproceedings{monroe2026chessformer,
title={Chessformer: A Unified Architecture for Chess Modeling},
author={Daniel Monroe and George Eilender and Philip Chalmers and Zhenwei Tang and Ashton Anderson},
booktitle={The Fourteenth International Conference on Learning Representations},
year={2026},
url={https://openreview.net/forum?id=2ltBRzEHyd}
}

Please cite the relevant paper(s) and consider starring both Maia-2 and Maia-3.

Contributing and contact

Contributions are welcome; see CONTRIBUTING.md. For questions, email josephtang@cs.toronto.edu or open a GitHub issue.

Report security vulnerabilities privately as described in SECURITY.md, not in a public issue.

License

Maia-2 is released under the MIT License.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

maia2-0.11.0.tar.gz (55.4 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

maia2-0.11.0-py3-none-any.whl (38.7 kB view details)

Uploaded Python 3

File details

Details for the file maia2-0.11.0.tar.gz.

File metadata

  • Download URL: maia2-0.11.0.tar.gz
  • Upload date:
  • Size: 55.4 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for maia2-0.11.0.tar.gz
Algorithm Hash digest
SHA256 d7c02445fb5d24e9beb6a19aaf3a5beb96192847424faa1cb120a9471385072f
MD5 de19f46c0095bf78aa6e1817c3edc1da
BLAKE2b-256 87b303a6fc05eef1a01f3572e40ba8fbdd2e96dfb3976325f5b9215ffdf7792e

See more details on using hashes here.

File details

Details for the file maia2-0.11.0-py3-none-any.whl.

File metadata

  • Download URL: maia2-0.11.0-py3-none-any.whl
  • Upload date:
  • Size: 38.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for maia2-0.11.0-py3-none-any.whl
Algorithm Hash digest
SHA256 939e69587026be62cd003b8cd1e6e2e66f1120390f68b9d363ce3da099c85029
MD5 ce90990e9ecf49721f48e9b4d8c5aed5
BLAKE2b-256 9c216ff621782cde9a98878d87e2a989a875f5a93f5abf207ccb8fc5acde3224

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page