nnue-pytorch: training Stockfish's NNUE evaluation with PyTorch
Stockfish NNUE (Chess evaluation) trainer in Pytorch
At a glance
- What is it?
- This is the official trainer for Stockfish's NNUE networks, built around a Docker-first workflow and a C++ extension. It is a tool for people who already have training data and a GPU, not a general-purpose chess engine.
- Who is it for?
- Adopt nnue-pytorch if you already have a GPU, a large data directory, and a reason to produce a Stockfish NNUE net; the Docker path via ./run_docker.sh is the documented route, and the Apple Silicon path through conda plus ./setup_script.sh is the documented alternative. Do not adopt it if you want a packaged library to embed in another engine, or if you are unwilling to build a 30-60GB container.
- Can I use it commercially?
- Yes, with conditions. GPL-3.0 is a copyleft licence: if you distribute software that includes it, you must release that software's source code under the same licence. Running it internally without distributing it does not trigger that obligation.
- Is it still maintained?
- Yes. The repository last received commits 51 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on September 15, 2026, and from our analysis. They are not legal advice.
DEEP OPEN-SOURCE ANALYSIS
The problem: producing a net Stockfish can actually load
NNUE evaluation is a small neural network that Stockfish consults instead of a hand-written evaluation function. The engine consumes the network in a specific binary format, and it has to be trained on positions labelled with game results. nnue-pytorch is the repository where that training happens. The README points at two wiki pages for the training procedure itself, one for train.py and one for easy_train.py, which tells you the project assumes you already understand the shape of the job. This is not a tutorial repository and it is not a library. It is the production toolchain the Stockfish project uses, published so that other people can produce nets that the engine can load. The audience is narrow: someone with a GPU, a large corpus of labelled positions, and a reason to care about evaluation quality in a chess engine.
How the pieces fit: trainer, checkpoints, and a matching loop
Training writes checkpoints. The README describes run_games.py as the piece that closes the loop: it finds every .ckpt file under a run directory, converts them to .nnue, and then plays games to rank them. Games are played with c-chess-cli and the resulting ratings are computed with ordo. The script runs in a loop and watches the directory for new checkpoints, so it can run alongside training on spare cores. That design is the most interesting thing in the repository. Instead of a single monolithic pipeline, you get a training process and a separate evaluation process that communicate through the filesystem. The cost is that you need three external binaries on hand (a Stockfish build, c-chess-cli, and ordo) plus an opening book file, all passed as command-line arguments. The benefit is that you can stop and restart either side independently, and a crashed matching run does not take your training down with it. The README credits Sopel for the sparse data loader, which is the component that keeps reading positions from being the bottleneck.
Getting it running: Docker first, conda for Apple Silicon
The documented primary path is ./run_docker.sh. It prompts for a GPU vendor (or CPU only) and for the path to your data directory, which gets mounted into the container. Once inside, training commands run directly. The script also supports non-interactive use if you supply the arguments through the CLI. The container ships CUDA 12.x or ROCm 6.4.3 plus dependencies, and the README states your local toolkit version does not matter. The warning that matters is the size: building the container takes time and roughly 30 to 60GB of disk. If you are on Apple Silicon, Docker gives you CPU only, because native MPS acceleration is not supported there. The README's alternative is conda or micromamba: create an environment with python=3.12, pytorch, torchvision, torchaudio, compilers, llvm-openmp, jpeg, libjpeg-turbo, cmake and make, then run pip install --no-cache-dir -r requirements.txt followed by ./setup_script.sh. The prerequisites section is explicit about drivers: an up-to-date ROCm driver for AMD, and an up-to-date NVIDIA driver plus the NVIDIA Container Toolkit for NVIDIA. For logging, the README gives tensorboard --logdir=logs and then http://localhost:6006/, with a note that the setup for easy_train.py still needs to move to the wiki.
Where this workflow will fight you
The README carries several TODO markers, and they are not cosmetic. Logging setup for easy_train.py is listed as unfinished, and the run_games.py section is also marked TODO: Move to wiki. That means the documentation you need for the automated matching loop is thin at the point where you would actually use it. The Docker image size is a real constraint, not a footnote. Building a 30-60GB container is a poor fit for a laptop with a small SSD, and the Apple Silicon situation is worse: the recommended acceleration path is not the container path, so you maintain two different setups depending on which machine you are on. There is also a hard dependency on external binaries that the repository does not ship. run_games.py needs a Stockfish executable, c-chess-cli, and ordo, and the README's example passes them as ./stockfish.master, ./c-chess-cli, and ./ordo. If you cannot build or obtain those, the automated evaluation loop is unavailable and you are back to judging checkpoints by hand. Finally, this is the wrong tool if you want to evaluate chess positions in your own application. It trains networks for Stockfish; it does not expose an inference API.
The alternative: training NNUE in TensorFlow
The README's thanks section links to DanielUranga/TensorFlowNNUE, which is the closest thing to a named alternative in the material. The difference in approach is the framework and, by extension, the dependency surface. nnue-pytorch is built on PyTorch and, in the Docker path, on a container that carries a specific CUDA or ROCm build plus a C++ compilation step that the README says Docker eliminates the need for. A TensorFlow-based trainer would put you in a different ecosystem for data loading, checkpointing, and GPU setup, with different container or environment requirements. The README does not compare the two, and I cannot say from this material which trains faster or produces stronger nets. What I can say is that the choice is not neutral: the surrounding tooling in this repository, particularly run_games.py and its assumptions about .ckpt files, is written for the PyTorch output format. Switching frameworks means giving up that matching loop or rewriting the conversion step yourself.
Licence and the cost of staying current
The repository is GPL-3.0. If you build a net with it and distribute that net alongside code, the licence terms are worth reading carefully rather than assuming; I am not in a position to give legal advice, and the README does not discuss licensing at all. On maintenance: there are no retrieved releases, so the project appears to move through commits on master rather than tagged versions. That matters for reproducibility. If you pin to a commit, you get a stable trainer but you also inherit whatever the container definition looked like at that point. If you track master, you get fixes but you also have to rebuild a very large container when the base image changes. The README's note that the container includes CUDA 12.x or ROCm 6.4.3 is the kind of detail that will drift, and it is the first thing to check when a rebuild fails.
Who this is for, and what to check before the first long run
This is for someone contributing nets to the Stockfish project or maintaining a fork that needs its own evaluation. It is not for someone who wants to add chess evaluation to an application, and it is not for someone without a GPU and a large data directory. Before starting a run that will take days, do three things. Confirm your driver stack matches the README's prerequisites for your vendor, because the AMD and NVIDIA paths differ and the Apple Silicon path is a third configuration entirely. Build the container once with ./run_docker.sh and check the disk cost before you commit to it. Then verify the evaluation loop works end to end on a small run directory: get a .ckpt, run run_games.py with your stockfish.master, c-chess-cli, ordo, and an opening book, and confirm it produces a ranking. If that loop does not work, you have no way to tell whether a training run is improving anything, and the README's own TODO notes mean you will be working that out from the script rather than from documentation.
Editorial conclusion
Adopt nnue-pytorch if you already have a GPU, a large data directory, and a reason to produce a Stockfish NNUE net; the Docker path via ./run_docker.sh is the documented route, and the Apple Silicon path through conda plus ./setup_script.sh is the documented alternative. Do not adopt it if you want a packaged library to embed in another engine, or if you are unwilling to build a 30-60GB container. Verify first that your driver stack matches the documented requirements (ROCm for AMD, NVIDIA Container Toolkit for NVIDIA), that your data directory is large enough to mount, and that you can run run_games.py against a stockfish.master binary, c-chess-cli, and ordo before committing to a long training run.
Community notes