PurpleMIST-Mini-2.0

PurpleMIST-Mini-2.0 Highlights

PurpleMIST-Mini-2.0 is a System One decision model that reads text and images. Give it a piece of state (a message, ticket, record, transcript, receipt or screenshot) and any number of typed questions about it. It returns a calibrated probability distribution for every answer, in one forward pass.

  • Flash-level quality at half the size. On the Jev Decision Index public suite it scores 46.5, against 46.7 for PurpleMIST-Flash-1.0 (7.9B). Mini-1.0 scored 13.1. On LocalLLaMA/typed-decisions it scores 0.723 zero-shot (KL 0.155, Brier 0.082), against 0.720 for Flash-1.0 and 0.601 for Mini-1.0, measured by the same harness.
  • Reads images. It scores 63.7 on the Decision Index public vision suite, 6th of the 24 models up to 6B parameters on the Vision board. A state can carry several images, which are placed in order.
  • Long context, nothing truncated. It was trained on states up to 98,304 tokens and served with a 262,144-token window on the Decision Index. All 140,178 text requests were answered whole, with none truncated or declined.
  • 19 languages. States and questions can be in English; Amharic, Hausa, Igbo, Nigerian Pidgin, Somali, Swahili, Yorùbá or isiZulu; or Arabic, Chinese, French, German, Hindi, Indonesian, Portuguese, Russian, Spanish or Turkish. The question can be in a different language from the state (0.937 accuracy on held-out cross-language questions).
  • Much better in African languages than Mini-1.0. It scores 0.636 accuracy on African Typed Decisions in eight languages, against 0.416 for Mini-1.0 and 0.668 for Flash-1.0, with the benchmark's own harness.
  • Calibrated. Each question type has its own temperature, fitted separately for text and image states on held-out states from every training source.
  • Fast. Median 70 ms and mean 92 ms per text request over the full Decision Index run on one RTX PRO 6000.

Model Overview

  • Type: decision model. It scores options and does not generate text.
  • Backbone: Qwen/Qwen3.5-4B-Base with its vision encoder and without its language-model head. The text model has 32 layers (24 Gated DeltaNet linear-attention and 8 full attention) with hidden size 2560, about 4.2B parameters. The vision encoder adds 0.33B, for 4.5B in total.
  • Attention: a two-block mask on the eight full-attention layers. The prefix (header, images and state) is causal and never sees the questions, so it is encoded the same way whatever is asked. Every question token sees the whole prefix and every other question, so a question is read alongside its options. The Gated DeltaNet layers stay causal.
  • Head: a pointer head. Each option's logit is a scaled dot product between projections (2560 → 1024) of the answer position and the option's own line. The head has 5.3M parameters.
  • Fine-tuning: full fine-tune of every text-model weight. The vision encoder was frozen.
  • Question types:
