Previous Page

nothing@nowhere - 2021-06-04

Leela chess zero Setup

In this tutorial we're going to setup leela chess zero on a debian-based system.

Nibbler Frontend Setup

First let's install nibbler:


[ 10.10.14.13/23 ] [ /dev/pts/77 ] [~/Documents]
→ mkdir Chess

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [~/Documents]
→ cd Chess

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [~/Documents/Chess]
→ git clone https://github.com/rooklift/nibbler
Cloning into 'nibbler'...
remote: Enumerating objects: 12569, done.
remote: Counting objects: 100% (1168/1168), done.
remote: Compressing objects: 100% (295/295), done.
remote: Total 12569 (delta 874), reused 1162 (delta 873), pack-reused 11401
Receiving objects: 100% (12569/12569), 2.60 MiB | 1.40 MiB/s, done.
Resolving deltas: 100% (8986/8986), done.

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [~/Documents/Chess]
→ cd nibbler/src

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ sudo apt install npm -y
#or sudo pacman -S npm

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ sudo npm install -g electron

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ pwd
/home/nothing/Documents/Chess/nibbler/src

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ vim nibbler.sh

#!/bin/bash
electron /home/nothing/Documents/Chess/nibbler/src/

:wq

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ chmod +x nibbler.sh

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ ./nibbler.sh


Here you can see that you can run nibbler with that bashscript, so let's add it to our PATH:


[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ sudo ln -s $(pwd)/nibbler.sh /usr/local/bin/nibbler

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Chess/nibbler/src]
→ nibbler

And there you go ! We can now run nibbler easily from our PATH variable.

Leela Chess Zero backend setup



I am currently on a debian-based system with a nvidia GTX 1050 graphics card, and following the instructions on the lc0 github repository, we see that i need to install the CUDA backend:


[ 10.10.14.13/23 ] [ /dev/pts/51 ] [Chess/nibbler/src]
→ sudo apt install ninja-build libgtest-dev meson -y

[ 10.10.14.13/23 ] [ /dev/pts/93 ] [Documents/Chess/lc0]
→ sudo apt reboot now
	

Now let's install both CUDA and CUDNN since i'm using a nvidia graphics card:

Let's install CUDA:


