CoolFace
Modelpublic

brpoplpush/quantik-attn-d192-b6

sourceHugging Facecc-by-nc-4.0updated 28d agoView on Hugging Face
1likes25downloads
Model Card

attn-d192-b6

A policy/value network for Quantik, 1,800,709 parameters.

Quantik is a two-player game on a 4x4 board with four piece shapes. A player may not place a shape in a row, column or 2x2 zone where that shape already appears, whoever played it — so a move can be blocked by your own piece. The first player to complete a line or zone holding all four distinct shapes wins. There are no draws.

This model predicts, for a given position, which move an exact solver would play (policy) and who is winning (value).

About this project

Quantik began as a holiday rivalry and became an engineering project. Before building an AI to play — or teach — the game, the game itself had to be represented precisely: an exact notation, a canonical form under the board's 192 symmetries, and a bitboard the rules can be computed on cheaply.

That foundation is what these models are trained on. Every label is exact, produced by a solver rather than by self-play, so the network fits ground truth instead of its own earlier opinions. The engineering is written up as a series on The Full-Stack Mind: first-principles representation, then Monte-Carlo search, beam search, exact endgame proof, and a tournament where the engines finally played each other.

  • —Series: <https://mauroberlanda.substack.com/t/quantik>

Architecture

A self-attention encoder over the sixteen cells. The same bet as the constraint model without the prior: it is told nothing about rows, columns or zones and has to discover them.

mermaid
flowchart LR
  IN["board<br/>(B,9,4,4)"] --> TOK["16 cell tokens<br/>Linear 9→D + learned position"]
  TOK --> BLK
  subgraph BLK["pre-norm encoder block × B"]
    direction LR
    N1["LayerNorm"] --> MHA["multi-head self-attention"]
    MHA --> R1["+ residual"]
    R1 --> N2["LayerNorm"] --> FF["FFN"] --> R2["+ residual"]
  end
  BLK --> PH["policy head<br/>Linear D→4 per cell<br/>transpose → 64"]
  BLK --> VH["value head<br/>mean over cells · MLP · tanh"]
  PH --> POL["policy logits (B,64)"]
  VH --> VAL["value (B,)"]
blocks6
d_model192
ff_multiplier2
heads4
value_hidden64
parameters1,800,709

Every architecture in this family is matched to within 1.2% on parameter count, so a comparison between them is about the design and not about capacity.

Results

metricvalue
Held-out optimal-move accuracy, plies 4-60.9102
Held-out optimal-move accuracy, plies 7-120.9914
Arena win rate vs the field (1800 games)54.2%

Held-out accuracy is measured on exactly solved positions sharing no canonical key with the training corpus, up to the 192 board symmetries — so it measures generalisation, not recall. It is reported split rather than pooled because the corpus contains nothing at the shallowest plies, and a pooled figure is dominated by deep positions where every model is near perfect.

Input and output contract

input   (B, 9, 4, 4) float32      tensor-board.v1, mover-relative
output  (B, 64) policy logits     action_index = shape * 16 + position
        (B,)    value in [-1, 1]  +1 = good for the side to move

Planes 0-3 are the side to move, 4-7 the opponent, 8 a ply indicator. position = row * 4 + col.

Legality masking happens outside this model

It emits logits over all 64 actions, including illegal ones. Applying the legal-move mask before the softmax is the caller's job. An unmasked `argmax` from this model will play illegal moves — silently, because an illegal move looks like a bad move rather than like a bug.

This is by design. Quantik's rules are exact and cheap to compute in quantik-core, so the network is never asked to approximate them and never spends capacity on legality.

Usage

There is no AutoModel for this architecture — the Hub cannot reconstruct it from weights alone. Two supported paths.

With quantik-models

Reads manifest.json and rebuilds the network from architecture_spec, and gives you the legality masking for free.

bash
# quantik-models is not on PyPI yet; install it from source.
pip install 'quantik-models[torch] @ git+https://github.com/mberlanda/quantik-models-py'
pip install huggingface_hub
python
from huggingface_hub import snapshot_download
from quantik_models.arena.registry import load_evaluator
from quantik_models.env import fastboard as fb

