swiftpick-30B-A3B

swiftpick-30B-A3B is a decision model for agentic AI, trained and served with strands-decider. Unlike an LLM, which can generate arbitrary text, a decision model picks between sets of options and rates things on a scale, and every answer carries a calibrated confidence. It fits the decisions inside an agentic workflow: model routing, tool selection, argument checking, triage, guardrails, evaluations, and the rote decisions of a hybrid agent that leaves the hard ones to an LLM. It reads its inputs in one forward pass of a 31B-parameter mixture-of-experts decoder that activates about 3B parameters per token.

This repository holds one trained checkpoint: a LoRA adapter on nvidia/Nemotron-3-Nano-Omni-30B-A3B-Reasoning-BF16 plus a small readout head that scores the options of a typed question (noul, a yes/no question; choice, one of N options; score, a level on an ordered scale). The code, the training recipe, the data inventory and the evaluations are at https://github.com/harishvs/strands-decider, under Apache-2.0. This model is a derivative of nvidia/Nemotron-3-Nano-Omni-30B-A3B-Reasoning-BF16 and carries its license, the NVIDIA Open Model Agreement (https://www.nvidia.com/en-us/agreements/enterprise-software/nvidia-open-model-agreement/): see LICENSE.md and NOTICE.

The code is on a branch, not main. The code that trained this model and loads it is the tag swiftpick-30B-A3B-v1-mm on branch nemotron-30b-a3b of https://github.com/harishvs/strands-decider; the repository's main branch, and every strands-decider release, cannot load this base yet. The training config is configs/v1/swiftpick-30B-A3B-nemotron-v1.yaml.

Trained on text; reads images, video and audio zero-shot. The adapter and head were trained on the base's text decoder alone (transformers' nemotron_h, without the base's Hub code). Served with --multimodal, the same weights also read images, video and audio through the base's own frozen encoders (transformers' native nemotron_h_omni); that use was never trained, so read the media results below before relying on it (docs/multimodal.md).

Not the v1 recipe exactly. It trains on the 123,339 rows of the StrandsAgents/strands-decider-2B-hobson-v21 release, without the v1 releases' 12,263 code-task rows, which are not public, and each of its three runs has LoRA rank 64 rather than 16 (the soup's adapter holds the three at rank 192). For comparison with the Results below, the Gemma 4 v1 releases score 180 (E2B) to 207 (26B-A4B) of 231 on JevBench at the same window.

Use

pip install torch==2.10.0 --index-url https://download.pytorch.org/whl/cu130
pip install "strands-decider[multimodal] @ git+https://github.com/harishvs/strands-decider@swiftpick-30B-A3B-v1-mm"  # [multimodal]: Pillow, PyAV
# The Mamba kernels as prebuilt wheels for that Python 3.12 / torch 2.10 / CUDA 13 build; the
# two projects' GitHub releases hold the other builds. A source build needs the CUDA toolkit.
pip install https://github.com/state-spaces/mamba/releases/download/v2.3.2.post1/mamba_ssm-2.3.2.post1+cu13torch2.10cxx11abiTRUE-cp312-cp312-linux_x86_64.whl \
  https://github.com/Dao-AILab/causal-conv1d/releases/download/v1.7.0/causal_conv1d-1.7.0+cu13torch2.10cxx11abiTRUE-cp312-cp312-linux_x86_64.whl

No strands-decider release loads this base yet, so the commands above install the tagged code, and the Mamba kernels it needs on a CUDA host (without them, loading refuses). Then ask one or more questions about a state on a GPU: the torso is 31B parameters, 62.5 GB in bfloat16, so it needs one 80 GB GPU, or serve --device-map auto across several. The 62.5 GB of base weights download from the Hub at first use.

strands-decider ask harishvs/swiftpick-30B-A3B \
  --state "Help! My payouts have been failing for 3 days! " \
  --choice "Which team should handle this?=billing,sales,retail" \
  --noul "Does this convey urgency?" \
  --score "How frustrated is the writer?=calm,frustrated,depressed"

The output of this checkpoint on one GPU:

noul_0 noul = 0.964
choice_0 -> billing (confidence 0.838)
    billing                  0.892
    retail                   0.054
    sales                    0.053
score_0 score = 1.05 (confidence 0.787)
    0: calm                                     0.082
    1: frustrated                               0.784
    2: depressed                                0.134

Or serve it over HTTP. The server binds to 127.0.0.1 and has no authentication: use it for local experiments.

