File size: 1,592 Bytes
4112ceb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
---
license: mit
tags:
  - chess
  - mixture-of-experts
  - transformer
  - recurrent
  - policy
  - pytorch
library_name: pytorch
---

# Chess MoE (five 99M experts + router)

Jointly trained Switch MoE. Five **99M** squares64 specialists plus a small
MLP router on the incumbent `global_hidden`. Compact vocab 1968.

This file is **`latest.pt` at step 550** (2026-09-14 20:15 UTC).
Train loss ~2.4342. Val hard CE ~1.2483.

## Elo

Search-free greedy policy (legal-masked argmax). No book, no Syzygy, no MCTS.
Opponent: Stockfish 19 `UCI_LimitStrength` / `UCI_Elo`, movetime=0.05s, ply cap 160.
This is **not** FIDE or Lichess Elo.

**Estimate: 2028 UCI_Elo**.

| SF UCI_Elo | Score | W-D-L | Ply-cap (counted as draw) |
|---|---|---|---|
| 2050 | 0.469 (32g) | 10-10-12 | 1 |

_logistic from 32 games vs 2050 score=0.469_

## Experts

- `incumbent`
- `puzzle`
- `endgame`
- `opening`
- `middlegame`

Router: LayerNorm → 736→256→256→5 (~257,221 params).
Hard argmax dispatch. Incumbent encode is reused if the gate picks it.

## Files

- `latest.pt` — full bundle (router + all five expert state dicts)
- `router.pt` — router head only
- `experts/<name>.pt` — each 99M specialist
- `router_config.json`
- `train.log`
- `elo_eval.json` (if present)

Load with this repo and `MOVE_VOCAB_VERSION=compact`:

```python
from chess_inference import load_checkpoint, get_model_move
model = load_checkpoint("latest.pt", device="cuda")
```

Not a drop-in replacement for the standalone incumbent / puzzle / endgame /
opening / middlegame repos. Those stay as the pre-joint specialists.