[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/debian10/x86_64/7fa2af80.pub
[sudo] password for nothing:
Warning: apt-key is deprecated. Manage keyring files in trusted.gpg.d instead (see apt-key(8)).
Executing: /tmp/apt-key-gpghome.A0PxT0WLxK/gpg.1.sh --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/debian10/x86_64/7fa2af80.pub
gpg: requesting key from 'https://developer.download.nvidia.com/compute/cuda/repos/debian10/x86_64/7fa2af80.pub'
gpg: key F60F4B3D7FA2AF80: "cudatools " not changed
gpg: Total number processed: 1
gpg:              unchanged: 1

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo add-apt-repository "deb https://developer.download.nvidia.com/compute/cuda/repos/debian10/x86_64/ /"

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo add-apt-repository contrib
'contrib' distribution component is already enabled for all sources.

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo apt update -y

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo apt install cuda -y

Hit OK and reboot the machine once apt install finished:


DKMS: install completed.
Setting up libgles-nvidia1:amd64 (465.19.01-1) ...
Setting up libegl-nvidia0:amd64 (465.19.01-1) ...
Setting up nvidia-settings (465.19.01-1) ...
Setting up libgles-nvidia2:amd64 (465.19.01-1) ...
Setting up libnvidia-ml1:amd64 (465.19.01-1) ...
Setting up libnvcuvid1:amd64 (465.19.01-1) ...
Setting up libnvidia-opticalflow1:amd64 (465.19.01-1) ...
Setting up nvidia-egl-icd:amd64 (465.19.01-1) ...
Setting up nvidia-smi (465.19.01-1) ...
Setting up nvidia-driver-bin (465.19.01-1) ...
Setting up libnvidia-encode1:amd64 (465.19.01-1) ...
Setting up nvidia-driver-libs:amd64 (465.19.01-1) ...
Processing triggers for nvidia-alternative (465.19.01-1) ...
update-alternatives: updating alternative /usr/lib/nvidia/current because link group nvidia has changed slave links
Setting up nvidia-driver (465.19.01-1) ...
Setting up cuda-drivers-465 (465.19.01-1) ...
Setting up cuda-drivers (465.19.01-1) ...
Setting up cuda-runtime-11-3 (11.3.1-1) ...
Setting up cuda-demo-suite-11-3 (11.3.58-1) ...
Setting up cuda-11-3 (11.3.1-1) ...
Setting up cuda (11.3.1-1) ...
Processing triggers for libc-bin (2.31-12) ...
Processing triggers for glx-alternative-nvidia (1.2.0) ...
Processing triggers for glx-alternative-mesa (1.2.0) ...
Processing triggers for update-glx (1.2.0) ...
Processing triggers for libc-bin (2.31-12) ...
Processing triggers for glx-alternative-nvidia (1.2.0) ...
update-alternatives: warning: forcing reinstallation of alternative /usr/lib/nvidia because link group glx is broken
Processing triggers for libc-bin (2.31-12) ...
Processing triggers for initramfs-tools (0.140) ...
update-initramfs: Generating /boot/initrd.img-5.10.0-kali8-amd64

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ sudo reboot now

After rebooting, make sure that cuda is on your system:


[ 10.0.0.10/16 ] [ /dev/pts/3 ] [~]
→ cd /usr/local

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [/usr/local]
→ ls -lash
total 48K
4.0K drwxr-xr-x 12 root root 4.0K Jun  4 17:38 .
4.0K drwxr-xr-x 14 root root 4.0K May 22 15:06 ..
4.0K drwxr-xr-x  3 root root 4.0K Jun  4 17:38 bin
   0 lrwxrwxrwx  1 root root   22 Jun  4 17:38 cuda -> /etc/alternatives/cuda
   0 lrwxrwxrwx  1 root root   25 Jun  4 17:38 cuda-11 -> /etc/alternatives/cuda-11
4.0K drwxr-xr-x 15 root root 4.0K Jun  4 17:38 cuda-11.3
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:06 etc
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:06 games
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:06 include
4.0K drwxr-xr-x  5 root root 4.0K Jun  4 14:14 lib
   0 lrwxrwxrwx  1 root root    9 May 22 15:06 man -> share/man
   0 lrwxrwxrwx  1 root root   57 Jun  4 12:40 nibbler -> /home/nothing/Documents/Chess/nibbler-2.1.6-linux/nibbler
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:06 sbin
4.0K drwxr-xr-x  9 root root 4.0K May 24 20:23 share
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:19 simple-cdd
4.0K drwxr-xr-x  2 root root 4.0K May 22 15:06 src

Now that cuda is installed, go install cuDNN

Even though i'm not on Ubuntu, this is still a debian-based distro, so it should be fine:


[ 10.10.14.13/23 ] [ /dev/pts/93 ] [~/Downloads]
→ sudo dpkg -i libcudnn8_8.2.0.53-1+cuda11.3_amd64.deb
Selecting previously unselected package libcudnn8.
(Reading database ... 393803 files and directories currently installed.)
Preparing to unpack libcudnn8_8.2.0.53-1+cuda11.3_amd64.deb ...
Unpacking libcudnn8 (8.2.0.53-1+cuda11.3) ...
Setting up libcudnn8 (8.2.0.53-1+cuda11.3) ...
Processing triggers for libc-bin (2.31-12) ...
	

Now that's done let's compile lc0 after cloning it:


[ 10.66.66.2/32 ] [ /dev/pts/8 ] [~/Documents/chess]
→ git clone -b release/0.27 --recurse-submodules https://github.com/LeelaChessZero/lc0.git ; cd lc0
Cloning into 'lc0'...
remote: Enumerating objects: 9590, done.
remote: Counting objects: 100% (206/206), done.
remote: Compressing objects: 100% (139/139), done.
remote: Total 9590 (delta 108), reused 119 (delta 67), pack-reused 9384
Receiving objects: 100% (9590/9590), 37.90 MiB | 1.69 MiB/s, done.
Resolving deltas: 100% (6773/6773), done.
Submodule 'libs/lczero-common' (https://github.com/LeelaChessZero/lczero-common.git) registered for path 'libs/lczero-common'
Cloning into '/home/nothing/Documents/chess/lc0/libs/lczero-common'...
remote: Enumerating objects: 152, done.
remote: Counting objects: 100% (12/12), done.
remote: Compressing objects: 100% (8/8), done.
remote: Total 152 (delta 2), reused 6 (delta 1), pack-reused 140
Receiving objects: 100% (152/152), 29.36 KiB | 2.10 MiB/s, done.
Resolving deltas: 100% (46/46), done.
Submodule path 'libs/lczero-common': checked out '00fd892e648160c294346c87449126d9bad80a16'


[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/lc0]
→ ./build.sh
~/Documents/Chess/lc0 ~/Documents/Chess/lc0
The Meson build system
Version: 0.56.2
Source dir: /home/nothing/Documents/Chess/lc0
Build dir: /home/nothing/Documents/Chess/lc0/build/release
Build type: native build
Project name: lc0
Project version: undefined
C++ compiler for the host machine: c++ (gcc 10.2.1 "c++ (Debian 10.2.1-6) 10.2.1 20210110")
C++ linker for the host machine: c++ ld.bfd 2.35.2
Host machine cpu family: x86_64
Host machine cpu: x86_64
meson.build:27: WARNING: Consider using the built-in warning_level option instead of using "-Wextra".
Library libprotobuf found: NO
Found pkg-config: /usr/bin/pkg-config (0.29.2)
Found CMake: /usr/bin/cmake (3.18.4)
Run-time dependency protobuf found: NO (tried pkgconfig and cmake)
Program protoc found: NO

|Executing subproject protobuf method meson
|
|Project name: protobuf
|Project version: 3.5.1
|C++ compiler for the host machine: c++ (gcc 10.2.1 "c++ (Debian 10.2.1-6) 10.2.1 20210110")
|C++ linker for the host machine: c++ ld.bfd 2.35.2
|Compiler for C++ supports arguments -DHAVE_PTHREAD: YES
|Compiler for C++ supports arguments -Wno-sign-compare: YES
|Compiler for C++ supports arguments -Wno-unused-parameter: YES
|Compiler for C++ supports arguments -Wno-ignored-qualifiers: YES
|Compiler for C++ supports arguments /wd4146: NO
|Compiler for C++ supports arguments /wd4244: NO
|Compiler for C++ supports arguments /wd4305: NO
|Compiler for C++ supports arguments /wd4506: NO
|Run-time dependency threads found: YES
|Build targets in project: 6
|Subproject protobuf finished.

Program git found: YES (/usr/bin/git)
Message: Using build identifier "git.29c15a4".
Library pthread found: YES
Library dl found: YES
Library libtensorflow_cc found: NO
Run-time dependency accelerate found: NO (tried pkgconfig and cmake)
Library mkl_rt found: NO
Library mklml found: NO
Library dnnl found: NO
Library openblas.dll found: NO
Library openblas found: NO
Program ispc found: NO
Library OpenCL found: YES
Run-time dependency opencl found: YES 2.2
Library cublas found: YES
Library cudnn found: NO
Library cudart found: YES
Program /usr/local/cuda/bin/nvcc found: YES (/usr/local/cuda/bin/nvcc)
Run-time dependency zlib found: YES 1.2.11
Run-time dependency GTest found: YES 1.10.0
Build targets in project: 14

lc0 undefined

  Subprojects
    protobuf: YES

Found ninja-1.10.1 at /usr/bin/ninja
[52/298] Compiling C++ object subprojects/protobuf-3.5.1/libprotobuf.so.p/src_google_protobuf_descriptor.cc.o
../../subprojects/protobuf-3.5.1/src/google/protobuf/descriptor.cc: In member function ‘google::protobuf::Symbol google::protobuf::DescriptorPool::NewPlaceholderWithMutexHeld(const string&, google::protobuf::DescriptorPool::PlaceholderType) const’:
../../subprojects/protobuf-3.5.1/src/google/protobuf/descriptor.cc:3896:58: warning: ‘void* memset(void*, int, size_t)’ clearing an object of type ‘class google::protobuf::EnumDescriptor’ with no trivial copy-assignment; use assignment or value-initialization instead [-Wclass-memaccess]
 3896 |     memset(placeholder_enum, 0, sizeof(*placeholder_enum));
      |         

[...]

../../src/mcts/stoppers/factory.cc:302:19: note: remove ‘std::move’ call
[265/298] Compiling C++ object liblc0_lib.so.p/src_selfplay_loop.cc.o
../../src/selfplay/loop.cc: In member function ‘void lczero::SelfPlayLoop::SendTournament(const lczero::TournamentInfo&)’:
../../src/selfplay/loop.cc:170:40: warning: ‘los.lczero::optional::value_’ may be used uninitialized in this function [-Wmaybe-uninitialized]
  170 |         << (los.value_or(0.0f) * 100.0f) << "%";
      |                                        ^
[298/298] Linking target encoder_test
~/Documents/Chess/lc0

	

Now that lc0 is done compiling, you will find the engine itself inside the cloned repository at build/release as the lc0 binary file:


[ 10.10.14.13/23 ] [ /dev/pts/77 ] [Documents/Chess/lc0]
→ cd build/release

[ 10.10.14.13/23 ] [ /dev/pts/77 ] [lc0/build/release]
→ ls -lash lc0
1.5M -rwxr-xr-x 1 nothing nothing 1.5M Jun  4 15:16 lc0

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [lc0/build/release]
→ ./lc0
       _
|   _ | |
|_ |_ |_| v0.23.3+git.29c15a4 built Jun  4 2021
^C
	

So let's use lc0 inside of nibbler:

Now as you can see just the lc0 binary itself isn't enough, we need the Network weights file, to get that let's go over to the lc0 training networks here:

Then import it in nibbler:

Sidenote: When you first start nibbler, you should see that it picks up your cuda version and your GPU. If it doesn't, go back and compile CUDA properly.

Then after setting a limit of threads, nodes, and eval per nodes, test the engine against yourself with F9 or against itself with F11

At first it takes a while to load the weights file, but once it's done loading, it will be ready to play as you can see above.

Easier Weight Files



As you can guess, the trained weight files from lc0 are within the elo range of IM / GM with insane inhuman moves, if you want opponent that does human-like moves, you can look for the human-like chess weights from maia chess:


[ 10.0.0.10/16 ] [ /dev/pts/3 ] [~/Documents/Chess]
→ cd Weights

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1100.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1200.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1300.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1400.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1500.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1600.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1700.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1800.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ wget https://github.com/CSSLab/maia-chess/releases/download/v1.0/maia-1900.pb.gz -q

[ 10.0.0.10/16 ] [ /dev/pts/3 ] [Documents/Chess/Weights]
→ ls -l
total 54572
-rw-r--r-- 1 nothing nothing 44289015 Jun  4 16:59 256x20-t40-1541.pb.gz
-rw-r--r-- 1 nothing nothing  1313193 Jan 14 06:25 maia-1100.pb.gz
-rw-r--r-- 1 nothing nothing  1249692 Jan 14 06:25 maia-1200.pb.gz
-rw-r--r-- 1 nothing nothing  1244431 Jan 14 06:25 maia-1300.pb.gz
-rw-r--r-- 1 nothing nothing  1328977 Jan 14 06:25 maia-1400.pb.gz
-rw-r--r-- 1 nothing nothing  1258199 Jan 14 06:25 maia-1500.pb.gz
-rw-r--r-- 1 nothing nothing  1313870 Jan 14 06:25 maia-1600.pb.gz
-rw-r--r-- 1 nothing nothing  1313415 Jan 14 06:25 maia-1700.pb.gz
-rw-r--r-- 1 nothing nothing  1289431 Jan 14 06:25 maia-1800.pb.gz
-rw-r--r-- 1 nothing nothing  1262607 Jan 14 06:25 maia-1900.pb.gz
	

Edit: lc0 does not feel human at all with any of these weights lol, if you want leela to replicate human mistakes, this is handled by the Temperature setting. If the Temperature is set to 0, leela will always pick the evaluated best move. The higher the Temperature, the less likely leela will pick the best move. Nibbler currently sets the Temperature maximum to be at 1, however this is not the real maximum temperature we can pass to leela. If you want to train against leela (making leela do mistakes in games) you can set the temperature from 1 to 2+ where a temperature of 2 is the equivalent of a really bad 600 human player, a temperature of 1.5 is the equivalent of a 1000 elo player, and from there it's really exponential, Temperature set at 1.3 feels like an 1600+ elo player and so on. To set the temperature to higher values, you can use an external 'script' to pass to nibbler:


[ 10.10.14.8/23 ] [ /dev/pts/33 ] [.config/Nibbler/scripts]
→ pwd

/home/nothing/.config/Nibbler/scripts
[ 10.10.14.8/23 ] [ /dev/pts/33 ] [.config/Nibbler/scripts]
→ ls -l
total 44
-rw-r--r-- 1 nothing nothing 77 Jun  4 12:38 example.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:49 tmp1.1.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:49 tmp1.2.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:48 tmp1.3.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:48 tmp1.4.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:11 tmp1.5.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:11 tmp1.6.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:11 tmp1.7.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:11 tmp1.8.txt
-rw-r--r-- 1 nothing nothing 75 Jul 11 14:11 tmp1.9.txt
-rw-r--r-- 1 nothing nothing 73 Jul 11 14:11 tmp2.0.txt

[ 10.10.14.8/23 ] [ /dev/pts/33 ] [.config/Nibbler/scripts]
→ cat tmp1.5.txt
setoption name temperature value 1.5
setoption name tempdecaymoves value 0

[ 10.10.14.8/23 ] [ /dev/pts/33 ] [.config/Nibbler/scripts]
→ cat tmp1.6.txt
setoption name temperature value 1.6
setoption name tempdecaymoves value 0

[ 10.10.14.8/23 ] [ /dev/pts/33 ] [.config/Nibbler/scripts]
→ cat tmp1.7.txt
setoption name temperature value 1.7
setoption name tempdecaymoves value 0

And from here simply load the script in nibbler:

Nihilism

Until there is Nothing left.



Creative Commons Zero: No Rights Reserved

About nihilist

Donate XMR: 8AUYjhQeG3D5aodJDtqG499N5jXXM71gYKD8LgSsFB9BUV1o7muLv3DXHoydRTK4SZaaUBq4EAUqpZHLrX2VZLH71Jrd9k8


Contact: nihilist@contact.nowhere.moe (PGP)