Usage
pip install "transformers>=5" torch safetensors huggingface_hub
from huggingface_hub import hf_hub_downloadimport importlib.util path = hf_hub_download('run-saina/saina-helm-0.8b', 'helm.py')spec = importlib.util.spec_from_file_location('helm', path)helm = importlib.util.module_from_spec(spec); spec.loader.exec_module(helm) model = helm.Helm('run-saina/saina-helm-0.8b')
helm.py builds the exact prompt the model was trained on; scores depend on that
format, so use it rather than a custom prompt. The model reads the last-token hidden
state, not generated text — generate() is not the intended interface.
Question types
ask() takes a piece of state (text or JSON) and any number of typed questions,
each answered with its own forward pass:
Table with columns: Type, You provide, You get| Type | You provide | You get |
|---|
yes_no | question, optional descriptions: {yes, no} | yes, no, confidence |
single_choice | question, options: {key: description or None} (2–255) | probabilities, selection, confidence |
multi_choice | question, options (2–255) | independent memberships per option |
rating | question, ordered levels (2–10) | probabilities per level, expected_level, confidence |
answers = model.ask( state='Order #4417: parcel arrived crushed, customer wants their money back. Third complaint this month.', questions={ 'refund': {'type': 'yes_no', 'question': 'Is a refund requested?'}, 'team': {'type': 'single_choice', 'question': 'Which team should handle this?', 'options': {'billing': 'Payments and refunds', 'shipping': 'Delivery and carriers', 'tech': None}}, 'issues': {'type': 'multi_choice', 'question': 'Which issues apply?', 'options': {'damaged': 'Item damaged', 'late': 'Late delivery', 'repeat': 'Repeat complainer'}}, 'urgency': {'type': 'rating', 'question': 'How urgent is this?', 'levels': ['Low', 'Medium', 'High', 'Critical']}, },)answers['urgency']['expected_level'] # e.g. 1.9 -> between Medium and High
Decision mode. Pass mode='decision' with a threshold (default 0.8) and,
for yes_no / single_choice, an optional min_margin; both can be overridden per
question. The answer then includes selected / selection / selections / level,
set to None with a reason (below_threshold, below_margin, tie) when the
model is not confident enough, so you can abstain and escalate instead of guessing.
Rating confidence accounts for distance between levels: probability spread across
neighbouring levels costs less than spread across distant ones.
For raw scores, model.predict(context, question, choices, mode='single_label' | 'multi_label')
returns one probability per choice.
Versions
Table with columns: Version, Date, Changes| Version | Date | Changes |
|---|
v1.0 | 2026-10-07 | First public release. |
Each release is a git tag on this repo, and main is the newest. Retrains that
only change the weights bump the minor version (v1.1). Changes that need callers
to change something (labels, prompt format, architecture) bump the major (v2.0).
Scores can shift between versions, so pin a tag if you've tuned thresholds.
path = hf_hub_download('run-saina/saina-helm-0.8b', 'helm.py', revision='v1.0')model = helm.Helm('run-saina/saina-helm-0.8b', revision='v1.0')
Limitations
- Probabilities are not calibrated; set thresholds on your own data.
- Results are sensitive to how options and questions are phrased.
- Evaluate on your task before relying on it for consequential decisions.