Walkthrough#

Open In Colab

Setup#

[ ]:
import importlib.util

DEV = True

if importlib.util.find_spec("google.colab") is not None:
    MODE = "colab-dev" if DEV else "colab"
else:
    MODE = "local"
[2]:
if MODE == "colab":
    %pip install -q lczerolens[hf]
elif MODE == "colab-dev":
    !rm -r lczerolens
    !git clone https://github.com/Xmaster6y/lczerolens -b main
    %pip install -q ./lczerolens --extra hf

Define a Board#

Define a chess board.

[3]:
from lczerolens import LczeroBoard

board = LczeroBoard("r1qr3k/pp3pB1/1np1pb2/8/3P3P/2N2PR1/PP1Q2P1/2KR4 b - - 0 22")
display(board)
../_images/notebooks_walkthrough_5_0.svg

Define a Model#

A model is based on a neural network and can be used to evaluate a board.

[4]:
from lczerolens import LczeroModel

model = LczeroModel.from_hf("lczerolens/maia-1100")

## Evaluate a Board

output = model(board)
output
[4]:
TensorDict(
    fields={
        board: Tensor(shape=torch.Size([1, 112, 8, 8]), device=cpu, dtype=torch.float32, is_shared=False),
        policy: Tensor(shape=torch.Size([1, 1858]), device=cpu, dtype=torch.float32, is_shared=False),
        wdl: Tensor(shape=torch.Size([1, 3]), device=cpu, dtype=torch.float32, is_shared=False)},
    batch_size=torch.Size([1]),
    device=None,
    is_shared=False)

The output is a TensorDict with different fields depending on the model, here the heads are:

  • policy -> predicted move probabilities

  • wdl -> win-draw-lose probabilities

[5]:
output["wdl"]
[5]:
tensor([[0.0265, 0.0594, 0.9142]], grad_fn=<SoftmaxBackward0>)

Evaluation is relative to the side to move. Here the black player is in a bad position.

Decode a Move#

The predicted policy is a 1858-dimensional vector, each index corresponds to a possible move (not necessarily legal!). The move are encoded relatively and should be decoded with the corresponding board.

[6]:
print("0 (w):", LczeroBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1").decode_move(0))
print("0 (b):", LczeroBoard("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq - 0 1").decode_move(0))
0 (w): a1b1
0 (b): a8b8
[7]:
best_move_index = output["policy"].argmax()
best_move = board.decode_move(best_move_index)

board.push(best_move)
display(board)
../_images/notebooks_walkthrough_13_0.svg

Yet this move is not legal! It is due to the model only being trained on legal moves.

[8]:
board.pop()
legal_indices = board.get_legal_indices()
legal_policy = output["policy"][0].gather(0, legal_indices)
best_move_index = legal_indices[legal_policy.argmax()]
best_legal_move = board.decode_move(best_move_index)

board.push(best_legal_move)
display(board)
../_images/notebooks_walkthrough_15_0.svg

You’re now ready to start using lczerolens! Be sure to check out the features section for more information on how to use the library.