Discerna-v1-475M
Discerna is a small decision model for text and images. You give it a state (any text or JSON), optional images, and named questions. It answers every question with a probability for each option, in one forward pass, without generating text.
- Three kinds of question: yes/no (
noul), one of 2–255 named options (choice), and a level on a scale of 2–10 (score). - Text and images together: up to 16,384 tokens of text. Each image is read in up to ten 512-pixel tiles plus a thumbnail; requests with images keep up to 896 tokens of text.
- Calibrated probabilities, one temperature per question type and option count.
- Many questions about the same state in one request.
- 475M parameters. Runs on CPU, Apple Silicon and NVIDIA GPUs; the weights take about 1 GB in half precision (the default on GPUs) and 1.9 GB in full precision (the default on CPU).
This repository holds the model and the discerna package that runs it (src/), with examples.
Quick start
Install the package (Python 3.12 or later):
pip install https://huggingface.co/CrazyH0rse/Discerna-v1-475M/resolve/main/wheels/discerna-1.0.0-py3-none-any.whl
Start the server. The first start downloads the model (1.9 GB); later starts use the cached copy:
discerna serve --model CrazyH0rse/Discerna-v1-475M
Get the examples (requests, photos and an answer key) and ask the server from another terminal:
hf download CrazyH0rse/Discerna-v1-475M --include "examples/*" --local-dir .
discerna ask examples/requests/support_ticket.json
discerna ask examples/requests/market_potatoes.json --image examples/images/market_potatoes.jpg --answers examples/answers.json
--image attaches any picture, and --answers marks each answer right or wrong from an answer key.
To answer one request without a server:
discerna decide --model CrazyH0rse/Discerna-v1-475M examples/requests/support_ticket.json
--model also takes a local folder, such as a full copy of this repository
(hf download CrazyH0rse/Discerna-v1-475M --local-dir Discerna-v1-475M).
Python
import discerna
model = discerna.load("CrazyH0rse/Discerna-v1-475M") # picks the device and precision
response = model.decide({
"state": {"channel": "email", "message": "I was charged twice for my March invoice. Please fix this before Friday."},
"questions": {
"team": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "payments, invoices, refunds", "technical": "bugs, errors, outages",
"sales": "pricing and new plans"}},
"urgent": {"type": "noul", "instructions": "Does this need a reply today?"},
"mood": {"type": "score", "instructions": "How upset is the customer?",
"criteria": ["calm", "annoyed", "angry"]},
},
})
print(response.answers["team"].choice) # billing
print(response.answers["urgent"].noul) # 0.358: the probability of "yes"
Images go in "images": [...]: PIL images or file paths (pathlib.Path) in Python, base64 or data
URLs over HTTP. model.decide_batch([...]) answers several requests together, which is faster on a GPU.
Requests and answers
The server takes the same JSON at POST /v1/decide.
| Field | Content |
|---|---|
state |
the input: text or any JSON value (optional) |
images |
pictures, in order (optional) |
questions |
{name: question}: one or more questions about the same state |
Each question has a type, its instructions, and criteria:
noul: criteria optional, e.g.{"yes": "...", "no": "..."}to describe each side. The answer isnoul, the probability of yes.choice: criteria are{"option name": "description or null"}. The answer haschoice(the most likely option),probabilitiesfor every option, andconfidence.score: criteria list the levels from lowest to highest. The answer hasprobabilitiesper level ("0","1", …),score(the expected level) and alegend.
The example above answers:
{
"model": "Discerna-v1-475M",
"answers": {
"team": {"type": "choice", "choice": "billing",
"probabilities": {"billing": 0.998, "technical": 0.0019, "sales": 0.00004}, "confidence": 0.998},
"urgent": {"type": "noul", "noul": 0.358},
"mood": {"type": "score", "score": 0.64, "probabilities": {"0": 0.375, "1": 0.608, "2": 0.017},
"confidence": 0.608, "legend": {"0": "calm", "1": "annoyed", "2": "angry"}}
},
"usage": {"input_tokens": 192, "output_tokens": 0}
}
A request beyond the model's limits gets HTTP 413 with "unsupported" in the body; an invalid request
gets 422.
How it works
Each question is read together with the state as one sequence: the state, the question, then each option behind a marker. One forward pass scores every marker, and a softmax over the options gives the probabilities.
| Part | Parameters | What it does |
|---|---|---|
| Text encoder | 354.5M | 16 bidirectional layers (10 short-convolution, 6 attention), width 1,024 |
| Vision tower | 85.8M | SigLIP2; reads each image tile |
| Projector | 8.4M | maps image features into the text encoder; image positions come first |
| Decision head | 26.2M | question-type embedding, 2 transformer layers, a scorer at each option marker |
Training
Training ran in five stages (listed under provenance in config.json):
- text decisions, all weights trained (3,000 steps of 32 examples);
- more text decisions, adding generated tasks (1,600 steps of 32);
- vision, through the projector and image-only adapters, with the vision tower frozen (3,000 steps of 16 image examples);
- text and images together, the adapters merged and all weights trained (2,500 steps of 32);
- temperature calibration on held-out text decisions.
Over all stages it trained on about 275,000 examples, counting repeats. Every source permits commercial use; sources under CC BY 4.0 are credited here as their licenses ask.
| Source | Publisher | License |
|---|---|---|
| MultiNLI (fiction genre left out) | NYU | OANC and per-genre licenses |
| WANLI | Liu et al. | CC BY 4.0 |
| CommonsenseQA | Talmor et al. | MIT |
| QASC | Allen Institute for AI | CC BY 4.0 |
| Civil Comments | Jigsaw / Google | CC0 1.0 |
| GoEmotions | Google Research | Apache 2.0 |
| HelpSteer2, HelpSteer3 | NVIDIA | CC BY 4.0 |
| Aegis AI Content Safety 2.0 | NVIDIA | CC BY 4.0 |
| MASSIVE 1.1 | Amazon | CC BY 4.0 |
| PubMedQA (artificial subset) | Jin et al. | MIT |
| TyDi QA | Google Research | Apache 2.0 |
| ToolACE | Team-ACE | Apache 2.0 |
| Glaive function calling v2 | Glaive AI | Apache 2.0 |
| DOCCI | Google LLC | CC BY 4.0 |
| CLEVR v1.0 | Johnson et al. | CC BY 4.0 |
- Generated decision tasks and sentence pairs were written by Qwen/Qwen3-30B-A3B-Instruct-2507 (Apache 2.0) and checked by a second labeling pass.
- Synthetic shape scenes were drawn by code; they contain no third-party data.
Limitations
- It is a small model. It does best on everyday decisions where the answer is in the input: routing messages, yes/no checks, simple ratings, intents.
- Images: it handles clear, simple scenes (a few objects, colors, positions). It is often wrong on busy real-world photos, small or handwritten text, counts of many objects and fine details, and it can be confidently wrong.
- Request wording: it works best with meaningful option names and the text in
state. With options named only by letters or numbers, and the text inside the question, accuracy drops. - Unsure answers: when unsure, it leans toward cautious options such as "none of these" or "neutral".
- Language: most of its training data is English.
- Probabilities: they are calibrated on general data. Check them on your own examples before relying on them.
- Stakes: do not use it for high-stakes decisions without human review.
License
- The model (
model.safetensors, withconfig.jsonand the tokenizer files) and the model code insrc/discerna/model/are under the LFM Open License v1.0. Commercial use is licensed only to organizations below 10 million US dollars in annual revenue. - All other code is under the Apache License 2.0.
Discerna is trained further from Liquid AI's LFM2.5-Encoder-350M (text encoder and tokenizer) and LFM2.5-VL-450M (vision encoder and projector). Its model code is adapted from Liquid AI's open d1-omni-600M implementation. NOTICE credits the base models, the training data and the example images.
- Downloads last month
- 14
Model tree for CrazyH0rse/Discerna-v1-475M
Base model
LiquidAI/LFM2.5-350M-Base