Skip to content

Commit

Permalink
Add models playing chess example
Browse files Browse the repository at this point in the history
  • Loading branch information
rlouf authored and brandonwillard committed Dec 3, 2023
1 parent e1c9604 commit 87ae656
Showing 1 changed file with 88 additions and 0 deletions.
88 changes: 88 additions & 0 deletions docs/examples/models_playing_chess.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
# Large language models playing chess

In this example we will make Mistral-7B play chess against a simple chess engine, ...

## The chessboard

The game will be played on a standard checkboard. We will use the `chess` [library](https://github.com/niklasf/python-chess) to track the opponents' moves, and check that the moves are valid. We will use the `chessboard` [library](https://pypi.org/project/chess-board/) to get a graphical representation of the current state of the game:

```python
import chess
import chessboard.display

board = chess.Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")
game_board = chessboard.display.start(board.fen())
```

## The opponents

Mistral-7B quantized will be playing White:

```python
from outlines import models

model = models.awq("model")
```

The X chess engine (3120 ELO) will be playing Black. We use the `chess` library to load the engine:

```python
engine = chess.engine.SimpleEngine.popen_uci(ENGINE_PATH)
engine.configure({"UCI_LimitStrength": True,"UCI_Elo": 1320})
```

## A little help for the language model

To make sure Mistral-7B generates valid chess moves we will use Outline's regex-guided generation. We define a function that takes the current state of the board and returns a regex that matches all possible legal moves:

```python
def generate_regex(board):
legal_moves = list(board.legal_moves)
move_strings = [board.san(move) for move in legal_moves]
# Remove + and # from the move strings
move_strings = [re.sub(r"[+#]", "", move) for move in move_strings]
regex_pattern = "|".join(re.escape(move) for move in move_strings)
regex_pattern = f"{regex_pattern}"
return regex_pattern
```

*Let's check how this works*

## Prompting the language model

The models' initial prompt

```python
prompt = "Score: 1-0 WhiteElo: 1600 BlackElo: 1600 Timecontrol: 1800+0 Moves: 1."
```

Update the prompt:

```python
def update_model_prompt(board, move):
```

## Let's play!


```python
while not board.is_game_over():
if board.turn == chess.WHITE: # Mistral's turn
regex_pattern = generate_regex(board)
guided = generate.regex(model, regex_pattern, max_tokens=10)(prompt)
move = board.parse_san(guided)
else: # Engine's turn
result = engine.play(board, chess.engine.Limit(time=0.6))
move = result.move

prompt = update_model_prompt(board, move)

board.push(move)
chessboard.display.update(board.fen(), game_board)
```




Idea: website with chess tournament.
*This example was originally authored by [@903124S](@903124S) in [this gist](https://gist.github.com/903124/cfbefa24da95e2316e0d5e8ef8ed360d).*

0 comments on commit 87ae656

Please sign in to comment.