strands-decider serve harishvs/swiftpick-30B-A3B --port 8000
curl -s localhost:8000/v1/systemone -H 'content-type: application/json' -d '{
  "state": "Help! My payouts have been failing for 3 days!",
  "questions": {"is_urgent": {"type": "noul", "instructions": "Does this convey urgency?"}}
}'

In Python, strands_decider.modeling.StrandsDeciderModel.load("harishvs/swiftpick-30B-A3B"). The adapter in lora/ is a standard PEFT adapter on the Nemotron-H text decoder (transformers.NemotronHForCausalLM(...).model); it covers attention, the Mamba in_proj and the shared experts, not the 128 routed experts, their router, or the Mamba out_proj and conv1d; the head is head.safetensors.

Results

evaluation tasks right Brier ECE served
JevBench public, window 4096 183/231 0.287 0.059 these files
internal set accuracy n
eval: held-out short tasks 0.689 6,000
eval: boardgame 0.829 900
eval: contractnli 0.875 1,026
eval: hotpotqa (held out) 0.886 959
eval: musique 0.935 1,199
eval: musique, answerable 0.947 599
eval: musique, unanswerable 0.923 600
eval: [4] adequacy_hs2 0.744 234
eval: [5] gen:adequacy 0.868 302

JevBench v1.5 method, open half only (an estimate, not an official score)

JevBench v1.5 (METHOD-v1.5.md and its equal-types headline amendment) scores Intelligence per request type (Choice, Noul, Score) and tier, chance-corrected per item. A Noul answer counts only when P(yes) is at least 0.80 or at most 0.20; anything between is an abstention and is scored wrong. The method averages an open half and a sealed half. The figures below apply §3.1-3.2 to the open half only, on the 231 public items above, for this model and the strands-decider releases measured the same way. They omit the sealed half, the new v1.5 open items, the judge tier, the overfit penalty, and the Calibration and Cost axes, so they are not a JevBench v1.5 score or rank.

system Intelligence, open half (equal types) frozen 50/25/25 view Choice CC Noul CC Score CC Speed
swiftpick-30B-A3B (this model) 42.4 49.4 70.4 -5.0 61.9 88.7
strands-decider-26B-A4B-gemma4-v1-2610 65.7 70.6 85.2 44.7 67.3 84.0
strands-decider-12B-gemma4-v1-2610 61.0 65.3 78.3 40.0 64.7 87.6
strands-decider-E4B-gemma4-v1-2610 46.3 52.3 70.4 14.2 54.4 87.5
strands-decider-2B-hobson-v21 29.2 38.1 64.8 -36.1 58.8 91.2
strands-decider-2B-qwen3.5-v1-2610 29.0 38.0 64.9 -25.9 48.1 90.8
strands-decider-E2B-gemma4-v1-2610 24.7 33.8 61.2 -42.1 54.8 89.3

This model's Choice score equals the E4B's and its Score result is the third best, but it gives 32 of its 74 Noul (yes/no) answers a probability between 0.20 and 0.80 (the 26B-A4B: 15). Picking the more likely answer, 54 of the 74 would be right; with the v1.5 threshold, 37 are. Speed is v1.5's latency score on the public standard items with the self-hosted adjustment; each release was measured on its own GPU (this model: one RTX PRO 6000). The script, the per-tier values and their item counts are in eval/jevbench-v1.5-open/.

Images, video and audio (zero-shot)

Served with --multimodal, the same weights read media through the base's frozen encoders; no media were used in training. Measured through the serving path on one RTX PRO 6000 Blackwell (96 GB, bf16), once with the media and once with them removed; bootstrap 95% intervals. Full detail, settings and dataset revisions: docs/multimodal.md.

modality set items accuracy ECE media removed chance reference
image NaturalBench, first 300 groups 1,200 0.820 (0.801-0.840) 0.038 0.500 0.5 strands-decider-2B-qwen3.5-v1-2610 --vision: 0.776
image POPE adversarial, first 600 600 0.870 (0.843-0.897) 0.038 0.500 0.5 strands-decider-2B-qwen3.5-v1-2610 --vision: 0.872
audio MINDS-14 en-US, 14 intents 563 0.986 (0.975-0.995) 0.026 0.082 0.071
audio Speech Commands v0.02 test, keyword yes/no 600 0.963 (0.948-0.978) 0.135 0.500 0.5
video Perception Test MC val, 16 frames 300 0.720 (0.670-0.770) 0.054 0.397 0.333

