YAML Metadata Warning:empty or missing yaml metadata in repo card

Check out the documentation for more information.

ptcg-gpt

A 30M-parameter GPT trained on PokΓ©mon TCG game-event streams from the Kaggle pokemon-tcg-ai-battle ladder replays. The backbone is the unmodified transformer block stack from Andrej Karpathy's nanoGPT (see NOTICE.md); the input embedder and output heads are replaced to consume/produce structured game-stream tokens instead of text. Two checkpoints ship:

checkpoint analogy trained with use it for
models/pretrain_30m_v1 foundation model world-model pretraining: next-token prediction over entire game streams (events, board snapshots, menus) + outcome value continued pretraining-style finetunes, probing what the model knows about game dynamics, init for new SFT runs
models/sft_30m_v1 instruct model action SFT on top of the foundation: pointer-head cross-entropy against the expert's chosen menu option at decision points only picking actions β€” this is the "plays the game" checkpoint, and the default --init-from for further finetuning

The training data is per-seat, append-only token streams serialized from real ladder episodes (stream format v2, 18 float features per token β€” path9_gpt/STREAM_SPEC.md is the normative contract). One document = one (game, seat), averaging ~2.4–2.7k tokens per seat-game across the shipped corpora (individual seat-games range from ~150 to ~6k).

What this repo can and cannot do. It can ingest replays, train, finetune, and evaluate on held-out data. It cannot play games: the competition game engine (cg.dll), the self-play driver, the Kaggle submission exporter, and the arena all deliberately stay in the parent research repo. path9_gpt/agent.py ships as the reference inference implementation (incremental serializer + KV-cache), but there is nothing here to plug it into.

Results

Training (both on one RTX 3060):

run data tokens seen wall time headline val metrics (shared 525-episode holdout + temporal tail)
pretrain_30m_v1 mid+top tiers, 114,756 seat-docs / 293.8M train tokens 704.9M (3 epochs) 4.75 h composite val loss 0.5545 (next-card CE 0.179, next-token-type CE 0.003, next-enum CE 0.035, value MSE 0.676) β€” still improving at schedule end
sft_30m_v1 top tier only, 17,948 docs / 1.42M decisions (+10% pretrain-replay mixture) 85.5M (2 epochs) 34 min top-1 single 0.704 Β· multi exact-set 0.619 Β· multi per-pick 0.816 Β· value MSE 0.637

Playing strength, measured in the parent repo's arena (not reproducible here β€” no engine):

opponent win rate
develop_first (rule-based baseline) 97.3%
prior best search-distilled agent 82.8% [78.3, 86.6] over 320 games
path5 board-snapshot behavior-cloning model 70.0% [62.5, 76.6]

Caveats that apply to any number you produce yourself: 100-game win rates carry roughly Β±10 pp of noise β€” use 300+ games before claiming anything; and argmax-vs-argmax mirror matches between behavior-cloned siblings are a degenerate evaluation (they swing wildly and mean nothing).

Quickstart

pip install -r requirements.txt
python -m pytest                      # from the repo root; needs torch

Load a checkpoint:

from path9_gpt.model import load_model

model = load_model("models/sft_30m_v1/best.pt").eval()
# checkpoints are self-describing {"state_dict", "config"} dicts (fp32, model-only)

Smoke-train on the bundled sample corpus (108 episodes, 522k tokens, mid tier). Commands are kept on one line so they paste into PowerShell as well as bash:

python -m path9_gpt.pack --data data/sample     # regenerate data/sample/packed/
python -m path9_gpt.train_pretrain --data data/sample --out runs/smoke --preset 7M --epochs 1 --lr 3e-4 --min-lr 3e-5 --batch-tokens 16384 --micro-batch-tokens 8192 --ctx-dropout 0.35 --device auto

(Add --n-layer 2 --n-embd 64 --n-head 2 to override the preset and make it near-instant on CPU.)

Finetune from a shipped checkpoint on your own data:

