Gavel Snake β tiny typed-decision models (capability demo)
Snake is just the demo vehicle β it showcases what Gavel is capable of, not
a product in itself. These models exist for one job: playing Snake inside
Gavel's live demo. Each move
of the game is a typed decision (up | down | left | right) made by one of
these small locally-trained classifiers β no text generation, no cloud API.
They prove the pattern; Gavel is the product.
Gavel itself is the open typed-decision layer for AI agents (typed questions in, calibrated decisions out; small supervised models instead of LLM calls for work that isn't generative). Full method, training scripts, and measured numbers in the Snake cookbook.
Metrics (all measured, see cookbook for method and caveats)
Val accuracy = agreement with the teacher policy on held-out states. Latency = batch-1, synchronized. Play = closed-loop games with a disclosed safety shield (vetoes counted).
| Folder | Params | Val acc | CPU decision | GPU decision | Closed-loop play |
|---|---|---|---|---|---|
gtiny-4m |
4.4M | 95.1% | 0.7 ms (~1,400/s) | 2.1 ms | board clear, 141 pts, 0 deaths |
bert-11m |
11M | 99.5% | 8.3 ms (~120/s) | 3.6 ms (~280/s) | ~47 pts avg, rare endgame deaths |
distil-66m |
66M | 96.8% (regime) | 20 ms (~50/s) | 4.6 ms (~220/s) | ~47 pts avg, hunts aggressively |
Reference measured on the same box: a hosted zero-shot decision API at 436 ms p50 and $0.042/M input tokens. The 4.4M model is ~600Γ faster on CPU alone at $0 marginal cost.
Labels are classifier indices [up, down, left, right]. Max 96 tokens.
gtiny-4m uses the v1 state format (no phase prefix); bert-11m and
distil-66m use the v2 phase hunt|survive format.
Comparison infographics (same measured numbers)
Built with Gavel β typed questions in, calibrated decisions out. Repo: https://github.com/syedsohailhussain1/gavel.
How to use
pip install huggingface_hub onnxruntime transformers
huggingface-cli download syedsohailhussain/gavel-snake-tiny \
--include "gtiny-4m/*" --local-dir models/snake
Single decision (Python):
import numpy as np, onnxruntime as ort
from transformers import AutoTokenizer
tok = AutoTokenizer.from_pretrained("models/snake/gtiny-4m")
sess = ort.InferenceSession("models/snake/gtiny-4m/model.onnx",
providers=["CPUExecutionProvider"])
e = tok("head(2,2) apple(9,5) len12 heading right || "
"up:free f8 s90 | down:body f0 s0 | "
"left:free f12 s30 | right:tail f6 s100",
return_tensors="np", truncation=True, max_length=96)
logits = sess.run(None, {"input_ids": e["input_ids"].astype(np.int64),
"attention_mask": e["attention_mask"].astype(np.int64)})[0][0]
print(["up", "down", "left", "right"][int(logits.argmax())])
Full playable demo (clone Gavel, no training needed):
git clone https://github.com/syedsohailhussain1/gavel.git
cd gavel
python models/training_state/gavel_snake.py play --brain onnx \
--onnx models/snake/gtiny-4m/model.onnx --tok models/snake/gtiny-4m \
--phased 0 --fps 12
(Use bert-11m / distil-66m folders the same way, dropping --phased 0 β
only gtiny-4m uses the v1 format.)
Honest limits
- Val accuracy β play quality; every row above earned its place in closed-loop games, and the demo counts shield vetoes on screen.
- Endgame deaths happen (greedy pursuit boxes itself around 25β30% board fill); rounds auto-reset with cumulative scoring.
- A toy game with structured state texts β this proves cheap typed decisions can drive a real-time loop, not that small models understand anything. Details in the cookbook's caveats section.


