File size: 4,760 Bytes
0946f34 f2582c0 0946f34 | 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 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | ---
license: agpl-3.0
language:
- en
base_model: UofTCSSLab/Maia3-79M
base_model_relation: quantized
tags:
- chess
- maia
- maia3
- chessformer
- move-prediction
- onnx
- onnxruntime-web
- webgpu
- fp16
---
# Maia3 ONNX (fp16 + fp32)
Browser-ready **ONNX** exports of the [**Maia3**](https://huggingface.co/collections/UofTCSSLab/maia3)
family of transformer models for human chess move prediction. Each of the four
size variants is provided in **fp16** (half-precision weights, the headline
quantized artifact) and **fp32** (full precision).
These are conversions of the original PyTorch checkpoints — same weights, same
predictions — repackaged so they run client-side with
[`onnxruntime-web`](https://onnxruntime.ai/docs/tutorials/web/) (wasm or WebGPU)
without a Python/PyTorch backend.
For the architecture, training recipe, and evaluation see the paper
[*Chessformer: A Unified Architecture for Chess Modeling*](https://openreview.net/forum?id=2ltBRzEHyd)
(ICLR 2026).
## Files
| Variant | Params | Base model | `fp16` | `fp32` |
|---------|-------:|------------|-------:|-------:|
| 3M | 3.2M | [Maia3-ablate-3M](https://huggingface.co/UofTCSSLab/Maia3-ablate-3M) | `maia3-3m-ablation.fp16.onnx` (6.7 MB) | `maia3-3m-ablation.fp32.onnx` (12.8 MB) |
| 5M | 5.2M | [Maia3-5M](https://huggingface.co/UofTCSSLab/Maia3-5M) | `maia3-5m.fp16.onnx` (10.8 MB) | `maia3-5m.fp32.onnx` (21.0 MB) |
| 23M | 22.9M | [Maia3-23M](https://huggingface.co/UofTCSSLab/Maia3-23M) | `maia3-23m.fp16.onnx` (45.8 MB) | `maia3-23m.fp32.onnx` (91.0 MB) |
| 79M | 78.9M | [Maia3-79M](https://huggingface.co/UofTCSSLab/Maia3-79M) | `maia3-79m.fp16.onnx` (156.1 MB) | `maia3-79m.fp32.onnx` (311.7 MB) |
The **fp16** files store weights in float16 (≈half the size) while keeping
float32 inputs/outputs, so they are numerically robust and a drop-in replacement
for the float32 graph.
## I/O contract
All models share one simplified signature:
```
inputs:
tokens float32 [batch, 64, 12] # current board only, piece-only one-hot channels
elo_self float32 [batch] # rating of the side to move
elo_oppo float32 [batch] # rating of the opponent
outputs:
logits_move float32 [batch, 4352] # move policy over the Maia3 move vocabulary
logits_value float32 [batch, 3] # [loss, draw, win] logits for the side to move
```
Positions are tokenized exactly as in the upstream Maia3 code (board mirrored when
Black is to move; move vocabulary of 4352 with 256 promotion entries). The single
64×12 board is replicated across the model's 8-position history internally, and the
ponder/timing head is dropped — matching the analysis export used by the Maia
platform frontend.
## Accuracy
Max per-position error of the **fp16** ONNX vs. the original **fp32** PyTorch
checkpoint (the fp32 ONNX matches PyTorch to ~1e-7):
| Variant | move-prob error | value-prob error |
|---------|----------------:|-----------------:|
| 3M | 1.3e-4 | 2.8e-4 |
| 5M | 1.7e-4 | 1.2e-4 |
| 23M | 6.9e-5 | 5.4e-4 |
| 79M | 9.6e-5 | 2.7e-4 |
## Usage (onnxruntime-web)
```js
import * as ort from 'onnxruntime-web'
// Load a variant (fp16 recommended for the browser)
const session = await ort.InferenceSession.create('maia3-79m.fp16.onnx', {
graphOptimizationLevel: 'basic', // see note below
executionProviders: ['webgpu'], // or ['wasm']
})
// tokens: Float32Array of length batch*64*12, elos: Float32Array length batch
const feeds = {
tokens: new ort.Tensor('float32', tokens, [batch, 64, 12]),
elo_self: new ort.Tensor('float32', eloSelf, [batch]),
elo_oppo: new ort.Tensor('float32', eloOppo, [batch]),
}
const { logits_move, logits_value } = await session.run(feeds)
```
**Optimization level:** set `graphOptimizationLevel: 'basic'`. ORT's aggressive
`all`/`extended` CPU fusions hit a known `SimplifiedLayerNormFusion` bug on fp16
cast boundaries in this graph; `basic` loads cleanly across ORT versions and is
what the browser runtime effectively uses.
## Conversion
Exported with PyTorch's ONNX exporter at **opset 17**, basic graph optimization
(constant folding + LayerNorm fusion, all default-domain ops), then weights
converted to float16 with float32 I/O preserved (`keep_io_types`). `RMSNorm` was
decomposed into opset-17 primitives prior to export.
## License
AGPLv3, inherited from the upstream Maia3 checkpoints.
## Citation
```bibtex
@inproceedings{monroe2026chessformer,
title={Chessformer: A Unified Architecture for Chess Modeling},
author={Daniel Monroe and George Eilender and Philip Chalmers and Zhenwei Tang and Ashton Anderson},
booktitle={The Fourteenth International Conference on Learning Representations},
year={2026},
url={https://openreview.net/forum?id=2ltBRzEHyd}
}
```
|