ルールエージェントを利用した初期学習¶
目的¶
notebooks/rule-ai-agent/ にある rule-based agent を Python
module として移植し、CSV 登録した deck と組み合わせて bootstrap 用 self-play JSONL を集める。
このデータは policy/value と belief の両方に使う。rule agent は最終 teacher ではなく、最初に「合法手を選び、盤面を進め、攻撃やサイド取得を経験する」ための補助 teacher として扱う。
実装方針¶
src/pca/rule_agents/base.pyBaseRuleAgentとRuleDecisionを定義する。legalize_selection()で min/max/count を守る。-
setup active では Basic Pokemon 以外を選ばない safety guard を入れる。
-
src/pca/rule_agents/agents/<agent_id>/ - agent ごとにディレクトリを分ける。
main.pyに notebook の%%writefile main.py相当を移植する。agent.pyにBaseRuleAgent/PortedRuleAgentを継承した class を置く。deck.csvにその agent の主 deck を置く。- 実行時に notebook を読む方式ではない。
-
提出形式に近い
obs -> selectedの構造を保つ。 -
configs/rule_agents.yaml - agent class、agent-local の主 deck CSV、互換 deck CSV、archetype、policy weight を登録する。
enabled: falseの agent は明示的に無効化される。match_weightで self-play に出す頻度を調整できる。0は完全除外、0.25は通常の約 1/4、1.0は通常頻度として扱う。policy_weight_scaleで policy imitation の強さを agent ごとに調整できる。train_policy/train_value/train_beliefで、その agent の record をどの学習に使うかを個別に制御できる。-
decks/rule_agents/<agent_id>.csvがあれば--rule-deck-dirで追加登録できる。 -
configs/rule/selfplay-rule-bootstrap-500g.yaml rule-agent-deck-pool: trueにより、configs/rule_agents.yamlのdeck_csvを両プレイヤーの deck pool として使う。- これにより、rule agent と紐づいた deck 同士で bootstrap self-play を集める。
- self-play 終了時に agent ごとの勝敗、通常勝ち、deck-out、サイド取得、攻撃回数を表示する。
agent-summary-outputで同じ agent 別集計を CSV に保存する。deck-summary-outputで deck ごとの勝率、通常勝ち、deck-out、サイド取得などを CSV に保存する。
JSONLのメタデータ¶
rule-pool self-play の record には次を保存する。
teacher_type: rule_agentteacher_idteacher_main_pokemonteacher_deck_csvteacher_compatibilityteacher_policy_weightteacher_policy_weight_scaleteacher_match_weightteacher_train_policyteacher_train_valueteacher_train_beliefteacher_result_side: win|loss|unfinishedteacher_source_notebookown_deck_card_ids
学習での扱い¶
Policy は teacher_policy_weight を掛ける。初期値は次の通り。
- 勝ち側:
0.40 - 負け側:
0.15 - 未完了:
0.10
Value target は下げない。負け record は負けとして、勝ち record は勝ちとして学習する。つまり「負けた側の手を完全に捨てる」のではなく、value では悪い結果として学び、policy imitation では弱く扱う。
Belief は --full-observation-targets で hidden state label を保存し、同じ JSONL から
belief_train.py を実行する。
agent ごとの品質差は次の2段階で扱う。
enabled: false: agent と deck を完全に self-play pool から外す。明らかに壊れている、または学習に入れたくない agent に使う。match_weight: self-play での出現頻度を下げる。弱いが belief/value 用の局面や負け方として少し残したい agent に使う。match_weight: 0は完全除外として扱う。policy_weight_scale: policy imitation の重みを倍率で下げる。勝敗によるteacher_policy_weightにさらに掛かる。train_policy: false: policy imitation には使わない。value / belief はtrain_value/train_beliefが true なら残す。train_value: false: policy とは別に、勝敗 value の教師からも外す。train_belief: false: hidden state 推定の belief 教師から外す。
低品質な rule agent は、基本的には match_weight
を下げ、train_policy: false、train_value: true、train_belief: true
とする。これにより「悪い手を真似る」ことは避けつつ、負け局面や hidden state
label は学習に残せる。明らかに壊れている agent は enabled: false で完全に外す。
実行例¶
PYTHONPATH=src uv run python -m pca.training.selfplay \
--config configs/rule/selfplay-rule-bootstrap-500g.yaml
Model vs Rule の self-play 収集¶
pca.training.selfplay は policy0 / policy1
を指定すると、左右で異なる policy を使える。未指定の場合は従来通り policy
1本を両プレイヤーに使う。
v13 model を p0、filtered rule agent pool を p1 にして JSONL を集める場合は次を使う。
PYTHONPATH=src python -m pca.training.selfplay \
--config configs/v13/selfplay-v13-ismcts-vs-rule.yaml
p0 のデッキは deck0-dir から選ばれ、p1 のデッキは rule-agent-deck-pool1: true により
configs/rule_agents_v13_filtered.yaml の有効な deck_csv
から選ばれる。逆向きで rule を p0、model を p1 にする場合は次を使う。
PYTHONPATH=src python -m pca.training.selfplay \
--config configs/v13/selfplay-rule-vs-v13-ismcts.yaml
この形式の JSONL は、model 側 record には model/search の policy target、rule 側 record には
teacher_type: rule_agent と teacher_policy_weight
を保存する。したがって、学習時には rule 側 imitation を弱くしつつ、model 側の search
target と同じファイルで混ぜられる。
macOS で CABT libcg.dylib が使える場合は、Docker なしで rule-pool self-play を回せる。
bash scripts/collect_rule_selfplay_local.sh
Docker で CABT 上の rule-pool self-play を回す場合は次を使う。
bash scripts/collect_rule_selfplay_docker.sh
10,000 試合などを chunk 単位で回す場合は、手書きループではなく次を使う。
bash scripts/run_rule_bootstrap_chunks.sh
デフォルトは 500 games x 20 chunks = 10,000 games である。各 chunk は個別 JSONL / summary
CSV として保存され、最後に data/selfplay/rule-bootstrap-10k.jsonl
へ結合される。デフォルト runtime は互換性のため docker のまま。Mac ローカル実行では
--runtime local を付ける。
主な上書き例:
bash scripts/run_rule_bootstrap_chunks.sh \
--runtime local \
--chunks 20 \
--games-per-chunk 500 \
--workers 8 \
--resume
-- 以降はそのまま pca.training.selfplay に渡る。
bash scripts/run_rule_bootstrap_chunks.sh \
--runtime local \
--run-name rule-bootstrap-10k-v2 \
--output-dir data/selfplay/rule-bootstrap-10k-v2 \
--merged-output data/selfplay/rule-bootstrap-10k-v2.jsonl \
-- --no-color
短い smoke run は次のように上書きする。
bash scripts/collect_rule_selfplay_docker.sh \
--games 20 \
--workers 4 \
--output data/selfplay/rule-bootstrap-smoke.jsonl \
--deck-summary-output data/selfplay/rule-bootstrap-smoke.deck-summary.csv
PYTHONPATH=src uv run python -m pca.training.belief_train \
--config configs/rule/train-belief-rule-bootstrap.yaml
PYTHONPATH=src uv run python -m pca.training.train \
--config configs/rule/train-policy-rule-bootstrap.yaml
10,000 試合 JSONL は大きいため、merged JSONL を一括で読むより chunk ごとに checkpoint を引き継ぐ方が安全である。Belief と Policy/Value を両方学習する場合は次を使う。
bash scripts/train_rule_bootstrap_chunks.sh --resume
デフォルトでは次の順で進む。
rule-bootstrap-10k-part000.jsonlで Belief を学習し、次 chunk の初期値にする。- 同じ chunk で Policy/Value を学習し、次 chunk の初期値にする。
part019まで繰り返す。- 最後に以下の stable checkpoint 名へコピーする。
checkpoints/belief_rule_bootstrap_10k_best.pt
checkpoints/belief_rule_bootstrap_10k_final.pt
checkpoints/policy_value_rule_bootstrap_10k_best.pt
checkpoints/policy_value_rule_bootstrap_10k_final.pt
短い smoke は次。
bash scripts/train_rule_bootstrap_chunks.sh \
--chunks 1 \
--checkpoint-prefix rule_bootstrap_smoke \
--no-final-aliases
注意点¶
notebook 由来 agent は特定 deck 前提の実装が多い。相性が低い deck は割り当てない。暗黙の
generic_advanced_heuristic fallback は使わないため、互換 deck / archetype / required
cards の登録を明示的に整える。