Skip to content
Open
Show file tree
Hide file tree
Changes from 21 commits
Commits
Show all changes
134 commits
Select commit Hold shift + click to select a range
6a3fb21
docs(jax-migration): add from-scratch parity-bar migration plan
thomas-schweich May 23, 2026
d78c652
docs(jax-migration): add Invocation block for /review-driven-developm…
thomas-schweich May 23, 2026
d7d6d54
feat(jax-migration): [jax-migration S1] foundation — JAX deps + orien…
thomas-schweich May 23, 2026
6f6089c
feat(jax-migration): [jax-migration S2] JAX core — config + supernet …
thomas-schweich May 23, 2026
14703bc
feat(jax-migration): [jax-migration S3] pydantic run_config — keystone
thomas-schweich May 23, 2026
2090ebf
feat(jax-migration): [jax-migration S4] MetricsLogger — torch-free JS…
thomas-schweich May 23, 2026
c77ed1e
feat(jax-migration): [jax-migration S5] Corpus + Lichess data
thomas-schweich May 23, 2026
d7cb0aa
feat(jax-migration): [jax-migration S6] pretraining trainer — lax.sca…
thomas-schweich May 23, 2026
aafb65f
feat(jax-migration): [jax-migration S7] adapter trainer + 8 strategies
thomas-schweich May 23, 2026
0a77ee8
feat(jax-migration): [jax-migration S8] eval surface — accuracy + pro…
thomas-schweich May 23, 2026
3e9702e
feat(jax-migration): [jax-migration S11] PAD-init engine token buffers
thomas-schweich May 23, 2026
e37ac58
feat(jax-migration): [jax-migration S12] lifecycle — SIGTERM + HF pus…
thomas-schweich May 23, 2026
f1aa7da
feat(jax-migration): [jax-migration S10] compatibility loader — v1 Py…
thomas-schweich May 23, 2026
dc3016b
feat(jax-migration): [jax-migration S9] sweep + lab + dashboard + wandb
thomas-schweich May 23, 2026
816ba86
feat(jax-migration): [jax-migration S13] scripts + data tools
thomas-schweich May 23, 2026
12d1213
feat(jax-migration): [jax-migration S14] docs + deploy v2 examples
thomas-schweich May 23, 2026
e20f120
feat(jax-migration): [jax-migration S15] comprehensive tests — full s…
thomas-schweich May 23, 2026
b89d4fa
feat(jax-migration): [jax-migration S16-prep] port benchmark.py + DEF…
thomas-schweich May 23, 2026
0840b14
feat(jax-migration): [jax-migration S16-fix] adapter val_loss + neste…
thomas-schweich May 23, 2026
014b436
chore(jax-migration): [jax-migration S16-cleanup] delete v1 GONE-BY-D…
thomas-schweich May 23, 2026
6bf5dc7
fix(jax-migration): [jax-migration S16-review] address multi-lane rev…
thomas-schweich May 23, 2026
92d618b
fix(jax-migration): [jax-migration S16-pr-review] address PR #115 cod…
thomas-schweich May 23, 2026
e0462dd
fix(jax-migration): [jax-migration S16-loop-r1] address loop round-1 …
thomas-schweich May 23, 2026
0c6fc72
fix(jax-migration): [jax-migration S16-loop-r2] daemon executor + tim…
thomas-schweich May 23, 2026
187eb99
fix(jax-migration): [jax-migration S16-loop-r3] pop workers from _thr…
thomas-schweich May 23, 2026
eee69b7
fix(jax-migration): [jax-migration S16-loop-r4] normalise numpy-scala…
thomas-schweich May 23, 2026
3129f83
feat(jax-migration): [parity-#1+#2+#3] CLI compat + bf16 + public API…
thomas-schweich May 24, 2026
6d49e53
perf: wire compute_dtype through scripts/benchmark.py
thomas-schweich May 24, 2026
381e3ab
docs(jax-migration): [parity-#4] re-verify §3 acceptance criteria wit…
thomas-schweich May 24, 2026
936523e
feat(jax-migration): [parity-#5] port adapter behavior fully
thomas-schweich May 24, 2026
ebc6a7d
feat(jax-migration): [parity-#6,#11] real AR generation + full edge-c…
thomas-schweich May 24, 2026
31de0bb
fix(jax-migration): [parity-#7] restore v1 GPU metric field names
thomas-schweich May 24, 2026
93dd992
test(jax-migration): [parity-#8] port deleted v1 tests as parity guards
thomas-schweich May 24, 2026
2242f29
docs(jax-migration): [parity-#9] rewrite DEFERRALS.md + correct final…
thomas-schweich May 24, 2026
3a0f8e2
feat(jax-migration): [parity-#43] opt-in jax.nn.dot_product_attention…
thomas-schweich May 24, 2026
b1b03b3
feat(jax-migration): [DEFERRALS follow-ups] KV cache + bottleneck res…
thomas-schweich May 24, 2026
7c9a1b5
fix(jax-migration): round-1 review fixes on DEFERRALS follow-ups
thomas-schweich May 25, 2026
cf72008
fix(jax-migration): round-2 review fixes on DEFERRALS follow-ups
thomas-schweich May 25, 2026
083b963
fix(jax-migration): round-3 review fixes on DEFERRALS follow-ups
thomas-schweich May 25, 2026
03b9838
fix(jax-migration): round-4 review fixes on DEFERRALS follow-ups
thomas-schweich May 25, 2026
be59a6d
perf(jax-migration): close the v1 perf gap and pull ahead on CUDA + ROCm
thomas-schweich May 27, 2026
474c4a9
perf(jax-migration): round-2 multi-agent fixes (Tier 1+2, plus empiri…
thomas-schweich May 27, 2026
2ad3d52
perf(jax-migration): round-3 Tier 1 fixes — bandwidth, optimizer, RoP…
thomas-schweich May 27, 2026
8c2a598
perf(jax-migration): round-4 A1+A3 ship, A2 empirically rejected
thomas-schweich May 27, 2026
1af5737
chore(jax-migration): housekeeping commit — A1-on-by-default, drop le…
thomas-schweich May 28, 2026
5246e02
perf(jax-migration): A.1 length bucketing K=3 + cost-curve harness + …
thomas-schweich May 28, 2026
6b8bf29
feat(jax-migration): C.5 — per-step grad-norm emission + clip-trigger…
thomas-schweich May 28, 2026
974e25f
perf(jax-migration): A.2 outcome-column trim + C.4 gradient accumulation
thomas-schweich May 28, 2026
c0c734a
feat(jax-migration): C.1 — optimizer choice (Lion alongside AdamW)
thomas-schweich May 28, 2026
e391b3b
feat(jax-migration): B.5 — variant-specific depth slicing + A.1 stage…
thomas-schweich May 28, 2026
384cd9a
fix(jax-migration): silence pyright errors in _branchless_clip_by_glo…
thomas-schweich May 28, 2026
9867ff0
fix(jax-migration): update Caddy 2.11.2 SHA + 5090 bench runner script
thomas-schweich May 28, 2026
8bce7ae
feat(jax-migration): --optimizer CLI flag + Lion path in 5090 bench r…
thomas-schweich May 28, 2026
cbb4ca1
fix(deploy): trim Docker build context + self-clean SHA tags after push
thomas-schweich May 28, 2026
efc69ca
fix(deploy): generate SSH host keys before sshd in runtime entrypoint
thomas-schweich May 28, 2026
929ab81
fix(deploy): make vast.sh readiness probe robust to broken CLI + null…
thomas-schweich May 28, 2026
44c49a7
fix(deploy): harden authorized_keys perms so sshd StrictModes accepts…
thomas-schweich May 28, 2026
55e8855
fix(deploy): extend vast.sh readiness wait to ~12.5 min for cold imag…
thomas-schweich May 28, 2026
f4cfb1b
fix(bench): PYRUN-configurable launcher in run_5090.sh for runtime image
thomas-schweich May 28, 2026
d10a64e
fix(bench): step-3 batch fits 32GB + non-fatal runs + stage gating
thomas-schweich May 28, 2026
425bb3f
bench(5090): 44c49a7 results — cost curve, fwd/bwd matrix, end-to-end…
thomas-schweich May 28, 2026
c35a4ce
fix(ci): install lab+wandb extras so Pyright resolves optional imports
thomas-schweich May 28, 2026
5470427
fix(ci): add --extra dashboard so dashboard tests run
thomas-schweich May 28, 2026
5f5cfa0
test(ci): drop deleted convert_published_checkpoints from smoke SCRIPTS
thomas-schweich May 28, 2026
2eb5836
fix(lichess): gate bulk-download fallback behind PAWN_ALLOW_BULK_DOWN…
thomas-schweich May 29, 2026
8c9c2d1
docs(v2): phase-A redesign plan + implementation spec
thomas-schweich May 29, 2026
ecfa2f8
feat(v2): format core — uniform V=2000 vocab + BOS/NULL, un-factor + …
thomas-schweich May 29, 2026
c4a770d
feat(v2): conditioning prefix + loss-mask/position contract — fixed-w…
thomas-schweich May 30, 2026
37a9e1a
feat(v2): trainer/eval/generation for the new format — reserved-colum…
thomas-schweich May 30, 2026
a6f5cb0
fix(train): thread cfg.conditioning into training corpus builders
thomas-schweich May 30, 2026
69df2d6
fix(phase-a): wire load-time C-mismatch assert into resume + adapter …
thomas-schweich May 30, 2026
735cee3
test(phase-a): pin SAVED_FIELDS to 12-field un-factor/tie schema
thomas-schweich May 30, 2026
d83606f
chore(v2): gitignore + untrack accidentally-committed bench results a…
thomas-schweich May 30, 2026
6ec224b
docs(v2): Phase B-E implementation specs
thomas-schweich May 30, 2026
5c8daec
feat(v2-B): distillation-canonical trainer — injectable teacher logit…
thomas-schweich May 30, 2026
2745f48
fix(v2-B): trainer parity — max_grad_norm wired + did_clip, grad-accu…
thomas-schweich May 30, 2026
f3f7229
feat(v2-B): supernet quality-parity harness (plan §7 Alt #1)
thomas-schweich May 30, 2026
08d3c55
test(v2-B): end-to-end distill script smoke + C-mismatch guard (TA-1)
thomas-schweich May 30, 2026
f9e57ff
fix(v2-B): validate --resume sidecar before JAX device init (determin…
thomas-schweich May 30, 2026
43595a1
perf(v2-C): enable JAX persistent compilation cache for the test suit…
thomas-schweich May 30, 2026
f502650
fix(v2-C): real FiLM via hooks (gamma*h+beta residual + V-wide output…
thomas-schweich May 30, 2026
22d7453
fix(v2-C): adapter resume — no warm opt-state on cold adapter params,…
thomas-schweich May 30, 2026
906e586
perf(v2-C): adapter K-step lax.scan loop + step_time resume fix (H11,…
thomas-schweich May 30, 2026
8e592b2
refactor(v2-C): consolidate adapter save dispatch into write_adapter_…
thomas-schweich May 30, 2026
bd8a83d
fix(v2-D): edge-case off-by-one (H5) + real linear probes (H6)
thomas-schweich May 30, 2026
e84ec34
fix(v2-D): observability — schedule_health.json (H7), wandb wiring, s…
thomas-schweich May 30, 2026
274f211
chore(v2-D): diagnostics + eval cleanup (8.3/8.4)
thomas-schweich May 30, 2026
f604927
fix(v2-E): sweeps — --config param passing + conditioning migration +…
thomas-schweich May 30, 2026
caf6a53
feat(v2): --variants flag for train_jax — train a subset of supernet …
thomas-schweich May 30, 2026
848445b
feat(v2): peak-LR sweep driver for the standalone large teacher pretrain
thomas-schweich May 31, 2026
0cabb02
docs(v2): replace stale JAX_PARITY_SHORTFALLS with gated V2_PARITY_AUDIT
thomas-schweich May 31, 2026
ecff5c6
fix(v2-parity/config-cli): Config & CLI surface parity
thomas-schweich May 31, 2026
50f3815
fix(v2-parity/metrics-dashboard): metrics schema, logging, dashboard …
thomas-schweich May 31, 2026
b937dab
docs(v2): mark metrics train/loss row resolved in parity audit
thomas-schweich May 31, 2026
29b1505
fix(v2-parity/pretrain-loop): Supernet pretraining: validation loop, …
thomas-schweich May 31, 2026
6bd1c71
fix(v2-parity/adapter-loop): Adapter training: legal-mask loss, illeg…
thomas-schweich May 31, 2026
6ad28ed
fix(v2-parity/adapter-strategies-rosa): Adapter strategy & RoSA polish
thomas-schweich May 31, 2026
a92fb57
fix(v2-parity/distill): Distillation trainer: resume, wandb, schedule…
thomas-schweich May 31, 2026
f37352c
fix(v2-parity/eval-accuracy-elo): Move-accuracy + Elo-stratified eval…
thomas-schweich May 31, 2026
2e7a900
fix(v2-parity/probes): Linear probes: feature coverage, regression pr…
thomas-schweich May 31, 2026
be42b04
fix(v2-parity/generation-diagnostics): Generation diagnostics: restor…
thomas-schweich May 31, 2026
fba2403
fix(v2-parity/edge-case-diagnostics): Edge-case diagnostics: schema c…
thomas-schweich May 31, 2026
52fd1e0
fix(v2-parity/lichess-data): Lichess data pipeline: carve-from-train,…
thomas-schweich May 31, 2026
85b4706
fix(v2-parity/lab-runner-core): TrialRunner daemon: scheduling, lifec…
thomas-schweich May 31, 2026
68d5201
fix(v2-parity/lab-mcp-tools): Lab MCP server: re-expose the 8 missing…
thomas-schweich Jun 1, 2026
d9d18a5
fix(v2-parity/lab-sweep): Lab sweep module: builtin_distributions + i…
thomas-schweich Jun 1, 2026
08d01f2
merge(v2-parity): lab subsystem rebuild (TrialRunner + MCP tools + sw…
thomas-schweich Jun 1, 2026
95b144a
fix(v2-parity/checkpoint-hf): Checkpoint/HF: hf_bucket mode, per-run …
thomas-schweich Jun 1, 2026
e69e3e7
fix(v2-parity/sweeps): Optuna sweeps: mid-trial pruning, search space…
thomas-schweich Jun 1, 2026
5f1adae
fix(v2-parity/perf-bench): Performance: benchmark.py engine calls, am…
thomas-schweich Jun 1, 2026
cd26c09
fix(v2-parity/data-tools-engine): Data tools + engine PAD-init: model…
thomas-schweich Jun 1, 2026
7086944
fix(v2-parity/public-api-cli): Public API & CLI compat: wrappers, --v…
thomas-schweich Jun 1, 2026
0d88d44
docs(v2-parity/legacy-converter-design): reconcile docs with the as-b…
thomas-schweich Jun 1, 2026
18a0047
fix(v2): untie output head by default — fixes single-step output coll…
thomas-schweich Jun 5, 2026
cda3f8a
fix(v2): restore v1 numerical recipe — fixes from-scratch pretrain co…
thomas-schweich Jun 6, 2026
6f8ec58
Mid-run perf improvements for stability changes
thomas-schweich Jun 6, 2026
9ffaa61
feat(v2): flash-attn fp32 custom-VJP backward (fixes pretrain diverge…
thomas-schweich Jun 8, 2026
0455387
feat(v2): teacher-forced compound (game-completion) legality eval
thomas-schweich Jun 8, 2026
4a2dc9e
fix(v2): compound-legality round-2 review fixes (game-completion no l…
thomas-schweich Jun 8, 2026
5f6c622
exp: autoregressive compound-legality runner
thomas-schweich Jun 8, 2026
68e9ee2
exp: vendored Pallas attention with fp32 softmax-gradient backward
thomas-schweich Jun 8, 2026
9c5e09b
exp: route _pallas_attn to vendored fp32-bwd kernel under PAWN_FLASH_…
thomas-schweich Jun 8, 2026
a41ee21
exp: resurrect factored v1 model + in-memory converter (v1 AR-legality)
thomas-schweich Jun 9, 2026
3bb5b68
exp: v1 teacher-forced legality eval (gate PASSED — conversion valida…
thomas-schweich Jun 9, 2026
5e02316
exp: v1 native AR game-completion runner (65.9% vs v2 34.6%)
thomas-schweich Jun 9, 2026
15e983d
merge: exp/ar-compound-legality — v2 AR game-completion runner (34.6%)
thomas-schweich Jun 10, 2026
d2a1ae3
merge: exp/flash-kernel-fp32-bwd — vendored fp32-bwd Pallas kernel (1…
thomas-schweich Jun 10, 2026
aa415c2
merge: exp/v1-ar-legality — factored v1 loader + teacher-forced/AR le…
thomas-schweich Jun 10, 2026
5df0309
fix(vendor): type the custom_vjp-erased mha return at the _mha_forwar…
thomas-schweich Jun 10, 2026
fd6504a
feat(v2): factored-embedding (v1-architecture) training pipeline — LR…
thomas-schweich Jun 10, 2026
623dd47
fix(factored): round-1 review fixes (arch guards, flash hard-reject, …
thomas-schweich Jun 10, 2026
ae48fec
fix(factored): round-2 review fixes (loud OOV embed guard, v2-dir rou…
thomas-schweich Jun 10, 2026
4c0752b
fix(factored): round-3 review fix — eval_jax adapts corpora for facto…
thomas-schweich Jun 10, 2026
e026900
fix(factored): round-4 review fixes (class↔config consistency guards)
thomas-schweich Jun 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -76,3 +76,6 @@ runs/

# Codex review scratch file (ephemeral, sometimes left behind by `codex review`)
.codex

# Rust scratch binaries (e.g. `rustc -o rust_out`)
/rust_out
652 changes: 329 additions & 323 deletions CLAUDE.md

Large diffs are not rendered by default.

15 changes: 15 additions & 0 deletions DEFERRALS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Deferrals

> Per `docs/jax_migration_plan.md` §9.4, a deferral is legitimate only
> when actually doing the work is *nonsensical, impossible, or actively
> detrimental*. Things on the §3 acceptance-criteria list cannot be
> deferred under any reason.

No deferrals.

The framework swap implements the full §3 acceptance-criteria contract.
Every v1 surface that existed on `main` has a v2 counterpart on this
branch — including `scripts/benchmark.py`, which was rewritten against
the JAX/Equinox/Optax stack (jit vs eager backbone steps, fresh-corpus
vs pre-staged data-pipeline bench, multi-process JAX concurrency
sweep, JAX adapter bench).
42 changes: 32 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Feel free to use PAWN in your own experiments. PAWN is developed as a personal p

## Model Variants

The model comes in three sizes, all trained from scratch on random chess games generated on-the-fly by a Rust-based chess backend. The v1.0.0 weights were trained together for 200K steps at batch size 256 on a single GPU — all three variants see the same random-game batches each step, with one forward/backward pass per variant in sequence (see [cotrain config](configs/cotrain_three_variants.json)). The numbers below come from the best 5K-cadence checkpoint by val loss (step 195,000 ≈ 49.9M sequences) for all three variants:
The model comes in three sizes, all trained from scratch on random chess games generated on-the-fly by a Rust-based chess backend. The v1.0.0 weights were trained together for 200K steps at batch size 256 on a single GPU — all three variants see the same random-game batches each step, with one forward/backward pass per variant in sequence. **The v1 numbers below come from the best 5K-cadence checkpoint by val loss (step 195,000 ≈ 49.9M sequences) for all three variants under the PyTorch stack. The v2 stack (JAX/Equinox/Optax) replaces multi-variant cotraining with the supernet's joint loss; v2 weights publish to new HF repos (`pawn-{small,base,large}-v2`).**

| Variant | d_model | Layers | Heads | Params | Top-1 | Legal rate | Game completion | Download |
|---------|---------|--------|-------|--------|-------|------------|-----------------|----------|
Expand Down Expand Up @@ -47,28 +47,50 @@ uv sync --extra cu128 # NVIDIA GPU (or --extra rocm for AMD)
Weights and data can be loaded directly from HuggingFace:

```bash
uv run python scripts/train.py --run-type adapter --strategy bottleneck \
uv run --extra rocm python scripts/train_jax_adapter.py \
--strategy bottleneck \
--checkpoint thomas-schweich/pawn-base \
--pgn thomas-schweich/pawn-lichess-full \
--bottleneck-dim 32 --lr 1e-4 --local-checkpoints
--bottleneck-dim 32 --lr 1e-4 --total-steps 200 --local-checkpoints
```

### Pretrain from scratch
The published `pawn-{small,base,large}` HF checkpoints are v1 PyTorch
artifacts — they're loaded through `pawn.legacy.convert_legacy_checkpoint`
which transposes weights into the v2 JAX layout. v2 republishes
under new HF repos (`pawn-{small,base,large}-v2` or similar).

### Pretrain the supernet

Random games are generated on-the-fly; no dataset required:

```bash
uv run python scripts/train.py --variant base --local-checkpoints

# Or train all three variants simultaneously on shared data
uv run python scripts/train.py --config configs/cotrain_three_variants.json
uv run --extra rocm python scripts/train_jax.py \
--supernet base --total-steps 100000 --batch-size 256 \
--local-checkpoints
```

The v1 cotrain path is GONE BY DESIGN — the supernet's joint loss
(`sum` of per-variant cross-entropies on the same batch) replaces it.

### Run probes and diagnostics

```bash
uv run python scripts/eval_probes.py --log-dir logs --device cuda
uv run python -m pawn.dashboard --log-dir logs # real-time monitoring
# Move accuracy + per-phase
uv run --extra rocm python scripts/eval_jax.py --checkpoint <converted-or-v2-dir>

# Linear probes
uv run --extra rocm python scripts/eval_probes_jax.py --checkpoint <converted>

# 5 generation diagnostics (all gated on outcome_prefix_trained)
uv run --extra rocm python scripts/eval_generation_jax.py \
--checkpoint <converted> --outcome-prefix-trained --edge-cases

# Elo-stratified Lichess accuracy
uv run --extra rocm python scripts/eval_vs_stockfish.py \
--checkpoint <converted> --pgn thomas-schweich/pawn-lichess-full

# Real-time monitoring
uv run --extra dashboard python -m pawn.dashboard --log-dir logs
```

## Architecture
Expand Down
6 changes: 3 additions & 3 deletions deploy/pod.sh
Original file line number Diff line number Diff line change
Expand Up @@ -326,8 +326,8 @@ cmd_launch() {
echo "Usage: $0 launch <name> <command...>"
echo ""
echo "Examples:"
echo " $0 launch exp1 scripts/train.py --variant base"
echo " $0 launch exp1 scripts/train.py --run-type adapter --strategy bottleneck \\"
echo " $0 launch exp1 scripts/train_jax.py --supernet base"
echo " $0 launch exp1 scripts/train_jax_adapter.py --strategy bottleneck \\"
echo " --checkpoint thomas-schweich/pawn-base --pgn thomas-schweich/pawn-lichess-full \\"
echo " --elo-min 1800 --elo-max 1900 --bottleneck-dim 32"
exit 1
Expand Down Expand Up @@ -389,7 +389,7 @@ case "${1:-}" in
echo " $0 create exp1 --gpu a5000"
echo " $0 create sweep1 --gpu a100-pcie --count 2 --community"
echo " $0 deploy exp1"
echo " $0 launch exp1 scripts/train.py --variant base"
echo " $0 launch exp1 scripts/train_jax.py --supernet base"
echo " $0 stop exp1"
;;
esac
6 changes: 3 additions & 3 deletions deploy/vast.sh
Original file line number Diff line number Diff line change
Expand Up @@ -622,8 +622,8 @@ cmd_launch() {
echo "Usage: $0 launch <name> <command...>"
echo ""
echo "Examples:"
echo " $0 launch exp1 scripts/train.py --variant base"
echo " $0 launch exp1 scripts/train.py --run-type adapter --strategy bottleneck \\"
echo " $0 launch exp1 scripts/train_jax.py --supernet base"
echo " $0 launch exp1 scripts/train_jax_adapter.py --strategy bottleneck \\"
echo " --checkpoint thomas-schweich/pawn-base --pgn thomas-schweich/pawn-lichess-full \\"
echo " --elo-min 1800 --elo-max 1900 --bottleneck-dim 32"
exit 1
Expand Down Expand Up @@ -685,7 +685,7 @@ case "${1:-}" in
echo " $0 create exp1 --gpu 4090 --max-price 0.5"
echo " $0 create cheap1 --gpu 3090 --interruptible"
echo " $0 deploy exp1"
echo " $0 launch exp1 scripts/train.py --variant base"
echo " $0 launch exp1 scripts/train_jax.py --supernet base"
echo " $0 stop exp1"
echo ""
echo "Setup:"
Expand Down
7 changes: 7 additions & 0 deletions docs/ACCURACY_CEILING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Theoretical Accuracy Ceiling

> **v1 metrics disclaimer.** All metrics and benchmarks attached to
> the published `pawn-{small, base, large}` HF repos are v1 PyTorch
> numbers. v2 republishes to new HF repos
> (`pawn-{small, base, large}-v2` or similar). The bridge that lets
> v2 code load the v1 repos is `pawn.legacy.convert_legacy_checkpoint`.


PAWN is trained on uniformly random chess games. At each position with
N legal moves, the next move is drawn uniformly from those N moves, so
the Bayes-optimal predictor (without outcome information) can do no
Expand Down
7 changes: 7 additions & 0 deletions docs/ADAPTERS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Adapter Methods

> **v1 metrics disclaimer.** All metrics and benchmarks attached to
> the published `pawn-{small, base, large}` HF repos are v1 PyTorch
> numbers. v2 republishes to new HF repos
> (`pawn-{small, base, large}-v2` or similar). The bridge that lets
> v2 code load the v1 repos is `pawn.legacy.convert_legacy_checkpoint`.


PAWN is designed as a testbed for parameter-efficient fine-tuning. The frozen ~36M-parameter backbone provides learned chess representations from pretraining on random games; adapters specialize those representations for downstream tasks like predicting human moves at a given Elo level.

All adapter implementations live in `pawn/adapters/`. Each wraps a frozen `PAWNCLM` backbone and exposes a uniform interface: `forward_hidden()`, `project_head()`, `forward()`, and `forward_generate()` (with KV-cache).
Expand Down
21 changes: 19 additions & 2 deletions docs/ARCHITECTURE.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# PAWN Architecture

> **v1 metrics disclaimer.** All metrics and benchmarks attached to
> the published `pawn-{small, base, large}` HF repos are v1 PyTorch
> numbers. v2 republishes to new HF repos
> (`pawn-{small, base, large}-v2` or similar). The bridge that lets
> v2 code load the v1 repos is `pawn.legacy.convert_legacy_checkpoint`.


PAWN (Playstyle-Agnostic World-model Network for Chess) is a causal transformer trained on random chess games via next-token prediction. It learns chess rules, legal moves, and board state representations purely from move sequences, with no hand-crafted features or external game databases.

This document describes the model architecture in detail.
Expand Down Expand Up @@ -82,7 +89,7 @@ x = x + FFN(RMSNorm(x))

A final RMSNorm is applied after the last transformer block, before the output projection.

**Attention.** Standard multi-head self-attention with no bias terms in any of the projection matrices (Q, K, V, output). Attention uses PyTorch's `scaled_dot_product_attention` with a causal mask combined with a padding mask. The padding mask ensures that PAD tokens are not attended to.
**Attention.** Standard multi-head self-attention with no bias terms in any of the projection matrices (Q, K, V, output). The v2 stack (JAX/Equinox/Optax) materialises the attention `QK^T` scores plainly with a causal × padding mask combined via `jax.numpy.where`; the v1 PyTorch stack used `torch.nn.functional.scaled_dot_product_attention`. At seq 512 attention is ~12% of step FLOPs and plain attention sidesteps fused-kernel maturity under JAX-on-ROCm. The padding mask ensures that PAD tokens are not attended to.

**Positional encoding.** [Rotary Position Embeddings (RoPE)](https://arxiv.org/abs/2104.09864) (Su et al., 2021) with base frequency 10000. RoPE is applied to the query and key vectors after projection, before the attention computation. Frequency tensors are precomputed for the full sequence length and stored as non-persistent buffers.

Expand All @@ -100,13 +107,23 @@ This uses three weight matrices per block instead of the standard two, with no b

## Model Variants

**v1 (published HF checkpoints — PyTorch):**

| Variant | d_model | Layers | Heads | Head dim | d_ff | Parameters |
|---------|---------|--------|-------|----------|------|------------|
| Small | 256 | 8 | 4 | 64 | 1024 | 8.94M |
| Base | 512 | 8 | 8 | 64 | 2048 | 34.65M |
| Large | 640 | 10 | 8 | 80 | 2560 | 66.91M |

All variants use the same vocabulary, sequence length (512), and architectural choices. They differ only in width, depth, and head count. A `toy` variant (d=64, 2 layers, 4 heads) exists for testing.
**v2 (JAX/Equinox/Optax — supernet + nested slices, all share depth + head_dim):**

| Variant | d_model | Layers | Heads | Head dim | d_ff |
|---------|---------|--------|-------|----------|------|
| Small | 256 | 10 | 4 | 64 | 1024 |
| Base | 512 | 10 | 8 | 64 | 2048 |
| Large | 640 | 10 | 10 | 64 | 2560 |

The v2 stack pins `head_dim = 64` so width slices align to whole heads and RoPE is variant-invariant; all variants share the supernet's depth (10 layers) so the inner `[:d_V, :d_V]` of every weight matrix gives a valid sub-model. A `TINY_SUPERNET` (d=192, 4 layers, 3 heads) exists for verification runs that don't need production scale.

The v1.0.0 parameter counts are slightly lower than the legacy `-legacy` repos with the same `d_model`/`n_layers`/`n_heads`, because the new 1,980-token vocabulary has roughly half the entries of the old 4,278-token vocab. The output projection (`lm_head`: `d_model → vocab_size`) is the only place vocab size enters the parameter count — factored input embeddings keep the input side compact regardless.

Expand Down
7 changes: 7 additions & 0 deletions docs/TRAINING.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Training Guide

> **v1 metrics disclaimer.** All metrics and benchmarks attached to
> the published `pawn-{small, base, large}` HF repos are v1 PyTorch
> numbers. v2 republishes to new HF repos
> (`pawn-{small, base, large}-v2` or similar). The bridge that lets
> v2 code load the v1 repos is `pawn.legacy.convert_legacy_checkpoint`.


## Prerequisites

- **Rust** (stable) -- required to build the chess engine native extension
Expand Down
Loading
Loading