The name of the Engine is 真零 (TrueZero), which is Chinese for "True Zero" and romanised using Jyutping for Cantonese (Zan1 Ling4).
Instead of using hand-crafted evaluations (HCE), this AI learns how to play through playing against itself, starting with zero prior knowledge except for the rules of chess.
The chess engine will then play games against itself using the evaluation to evaluate chess positions, done using Monte Carlo Tree Search (MCTS).
This project is still very much work-in-progress.
Firstly, download this repository onto your computer.
git clone https://github.com/andreaslam/ZanLing-TrueZero
Make sure you have Rust installed. If not, follow the instructions here.
Make sure you have Python installed. If not, download the latest version here.
Configure tch-rs from the instructions here. For now, the neural net for this project is not provided but the NN architecture is available here for reference.
Navigate to the Rust crate (which lives in src/rust):
cd ZanLing-TrueZero/src/rust
Then, build using cargo:
cargo build --release
Then choose a binary to run!
Project layout: Rust binaries live in
src/rust/src/bin/and are auto-discovered by Cargo. Data folders (nets/,games/,hidden/,python_client_games/,experiment_nets/,frames/) live at the project root (ZanLing-TrueZero/) and are resolved automatically — both the Rust code (tzrust::data_path()) and the Python code (src/python/paths.py) anchor paths to the project root, so you can run everything from any working directory.
Alternately, you can use Docker to set up this project for training. This assumes that you are using Linux Ubuntu to train since the base Docker Image uses Ubuntu.
Firstly, run
docker pull andreaslam/tz
You may need to change your directory and locate this project.
cd ..
cd app
Set the following environment variables to configure tch-rs before running anything. This assumes you use PyTorch version 2.1 to use and set up. Use a virtual environment if neeeded.
export LIBTORCH_USE_PYTORCH=1
PYTORCH_PATH=$(python3 -c "import torch; print(torch.__path__[0])")
export LD_LIBRARY_PATH="$PYTORCH_PATH/lib:$LD_LIBRARY_PATH"
On Windows, it's
$env:LIBTORCH_USE_PYTORCH=1
$PYTORCH_PATH = python -c "import torch; print(torch.__path__[0])"
$env:PATH = "$PYTORCH_PATH\lib;$env:PATH"
$env:LIBTORCH_BYPASS_VERSION_CHECK=1
Before data generation, ensure that the loaded copy of the Repository is up-to-date.
git pull
To run data generation, simply run the python training client client.py, the main binary and the server binary as follows. Open a new terminal window for each.
Python side (from src/python):
cd src/python
python client.py
Rust side (from src/rust):
cd src/rust
cargo run --bin main --release
cd src/rust
cargo run --bin server --release
All data (nets/, games/, hidden/, python_client_games/, log.npz) is read from and written to the project root automatically, regardless of where you launch each process.
To use TrueZero through UCI, run the following from src/rust:
cd src/rust
cargo run --bin ucimain --release
The engine loads its network from nets/ at the project root. The compiled binaries (in src/rust/target/release/) can also be launched directly from any directory.
getdecode.rs- used for obtaining the encoded NN inputs.getmove.rs- used for obtaining a single tree search.getgame.rs- used for obtaining a game.getinferencetime.rs- used for benchmarking inference times and batching effectiveness through calculating the nodes/s.
uci.rs- contains code for UCI implementation. Code modified from JW's monty engineucimain.rs- used for running games using UCI.
boardmanager.rs- a wrapper for the cozy-chess library. Manages and handles draw conditions, such as fifty-move repetition, threefold repetition and must-draw scenarios.cache.rs- contains abstractions for the cache key.dataformat.rs- contains necessary abstractions forfileformat.rs.decoder.rs- used to decode and encode inputs for the Engine. Also handles the creation of child nodes. This is where NN inference happens.dirichlet.rs- Dirichlet noise generator.elo.rs- contains code for elo calculation used inenginetest.rs.fileformat.rs- contains the code for saving data files for training the Engine.mcts_trainer.rs- used for MCTS tree search. Initialises the NN and manages the entire tree search. Adds Dirichlet noise to search results.mcts.rs- abstraction for non-trainer MCTS search. Supports UCI search options, such asgo infinite.mvs.rs- a large array that contains all possible moves in chess. Used for indexing and storing (legal) move order. Statically loads and stored during programme execution.message_types.rs- contains the message protocols for processes (such as the Generator and the training loop) to communicate with the server and vice vera.selfplay.rs- facilitates selfplay. This is where search is initialised. Contains temperature management.
main.rs- runs multi-threaded data generation code, where each thread runs an independent game. It needs to be connected toserver.rsvia TCP in order to get the latest Neural Net. It also sends key statistics for live telemetry.server.rs- a TCP server that co-ordinates Rust data generation and Python training. It sends each connected instance a unique identifier, broadcasts key information to different processes, which include statistics, Neural Network information and training settings.
client.py- runs training and manages neural network training. Connects toserver.rsvia TCP to receive file paths for neural network training.
exec_plotter.py- debugging code that shows the thread schedule. Useful for debugging async tasks (such as data generation code for the Engine)experiment.py- code that can convert data generated fromclient.pyinto TensorBoard-readable format. This is an alternative experiment visualiser. Additionally, the code supports remote visualisation if SSH port forwarding is enabled on your device.gui.py- GUI code forscheduler.py. Code is currently work in progress. Running this file directly launches a demo version without server backend.onnx_exporter.py- contains code to convert.ptmodel weights to.onnxscheduler.py- code for TrueScheduler, an experiment scheduler for scheduling experiments and monitoring server controls. This GUI also supports remote SSH logins to schedule experiments on external devices.visualiser.py- visualises training data and monitoring key performance indicators logged inclient.py, where code fromlib/plotter.py. For more details on thelibfolder see here.visualisenet.py- code that allows visualisation of neural network activations. Generates a.giffile for an animation of a policy-only game.
This Python and Rust Engine uses the following:
- Matplotlib - used for plotting and creating animations and visualisations in
visualisenet.py. - NumPy - used for processing data (chess board representation after one-hot encoding, handling final outcome and final game result)
- PyTorch - used for creating and training the Neural Network. Also used for visualising experiments through its TensorBoard API.
- cozy-chess - chess move generation library. There is a simple wrapper of this library that TrueZero uses that covers draws, repetitions and serves as an interface between cozy-chess and the rest of the code.
- flume - multi-sender, multi-producer channels used to send data between channels for data generation.
- tch-rs - Rust wrapper of libtorch. Used for Neural Network inference.
- crossbeam - enables multithreading data generation.
- serde - serialises messages to send across TCP server and serialises finished data files to binary.
I would like to extend my heartfelt thanks to Karel Peeters for his persistent help and guidance. Without him this project would not been possible.
Portions/entire files of code from KZero are being used in this Repository with express permission from Karel, which include:
src/dirichlet.rssrc/fileformat.rssrc/dataformat.rs- the
libfolder used for reading KZero's custom data format and training