With the media removed it still answers at a mean confidence of 0.74 to 0.82 on the image and keyword sets: check that the media are there before you ask. Abstract video questions are weak (0.44 on 73 questions). Datasets, none redistributed: NaturalBench (Apache-2.0), POPE, MINDS-14 (CC BY 4.0, PolyAI), Speech Commands (CC BY 4.0, Google), Perception Test (CC BY 4.0, Google DeepMind).

JevBench is the external benchmark (231 public tasks); the internal sets are this recipe's held-out short tasks, multi-step documents and answer-adequacy judgements. evaluation/README.md in the code repository describes each set, and its results pages give the figures by version. Per-skill results and the raw reports and logs are in eval/summary.json and eval/internal/.

Limitations

  • Its yes/no answers hedge. 32 of its 74 JevBench noul answers put P(yes) between 0.20 and 0.80 (the 26B-A4B v1 release: 15). Read noul as a probability: a consumer that acts only on confident answers, as JevBench v1.5 does, loses those.
  • Judgement trails the Gemma 4 26B-A4B v1 release: HelpSteer2 adequacy 0.744 against 0.808, BoardgameQA 0.829 against 0.869, JevBench's standard tier 65/72 against 72/72.
  • No code-task training rows (see above), and no held-out code evaluation for this model.
  • Images, video and audio are zero-shot (never trained). Measured on a few public sets only (Results); with the media missing it still answers at high confidence, so check that they are there. Video reads at most 16 frames, and abstract video questions are weak.
  • It needs a CUDA GPU with about 80 GB and the Mamba kernels, and downloads 62.5 GB of base weights at first use. There is no practical CPU path: the kernels take CUDA tensors only, and without them the PyTorch fallback is many times slower.
  • The general points below were measured on earlier releases; this model's own figures are in Results.
  • Questions are read less than documents. With the state and options fixed, a changed question often gets the same answer. Phrase a question so the obvious reading is the intended one.
  • Long, multi-step documents are the weak spot: JevBench's hard tier scores far below its easy tier.
  • score and noul transfer poorly to rubrics and yes/no tasks unlike the training mix. Train on a rubric resembling yours.
  • Calibration is one temperature per primitive, fitted on held-out short classification. The confidence bands are established there only: measure on your own traffic before you trust a threshold.
  • Trained on public datasets, so it inherits their domains and their label noise.

evaluation/README.md, section "Limitations", has the measured figures behind the general points, from earlier strands-decider releases.

Training data

The datasets list in the metadata holds the Hub datasets that the recipe reads. hotpotqa/hotpot_qa is for evaluation only. The recipe also uses these sources:

  • ContractNLI and MuSiQue, from their authors' releases (not from the Hub).
  • Synthetic rows that open-weight language models generated and checked.
  • The output distributions of the frozen teacher model Qwen/Qwen3.5-4B. They are training targets through data/teacher_v20.jsonl, which recipe.sh distill builds from the committed distributions (the teacher's on the short-task rows, v14's on the multi-step rows); no parent model is trained. A frozen-KL term (weight 0.3) also keeps the answers close to the released StrandsAgents/strands-decider-2B-hobson-v19.

In the code repository, data/sources.md lists every source with its revision, role, license and attribution, and data/README.md states what is committed, what is downloaded and the reproduction contract.

Training

Three training runs of configs/v1/swiftpick-30B-A3B-nemotron-v1.yaml (seeds 0, 1 and 2) by training/run_recipe.sh under torchrun on the eight GPUs of a g7e.48xlarge host (NVIDIA RTX PRO 6000 Blackwell Server Edition), about 1 h each, then python -m training.soup and calibration. Configs: train_config.json (seed 0's) and training/configs/, the runner's copies (it copies a parent config too; this recipe trains no parent).

To retrain, run the config's header commands on one host with eight GPUs of 80 GB or more (a run peaks at 64.4 GiB per GPU), after training/recipe.sh build fetch multistep generated adequacy distill and the download of the v19 checkpoint the header names. training/README.md has the setup, the stages and the hardware notes.

Provenance

provenance.json: base model and revision (pinned: the training config's base_revision, which the loader reads), and the sha256 of the config, adapter and head, and a fingerprint of the source checkpoint. MANIFEST.sha256 lists every file; python -m training.hf_export verify <folder> checks them. The run records keep their timings and results; host paths, cloud identifiers and cost fields are removed.

Downloads last month

-

Downloads are not tracked for this model. How to track
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for harishvs/swiftpick-30B-A3B

Adapter
(3)
this model

Datasets used to train harishvs/swiftpick-30B-A3B

Evaluation results