evaluator = load_evaluator(snapshot_download("brpoplpush/quantik-attn-d192-b6"), "cpu")

boards = fb.empty_boards(1)                    # (1, 8) uint16
policy, value = evaluator.evaluate(boards)     # masking applied

With ONNX Runtime, and neither torch nor this package

bash
pip install onnxruntime numpy huggingface_hub
python
import numpy as np, onnxruntime as ort
from huggingface_hub import hf_hub_download

path = hf_hub_download("brpoplpush/quantik-attn-d192-b6", "model.onnx")
session = ort.InferenceSession(path)

# (B, 9, 4, 4) float32, mover-relative — see the contract above.
tensors = np.zeros((1, 9, 4, 4), dtype=np.float32)
policy, value = session.run(None, {"board": tensors})

# The mask is yours to apply. `legal` is a (B, 64) bool array;
# quantik_models.env.fastboard.legal_masks computes it, and so
# does quantik-core in Rust.
# policy = np.where(legal, policy, -np.inf)

The rules engine

Legality, symmetry and the exact solver live in quantik-core, which is published for both languages and is what generated the training labels.

bash
pip install quantik-core     # Python, >=3.12
cargo add quantik-core       # Rust, 2021 edition

How it was trained

corpusexact-sampled.npz
architecture presetmedium
epochs16
batch size1024
learning rate0.0006 (cosine to 1e-05)
weight decay0.0001
seed20260828
symmetry augmentationyes
ply-balanced samplingyes

Labels are exact, not bootstrapped: every training target comes from a solved position, so the network is fitting ground truth rather than its own earlier opinions.

The learning rate is a property of the architecture rather than a project-wide default. A single shared rate is not equal treatment between architectures — it privileges whichever one it was chosen for — and correcting that in this project reversed several conclusions rather than merely shifting decimals. Ply-balanced sampling gives every game stage equal attention instead of attention proportional to how many positions it happens to contribute. The corpus is dominated by late positions; the match is decided early.

Limitations

Accuracy is not uniform across the game. Deep positions are nearly forced and every model in this family is close to perfect there; the shallow openings are where they differ and where they are weakest.

plyaccuracy on provably won positions
40.8693
50.8971
60.9615
70.9848
80.9910
90.9923
100.9958
110.9932
121.0000

Weakest at ply 4 (86.9%), strongest at ply 12 (100.0%).

The evaluation is against solved positions and other engines, not against people. Nothing here says how it plays against a human.

One training seed. Every number on this card comes from a single run of this architecture.

Files

  • —model.safetensors — sha256:3b72617e91bf3a77ffb2a16cf40073848866f7a4f68cbb785604e7098e101989
  • —model.onnx — opset 18, sha256:c77dc137540de3726a4f298ab5a8b2a2cbe141f8a57a2cb2c403dcc02e4d4f7c, dynamic batch dimension
  • —config.json — the architecture spec, readable without loading anything
  • —manifest.json — the model-checkpoint.v1 record this repo was staged from
  • —training-report.json — the epoch that produced these weights, and its metrics

Contract version 1.2.0. Exported 2026-08-29.

Other models in this family

Same contract, same corpus, same training protocol — interchangeable at the interface, so they can be compared directly.

Source

  • —Model code and training: https://github.com/mberlanda/quantik-models-py
  • —Rules engine (Python): https://github.com/mberlanda/quantik-core-py
  • —Rules engine (Rust): https://github.com/mberlanda/quantik-core-rust
  • —Shared schemas: https://github.com/mberlanda/quantik-core-contracts

Licence

The weights in this repository are CC BY-NC 4.0. Free to use, share and adapt for research, teaching and any other non-commercial purpose, with attribution. Commercial use requires a separate agreement — open an issue on the source repository or contact the author.

This is deliberately not an OSI-approved open-source licence. Every OSI licence permits royalty-free commercial use, which is the one thing this reserves.

The code is separate and more permissive. quantik-models and quantik-core are MIT, so the training pipeline, the rules engine and the evaluation harness carry no such restriction — only these weights do.