Let’s use compute / AlphaZero

AlphaZero in two runs

September 26, 2026

A Connect Four player that started from random weights and learned only by playing itself. The first run was killed by its timeout. The second picked up where it stopped.

At iteration 0 our network lost 58 of 64 games to classic Monte Carlo tree search, which picks each move by playing 1,000 random games to the end. Thirty-four training iterations later it won 60, drew 1 and lost 3. It never saw a human game or an opening book. We spent $4.01, a third of it on three runs that crashed before training started.

Score by training iteration. Against rollout MCTS it climbs from 8% at iteration 0 to 65% at iteration 10 and 95% at iteration 34. The raw policy without search reaches about 50 to 60% against the one-ply heuristic. Random and one-ply opponents are near 100% throughout.
64 games per point, alternating first move. A vertical line marks where the second run resumed.

The loop

AlphaZero is three pieces in a cycle:

  1. Search. Before each move, a tree search asks the network two questions about positions it explores: which moves look promising, and who is winning. It runs 64 of these simulations and counts how often it visited each move.
  2. Self-play. The network plays itself, 768 games per iteration, choosing moves from those visit counts. Every position is saved with the search’s visit counts and, once the game ends, who won.
  3. Training. The network learns to predict the search’s visit counts and the final result. A network that predicts better makes the next search stronger, which produces better training targets.

Our network is small: five residual blocks, 374,810 parameters. One iteration takes about 75 seconds on an H100. Self-play is 17 seconds, split over 12 worker processes that each batch their games’ positions through the GPU at once. Training is 4 seconds. The rest is measuring strength.

Watch it play

Recorded games against the 1,000-playout searcher, early and late. Orange is our network, yellow is the searcher.

AlphaZero networkRollout MCTS

Loading recorded games…

What the numbers say

Won–drawn–lost out of 64 games, from the network’s side.
OpponentIter 0Iter 10Iter 34
Random mover63–0–164–0–064–0–0
Win-or-block heuristic52–0–1261–1–264–0–0
Rollout MCTS, 1,000 playouts4–2–5840–3–2160–1–3
Untrained network, same search34–9–2156–2–662–2–0
No search at all, vs win-or-block1–0–6339–1–2434–1–29

We planned to measure progress against a random mover and a heuristic that takes a winning move when there is one and blocks the opponent’s when it must. Both turned out useless as yardsticks. Search does the heavy lifting against them: with 64 simulations, even the untrained network wins 81% against the heuristic. The rollout searcher is the opponent that shows learning.

The last row is the network alone, playing its top-rated move with no search. It learned enough to beat the heuristic about half the time, then stalled. The heuristic punishes every missed block, and the raw network still misses some. With search, the same network won every game against it from iteration 18 on.

Each point is 64 games, which carries roughly ±12 points of noise in the middle of the scale. The dip at iteration 12 is within that.

Surviving a timeout

Every Compute run has a kill limit. We set the first run’s to 15 minutes on purpose, because the question was whether a run that hits it loses its work.

It doesn’t. After every iteration the job overwrites a checkpoint in Compute’s artifact folder: the network, the optimizer, the last eight iterations of self-play games, and the scores so far. The run was killed partway through iteration 11. The artifact it left held iteration 10, complete, and downloaded fine afterwards.

Resuming was harder. Compute can’t hand one run’s artifact to the next as input. A job can fetch it itself by installing the Compute command-line tool and signing in with an API key stored as a secret. That puts a key to the whole account on a rented GPU, so we didn’t. Instead the first run also copied each checkpoint to Hugging Face. The second run downloaded it in under a second and carried on from iteration 11 with the same optimizer state and replay data. It stopped itself after 19 minutes, at iteration 34. We’ve asked Compute for a way to pass artifacts between runs.

Three crashes first

Self-play is slow Python tree search, so it runs in parallel worker processes. Getting those workers started on Compute took three tries and $1.36:

Now each worker is an ordinary python train.py --az-worker process connected to the parent over a local socket. If one dies, the parent prints why and exits.

Run it yourself

With Compute set up and train.py downloaded, a three-iteration check costs about $0.35:

compute run train.py::train --gpu runpod/H100-SXM --dry-run
compute run train.py::train --gpu runpod/H100-SXM \
  --timeout 300 --args '{"sample": true}' --wait

The reproduction guide covers the two-run training, both ways of resuming, and every setting. There are also instructions for an agent. We stopped at Connect Four: 9×9 Go needs roughly 25 times the search per game, and 19×19 is far beyond one GPU.

Code and history · Download the network