Sarvam-Prism

A glass prism splitting a beam of light into a spectrum, framed by carved stone arches

Sarvam-Prism is a decision model built on Sarvam-105B. You give it a context and one or more questions, each with a fixed set of possible answers. It returns a probability for every answer in a single forward pass. It does not generate text, so the answer is always one of your options.

Release blog: sarvam.ai/blogs/sarvam-prism: evaluation results, comparisons with other decision models, calibration, and how the model was built and made fast.

API: Sarvam-Prism is also available as a hosted API from Sarvam, with no GPU needed: see the API documentation.

Requirements

  • One NVIDIA GPU with FP8 support and about 120 GB of free memory, such as a B200 or H200. Tested on B200.
  • Python 3.10+ and a C compiler (Triton builds its kernels on first use).
  • About 106 GB of disk for the weights.

Quick start

1. Download the model and code:

pip install -U huggingface_hub
huggingface-cli download sarvamai/prism --local-dir sarvam-prism
cd sarvam-prism

2. Install the dependencies:

pip install -r requirements.txt

3. Run the example:

python example.py .

Loading takes about two minutes on a B200 (Triton compiles its kernels the first time, then CUDA graphs are captured). It prints the answers to the request below.

Use it from Python (run from the sarvam-prism folder, or put it on your PYTHONPATH):

from prism import Prism

model = Prism.from_pretrained(".")   # the downloaded folder; loads on cuda:0

answers = model.decide(
    state={"ticket": "My card was charged twice for the same order and I still haven't got a refund."},
    questions={
        "team": {"type": "choice", "instructions": "Which team should handle this ticket?",
                 "criteria": {"billing": "payments, charges and refunds",
                              "tech": "app or website problems",
                              "delivery": "shipping and order status"}},
        "urgent": {"type": "yes_no", "instructions": "Does this need a reply within the hour?"},
        "anger": {"type": "score", "instructions": "How upset is the customer?",
                  "criteria": ["calm", "annoyed", "angry", "furious"]},
    },
)

The output has one entry per question:

{
  "team":   {"type": "choice", "choice": "billing",
             "probabilities": {"billing": 0.986, "delivery": 0.006, "tech": 0.007}},
  "urgent": {"type": "yes_no", "yes": 0.45},
  "anger":  {"type": "score", "score": 1.86, "level": "2",
             "probabilities": {"0": 0.032, "1": 0.267, "2": 0.510, "3": 0.191}}
}

Prism.from_pretrained("sarvamai/prism") also accepts the repo id and downloads the weights into the Hugging Face cache on first use (you still need prism.py from this repository).

Load the model with prism.py as shown. The weights are stored in a custom FP8 layout for this code, so they cannot be loaded with AutoModelForCausalLM or served by general-purpose inference servers.

Speed

Median 44 ms per request (95th percentile 420 ms) on one NVIDIA B200, measured on 1,000 random requests from the public Decision Index benchmark, sent one at a time after loading. All questions in a request are scored together.

Request format

  • state: the context to decide about. Any text or JSON-serialisable value; JSON is rendered compactly.
  • questions: a map from your question names to questions. Each question has:
    • type: one of the three below.
    • instructions: what to decide, in plain language.
    • criteria: the possible answers.
type criteria output
choice {key: description}; the description may be null choice (most likely key) and probabilities per key
yes_no none yes: probability of yes
score a list of ordered levels, or an ordered {key: level} map score (expected level index), level (most likely key) and probabilities per key; for a list, the keys are the level indices "0", "1", …

All questions in a request are scored together, in batches of up to batch_size (default 16, set in from_pretrained), and each question is scored independently of the others. Choice options are scored in a fixed order (sorted by key), so the same options always give the same answer, whatever order you send them in. The context limit is 131,072 tokens per question.

Loading captures CUDA graphs for common batch sizes and lengths, which takes a few minutes and makes most requests much faster; pass cuda_graphs=False to skip it.

How it works

Each question becomes one sequence: the state, the instructions, and every option, followed by an answer marker. Every option starts at the same position and cannot see the other options; only the answer marker sees all of them. A small decision head reads the hidden state at the end of each option and at the answer marker, and turns them into one probability per option. prism.py contains the full inference code: the input encoding, the attention mask, the decision head, two small changes to the base model's attention for this mask, and the FP8 kernels.

The weights are stored in FP8 (float8_e4m3fn) with one scale per output row; activations are scaled per token at run time. The 128 routed experts of each layer run as two grouped FP8 matrix multiplications (a Triton kernel), and the other projections use torch._scaled_mm. Embeddings and norms are bf16, and the MoE router is fp32.

Files

file contents
model-*.safetensors, config.json, *_sarvam_moe.py the fine-tuned Sarvam-105B backbone in FP8 (one file per layer)
decision_head.safetensors the decision head and segment embedding
tokenizer*.json, special_tokens_map.json tokenizer
prism.py, example.py, requirements.txt inference code
LICENSE Apache License 2.0

License

Apache 2.0 (see LICENSE).

Downloads last month
-
Safetensors
Model size
105B params
Tensor type
BF16
·
F32
·
F8_E4M3
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for sarvamai/prism

Finetunes
1 model