Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

SAZ2 自己対局教師データ(rsshogi.sazpack)

rsshogi.sazpack は SAZ2 形式の自己対局教師データを読み書きするモジュールである。 現行形式は version 4 であり、読み込み関数は他の版を ValueError として拒否する。 SAZ2 は各対局の初期局面(32 バイトの PackedSfen)、終局結果、終局理由、入玉ルールに加えて、各手番における探索ルート、対局結果、ネットワーク生出力の WDL(勝、分、敗)分布、候補手ごとの Policy 重みと訪問数、詰み手数や残り手数などの探索テレメトリをコンパクトなバイナリとして保持する。

from rsshogi.sazpack import (
    SazGame,
    SazPolicyEntry,
    SazPosition,
    SazWdl,
    decode_sazpack,
    decode_sazpack_file,
    write_sazpack,
    write_sazpack_file,
)

データクラス

SazWdl

SazWdl(win: int, draw: int, loss: int) -> SazWdl

手番側視点での勝ち(win)、引き分け(draw)、負け(loss)の重みを uint16(0..=65535)で保持するクラスである。 SAZ2 バイナリへ書き出す際、win + draw + loss == 65535(量子化スケール合計)を満たす必要がある。

プロパティ型範囲説明
winint0..=65535勝利確率の量子化重み。
drawint0..=65535引き分け確率の量子化重み。
lossint0..=65535敗北確率の量子化重み。

SazPolicyEntry

SazPolicyEntry(
    mv: Move | Move32 | int | str,
    prior: int,
    raw_prior: int,
    visits: int,
    lower: int,
    upper: int,
) -> SazPolicyEntry

探索における 1 つの候補手の Policy 重み、訪問数、および結果区間(Outcome Bound)を保持するクラスである。 コンストラクタの mv には Move、Move32、int(0..=65535)、または USI 文字列を渡すことができ、mv プロパティからは正規化された USI 文字列として取得できる。

プロパティ型範囲 / コード説明
mvstrUSI 文字列候補手の USI 表記(例:"7g7f")。
priorint0..=65535探索で使用した Policy 重み(同一局面の全候補手の合計が 65535)。
raw_priorint0..=65535ニューラルネットワークが出力した生の Policy 重み(同一局面の全候補手の合計が 65535)。
visitsint0..=4294967295探索終了時点の累積訪問数(uint32)。
lowerint0, 1, 2結果区間の下限コード(0:負け、1:引き分け、2:勝ち)。
upperint0, 1, 2結果区間の上限コード(0:負け、1:引き分け、2:勝ち)。

lower と upper は lower <= upper を満たす必要がある。

SazPosition

SazPosition(
    played: Move | Move32 | int | str,
    root_wdl: SazWdl,
    outcome_wdl: SazWdl,
    raw_wdl: SazWdl,
    raw_mate: int,
    raw_moves_left: int,
    plies_left: int,
    requested_visits: int,
    target_weight_milli: int,
    exploration_flags: int,
    policy: Sequence[SazPolicyEntry],
    mate: int | None = None,
) -> SazPosition

対局内の 1 局面分の着手と自己対局教師データを保持するクラスである。

プロパティ型範囲説明
playedstrUSI 文字列実際に選択された着手の USI 文字列(現在局面で合法手である必要がある)。
root_wdlSazWdl合計 65535探索完了時のルート WDL 分布。
outcome_wdlSazWdl合計 65535対局結果に基づく WDL 分布。
raw_wdlSazWdl合計 65535ネットワーク出力の生の WDL 分布。
raw_mateint0..=65535ネットワーク出力の詰み指標(uint16)。
raw_moves_leftint0..=65535ネットワーク出力の予想残り手数(uint16)。
plies_leftint0..=65535実際の終局までの残り手数(uint16)。
requested_visitsint0..=4294967295探索時に要求された目標訪問数(uint32)。
target_weight_milliint0..=65535学習ターゲット重みのミリ単位表現(1000 が標準重み 1.0)。
exploration_flagsint0..=255探索モードやノイズ付与状態を表すビットフラグ(uint8)。
mateint | None-32768..=32767探索で判明した詰み手数(int16、未判明時は None)。
policylist[SazPolicyEntry]1 件以上合法な候補手ごとの Policy エントリのリスト(同一手の重複は不可)。

