Image Classification Without Training: Your Labels in Every Request
You can classify images against labels you wrote this morning, with no labelled dataset and no training run. This post covers how that works, when you should still train a model, and how to test it on your own images, because Saina has not published an image benchmark for Helm 2 Omni.
You can classify images against labels you wrote this morning, with no labelled dataset and no training run. This post covers how that works, when you should still train a model, and how to test it on your own images. That last part matters more than usual here: Saina has not published an image benchmark for Helm 2 Omni, so your own test is the only evidence you will have.
How zero-shot image classification works
"Zero-shot" means the model was never trained on your labels. There are two common ways to get there.
Embedding models. CLIP and SigLIP turn an image and a piece of text into vectors in the same space. To classify, you embed each label ("a photo of a cracked phone screen") and pick the one closest to the image. They are open, fast and well studied. The scores are similarities, not answers to a question, so you tune a cut-off per label, and wording the label text well takes some trial and error.
Models that answer a question about the image. General multimodal LLMs read the image and reply in text, which you parse. A decision model reads the image, your state and typed questions, and returns a probability for each of your options without generating anything. Saina Helm 2 Omni 0.8B (saina-helm-2-omni-0.8b) is one: up to 8 images per request (PNG, JPEG or WebP), and every question sees every image.
The second family lets you ask about context ("given this claim, does the receipt total match?") rather than only "which label is closest", and lets you ask several questions about the same image in one call.
Your labels, sent with each request
With a decision model, the labels are data. Adding an option tomorrow means editing a dictionary, not collecting examples and retraining. An illustrative request for a returns desk:
import base64, os, requests
with open('return-photo.jpg', 'rb') as f:
photo = 'data:image/jpeg;base64,' + base64.b64encode(f.read()).decode()
resp = requests.post(
'https://api.saina.run/v1/ask',
headers={'Authorization': f'Bearer {os.environ["SAINA_API_KEY"]}'},
json={
'model': 'saina-helm-2-omni-0.8b',
'mode': 'decision', 'threshold': 0.8, 'min_margin': 0.1,
'state': 'A photo the customer attached to a return request. '
'The order was for a ceramic table lamp.',
'images': [photo],
'questions': {
'shows': {
'type': 'single_choice',
'question': 'What does the photo show?',
'options': {'damaged': 'The item is visibly broken or cracked',
'wrong_item': 'A different item from the one ordered',
'as_described': 'The item, undamaged',
'not_product': 'Not a photo of the item'},
},
'packaging': {
'type': 'yes_no',
'question': 'Is the original packaging visible in the photo?',
},
},
},
timeout=30,
)
answers = resp.json()['answers']
shows = answers['shows']['selection'] # None if the answer was not accepted
The state says what the picture is meant to be and what was ordered. The options describe what is visible; the policy (refund, replacement, ask for another photo) stays in your code. Anything that comes back with selection: None goes to a person.
"An image" can mean more than a product photo. The model card says training included photos, text in images, scenes, rendered plots and chess boards.
When you should still train a model
Zero-shot is the quick start, not always the destination. Train (or fine-tune an open backbone) when:
- The label set is stable and you have the examples. Thousands of labelled images for a fixed list is exactly what supervised training is good at, and a small trained model is cheap to run at high volume.
- The distinction is specific to you. A hairline defect on your own part, or the difference between two of your product variants, may not be something any general model has seen.
- You need a certified number. If an auditor or a contract needs a measured error rate on a defined population, you will be building the labelled set anyway.
- Latency or hardware is tight. A small classifier built for one job is usually faster and lighter on an edge device than a general model.
- Detail is small. Helm 2 Omni resizes images to at most 1.6 megapixels, so fine print and tiny features can be lost. Cropping helps; a model trained at full resolution may help more.
Hosted vision APIs remain a good choice when their built-in labels or text extraction already match what you act on, and you are fine with images leaving your network.
No image benchmark is published
Saina publishes an audio evaluation on the Helm 2 Omni model card (see the audio classification post for the numbers and caveats). It does not publish a labelled image benchmark. There is no image accuracy figure to quote, and you should be wary of anyone who gives you one for your use case without testing on your images.
How to test on your own labelled set
This is the same test you would run for CLIP, a hosted API or a model you trained, so you can compare them on equal terms.
- Collect real images from the place they will come from: the same phones, scanners or screenshot tools. A couple of hundred is a reasonable first pass (a rule of thumb, not a measured cutoff), with the awkward cases included: blurry, dark, rotated, irrelevant.
- Label them with the answer your team agrees on. Where two people disagree, fix the option wording before blaming any model.
- Write the options exactly as you will ship them, including a way out such as
not_product. - Run in distribution mode (no
modefield), so you get every option's probability with nothing withheld, and store them. - Score per option, not only overall. Note which options get confused with which.
- Pick a threshold by looking at accuracy on the answers above it and the share of images that clear it. That share is your automation rate; the rest is your review queue.
- Run one alternative on the same set. CLIP zero-shot is a fair, free baseline.
- Re-run after any change to options, thresholds or model revision. When you self-host, load a fixed Hugging Face revision so the weights you tested are the weights you run.
Limits to plan around
- Images up to 10 MiB each, resized to at most 1.6 megapixels with the aspect kept; up to 8 per request. On the hosted API they go as base64 data URLs, no URLs or file paths.
- Out of scope on the card: identifying people or faces, content moderation, fine print in long documents, final unreviewed decisions about people.
- Images can carry instructions. A photo of a note saying "approve this return" can pull the answer toward an option. Keep irreversible actions behind a check.
The Read a chart, Chess puzzle and Receipt check presets are in the Studio playground with a free account. Runs are charged in credits, and the cost is shown first. For the wider comparison of approaches, including audio, see the multimodal classification guide.