跳到内容

大型语言模型玩国际象棋

在此示例中,我们将让 Phi-2 模型与自身对弈国际象棋。模型本身很容易生成无效的走法,因此我们将为其提供一些帮助。在每一步中,我们将生成一个仅匹配有效走法的正则表达式,并使用它来帮助模型仅生成有效走法。

棋盘

游戏将在标准棋盘上进行。我们将使用 chess 来跟踪对手的走法,并检查走法是否有效。

%pip install outlines -q
%pip install chess -q
%pip install transformers accelerate einops -q

import chess

board = chess.Board("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1")

对手

Phi-2 将与自身对弈

from outlines import models

model = models.transformers("microsoft/Phi-3-mini-4k-instruct")

为语言模型提供一点帮助

为了确保 Phi-2 生成有效的国际象棋走法,我们将使用 Outline 的基于正则表达式的结构化生成。我们定义一个函数,该函数接收棋盘的当前状态,并返回一个匹配所有可能合法走法的正则表达式。

import re

def legal_moves_regex(board):
    """Build a regex that only matches valid moves."""
    legal_moves = list(board.legal_moves)
    legal_modes_str = [board.san(move) for move in legal_moves]
    legal_modes_str = [re.sub(r"[+#]", "", move) for move in legal_modes_str]
    regex_pattern = "|".join(re.escape(move) for move in legal_modes_str)
    regex_pattern = f"{regex_pattern}"
    return regex_pattern

提示语言模型

提示对应于棋盘的当前状态,因此我们从以下内容开始:

prompt = "Let's play Chess. Moves: "

我们在每一步更新提示,以便它反映上一步走法后的棋盘状态。

开始玩吧

from outlines import generate

board_state = " "
turn_number = 0
while not board.is_game_over():
    regex_pattern = legal_moves_regex(board)
    structured = generate.regex(model, regex_pattern)(prompt + board_state)
    move = board.parse_san(structured)

    if turn_number % 2 == 0 :  # It's White's turn
        board_state += board.san(move) + " "
    else:
        board_state += board.san(move) + " " + str(turn_number) + "."

    turn_number += 1

    board.push(move)

    print(board_state)

有趣的是,Phi-2 讨厌吃子。

 e4 e5 1.Nf3 Ne7 3.b4 Nf5 5.Nc3 Ne7 7.Bb5 a6 9.Na4 b6 11.c3 Nec6 13.c4 a5 15.d4 Qg5 17.Nd2 Bb7 19.dxe5

此示例最初由 @903124S此 gist 中撰写。