Type You give You get back
choice instructions and named options (criteria: key → description) {"choice": key, "probabilities": {key: p}}
noul a yes/no statement {"noul": p_yes}
score instructions and ordered level descriptions (lowest first) {"score": expected level, "probabilities": {"0": p, ...}}
  • Weights: bf16 safetensors, 8.5 GB. Run it in bf16, which is the precision it was calibrated in.
  • Context: Decider defaults to 98,304 tokens per pass, the training length. It never truncates: when the questions do not fit beside the state, they are split across several passes, and a state that cannot fit at all is declined. Pass a larger max_len (up to the backbone's 262,144) for longer inputs.
  • Images: up to 1,024 tokens per image by default (about 1 MP, at 32 × 32 pixels per token). Training used one image per state. Several images work and are placed in order, but the model never trained on comparing them.

Quickstart

pip install "transformers>=5.22" "torch>=2.10" huggingface_hub pillow
pip install flash-linear-attention causal-conv1d     # optional: fast kernels for the linear-attention layers
import os, sys
from huggingface_hub import hf_hub_download

repo = "olaverse/PurpleMIST-Mini-2.0"
sys.path.insert(0, os.path.dirname(hf_hub_download(repo, "purplemist.py")))
from purplemist import Decider

d = Decider.from_pretrained(repo, device="cuda")

state = {"channel": "whatsapp",
         "message": "Ẹ jọ̀ọ́, wọ́n ti yọ owó lẹ́ẹ̀mejì lórí káàdì mi fún ọjà kan náà. Mo fẹ́ kí ẹ dá owó mi padà."}
questions = {
    "team":    {"type": "choice", "instructions": "Which team should handle this?",
                "criteria": {"billing": "payments, charges and refunds", "delivery": "orders in transit",
                             "technical": "app or account problems"}},
    "refund":  {"type": "noul", "instructions": "The customer is asking for money back."},
    "urgency": {"type": "score", "instructions": "How urgent is this?",
                "criteria": ["can wait", "normal queue", "today", "immediately"]},
}
print(d.decide(state, questions))

With images. Pass a path, bytes, base64 string, data URL or PIL image, or a list of them:

q = {"total_ok": {"type": "noul", "instructions": "The receipt total matches the sum of its line items."},
     "category": {"type": "choice", "instructions": "What kind of purchase is this?",
                  "criteria": {"food": "groceries or restaurant", "transport": "fuel, taxi or tickets",
                               "other": "anything else"}}}
print(d.decide("", q, image="receipt.jpg"))
print(d.decide({"note": "before and after the repair"}, {"fixed": {"type": "noul",
      "instructions": "The crack visible in the first photo is gone in the second."}},
      image=["before.jpg", "after.jpg"]))

state can be a string or any JSON-serialisable object, and may be empty when an image carries the content. Instructions and option descriptions can be in English or in the state's language.

Serving over HTTP

serve.py runs the model as a small local server with the System One request shape (POST /v1/systemone, also served at /v1/decisions). Vision requests add "images": [...] (data URLs, base64 strings or paths) to the body.

hf download olaverse/PurpleMIST-Mini-2.0 serve.py purplemist.py --local-dir purplemist
python purplemist/serve.py --model olaverse/PurpleMIST-Mini-2.0 --port 8000
curl -s localhost:8000/v1/systemone -H 'content-type: application/json' -d '{
  "state": {"message": "I was charged twice, please refund me"},
  "questions": {
    "team":   {"type": "choice", "instructions": "Which team?", "criteria": {"billing": "payments", "tech": "app problems"}},
    "refund": {"type": "noul", "instructions": "The customer asks for money back."}}}'

The server also offers GET /health and GET /v1/models, and handles one request at a time. Requests that do not fit the context window get HTTP 422 with a "maximum context length" message. The answer fields match Ollama's decision API (choice, noul, score, probabilities, confidence, legend).

Options: --max-len sets the tokens per pass (default 98,304), and --image-max-tokens sets the per-image cap (default 1,024; the Decision Index vision board runs at 1.6 MP, which is --image-max-tokens 1600).

Evaluation

Jev Decision Index (public text suite)

The Jev Decision Index tests decision models on 37 public benchmarks in five areas. Each score is chance-corrected, so 0 is random guessing and 100 is perfect, and an unanswered request counts as wrong. PurpleMIST-Mini-2.0 was run with the maintainers' kit (apolinario/decision-index, edition 0.3) on one RTX PRO 6000, served by serve.py --max-len 262144. The rebuilt suite matched the board's frozen files byte for byte. This needed the kit's SGD builder change 2d7791c reverted, as described in issue #274.

All 140,178 requests were answered, with none truncated, declined or errored. Its public index is 46.5.

