qwen2.5-3b-chess
Built with Qwen — 土台の Qwen2.5-3B-Instruct と同じ Qwen RESEARCH LICENSE AGREEMENT に従います(非商用に限る。下の「ライセンス」の節)。
Qwen2.5-3B-Instruct を、Stockfish を教師にした知識蒸留と DAgger(3周)で LoRA ファインチューニングし、マージしたチェスの指し手選択モデルです。局面(FEN)と番号付きの候補手リストを受け取り、最善と思う手の番号だけを返します。
English — Qwen2.5-3B-Instruct fine-tuned (LoRA, merged) to pick a chess move from a numbered list of candidate moves. Trained by distillation from Stockfish plus 3 rounds of DAgger. With a rule-based inference-time guard, it wins ~24% of games against Lichess Stockfish level 3 (300 games) and almost never beats level 4. Includes a Q4_K_M GGUF.
- 開発記録・コード: https://github.com/ryuheitakeda/chess-llm-assistant
- 現在の版: v7(以前の v3 は
v3タグで参照できます)
結果(推論時ガード併用)
| 相手 | 結果 |
|---|---|
| Lichess Stockfish レベル3(手元で再現、300局) | 71勝42分187敗(勝率24%、スコア31%) |
| Lichess Stockfish レベル3(Lichess本番、9局) | 3勝6敗 |
| Lichess Stockfish レベル4(手元で再現、200局) | 3勝8分189敗 |
「手元で再現」は、Lichess の AI レベル設定(Skill Level・深さ・思考時間)をローカルの Stockfish で再現したものです。
使い方
学習時と同じプロンプト形式で使ってください。
import re, chess, torch
from transformers import AutoTokenizer, AutoModelForCausalLM
repo = "Ryu-tek/qwen2.5-3b-chess"
tok = AutoTokenizer.from_pretrained(repo)
model = AutoModelForCausalLM.from_pretrained(repo, dtype=torch.float16, device_map="auto")
board = chess.Board()
legal = list(board.legal_moves) # 推奨: ここでガード(下記)を通して候補を絞る
numbered = "\n".join(f"{i}: {board.san(m)}" for i, m in enumerate(legal))
prompt = f"""あなたはチェスの強豪プレイヤーです。以下の局面で、最善だと思う手を選んでください。
FEN: {board.fen()}
手番: {"白" if board.turn else "黒"}
指せる手の一覧:
{numbered}
一番良いと思う手の番号だけを、他の文章を一切つけずに数字のみで答えてください。"""
text = tok.apply_chat_template([{"role": "user", "content": prompt}], tokenize=False, add_generation_prompt=True)
inputs = tok(text, return_tensors="pt").to(model.device)
out = model.generate(**inputs, max_new_tokens=6, do_sample=False)
answer = tok.decode(out[0][inputs["input_ids"].shape[1]:], skip_special_tokens=True)
print(board.san(legal[int(re.findall(r"\d+", answer)[0])]))
GGUF: qwen2.5-3b-chess-Q4_K_M.gguf(約2GB)を LM Studio や llama.cpp で使えます。
推論時ガード(強く推奨): 候補リストを作る前に、ステイルメイト・千日手・相手に1手詰めを許す手、そして SEE(静的交換評価)で駒損になる手を除外してください。モデル単体より大きく強くなります(Stockfish Elo1320 に100局:ガードなし相当 1勝 → SEE ガードあり 12勝)。実装は GitHub の guard.py を参照。
学習
| 段階 | 内容 |
|---|---|
| v3 | Stockfish のラベル付き局面 + Stockfish が詰ませ切った終盤の手順 |
| v5〜v7 | DAgger 3周(モデル自身の対局局面にフル強度 Stockfish が正解付け)、過去データの replay、v6 から答えの番号だけに損失 |
LoRA: r=16, α=32, q/k/v/o_proj。学習環境: RTX 3080 / Kaggle T4。DPO も試しましたが改善せず、採用していません(詳細は GitHub)。
限界
- 探索をせず1手ずつ選ぶため、自分から優位を作る力は Lichess レベル4に届きません
- 学習データは主に白番の局面です
- チェスの学習・研究用です。オンライン対局で人間を相手に使うことは、各サイトの規約違反になります
ライセンス
- このモデルは Qwen/Qwen2.5-3B-Instruct をファインチューニングした派生物で、土台と同じ Qwen RESEARCH LICENSE AGREEMENT に従います。使えるのは非商用の目的だけです(商用で使うときは、Alibaba Cloud の許諾が要ります)
- ライセンスの全文:https://huggingface.co/Qwen/Qwen2.5-3B-Instruct/blob/main/LICENSE (このリポジトリにも
LICENSEとして写しを置きます) - 変えたところ:土台の重みに、LoRA(r=16、q/k/v/o_proj)で学習した差分をマージしました(学習の方法は「学習」の節)
- Qwen is licensed under the Qwen RESEARCH LICENSE AGREEMENT, Copyright (c) Alibaba Cloud. All Rights Reserved.
- Built with Qwen