lc0_dart 0.1.2 copy "lc0_dart: ^0.1.2" to clipboard
lc0_dart: ^0.1.2 copied to clipboard

LC0 (Leela Chess Zero) classical CNN inference in pure Dart with a PUCT / virtual-loss MCTS and a UCI shell. Loads a .pb.gz LC0 network (LINEAR16 / FLOAT16 / BFLOAT16), folds BatchNorm at load time, r [...]

lc0_dart #

LC0 (Leela Chess Zero) classical CNN inference in pure Dart, packaged as a UCI-compatible chess engine that plays legal chess against any GUI (Arena, Cute Chess, Lichess board editor, ...).

The heavy lifting (Conv2d, Lc0Reader, Lc0Net, Lc0Input) lives in the sibling dart_pytorch package; this project depends on it plus dartchess for move generation, and glues them together with the ported LC0 policy-index tables and a batched PUCT search (virtual loss) that reaches ~1300 rollouts/sec on an RTX 3060 at B=32.

Install #

# pubspec.yaml
dependencies:
  lc0_dart: ^0.1.0

The dart_pytorch dependency needs a native CUDA library (native/lib/libmat_mul.so — Linux/WSL2 today; build with nvcc --shared -Xcompiler -fPIC -o native/lib/libmat_mul.so lib/native/src/engine.cu from that package). Pass device: Device.CPU when constructing Lc0Net to skip GPU entirely.

Quick start #

# One-time model download
mkdir -p models/lc0 && cd models/lc0
curl -sSL -O \
  "https://storage.lczero.org/files/networks-contrib/744706.pb.gz"
cd ../..

# One-shot inference (WDL + top 20 raw policy slots)
dart pub get
dart run bin/lc0_demo.dart                                    # starting position
dart run bin/lc0_demo.dart 'rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq - 0 1'

# UCI engine: pipe commands manually or plug into a chess GUI
dart run bin/lc0_uci.dart --rollouts 400 --batch 32   # ~300 ms/move on GPU
uci
isready
position startpos moves e2e4 c7c5
go

Once running you can change search depth on the fly:

setoption name Rollouts value 100

Sample UCI transcript — Fool's Mate defence, Black to move after 1. f3 e5 2. g4:

info string [mcts 10] nodes=41 Q=0.167 time=9980ms  (4 n/s)
info string top: d8h4 n=8 Q=1.000 P=0.8%  |  g8e7 n=4 Q=0.080 P=37.9%  ...
bestmove d8h4

Even though the policy prior for Qh4 is only 0.8%, MCTS seeds every root child with one rollout, the resulting position is checkmate (Q=+1 for the mating side), and PUCT commits to it immediately. That's the whole reason MCTS matters: policy-only picked Ne7 here.

Scope #

  • In scope: classical CNN body (128×10 with SE), WDL value head, policy → 1858 legal-move ranking via the ported kConvPolicyMap + kMoveStrs tables, dartchess-backed move generation, batched PUCT search with virtual loss + root-child seeding for cheap mate-in-1 discovery, CPU / GPU tensor backends via dart_pytorch, UCI shell.
  • Out of scope: multi-thread search, Dirichlet noise, tablebases, ponder, tuned time management, attention-body networks (BT2, BT3, T78+), Mish activation, Smolgen.

At 400 rollouts / batch 32 on an RTX 3060 (~300 ms/move) this plays qualitatively stronger chess than raw policy: sees mate-in-1 instantly, avoids most tactical blunders, and follows opening theory correctly. It is still a tiny 128×10 network with a fixed-depth search — this is a demonstration, not a Stockfish substitute. Larger nets (e.g. t1-256x10, ~37 MB) drop straight into the same reader and forward path.

What we ported #

See REFERENCE.md for the file-by-file mapping between this Dart port and its LC0 C++ source (expected at /mnt/c/www/cpp/lc0 — clone with git clone --depth 1 https://github.com/LeelaChessZero/lc0.git).

1
likes
120
points
134
downloads

Documentation

API reference

Publisher

unverified uploader

Weekly Downloads

LC0 (Leela Chess Zero) classical CNN inference in pure Dart with a PUCT / virtual-loss MCTS and a UCI shell. Loads a .pb.gz LC0 network (LINEAR16 / FLOAT16 / BFLOAT16), folds BatchNorm at load time, runs an SE-aware residual tower on CPU or CUDA, and emits WDL + policy logits or a full search result.

Repository (GitHub)
View/report issues

Topics

#chess #leela-chess-zero #mcts #uci #inference

License

MIT (license)

Dependencies

dart_pytorch, dartchess

More

Packages that depend on lc0_dart