Area Mini-2.0 Flash-1.0 (7.9B) Mini-1.0 (1.9B)
Public index 46.5 46.7 13.1
Knowledge & reasoning 31.7 34.9
Language understanding 52.8 53.1
Retrieval & classification 52.3 47.5
Tools & automation 61.2 65.1
Arts & human taste 30.0 25.5
  • Biggest gains over Flash-1.0: BPoMP (+28.9), RAGTruth (+22.4), BANKING77 (+14.6), CLINC150 (+13.7) and the home-appliance simulator (+12.5). These benchmark families, or close relatives, have public training data, and 2.0 trained on far more of it. Only train splits were used.
  • Biggest losses against Flash-1.0: HellaSwag (−23.8), When2Call (−23.3), GSM8K (−21.1) and CRUXEval (−17.2). These lean on reasoning and world knowledge, where the larger backbone helps.
  • Against models of its size: among the 49 board entries with 3 to 5.6B parameters, it is ahead of 30, and 3.8 points above their median (42.7). The strongest 4B models score about 67, so there is a lot of headroom.

The board's Full score comes from the maintainers' private tests, which they run after review, so it is still pending.

Jev Decision Index (public vision suite)

Eleven public benchmarks, 12,210 multiple-choice questions over one to four images. It was run with the kit's decide engine (protocol=decisions) against serve.py --image-max-tokens 1600, at native resolution up to 1.6 MP as the board requires. The rebuilt suite matched the board's pinned hashes, which needed Pillow 12.3.0. All 12,210 rows were answered, including the 574 multi-image rows.

Its public vision index is 63.7.

Benchmark Mini-2.0 Perplexity Decider Flash v1.2 (4B) vLLM-SR d3-mini (4B) Sieve-Vision-4B
Public vision index 63.7 72.5 67.7 65.2
CV-Bench 73.0 75.6 73.9 69.9
BLINK 53.8 55.5 53.4 52.0
RealWorldQA 57.8 63.1 57.8 60.3
CharXiv 66.9 76.9 73.9 63.2
InfographicVQA 90.2 94.0 94.5 92.4
Mind2Web 67.7 92.9 77.5 92.6
Winoground 80.2 83.5 81.5 75.5
KIE (CORD+FUNSD) 90.0 91.7 92.2 89.6
Moderation (Hateful Memes) 24.3 54.5 37.4 22.5
R-Bench-M (weight 0.5) 22.6 23.5 18.8 20.4
MMMU-Pro vision (weight 0.25) 25.2 31.5 32.7 29.2

Other models' scores are as published on the board. Mini-2.0's are from its own complete run, not yet reviewed.

  • Rank: 6th of 24 models up to 6B parameters, and 38th of 63 overall.
  • Strongest: receipts and forms (KIE 90.0), infographics (90.2) and Winoground (80.2).
  • Weakest: hateful-meme moderation (24.3) and web-page element picking (Mind2Web 67.7). Neither task is in the training data.
  • Multi-image: on BLINK, where some questions use two to four images, it scores 53.8, in line with the 4B leaders, even though it trained on single images only.
  • Speed: the full vision run took about 215 ms per row on one RTX PRO 6000.

Held-out sets

These come from the training repository's evaluation script, which reads the held-out splits of the training data after calibration.

Set Decisions Accuracy Brier KL ECE
LocalLLaMA/typed-decisions test (English, zero-shot) 2,000 0.724 0.080 0.152 0.114
African Typed Decisions, 8 languages 15,050 0.638 0.125 0.226 0.077
African scenarios, held out 1,834 0.916 0.087 0.152 0.110
Questions in other languages, held out 1,686 0.937 0.075 0.156 0.078
Open-Jev test 7,632 0.896 0.147 0.259 0.023
Open-Jev out-of-distribution 9,855 0.831 0.275 0.561 0.086
tasksource test 3,773 0.854 0.180 0.337 0.021
Najd 4,368 0.857 0.196 0.488 0.011
HelpSteer2 (score) 5,000 0.612 0.504 0.900 0.019
Hard programmatic tasks 4,683 0.949 0.055 0.111 0.008
Long context, 16k to 94k tokens 459 0.704 0.314 0.845 0.104
Receipts (image) 2,116 0.984 0.027 0.047 0.066
Screenshots (image) 1,249 0.907 0.087 0.148 0.086
Real photos (image) 237 0.907 0.116 0.202 0.052

