Evaluate positions and batches#
This notebook exercises the current LczeroEvaluator contract on real python-chess boards. It uses the repository’s tiny deterministic fixture so it runs offline; replace load_fixture_evaluator() with LczeroModel.from_path(...) or LczeroModel.from_hf(...) for a trained lc0-family model. Fixture observations demonstrate API behavior, not chess strength.
[1]:
import chess
from examples.decision_analysis_tutorial import load_fixture_evaluator
runtime = load_fixture_evaluator()
boards = [chess.Board(), chess.Board()]
boards[1].push_uci("e2e4")
evaluations = runtime.evaluator.evaluate(boards)
len(evaluations), evaluations.tensors.batch_size
[1]:
(2, torch.Size([2]))
The evaluator preserves the batch while each row exposes chess-aware legal actions. Raw network logits remain in the nested TensorDict; user-facing policy probabilities are masked and normalized over legal moves.
[2]:
summary = []
for evaluation in evaluations:
summary.append(
{
"turn": "white" if evaluation.position.turn else "black",
"best_move": evaluation.policy.best_move.uci(),
"top_three": [(action.move.uci(), round(action.probability, 4)) for action in evaluation.policy.top(3)],
"value": evaluation.value.value,
}
)
summary
[2]:
[{'turn': 'white',
'best_move': 'e2e4',
'top_three': [('e2e4', 1.0), ('d2d4', 0.0), ('a2a3', 0.0)],
'value': 0.20000000298023224},
{'turn': 'black',
'best_move': 'e7e5',
'top_three': [('e7e5', 1.0), ('d7d5', 0.0), ('a7a5', 0.0)],
'value': 0.20000000298023224}]
Freeze runtime tensors into an immutable, tensor-free record before persisting or comparing evidence. The digest covers canonical versioned JSON.
[3]:
record = evaluations[0].record()
assert record.position.board() == boards[0]
assert record.policy[0].move <= record.policy[-1].move
{"schema_version": record.schema_version, "digest": record.digest()}
[3]:
{'schema_version': 1,
'digest': '3ce6852bf83e37ea54dbf2178b46c1ce0f8a3c67d5ce30dc96562438207f50de'}