basal-omni-1.0-ultra and engine basal 2.1
The most capable model of the basal family: basal-omni-1.0-ultra (31B) scores 0.879 on Werdykt, 5.8 points above Jev 1.14, and is level with Liquid d1-ultra. Engine basal 2.1 adds the experimental classify, verify, compress and extract tasks and leaves every other answer unchanged. The experimental basal-omni-1.1-max joins for the tasks.
basal-omni-1.0-ultra is the most capable model of the basal family: 31 billion parameters on Google Gemma 4, the same decision API, text and images in one request. On Werdykt, our hidden benchmark of Polish and English decisions, it scores 0.879: above basal-omni-1.0-max in every one of the 10 categories and 5.8 points above Jev 1.14. It is level with Liquid d1-ultra.
With it we release engine basal 2.1 with four experimental tasks: classify, verify, compress and extract. Every other answer of the engine is the same as in 2.0. For the tasks there is also the experimental basal-omni-1.1-max; basal-omni-1.0-max stays the default 12B model.
basal-omni-1.0-ultra
ultra works like the other basal models: it reads a state and answers typed questions with a calibrated probability for each allowed answer, without generating text. It takes text and images. It does not take audio, because the 31B base model has no audio encoder; for recordings use basal-omni-1.0-mini and max.
- bf16 weights: 59 GB. Server
--mode eager --media onneeds a card with 80 GB of memory; on such a card ultra answers states of up to about 10,000 tokens. - FP8: 33 GB. basal-omni-1.0-ultra-FP8 runs through
--mode vllmand reads text only. On questions with 2–10 options it picks the same answer as bf16 in 98.1% of decisions, and accuracy differs by −0.4 points (one H100). - Availability. Both ultra repositories appear on Hugging Face on Saturday 17 October at 09:00 (Warsaw).
Ultra's results
Werdykt is 5,000 hidden decisions in Polish and English across 10 categories; every system gets the same questions. ultra answered in --deterministic mode, the API systems through OpenRouter.
| System | Werdykt | Polish | English |
|---|---|---|---|
| basal-omni-1.0-ultra · 31B | 0.879 [0.871–0.887] | 0.881 | 0.877 |
| Liquid d1-ultra · API | 0.881 [0.873–0.890] | 0.879 | 0.883 |
| basal-omni-1.0-max · 12B | 0.823 [0.813–0.832] | 0.824 | 0.821 |
| Jev 1.14 · API | 0.822 [0.811–0.831] | 0.824 | 0.819 |
- Against basal-omni-1.0-max: +5.6 points and a higher score in every one of the 10 categories, most of all in long documents (0.854 vs 0.742), rules (0.550 vs 0.418) and an agent's next step (0.928 vs 0.838).
- Against Jev 1.14: +5.8 points (0.879 vs 0.822).
- Against Liquid d1-ultra: a statistical tie. The difference is −0.2 points and its 95% interval (−1.0 to +0.7) includes zero. ultra leads in 6 categories (most in contracts: +3.2), d1-ultra in 3 (most in recognising that an answer cannot be determined: +7.4), and retrieval is a tie.
- Calibration: calibration error (ECE) 0.038. At a 1% error target ultra automates 72.0% of decisions, with an observed error of 1.37% (d1-ultra on the same board: 72.7% at 1.25% error). d1-ultra is better calibrated (ECE 0.018).
- Polish medical exam (LEK), our measurement: 86.9% in Polish and 87.0% in the English version (basal-omni-1.0-max: 75.0% and 80.9%), on the same questions and with the same protocol as in the 2.0 article.
We have not yet measured ultra's speed in a separate pass, so ultra's time and cost are empty on the Werdykt board. Full table: Werdykt.
Engine basal 2.1: tasks
Engine v2.1.0 adds four task types on the same API, for the models you already run. The engine expands each task into the model's decisions over a shared state, so the model still writes no text, and every part of the answer has a probability.
classify: labels with a short rubric each; the result is the label and a probability for each one.verify: for each statement: supported, contradicted or not stated by the state.compress: the sentences, lines or paragraphs a question needs, as shorter text for another model.extract: JSON schema fields copied exactly from the document, with character offsets, or chosen from a list.
| Task | Set | Questions | Result |
|---|---|---|---|
classify | CLINC150 “plus”, 151 labels including out-of-scope | 1 000 | 85.4% accuracy |
classify | BANKING77, 77 labels | 1 000 | 74.6% accuracy |
verify | VitaminC, three answers | 1 000 | 80.3% accuracy |
verify | RAGTruth, response vs source | 1 000 | 80.3% accuracy |
compress | QASPER, paragraphs, 30% of the characters | 248 | 90.1% of the needed paragraphs kept |
extract | synthetic PL / EN invoices, 12 fields | 400 | 90.1% of fields correct |
{"state": "I was charged twice for my card payment yesterday.",
"questions": {"intent": {"type": "classify", "none": true, "labels": [
{"name": "card_payment_duplicate", "rubric": "a card payment was taken more than once"},
{"name": "card_lost", "rubric": "the card is lost or stolen"},
{"name": "refund_status", "rubric": "asks about a refund in progress"}]}}}
→ answers.intent (basal-omni-1.0-max, v2.1.0, bf16):
{"label": "card_payment_duplicate", "confidence": 0.9996,
"scores": {"card_payment_duplicate": 0.9996, "card_lost": 0.0002, "refund_status": 0.0000, "none": 0.0002},
"automated": {"0.01": null, "0.05": null}}The automated field has a value only with a threshold certified for that task in the calibration file. Without one it is null: the thresholds of ordinary decisions do not carry over to new label sets (at a 1% target, 2 to 9% of automated answers were wrong).
The rest of the engine is unchanged. Tasks are a new path; ordinary questions run through the same code as in 2.0. On basal-omni-1.0-max, 23,276 of 23,278 release-check decisions get the same answer on engine 2.1 as on 2.0. The two differences are near-ties between two options. Details: tasks on the server page and TASKS.md.
basal-omni-1.1-max: an experimental task model
basal-omni-1.1-max is basal-omni-1.0-max after a short extra round of training on the task formats. It is better at the tasks and slightly weaker on general decisions, so basal-omni-1.0-max stays the default 12B model.
- Tasks: the mean over the six sets in the table above rises from 83.5 to 85.1. Overlap check: 27 test items (12 VitaminC, 15 QASPER) share a 13-word span with the training data; without them the gains are +4.2 and +2.7 points and the mean is still 85.1.
- Werdykt: 0.821 vs 0.823 (inside the interval). At a 1% error target it automates fewer decisions: 57.7% vs 60.1%.
- ContractNLI: −13.7 points (0.583 vs 0.720; 95% interval −19.3 to −7.7). On plain entailment questions 1.1-max too often picks “the text does not say enough”. For such questions outside
verifyuse 1.0-max. - Availability. On Hugging Face from Saturday 17 October, 09:00.
What does not change
basal-omni-1.0-mini and basal-omni-1.0-max keep the weights of the 14 October release; we are not releasing a new mini. The basal-2.0 models are also unchanged. Engine 2.1 serves them the same way as 2.0.
Limitations
- The tasks are experimental. Their API may change in a minor release.
extractdoes not yet return lists of objects (invoice line items) or text fields from images. - ultra does not hear. It takes text and images; FP8 takes text only. We have not yet measured ultra's speed in a separate pass.
- 1.1-max is a trade-off. It gains on the tasks and loses on ContractNLI and on automation at the 1% target.
- Leave calculations to code. Rules, deadlines and exact thresholds are the weakest point of one-pass decisions.
- Keep oversight of consequential decisions. Decisions with serious consequences for people require human oversight.
Getting started
uv venv --python 3.12 --allow-existing ~/basal-env && source ~/basal-env/bin/activate
uv pip install torch==2.11.0 torchvision==0.26.0 --index-url https://download.pytorch.org/whl/cu128
uv pip install "basal[media] @ https://github.com/rkinas/basal/archive/refs/tags/v2.1.0.tar.gz"
basal-serve --model Remek/basal-omni-1.0-ultra --mode eager --media on --port 8000uv pip install vllm==0.31.0 "basal @ https://github.com/rkinas/basal/archive/refs/tags/v2.1.0.tar.gz"
basal-serve --model Remek/basal-omni-1.0-ultra-FP8 --mode vllm --max-len 16384 --gpu-memory 0.9 --port 8000We publish the ultra and 1.1-max repositories on Saturday 17 October from 09:00. Engine v2.1.0 is already on GitHub and works with mini and max right away. Send tasks as a POST to /v1/basal or /v1/systemone.