Mini-1.0 scored 0.560 on typed-decisions and 0.413 on African Typed Decisions with the same script, and Flash-1.0 scored 0.717 and 0.674. The Open-Jev, tasksource and Najd gains over 1.0 partly reflect a closer domain fit, since 2.0 trains on much more of those sources. Long context is the weakest new skill.

Training

  • Data: 2,163,851 training decisions. The sources are:

    • public System One and preference data: tasksource (train splits only, no per-task cap), Open-Jev train, HelpSteer2, jev-decisions-clean50k, two synthetic sets and Najd development;
    • African decisions, both written natively in eight languages and translated from the public training states;
    • image states: receipts, screenshots and real photos;
    • questions asked in a different language from the state, in 18 languages;
    • hard programmatic tasks (code execution, causal and boolean logic, date arithmetic, object tracking, multi-hop lookups and similar), generated with exact answers;
    • hard reasoning cases written by open-weight models (DeepSeek-V4-Pro, Nemotron-3-Ultra and Qwen3.5-397B) and kept only when at least two of three judges agreed;
    • long-context states of 16k to 94k tokens: labelled states hidden among other documents, and long logs.

    Every source allows commercial use, and every model-written case comes from a model whose terms allow distillation. LocalLLaMA/typed-decisions train was not used, which keeps the English result zero-shot. Corpora distilled from the Jev API were excluded.

  • Objective: soft-target cross-entropy against each question's reference distribution. Options are shuffled during training.

  • Run: full fine-tune with FSDP2, 7,372 steps at learning rate 5e-6, on 4× H200. Sequences went up to 98,304 tokens with no truncation: questions that did not fit beside their state were split across sequences.

  • Calibration: after training, temperatures were fitted per question type, separately for text and image states, on 1,455 states that training never used. The states are spread across the training sources, each weighted equally. Text temperatures are choice 1.074, noul 1.468 and score 0.955. Image temperatures are choice 0.993, noul 1.117 and score 1.074. Both sets are stored in purplemist_config.json.

Limitations

  • Gold comes from LLM teachers. Most reference answers were generated by language models, so a score measures agreement with those teachers, not ground truth. The programmatic tasks are the exception.
  • African data is machine-written. It was machine-written and machine-checked, not reviewed by native speakers.

Citation

@misc{purplemist-mini-2.0,
  title  = {PurpleMIST-Mini-2.0: a calibrated multimodal System One decision model},
  author = {Olaverse},
  year   = {2026},
  url    = {https://huggingface.co/olaverse/PurpleMIST-Mini-2.0}
}
Downloads last month
-
Safetensors
Model size
5B params
Tensor type
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for olaverse/PurpleMIST-Mini-2.0

Finetuned
(262)
this model

Datasets used to train olaverse/PurpleMIST-Mini-2.0

Collection including olaverse/PurpleMIST-Mini-2.0

Evaluation results

  • LocalLLaMA/typed-decisions leaderboard
  • Accuracy View evaluation results
    source
    General, zero-shot: never trained on the Typed Decisions train split. Test split, 400 cases, 2,000 decisions, one request per case, all answered. Scored with the African Typed Decisions harness (English original rows). bf16, calibrated temperatures.
    0.72 *
  • Kl From Gold View evaluation results
    source
    General, zero-shot: never trained on the Typed Decisions train split. Test split, 400 cases, 2,000 decisions, one request per case, all answered. Scored with the African Typed Decisions harness (English original rows). bf16, calibrated temperatures.
    0.16 *
  • Brier View evaluation results
    source
    General, zero-shot: never trained on the Typed Decisions train split. Test split, 400 cases, 2,000 decisions, one request per case, all answered. Scored with the African Typed Decisions harness (English original rows). bf16, calibrated temperatures.
    0.08 *
  • olaverse/african-typed-decisions
  • Accuracy Translated View evaluation results
    source
    whole case per request; calibrated temperatures from purplemist_config.json; bf16
    0.64 *