python -m path9_gpt.train_sft --init-from models/sft_30m_v1 --data <your_top_tier_dir> --out runs/sft_v2 --epochs 2 --lr 1e-4 --min-lr 1e-5 --warmup-frac 0.03 --batch-tokens 65536 --micro-batch-tokens 8192 --ctx-dropout 0.35 --val-episodes models/val_episodes_v1.txt --device cuda

Always pass --val-episodes models/val_episodes_v1.txt β€” it pins the shared holdout the shipped numbers were measured on, so those episodes never leak into your training set and your val numbers stay comparable. See docs/FINETUNING.md for the full ingest β†’ pack β†’ train walkthrough and docs/DESIGN.md for the architecture and the lessons/pitfalls list.

Repo layout

path what
path9_gpt/ the package (name kept from the parent repo for checkpoint/tooling compatibility)
path9_gpt/STREAM_SPEC.md normative wire-format contract (stream v2): token grammar, feature layouts, ingest record schema
path9_gpt/BRIEF.md historical working notes from the parent repo
path9_gpt/vocab.py vocab constants + card-attribute feature matrix loader (card_features_v1.npz ships in-package; --build needs the parent repo's engine, see docs)
path9_gpt/stream.py StreamSerializer β€” single implementation shared by offline serialization and live inference
path9_gpt/ingest.py raw episode JSONs (or datagen shards) β†’ stream shards, with dedup, tier/day stamping; --oracle stores hidden-info labels in the records (unused by the v1 trainers β€” reserved for future aux losses)
path9_gpt/replay_compat.py vendored replay-parsing helpers from the parent repo (keeps this repo engine-free)
path9_gpt/pack.py / dataset.py one-time columnar pack of a dataset dir; memmap-backed loading, length-bucketed batching
path9_gpt/model.py nanoGPT blocks (vendored, unmodified) + structured embedder + pointer/value/world-model heads + KV-cache path
path9_gpt/train_pretrain.py / train_sft.py stage 1 / stage 2 training CLIs
path9_gpt/agent.py reference inference agent (serializer + KV cache + fallback chain) β€” no engine here to run it against
path9_gpt/audit_value.py / deck_stats.py / bench_latency.py value-head calibration audit Β· corpus deck statistics Β· CPU latency bench
tests/ pytest suite (engine-free, fully self-contained: data/sample feeds the pack tests, data/raw_episodes_sample feeds the golden-parity/grammar tests)
models/pretrain_30m_v1/, models/sft_30m_v1/ best.pt (fp32, model-only) + report.json + log.jsonl each
models/val_episodes_v1.txt the shared 525-episode holdout list β€” pass to every training run
data/sample/ 108-episode sample corpus (216 seat-docs, 15,657 decisions, 522,262 tokens); packed/ is regenerable
data/raw_episodes_sample/ 4 raw ladder episode JSONs (gzipped, with visualize) β€” standalone input for the serializer contract tests and a tiny ingest --src smoke
scripts/shrink_fp16.py fp32 β†’ fp16 checkpoint shrink (see below)
docs/ DESIGN.md, FINETUNING.md, the original 2026-07-20 planning doc

Note for GitHub

Each best.pt is 121 MB fp32, which is over GitHub's 100 MB per-file hard limit. This repo is therefore initialized with git-lfs tracking models/**/*.pt (see .gitattributes), so pushing to GitHub works as-is β€” but anyone cloning needs git-lfs installed to get real checkpoints instead of LFS pointer files. If you would rather not depend on LFS, run scripts/shrink_fp16.py to produce an fp16 copy (~61 MB, fits under the limit; fp16 rounding changes logits marginally β€” keep the fp32 original around for training resumes and exact reproduction) and commit that instead.

Licensing

  • This repo has no license yet. Default copyright applies (all rights reserved) β€” pick a license before publishing anywhere public.
  • The transformer blocks inside path9_gpt/model.py derive from nanoGPT and are MIT-licensed β€” attribution and license text in NOTICE.md.
  • The training data derives from Kaggle ladder replays of the pokemon-tcg-ai-battle competition (this includes data/sample/ and data/raw_episodes_sample/). Check the competition's data/terms of use before redistributing any of it or models trained on it beyond this circle.
Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. πŸ™‹ Ask for provider support