Introducing Saina Helm 2 Omni: A Multimodal Decision Model for Images and Audio
Saina Helm 2 Omni 0.8B takes the same decision contract as every Saina model and adds images and short audio clips to the state. Typed questions in, a probability for every option out, nothing generated. Open weights under Apache 2.0.
Plenty of automation decisions start with a file, not a paragraph. A support message arrives with a screenshot of the error. An expense claim comes with a photo of the receipt. A microphone in a warehouse picks up a sharp noise at 3 a.m. Until now a Saina model could only read the text around those files.
Saina Helm 2 Omni 0.8B reads the files too. It is a decision model: you send state, typed questions and the options you own, and you get back a probability for every option. Nothing is generated. Omni keeps that contract and lets the state include up to 8 images and 4 audio clips. It is available now on the hosted API as saina-helm-2-omni-0.8b, with open weights under Apache 2.0.
If you haven't met the contract before, Introducing Saina Helm covers it from the start.
What it reads
- Text: the
state(a string or JSON) and your questions, as in every Saina model. - Images: PNG, JPEG or WebP, up to 8 per request, 10 MiB each. Each image is resized to at most 1.6 megapixels with its aspect ratio kept.
- Audio: WAV, FLAC, MP3, Ogg or WebM, up to 4 clips per request, 10 MiB and 10 seconds each. A longer clip is refused, never cut.
Every question in the request sees all the media, and all of them are answered from one pass over the shared state and media. Ask five questions about one screenshot and the screenshot is read once.
On the hosted API, media go in the request body as base64 data URLs (no URLs or file paths), the body can be up to 25 MiB, and the context window is 32,768 tokens including media. Media are billed as input tokens: one per 32 × 32 pixels of a resized image, and 124 for a 10-second clip. There is no video yet.
How it hears
Omni has no separate audio model. Each clip is converted to a 16 kHz log-mel spectrogram, which is an image of how much energy the sound has at each pitch over time, and that image goes through the same vision tower that reads your photos and screenshots.
Two practical consequences. First, there are no extra audio weights to download or serve. Second, anything above 8 kHz is not in the input at all, and long speech is out of reach: the model can recognise a short spoken word, not follow a conversation.
How you phrase an audio question matters. The model card's advice: say in the state what the clip is ("The clip is a short recording of English speech"), name the sounds plainly in the options, and ask short, literal questions about what is audible rather than questions that need several steps of inference.
Decisions it fits
The intended use on the card is decisions where a wrong answer can be recovered or is reviewed before it takes effect. Some shapes that fit:
- Support screenshot routing. The ticket text plus the customer's screenshot, and a
single_choicequestion for which team takes it. - Receipt against claim. The claimed amount and the policy in the state, the receipt as an image, and a
yes_noquestion on whether the total matches. - Sound alerts. A short clip from a monitored room and a
multi_choicequestion over the sounds you care about, such as breaking glass, an alarm or a raised voice. - Synthetic-voice flag on a call. A
yes_noquestion on whether the speech sounds synthesized or voice-converted, feeding a step that asks for extra verification. A high score there is a reason to check again, never proof of fraud.
Where a wrong answer costs something, run in decision mode. With a threshold (default 0.8) and optionally a min_margin, an answer the model isn't sure of comes back with no selection and a reason (below_threshold, below_margin or tie), so your workflow can send it to a person instead of acting on a guess. LLM decision making covers when that is a better fit than a chat model with vision, and when it isn't.
What it is not for
From the model card's out-of-scope list:
- Generating text of any kind. It only scores the options you supply.
- Final, unreviewed decisions about people: credit, employment, medical, legal.
- Identifying people, faces or the voices of specific individuals.
- Content moderation. It was not trained or evaluated for it.
- Fine print in long documents. Images are read at up to 1.6 megapixels.
- Transcribing long speech, audio over 10 seconds, and video.
- Non-English text and speech, which are largely untested.
- Acting directly on untrusted content. Images and audio can carry instructions just as text can, so limit what the output is allowed to trigger.
What we have measured
Audio. The model card reports a held-out evaluation: 4,120 clips from 21 public sources, 5,572 single-answer questions, sent through the saina package exactly as an API request would be. Omni picks the labelled answer 69.4% of the time. By source, for example:
| Source | What is asked | Correct |
|---|---|---|
| Medley-solos-DB | solo instrument | 98% |
| ASVspoof 2019 LA | synthetic or converted voice vs real speech | 93% |
| FSD50K | everyday sound events | 77% |
| VocalSound | laughs, coughs and other vocal sounds | 73% |
| MIMII | normal vs faulty machine sounds | 70% |
| Speech Commands | spoken command words | 67% |
| FLEURS | spoken language | 54% |
Questions have 2 to 8 options, so chance differs from source to source, and these figures come from the card's held-out evaluation on public datasets. They are not a promise about your recordings. Test on a labelled sample of your own before you automate anything.
Images. No labelled image benchmark is published, so we are not giving an image accuracy number. Training included photos, text in images, scenes, rendered plots and chess boards. Treat image questions as untested on your data until you have checked them.
Two requests
Both are illustrative. The request shape follows the API docs; the base64 strings are cut short.
An image, checking a receipt against a claim:
curl https://api.saina.run/v1/ask \
-H "Authorization: Bearer $SAINA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "saina-helm-2-omni-0.8b",
"mode": "decision",
"threshold": 0.8,
"state": {"claimed_usd": 244.80,
"policy": "Client meals up to $300 with an itemized receipt."},
"images": ["data:image/png;base64,iVBORw0KGgo..."],
"questions": {
"total_matches": {"type": "yes_no",
"question": "Does the receipt total match the claimed amount?"},
"itemized": {"type": "yes_no",
"question": "Is the receipt itemized?"}
}
}'
Audio, flagging a call for extra verification:
curl https://api.saina.run/v1/ask \
-H "Authorization: Bearer $SAINA_API_KEY" \
-H 'Content-Type: application/json' \
-d '{
"model": "saina-helm-2-omni-0.8b",
"mode": "decision",
"state": "Inbound call to the bank: a short recording of English speech. The caller asks to raise their daily transfer limit.",
"audios": ["data:audio/wav;base64,UklGRi..."],
"questions": {
"spoof": {"type": "yes_no",
"question": "Is this speech synthesized or voice-converted by a computer?"},
"action": {"type": "single_choice",
"question": "How should the agent proceed?",
"options": {"proceed": "Proceed with normal checks",
"verify": "Require extra verification because the voice may be fake",
"block": "Refuse and flag the account"}}
}
}'
The question keys (total_matches, spoof, action) are your own names; the answers come back under the same keys. usage.input_tokens in the response includes the media.
Try it
- No account: the live demo on the home page gives 5 free runs. Its image and audio examples include Screenshot triage, Chart reading, Chess puzzle, Breaking glass, Voice check, Care monitor and Machine fault.
- Playground: create a free account and open the console. The image and audio presets include Screenshot triage, Receipt check, Voice fraud check, Care monitor, Instrument tag and Compressor fault. The free plan adds 1 credit on each day you use it, kept for 30 days, and output is free. Subscriptions start at $5 a month.
- API: name
saina-helm-2-omni-0.8binmodel.saina-helmstill selects the text-only Helm 2, so existing workflows don't change. - Open weights:
run-saina/saina-helm-2-omni-0.8bon Hugging Face. Run your own server withpip install "saina[local,server,media]", or load it in Python withHelmModel.from_pretrainedpinned to a revision. It is also published as GGUF for llama.cpp, for Ollama (this needs the Saina Ollama build) and as MLX for Apple silicon.
The examples on the home page show recorded scores. Each one is a single example, not a benchmark result, and the best way to judge Omni is still a few dozen of your own files with answers you already know.
Questions or integration help: [email protected].