A general-purpose decision model https://vski.ai
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-10-11 22:18:03 +00:00
data primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
examples primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
primes primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
validation primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
.gitignore primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
CITATION.cff primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
config.json primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
head.safetensors primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
head_config.json primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
LICENSE primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
manifest.json primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
model.safetensors primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
README.md Update README.md 2026-10-11 22:18:03 +00:00
tokenizer.json primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00
tokenizer_config.json primes 1.0.0 — 0.6B base decision model (weights, torch example, public validation set, finetuning data example) 2026-10-11 16:20:39 +02:00

Primes 0.6b

A 0.6B base decision model. Give it a situation, an optional query, and a set of options; it returns a calibrated probability distribution over the options — one forward pass per option, softmax across them. No token generation, no sampling, no prompt tricks: the same inputs always produce the same distribution. Built as a base for finetuning on domain-specific decision problems.

This is the base model designed for fine-tuning.

GGUF

state  = "The warehouse door is locked. Security patrols every 20 minutes.
          A side window is open two floors up. Your lockpick is bent."
query  = "get inside without being seen"          # optional
options= ["pick the lock", "climb to the window", "wait for the patrol", "leave"]

-> climb to the window  (0.46)   wait for the patrol (0.27)
   pick the lock (0.21)  leave (0.05)

Model description

  • Architecture: Qwen3-0.6B backbone (Qwen3Model, 28 layers, hidden 1024, tied embeddings; the language-model head is dropped) + a 0.5M-parameter decision head: Linear(1024, 512) → GELU(exact erf) → Linear(512, 1) over the mean-pooled final hidden state. Merged inference weights — no adapters to attach.
  • Training: fine-tuned from Qwen/Qwen3-0.6B on English decision problems (everyday scenarios, games, shopping, legal and data-science reasoning, structured HTML/JSON documents) with soft labels distilled from a larger Qwen3 teacher.
  • Intended use: a base model for finetuning on your own decision data; also usable zero-shot as a scorer/reranker for multiple-choice selection.
  • Release: 1.0.0, 2026-10-11. Checksums in manifest.json.

Metrics (public validation set, 423 decisions)

Reference run of validation/validate.py (bf16 backbone + fp32 head, single consumer GPU; validation/results.json):

metric value
top-1 accuracy 0.9456
MRR 0.9716
NLL 0.2388
ECE (10 bins) 0.0975
random baseline 0.2930
split n top-1
with query 273 0.9560
query-less 150 0.9267

Per option-count (K=2..8): 0.946, 0.965, 0.918, 0.950, 0.886, 1.000, 0.929. The validation set excludes the numeric-reasoning lane (see Limitations), so these numbers describe the model's supported scope.

Quickstart (torch)

python examples/decide.py          # three demo decisions

or in code:

import sys; sys.path.insert(0, ".")
from examples.decide import Primes

m = Primes()                        # cuda/bf16 if available, else cpu/fp32
out = m.decide(
    "Two job offers: a stable team with legacy code, or a risky startup doing ML.",
    ["stable team", "risky startup"],
    query="maximize career growth in two years")
print(out["choice"], out["confidence"])   # -> stable team 0.689

Deps: torch, transformers, safetensors, numpy. The decision head always runs in fp32 (numpy) exactly as shipped, independent of the backbone dtype/device.

Input & output contract

Every input text is serialize(query, option, context) — this must be byte-identical in training and inference or the input distribution shifts silently:

Query: {query}            # missing/empty -> "select best"
Option: {option}
Context: {context}        # whitespace runs collapsed to single spaces

Truncated at 704 tokens. The head consumes the mean-pooled final hidden state over non-pad tokens (Qwen adds no BOS, so plain tokenization matches). One decision = K forward passes (batched) + softmax over the K logits. primes/runtime.py is the reference implementation; vendor it rather than reimplementing.

Finetuning

The model is a standard Qwen3Model + a small separable head, so the usual toolbox applies (PEFT/LoRA on the backbone, head retrained or frozen):

  • Data format — one JSON record per decision, exactly as in data/train_example.jsonl (16 samples from the training distribution):

    {"id": "train-ex-001", "query": null, "context": "...",
     "options": ["...", "..."], "gold": 0}
    

    query may be null (serialized as select best); gold is the 0-based index of the correct option. Train one example per (query, option, context) triple with a cross-entropy over the K logits of the decision.

  • Keep serialize() byte-identical and the 704-token cap.

  • The head is 0.5M parameters — retraining it alongside the backbone is cheap; it also transfers as-is if only the domain shifts.

  • After finetuning, validation/validate.py doubles as a drift check against the published numbers (--no-gate to just measure).

Limitations

  • Numeric multi-value reasoning is out of scope. Decisions that require argmax-style comparison over five or more numeric values were excluded from training (the 0.6B backbone cannot carry that objective without degrading the rest); the public validation set excludes the lane accordingly. Route such decisions to a dedicated numeric expert or plain code.
  • English-centric training data; no generation of any kind; contexts beyond 704 tokens are truncated.
  • Calibrated for single-choice decisions over small option sets (validated on K=2..8). Confidence is a probability of correctness among these options — re-score with a different option set and the distribution changes accordingly.
  • Decisions with no single defensible answer (unanswerable or multi-select) are not represented in the public data.

Files

file size what
model.safetensors 1.19 GB merged backbone (bf16, Qwen3Model)
head.safetensors + head_config.json 2.1 MB decision head (fp32)
config.json, tokenizer.json, tokenizer_config.json 11 MB config + tokenizer
primes/ reference runtime (serialize, Head, softmax)
examples/decide.py torch scorer + demos
validation/ public val set (423), validate.py, reference results.json
data/train_example.jsonl 16-sample finetuning-format example
manifest.json sha256 checksums of everything above

Validation

python validation/validate.py                 # ~3 min on one GPU
python validation/validate.py --device cpu    # slower, same numbers

Prints top-1/MRR/NLL/ECE plus splits and per-K breakdown, writes validation/results.json, and exits non-zero if top-1 or ECE drift beyond tolerance of the published numbers — usable as an install smoke test.

License

Apache-2.0. Derivative of Qwen/Qwen3-0.6B (Apache-2.0); see LICENSE and manifest.json.

Citation

@misc{nesterov2026primes,
  author       = {Anton A. Nesterov},
  title        = {Primes: a 0.6B base decision model},
  year         = {2026},
  url          = {https://vski.sh},
  note         = {version 1.0.0}
}

Anton A. Nesterov — vski.sh