SazGame

SazGame(
    stem: str | bytes | bytearray,
    game_result: GameResult | int | str,
    termination_reason: int,
    entering_king_rule: int,
    positions: Sequence[SazPosition],
) -> SazGame

1 対局分の SAZ2 データを保持するクラスである。 コンストラクタの stem には初期局面の SFEN 文字列、または 32 バイトの PackedSfen(bytes / bytearray)を指定できる。

プロパティ型説明
stem_packed_sfenbytes初期局面の 32 バイト PackedSfen。
game_resultGameResult対局結果(棋譜管理の GameResult を参照)。
termination_reasonintSAZ2 の終局理由コード(下表参照)。
entering_king_ruleintSAZ2 の入玉ルールコード(下表参照)。
positionslist[SazPosition]初期局面から着手順に並んだ SazPosition のリスト。

termination_reason と entering_king_rule のコード一覧

termination_reason意味entering_king_rule意味
0合法手なし(詰みなど)0入玉ルールなし
1千日手引き分け124 点法
2連続王手の千日手による勝ち224 点法(駒落ち対応)
3連続王手の千日手による負け327 点法
4優等局面による終了427 点法(駒落ち対応)
5劣等局面による終了5トライルール
6入玉宣言勝ち6未設定
7最大手数到達--
8投了--
9裁定--

8 と 9 の終局局面には合法手が残る。 8 は敗者側が投了した終局を表し、評価値の閾値で手番側(最後に記録された局面の手番)の負けを確定させる自己対局の打ち切りを含む。 9 は投了を伴わない宣言であり、引き分けを宣言した場合の game_result は GameResult.DRAW_BY_ADJUDICATION になる。


シリアライズとデシリアライズ関数

write_sazpack および write_sazpack_file は、WDL 分布と Policy 重みの合計値(65535)を検証し、違反がある場合は ValueError を送出する。 SazGame に初期局面を SFEN 文字列で渡す場合は構築時に解析するが、32 バイトの PackedSfen を渡す場合は長さだけを確認する。 読み書き時に盤面を再生する検証は行わないため、着手の合法性、候補手の重複、勝敗上下限の大小関係、終局結果と終局理由の整合性は利用側で確認する。

関数シグネチャ説明
write_sazpack(games)(games: Sequence[SazGame]) -> bytesSazGame のシーケンスを SAZ2 バイナリへ変換して bytes を返す。
write_sazpack_file(path, games)(path: str | PathLike, games: Sequence[SazGame]) -> NoneSazGame のシーケンスを SAZ2 バイナリファイルへ書き出す。
decode_sazpack(data)(data: bytes | bytearray) -> list[SazGame]SAZ2 バイナリから list[SazGame] を復元する。
decode_sazpack_file(path)(path: str | PathLike) -> list[SazGame]SAZ2 バイナリファイルから list[SazGame] を復元する。
from rsshogi.record import GameResult
from rsshogi.sazpack import (
    SazGame,
    SazPolicyEntry,
    SazPosition,
    SazWdl,
    decode_sazpack,
    write_sazpack,
)

wdl = SazWdl(win=40000, draw=5535, loss=20000)
policy = [
    SazPolicyEntry("7g7f", prior=45000, raw_prior=42000, visits=120, lower=0, upper=2),
    SazPolicyEntry("2g2f", prior=20535, raw_prior=23535, visits=80, lower=0, upper=2),
]
position = SazPosition(
    played="7g7f",
    root_wdl=wdl,
    outcome_wdl=SazWdl(65535, 0, 0),
    raw_wdl=wdl,
    raw_mate=0,
    raw_moves_left=80,
    plies_left=75,
    requested_visits=200,
    target_weight_milli=1000,
    exploration_flags=1,
    policy=policy,
    mate=None,
)
game = SazGame(
    stem="lnsgkgsnl/1r5b1/ppppppppp/9/9/9/PPPPPPPPP/1B5R1/LNSGKGSNL b - 1",
    game_result=GameResult.BLACK_WIN,
    termination_reason=0,
    entering_king_rule=3,
    positions=[position],
)

blob = write_sazpack([game])
restored = decode_sazpack(blob)
assert restored[0].positions[0].played == "7g7f"
assert len(restored[0].positions[0].policy) == 2

関連項目