Decision models
Train a ModernBERT or Ettin encoder, such as kev, to score the candidates of typed decisions with calibrated probabilities, evaluate it on a GPU, and download it or publish it to Hugging Face.
A decision model answers typed questions about a text: which team should handle a request, whether it needs a refund, how urgent it is on a scale. Each question comes with its candidate answers. The model scores every candidate and returns a probability for each, calibrated with a temperature fitted on your own data. kev is one: a ModernBERT encoder of about 400 million parameters.
A decision project trains such a model on your own decisions, with LoRA or full training on one GPU. Each run scores the base model and the tuned model on your test cases, fits the temperature that calibrates the probabilities, and keeps a model that you download, publish to your Hugging Face account and load with kev. Decision models need the Pro plan: see Plan. Tensorant doesn't serve them yet: see What decision projects don't have yet.
When to use a decision model
| Model | It answers with | Use it when |
|---|---|---|
| A chat model, trained with SFT, DPO or RL | Text it writes | The answer is open: an explanation, a summary, a JSON object |
| A decision model | A probability for each candidate you give it | The answer is one of a few known options: a route, a yes or no, a level on a rubric |
Use a decision model for routing, triage, moderation and scoring, where you know the options and need probabilities you can act on, such as sending a case to a person below 70%. It never answers outside its candidates, and the candidates can differ from one question to the next: the model reads them with the question.
Before you start
- A decision project. See Create a decision project.
- The Pro plan, to create the project and launch its runs. See Plan.
- A version with training, validation and test cases. See Prepare your data.
- A GPU account and storage, connected by an owner. See Training runs.
- A training run left in your plan this month. A decision run counts as any training run does, and so does an evaluate run.
- The member or owner role.
Create a decision project
A project's kind comes from its base model when you create it, and never changes.
- Open the project switcher and choose New project.
- Under Hugging Face base model, enter a decision model, or pick one under Decision models (on the Pro plan) in the suggestions:
skundu42/kev,jhu-clsp/ettin-encoder-400moranswerdotai/ModernBERT-base. See Supported models. - Wait for the model check. For kev it says "Decision model · ModernBERT · head kept · ≈396M parameters".
- Enter a Project name and choose Create project.
What the check says about the model's head:
| The model | The check says | What training does |
|---|---|---|
| A scorer with one output, such as kev | head kept | Training continues from its head, and its own temperature (from its kev_config.json) scores it before training. |
| ModernBERT or an Ettin encoder without a head | new head | Training adds a new head that gives each candidate one score. |
| A ModernBERT model with another head, such as a classifier with several outputs | head replaced, with "Its classification head is replaced by a new one-score head." | Training replaces its head with a new one-score head. |
Encoders of other families, BERT, RoBERTa, DeBERTa v2 and v3, XLM-RoBERTa, ELECTRA and DistilBERT, are refused: "Tensorant trains decision models on ModernBERT and Ettin encoders." On a plan without decision models, the dialog shows the plan message with Upgrade, and Create project is unavailable.
A decision project's sidebar has Data (Sources, Review, Versions) and Tune (Runs, Evaluations). Home shows its next step: add sources, review the cases, create a version, then train or evaluate.
What decision projects don't have yet
A decision project has no Playground, Models, Experiments or Recipes: Tensorant doesn't serve decision models yet, and doesn't generate decisions from documents. It trains with the decision objective alone, so no SFT, DPO or RL, and has no training trials. Agents and the CLI can't work in decision projects yet. The API refuses the work of those pages, DPO, RL and every request of an agent with "Decision projects can't use this yet."
To use a trained model, download it or publish it to Hugging Face, and load it with kev.
How a run works
A case is one state, such as a support ticket or an agent's trace, with one or more typed questions about it. Each question is one decision: its candidates, and the gold probability of each.
A decision is scored the way kev scores it. Its question becomes one prompt, such as this one for the first question of the typed-decisions row below:
Decision type: choice
Instructions: What should the observability system do with this trace?
State:
{"agent": {"autonomy": "checkpointed", "model": "internal-agent-v1"}, "task": "Rotate the expired TLS certificate on the staging load balancer.", "trace_summary": {"constraint_violations": 0, "irreversible_actions": 0, "steps": 11, "tool_errors": 0}}
Criteria:
0: continue: Let the agent proceed without interruption.
1: human_review: Queue this trace for a human to review.
2: observe: Keep running, but flag the trace for later sampling.
3: stop: Halt the agent now.Each candidate is read as the pair of that prompt and the candidate, and gets one score. The probabilities are the softmax of the scores divided by the temperature. A temperature above 1 makes the probabilities less sure, below 1 more sure.
A run, on one GPU:
- Checks every decision, before the model's weights download: each prompt and candidate pair must fit in the Token limit, and each decision may have at most Most candidates. A decision is never cut short: the run stops instead, naming how many decisions are over. See When something goes wrong.
- Scores the base model on the version's test split, with the model's own temperature (1 for a model without one). This is its first evaluation.
- Trains with LoRA or full training, one decision a step with all its candidates. The loss compares each decision's probabilities with its gold probabilities, so gold that splits between candidates trains the model to be unsure between them. Every tenth of the steps it measures the loss on the validation split and saves the model, and it keeps the one with the lowest validation loss. With LoRA, the added weights are then merged into the model.
- Calibrates: it fits the temperature that gives the lowest loss on the validation split, between 0.05 and 20. With fewer than 50 validation decisions it keeps the base model's temperature, and the log says so.
- Scores the tuned model on the test split, with that temperature. This is its second evaluation.
- Exports the model kev loads.
The validation split picks the kept model and fits the temperature, and the test split is used only to score. Unlike a chat run, a decision run reads the test cases on the GPU machine, to score them there.
Prepare your data
A decision project imports cases in one of two shapes. It imports no documents: its import takes JSON Lines, JSON, CSV, TSV, YAML or Excel rows.
Typed decisions
Each row is a case: a state, its questions by identifier, and the gold answer of each question. This is a row of LocalLLaMA/typed-decisions, shortened to three of its five questions and a shorter state, and written as objects for reading:
{
"workflow": "agent_trace_observability",
"state": {"agent": {"autonomy": "checkpointed", "model": "internal-agent-v1"}, "task": "Rotate the expired TLS certificate on the staging load balancer.", "trace_summary": {"constraint_violations": 0, "irreversible_actions": 0, "steps": 11, "tool_errors": 0}},
"questions": {
"action": {"type": "choice", "instructions": "What should the observability system do with this trace?", "criteria": {"continue": "Let the agent proceed without interruption.", "human_review": "Queue this trace for a human to review.", "observe": "Keep running, but flag the trace for later sampling.", "stop": "Halt the agent now."}},
"needs_review": {"type": "noul", "instructions": "This trace requires human review.", "criteria": {"false": "No human attention is warranted.", "true": "A human should inspect this run."}},
"risk": {"type": "score", "instructions": "How risky was the agent's behaviour in this trace?", "criteria": ["Benign: read-only or clearly safe actions.", "Low: routine writes within scope.", "Moderate: irreversible or out-of-scope actions.", "High: destructive, security-relevant, or policy-violating actions."]}
},
"gold": {
"action": {"label": "continue", "probabilities": {"continue": 0.583333, "human_review": 0.29, "observe": 0.09, "stop": 0.036667}},
"needs_review": {"label": "false", "probabilities": {"false": 0.643333, "true": 0.356667}},
"risk": {"label": "1", "probabilities": {"0": 0.3, "1": 0.616667, "2": 0.076667, "3": 0.006667}}
}
}The dataset keeps state, questions and gold as JSON text in its columns, as a CSV cell can. The import reads questions and gold from JSON text or objects alike. A state that is text is kept as it is; any other JSON value becomes JSON text with sorted keys, as kev writes it.
A question has a type, its instructions and its criteria, which give its candidates:
type |
criteria |
Candidates, in order | Candidate keys |
|---|---|---|---|
choice |
Names, each with a description or null |
"name: description", or the name alone, sorted by name | The names |
noul (no or yes) |
false and true, each with its text, or null |
The two texts, or "No" and "Yes" | false, true |
score |
A list of levels, in order | The levels, in the list's order | 0, 1, 2... |
The gold of a question is the first of these it has:
probabilities: a probability for every candidate key, summing to 1. Several annotators who disagree, as in typed-decisions, give a split gold.label: one candidate key, which gets probability 1.noul, for anoulquestion: the probability oftrue.score, for ascorequestion: the level that gets probability 1, counted from 0.
Other fields of a gold entry, such as typed-decisions' confidence, are left out. Probabilities are stored with 4 decimals: 0.583333 becomes 0.5833.
Map the columns under Column mapping, with Import as set to Typed decisions · state, questions, gold: State column, Questions column, Gold column and Category column (optional). A column left empty is found by its name: state, questions and gold. Rows with these three columns are proposed as typed decisions, and a workflow column, as typed-decisions has, becomes the category.
Labelled texts
Each row is a text and its label, such as a CSV of support messages:
text,label
I was charged twice this month.,billing
The app crashes when I open settings.,technical
How do I change the email on my account?,accountWith Import as set to Labelled texts · a text and its label, each row becomes a case: its text is the state, and one choice question asks for its label among the import's labels.
- Labels lists the candidates: 2 to 16 distinct labels. It is filled in from the label column of the first rows: remove a label with its ×, add one with Add a label, or choose Use the labels of the rows. A row whose label is not listed is skipped.
- Question identifier (optional) names the question in results:
labelunless you change it. - Instructions (optional) say what the model is asked about each text: "Choose the label that fits the text." unless you write your own.
- A number or true or false label is matched as written, such as
1ortrue. - A Hugging Face class column holds class numbers, so its labels are the numbers (
0,1...), not the class names.
Map Text column, Label column and Category column (optional). Labels have no descriptions: to describe the candidates, import typed decisions instead.
Import the cases
- In Sources, choose Add sources, and upload files, paste rows or load a Hugging Face dataset, as for any import. See Sources.
- Check the mapping. Preview of the first N rows. The import checks every row. shows the cases as the mapping reads them. For files and pasted rows, it also marks the rows that can't be used, with the reason.
- Choose what to use the rows for: training and validation, or held out for test. See Training or evaluation.
- Keep Approve the cases as they arrive ticked, or untick it to read each case in Review first.
- Import.
A row that can't be used is skipped and listed in the import report with its reason, which names question identifiers and never your text, such as "Question route: gold probabilities must sum to 1". See When you import.
To import typed-decisions itself, load LocalLLaMA/typed-decisions on the Hugging Face tab and choose the subset all, or one workflow's. Import the train split for Training and validation, then the test split, which always stays held out. all has 1,200 training and 400 test cases of 5 questions each.
Review and versions
In Review, a case shows its State (JSON indented), then each question with its type, its instructions, and its candidates with bars for their gold probabilities. Gold label names the candidate with the highest. Choosing another label sets its probability to 1 and the others to 0, and Save returns the case to pending. Probabilities themselves can't be edited. Approve and Reject work as for examples, and Category is under More.
A version of a decision project holds approved cases. It keeps each case whole, all its questions in one split, and keeps cases that share a state, or the same decision, together in one split. Versions shows each split's cases and their decisions.
Readiness for training counts the tokens of every prompt and candidate pair of the cases it checks, with the model's own tokenizer: Longest pair (tokens), Decisions over the limit, Token limit and Decisions checked. It checks a sample of the cases, as for examples, and a run checks every decision before it trains.
Configure a decision run
Saving a run never starts a GPU.
- Open Runs under Tune and choose Configure a run.
- Under Run, keep Train model. To score a model without training, see Evaluate a model.
- Training objective is Decision · candidate scoring. Choose the Training method: LoRA, or Full training · every weight, more GPU memory. Choosing one sets Learning rate to its own default.
- Choose the Dataset version.
- Choose the Training provider, Training GPU, Time limit (hours) and Price limit ($/hour), as for any training run. A decision run has no baseline to choose: it scores the base model itself.
- Under Decision settings, check Token limit, Most candidates, Learning rate and Epochs. See Settings.
- Look at Readiness for training below the form.
- Choose Save training draft, then launch it as you would any run. See Launch a run.
Number of GPUs shows 2, 4 and 8 with "(decision models train on one GPU)", and they can't be chosen. On a plan without decision models, the form shows the plan message with Upgrade, or See plans if you are not an owner. A draft still saves.
Settings
Under Decision settings:
| Field | Default | Range | What it does |
|---|---|---|---|
| Token limit | 1,024 | 128 to the model's limit: at most 7,999 tokens, kev's limit, and at most the model's own positions | Every prompt and candidate pair must fit in it. Nothing is cut short: a longer decision stops the run before training. |
| Most candidates | 16 | 2 to 16 | The most candidates a decision may have. A run of a version with a decision of more can't be saved or launched. |
| Learning rate | LoRA: 0.0002; full training: 0.00002 | Full training: at most 0.0001 | How far each update moves the model. |
| Epochs | 3 | 0.1 to 20 | Passes over the training decisions. |
Under Advanced settings:
| Field | Default | What to know |
|---|---|---|
| Adapter size (LoRA rank), Adapter scaling (LoRA alpha) | 16 and 32 | LoRA only. LoRA trains small added weights on the encoder's linear layers, and the head in full. They are merged into the model at the end, so the result is a whole model either way. |
| Gradient accumulation | 32 | Decisions per update. A decision run trains on one decision a step, with all its candidates, so there is no Micro batch size: gradient accumulation alone sets the batch. Raise it for a larger batch. |
| Container disk (GB), Output volume (GB) | 50 and 80 | As for other runs. The output volume holds the model and its checkpoints. |
| Model revision | main |
Pinned to one commit when you save. |
Every decision run also uses a weight decay of 0.01, a warmup over the first 3% of the steps, AdamW, bfloat16 arithmetic over full-precision weights, gradient checkpointing and seed 42.
GPU memory
The model check estimates a decision model's GPU memory from its parameters: 4 bytes a parameter with LoRA and 16 in full training, plus 6 GiB. For kev that is about 7.5 GiB with LoRA and 11.9 GiB in full. Training GPU marks each GPU by it, and the launch refuses a smaller one.
The estimate assumes decisions of up to 16 candidates of 1,024 tokens, and is only an estimate. A run with a long token limit, or with many candidates, can pass the launch check and then stop on the GPU with "…does not fit in this GPU's memory…" (see When a run stops), once its GPU has started and is billed. Start at the default token limit, and choose a larger GPU before you raise it.
Follow a run
Select the run to open it. The page refreshes by itself. Its status says what the run does: Checking decisions, Scoring base model, Training · step N / M (Training · N% in the list), Calibrating, Scoring tuned model and Exporting model. Its steps are Launched, Preparing, Checking, Scoring base model, Training, Calibrating, Scoring tuned model, Exporting and Model ready.
Besides what every run shows (see Follow a run), a decision run shows:
- Loss: the training loss and the validation loss by step. While the run goes on, a sentence below says what it does, such as "Fitting the temperature that calibrates the probabilities, on the validation split."
- Run: Token limit, Candidates, Learning rate, Epochs and, once known, Temperature.
- Scores on the test split of the version, once the run has scored the tuned model: Accuracy, Log loss, Brier score and Calibration error (ECE) of the tuned model, each with the base model's score and the change below it, green when it improved and red when it got worse. A lower log loss, Brier score and calibration error are better. Compare evaluations opens the two evaluations side by side. A sentence gives the temperature, such as "The tuned model's probabilities use a temperature of 1.27, fitted on the validation split."
- Training logs, which hold numbers only, never your cases. The first line reads "Decisions checked in S s: N train, N validation, N test; P pairs, the longest L tokens (limit T, model M); at most C candidates (limit K).", and the next ones give the base model's scores, the steps trained with the kept model's validation loss, the temperature, the tuned model's scores and the peak GPU memory.
- In the ⋯ menu, Download job files: the run's cases, as the GPU reads them, and its configuration. Unlike a chat run's, they hold the test cases too.
While the console is open, a notice says when the run finishes ("Training finished": "run: the model is ready."), fails ("Training failed", with the reason) or stops before its output was collected ("Training stopped": "run: its model waits for recovery."), with Open run.
The result
A finished decision run shows Model ready. The model is the folder kev loads, with the temperature its run fitted, and the run's two evaluations are in Evaluations. The panel says "The model is saved and checked (size), with the temperature that calibrates its probabilities." Use this model offers:
- Download model, with its size: a ZIP of the model. Every role can download it, and each download is recorded in the audit trail.
- Publish to Hugging Face: see Publish to Hugging Face.
- Open repository, once published.
- Evaluate model: score it on another version. See Evaluate a model.
The ZIP holds training_manifest.json (the run, its version and its settings) and a model folder:
| File | What it is |
|---|---|
model.safetensors |
The weights in full precision, about 1.6 GB for a 400-million-parameter model |
config.json |
The model's configuration, with one output |
tokenizer.json, tokenizer_config.json |
The tokenizer, and special_tokens_map.json when the tokenizer writes one |
kev_config.json |
What kev reads: the token limit, the most candidates, the base model and its revision, and the temperature, with the calibration's record |
training_config.json |
The run's training settings |
The scores in the run are on the test split of the version the run trained on. To score the model on another version, evaluate it.
Load it with kev
The DecisionModel of kev loads the model folder. kev runs on a Linux machine with a CUDA GPU, and expects Python 3.12, PyTorch 2.11 and Transformers 5.16, as its GPU and container guide describes. Unzip the download into a kev checkout, here as models/routing (use your file's name in place of model.zip):
git clone https://github.com/skundu42/kev.git
cd kev
unzip ~/Downloads/model.zip -d ./models/routingThen, in the kev folder:
from kev.inference import DecisionModel
model = DecisionModel.from_pretrained("./models/routing/model")
result = model.predict(
state="The text the decision is about.",
questions={
"answer": {
"type": "choice",
"instructions": "Choose the option that fits the text.",
"criteria": {"first": "The first option", "second": "The second option"},
},
},
)
print(result)kev refuses a decision with more candidates than Most candidates, or a prompt and candidate longer than the Token limit, rather than cutting it short.
Publish to Hugging Face
Publish to Hugging Face, in Use this model, uploads the model to a repository of your organization's Hugging Face account, private by default, with your organization's own token with write access. It works as it does for an adapter: see Publishing adapters to Hugging Face. The repository starts as your token's account and the base model's name with -decision, such as acme/kev-decision. A notice says "Model published to Hugging Face" when it is done.
One commit adds model.safetensors, config.json, the tokenizer files, kev_config.json and, if the repository has none, a model card. The card names the base model and its revision, the method, the epochs, the learning rate, LoRA's rank and alpha for a LoRA run, the token limit, the most candidates and the temperature, and shows how to load the model with kev. It names no dataset and carries no scores. The published kev_config.json leaves out the calibration's record, whose counts and losses describe your validation split; kev doesn't read it. Before uploading, Tensorant checks again that the model in storage is the one the run verified.
Evaluate a model
An evaluate run scores one model on a version's test split, on a GPU, and trains nothing: the project's base model, or the model of a finished training run of the project. Use it to score the base model before you train, or a trained model on a newer version.
- In Evaluations, choose Evaluate model. Evaluate model is also on Home, and in Use this model on a finished run, which chooses that run's model.
- Run is Evaluate model. Under Model, choose Base model · model, or a finished run, listed as run · trained on vN.
- Choose the Dataset version: its test split is scored.
- Choose the provider, GPU, time limit and price limit. A GPU is checked against the memory LoRA training would need: "Memory is estimated as for training with LoRA; scoring needs less."
- Check Token limit and Most candidates under Decision settings.
- Choose Save evaluation draft, then launch it. It counts toward your plan's training runs, and needs the Pro plan.
Its status reads Checking decisions, Scoring model and Saving scores, and its steps are Launched, Preparing, Checking, Scoring and Evaluated. When it completes, it shows the model's scores and temperature, and a notice says "Evaluation finished": "run: the scores are ready.", with Open evaluation. It is named "Evaluation N on vX", where a training run is "Model N on vX".
A run's model is scored with the revision of the base model that run trained on, and must be in the storage your organization uses now. The evaluation of a run's model is compared with that run's own evaluation of the base model when that scored the same version.
Decision evaluations
Evaluations lists a decision project's evaluations as Base model or Tuned model, with the model, the version and the main score, Accuracy. All, Base model and Tuned models filter the list. An evaluation is named "Baseline N on vX" when it scored the base model and "Tuned N on vX" when it scored a trained one.
| Metric | What it measures | Better |
|---|---|---|
| Accuracy | Share of decisions whose top candidate has a gold probability above zero. | Higher |
| Log loss | Cross-entropy of the predicted probabilities against the gold probabilities, averaged over decisions. | Lower |
| Brier score | Squared differences between the predicted and the gold probabilities, summed over the candidates and averaged over decisions. From 0 to 2. | Lower |
| Calibration error (ECE) | Expected calibration error over 15 confidence bins: how far the top candidate's probability is from its gold probability. A measure of the whole test split, not of each decision. | Lower |
| Rubric error | Score questions only: how many levels the predicted expected level is from the gold one. | Lower |
Probabilities switches between Calibrated, at the evaluation's temperature, and Uncalibrated, at temperature 1 as the model gives them. Log loss, Brier score, calibration error and rubric error are recorded both ways, the second as metric (uncalibrated). Accuracy is the same either way. The bars always show the calibrated probabilities.
An evaluation's results show the metrics, the scores broken down by Category, Question or Question type under Break down by, and the test decisions, 25 a page. Choose a group, or one under Filter group, to filter the decisions. Open a decision to see each candidate's probability beside its gold probability, the scores, and its case.
Compare with pairs two decision evaluations of the same version, decision by decision, as comparisons of answers do. A decision is Newly right or Newly wrong on accuracy, and Improved or Regressed on another metric, by the metric's direction: a lower log loss is an improvement. Decisions compared counts the pairs, and Independent cases the test cases they come from. The likely range draws the test cases again 2,000 times, each case with all its decisions, and needs at least 10 test cases. A decision evaluation can't be compared with an evaluation of a chat model's answers.
Plan
Decision models are on the Pro plan. Creating a decision project, and launching a decision run or an evaluate run, are refused on other plans with "Decision models are on the Pro plan. An owner can change the plan under Settings → Plan and billing." The notice offers Open Plan and billing. A draft run saves on any plan, and a run that is already going is left alone if the plan changes. Downloading and publishing a model you trained needs no particular plan. See Decision models in Plans and billing.
Tips
- Start at the default token limit. The memory estimate assumes 1,024 tokens. Before you raise the limit, choose a GPU with more memory. Readiness for training shows your longest pair.
- Keep the candidates few and distinct. Each candidate is one more pair to score in every step, and candidates that read alike are hard to tell apart.
- Give the validation split at least 50 decisions. With fewer, the temperature can't be fitted and stays the base model's.
- Keep the gold you have. Probabilities from several annotators teach the model where people disagree.
- Score the base model first. An evaluate run of the base model shows how far it is from your gold before you train. A training run scores it anyway.
- Read the calibration error too. A model can gain accuracy while its probabilities get less trustworthy.
Limits
| Limit | Value |
|---|---|
| Base model | 1.2 billion parameters, so that a trained model fits in its 5 GB archive |
| GPUs per run | 1 |
| Training method | LoRA or full training |
| Decisions per step | 1, with all its candidates; Gradient accumulation sets the batch |
| Token limit | 128 to 7,999 tokens, kev's limit, and at most the model's own positions; 1,024 by default |
| Candidates of a decision | 2 to 16 |
| Questions of a case | 1 to 32, each identifier 1 to 64 letters, digits, underscores, hyphens or periods |
| State | 32,000 characters |
| Instructions, and each candidate | 2,000 characters |
| Gold probabilities | Each from 0 to 1, summing to 1; stored with 4 decimals |
| Labels of a labelled import | 2 to 16 distinct labels, each up to 200 characters, 2,000 together |
| Category | 80 characters |
| JSON in a state, instructions or criteria | 32 levels of nesting |
| Cases in a version | 50,000 approved cases, 64 MB with their sources |
| Validation decisions to fit a temperature | 50 |
| Test decisions a run scores | 25,000; a run's report holds one result for each test decision of each model it scores |
| A trained model's archive | 5 GB |
| Machine memory | The run holds the token IDs of every prompt and candidate pair of the version in the machine's memory, beside the GPU's. A version of long states with many questions and candidates needs a machine with more memory. |
When something goes wrong
When you create the project
| Problem | What to do |
|---|---|
| "Decision models are on the Pro plan. An owner can change the plan under Settings → Plan and billing." | Ask an owner to upgrade to Pro: the notice offers Open Plan and billing. See Plan. |
| "Tensorant trains decision models on ModernBERT and Ettin encoders." | The model is an encoder of another family. Choose a ModernBERT or Ettin encoder. See Supported models. |
| Warning: "Its classification head is replaced by a new one-score head." | Not a problem: the model's own head doesn't give each candidate one score, so training starts a new head. To keep a head, choose a scorer with one output, such as kev. |
| "This model is not a decision model: choose a ModernBERT or Ettin encoder." | A decision project needs a decision model. A request sent with the API gets this too. |
| "This model is too large to train as a decision model: a trained model is exported in a 5 GB archive at most. Choose a model of at most 1.2 billion parameters." | A trained model is exported in full precision, 4 bytes a parameter. Choose a smaller model, such as kev or an Ettin encoder up to 1B. A run of a project whose model has grown past the limit since gets it too, when it is saved or launched. |
| "This project trains decision models; choose a ModernBERT or Ettin encoder." | In Project settings, a decision project's base model can change only to another decision model, and only while nothing fixes it. See When the base model can no longer change. |
| "This project trains chat models; choose a model with a chat template." (the console's message) | In a chat project's settings, a decision model can't be the base model. Create a decision project for it. A request sent with the API gets "Choose a model with a tokenizer chat template". |
| "Test sessions and API models serve chat models: choose a model with a chat template." (the console's message) | A decision model can't be deployed for testing or published as an API model. Download it, or publish it to Hugging Face. A request sent with the API gets "Choose a model with a tokenizer chat template". |
| "Decision projects can't use this yet." | A page or tool for chat projects: the Playground, models, experiments, recipes, DPO, RL, trials, or an agent or the CLI. See What decision projects don't have yet. |
When you import
| Problem | What to do |
|---|---|
| "Decision projects import typed decisions or labelled texts. Choose the decisions mapping mode (state, questions and gold columns) or the labels mode (text and label columns)." | Set Import as to Typed decisions or Labelled texts. A decision project imports no documents or chat examples. |
| "Typed decisions and labelled texts import into decision projects. Choose text, qa, chat or preference mapping mode." | A chat project can't import decisions. Create a decision project for them. |
| "Use named state, questions, gold or category columns" or "Use named text, label or category columns, the labels list, and optionally the question's identifier and instructions" | The mapping names something its mode doesn't read, or a value that is too long: a column name over 200 characters, or instructions or labels over 2,000. |
| "Choose the labels: a list of 2 to 16 distinct labels." | Under Labels, keep 2 to 16 labels that differ from each other. |
| "Questions: each identifier must be 1 to 64 letters, digits, underscores, hyphens or periods" | Fix Question identifier (optional), or leave it empty for label. |
| "Its label is not one of the import's labels" (skipped row) | Add the label under Labels and import again, or leave the row out. |
| "The mapped label column is missing or null" (skipped row) | Name the right Label column, or leave out the rows without a label. |
| "The mapped category column holds a NUL character or invalid Unicode" (skipped row) | Fix the row's category text. |
| "The mapped category column is missing or null" or "Category must be text with at most 80 characters" (skipped row) | Fix the category, or clear Category column (optional). |
| "State: expected text" or "State: expected text of at most 32,000 characters" (skipped row) | Give the row a state that isn't empty, of at most 32,000 characters. |
| "Questions: expected 1 to 32" or "Questions: expected an object of questions by identifier" (skipped row) | Give each case 1 to 32 questions, as an object by identifier. |
| "Question id: expected the type choice, noul or score" (skipped row) | Set the question's type to choice, noul or score. |
| "Question id: instructions are required" or "Question id: instructions must be at most 2,000 characters" (skipped row) | Give the question instructions of at most 2,000 characters. |
| "Question id: choice criteria must map non-empty names to descriptions", "Question id: noul criteria must have exactly false and true, or be null" or "Question id: score criteria must be a list of levels" (skipped row) | Shape the criteria for the question's type. See Typed decisions. |
| "Question id: expected 2 to 16 candidates", "Question id: candidates must not be empty", "Question id: each candidate must be at most 2,000 characters" or "Question id: candidates must be distinct" (skipped row) | Give the question 2 to 16 candidates that differ, none empty, each of at most 2,000 characters. |
| "Question id: gold is missing" or "Gold: expected entries only for the questions" (skipped row) | Give exactly one gold entry for each question. |
| "Question id: gold probabilities must name exactly the candidate keys" or "Question id: the gold label is not a candidate" (skipped row) | Use the candidate keys: a choice's names, false and true, or a score's levels from 0. |
| "Question id: gold probabilities must be numbers from 0 to 1" or "Question id: gold probabilities must sum to 1" (skipped row) | Fix the probabilities. They must sum to 1 within 0.000001. |
| "Question id: gold needs probabilities or a label", "Question id: the gold noul must be a probability from 0 to 1" or "Question id: the gold score must be a level from 0 to N" (skipped row) | Give the question's gold as probabilities, a label, a noul probability or a score level. |
When you create a version
| Problem | What to do |
|---|---|
| "Approve cases in Review before creating a version." | Approve cases in Review first. |
| "Your first version needs at least 10 cases that share no state or decision with each other, or a separate test file, so test cases never share a state or a decision with training cases. You have N." | Approve more cases with states of their own, or import a separate test set for Test (held out) and approve its cases. |
| "A version needs at least 3 cases that share no state or decision with each other: 2 for training and validation, 1 for testing. You have N." | Approve cases with states of their own. |
| "A version needs train, validation and test cases, and has none for splits. Assign rows to splits when you import them, or approve more cases that share no state or decision with the others." | Import cases for the missing split, such as a dataset's test split, or approve more cases. |
| "Some test cases share a state or a decision with training cases. Reject the overlapping cases in Review, then create the version." | Find the overlap with search in Review and reject it, or delete one of the imports. |
| "An edited case now shares a state or a decision with cases in another split. Change or reject it in Review, then create the version." | Change or reject the edited case. |
| "A version holds chat examples or decision cases, not both. Reject the approved examples of the other kind in Review, then create the version." | Reject the examples that aren't cases. |
| "A version holds at most 50,000 approved cases…" or "Approved cases and their sources are over the 64 MB limit of a version…" | Reject cases you don't need. |
| "Wait for the quality checks of approved cases to finish, then create the version." | Wait for the checks in Activity. |
In Readiness for training
| Problem | What to do |
|---|---|
| Blocked: N decisions longer than the T-token limit, with "Question id: its longest prompt-and-candidate pair is L tokens, over the T-token limit. Shorten the case, or raise the token limit when you configure a run." | Raise Token limit within the model's limit, with a larger GPU, or shorten those cases in your data and import them again. |
| "The token limit (N tokens) is longer than the model's P-token context." | Lower Token limit to the model's limit. |
| "Question id has N candidates, over the 16 a decision can have. Repair or reject this case in Review." | Reject the case, and import it again with at most 16 candidates. |
| A case's problem, such as "Question id: gold is missing", followed by "Repair or reject this case in Review." | The case was stored without its checks. Reject it, and import it again. |
| "The selected model's tokenizer cannot encode this case's prompts and candidates; review its text." | Look at the case's text, and reject it if it can't be fixed. |
| "Token analysis reached its bounded text budget; a run checks every case before it trains." | The free check stopped counting long cases. The run checks every decision before it trains. |
| Warning: "Checked a random sample of N of M cases, so counts and categories are estimates." | Not a problem: the check reads a sample. The run checks every decision. |
| Warning: "Includes pending and approved cases. Only approved cases go into a version, and its splits are chosen when it is created." | Not a problem: the check of Cases not in a version yet reads pending cases too. |
| Warning: "Cases that share no state or decision with each other are counted among the cases checked; unseen cases may share a state or a decision with them." | Not a problem: the count comes from the sample. |
| Warning: "A first version needs at least 10 cases that share no state or decision with each other, or a separate test file." | Approve more cases with states of their own, or import a test set for Test (held out). |
| Warning: "The test split has fewer than 10 cases that share no state or decision with each other, so score ranges and category comparisons will be rough." | A comparison needs at least 10 independent test cases for a likely range. Import more test cases. |
| Warning: "The sources of some cases could not be read in this check, so the counts of cases that share no state or decision with each other may be low." | Use Check connection on the Data storage card in Connections, then check again. |
In Review
| Problem | What to do |
|---|---|
| A case's problem, such as "Question id: candidates must be distinct", when you save | Review saved nothing: the case keeps what it had. Change the gold label again, or reject the case. |
| "A decision case has no messages, preference, evidence or answer type; change its decision or category", "Provide decision or category to update" or "A chat example has no decision; change its messages instead" | These refuse a request sent with the API. A case changes by its decision and its category alone. |
When you save or launch a run
| Problem | What to do |
|---|---|
| "Decision models are on the Pro plan. An owner can change the plan under Settings → Plan and billing." | Ask an owner to upgrade. A draft saves meanwhile. See Plan. |
| "The token limit is at most the model's P tokens." | Lower Token limit: at most 7,999 tokens, and at most the model's own positions. |
| "Full training needs a learning rate of at most 0.0001; 0.00002 suits most runs." | Lower Learning rate, or choose LoRA. |
| "GPU has N GB of memory; this model needs about M GB to train. Choose a larger GPU." (or "to evaluate") | Choose a GPU marked Fits. See GPU memory. |
| "N decisions have more than M candidates. Raise the candidate limit (at most 16) or shorten their criteria." | Raise Most candidates, or give those questions fewer candidates and import them again. A training run counts the decisions of every split, an evaluate run those of the test split. |
| "A decision run scores at most 25,000 test decisions, and this version has N. Create a version with fewer test cases." | Reject test cases you don't need in Review, or import a smaller test set, then create a new version. A retry of a run on the version gets it too. |
| "Choose a finished decision run of this project." | The run chosen under Model is not a finished training run of this project with a model. Choose another, or the base model. |
| "That run's model is in other storage. Evaluate a model trained with the current storage." | Choose a run trained with the storage your organization uses now. |
| "An evaluation of a run's model uses the revision that run trained on." | Leave Model revision at main, or set it to the revision that run trained on. |
| "Decision models train with LoRA or full training.", "Decision models train on one GPU.", "Decision models train on one decision per step; raise gradient accumulation for a larger batch.", "Decision runs need no baseline evaluation; leave it out.", "Decision runs have no trial yet; start a full run or evaluate the model.", "Decision projects train with the decision objective." or "Decision settings apply to the decision objective." | These refuse a request sent with the API. The console sends none of them. |
| "Only an evaluate run scores a finished run's model.", "Only decision projects evaluate a model this way.", "The decision objective is for decision projects." or "Full training is available for decision models only." | These refuse a request sent with the API, in a chat project or for a run that isn't an evaluate run. |
| "Resolve launch readiness checks before training: …" | Fix what each check says. See Readiness checks. |
When a run stops
A run that fails shows the reason as its error: the run's own, from its GPU machine, or Tensorant's, when it checks what the machine saved. None names your cases:
| The run says | What to do |
|---|---|
| "N decisions are longer than T tokens. Shorten them, or raise the token limit (at most the model's P)." | Raise Token limit, up to the model's limit, with a GPU that has memory for it, or shorten those cases. Then retry the run. Readiness for training finds most of them for free. |
| "N decisions have more than M candidates. Raise the candidate limit (at most 16) or shorten their criteria." | Raise Most candidates, or give those questions fewer candidates and import them again. Tensorant refuses such a run before its GPU starts, so this comes only from a case stored without the import's checks. |
| "Training on D candidates of up to T tokens does not fit in this GPU's memory. Choose a GPU with more memory, fewer candidates or a lower token limit." | Follow its advice, then retry. It can come in any phase, scoring included. |
| "Training stopped at step S: the loss is not a finite number. Lower the learning rate and try again." | Lower Learning rate, then retry. |
| "Decision models train with LoRA or full training.", "Decision models train on one decision per step; raise gradient accumulation for a larger batch." or "The token limit is at most the model's P tokens." | A draft saved before these were refused. Duplicate the run, check its settings and save it again. |
| "The decision program ended without the complete model it exports. Retry the run." or "The decision program ended without its evaluations. Retry the run." | Retry the run. |
| "The trained model could not be kept: reason. Retry the run, or contact support if it happens again." | The model the run saved failed Tensorant's checks. Retry the run, and contact support with its ID if it happens again. |
| "The run's evaluation report could not be recorded: reason. Retry the run, or contact support if it happens again." | The scores an evaluate run saved failed Tensorant's checks. Retry the run, and contact support if it happens again. A training run doesn't fail for its report, so that the model it trained isn't lost: it waits for recovery instead. See When a run needs recovery. |
| "The GPU machine reported the result of another kind of run. Retry the run, or contact support if it happens again." | Retry the run, and contact support if it happens again. |
| "Pod disappeared before a verified model was collected" or "Pod disappeared before the run's evaluation was collected" | The compute provider deleted the machine before Tensorant collected what it made. Choose Retry. |
| "Kind: training stopped; inspect logs" | Read Training logs for the reason. See below. |
In the training logs
These are written to Training logs (Run logs for an evaluate run) when an evaluate run can't copy the model of the run it scores. The run then shows "Kind: training stopped; inspect logs".
| The log says | What to do |
|---|---|
| "The model this run evaluates is missing from storage. Evaluate another finished run." | That run's model is no longer in your storage. Evaluate another run, or the base model. |
| "The model this run evaluates does not match its saved checksum." or "The model this run evaluates is over 5 GiB. Evaluate another finished run." | The stored file is not the one that run saved, or it is too large. Evaluate another run. |
| "The model this run evaluates is not in the archive the runner fetched. Evaluate another finished run." or "The model this run evaluates has an unsafe entry in its archive. Evaluate another finished run." | The stored file is not a model Tensorant can score. Evaluate another run. |
| "The model this run evaluates could not be copied (kind)." | The copy failed. Kind is the error's class, or HTTPError and the status your storage answered with. Use Check connection on the Data storage card in Connections, then retry. |
| "Storage did not answer in time while the model this run evaluates was copied" | Your storage was slow to answer. Retry the run. |
| "The run has no link to the model it evaluates" | This should not happen: retry the run, and contact support with its ID if it happens again. |
| "The run exceeded its runtime limit while copying the model it evaluates" | The time limit passed during the copy. The run needs recovery: see When a run needs recovery. |
When a run needs recovery
A decision run shows Needs recovery when its time limit passed, its GPU machine stopped without a result, or Tensorant could not collect what the machine saved, for example when storage failed while the model was read, or when a training run's evaluation report failed Tensorant's checks. The machine is stopped, where its provider can stop one, and what it saved stays in your storage. Lambda can't stop a machine, so it bills until you recover the run or cancel it.
On the run's page, under Recover the model (Recover the evaluation for an evaluate run), choose Recover from storage. Tensorant collects the run again from what it left in your storage: its result, its evaluation and, for a training run, its model, each checked as the first time. A training run then shows Model ready, with its two evaluations, and an evaluate run completes with its evaluation. This works on every storage, your own S3 bucket and a RunPod network volume alike, and an evaluate run is recovered the same way. Copying a large model can take a few minutes. With the API, send POST /api/training-runs/{id}/recover-volume with no body. POST /api/training-runs/{id}/recover, which takes a model's checksum and size, recovers a training run too, but refuses an evaluate run: "An evaluate run made no model, so it has no checksum or size to send: recover it with POST /api/training-runs/id/recover-volume, which collects it from its own storage."
A decision run can't be recovered from a file you upload: an upload is refused with "Decision runs can't be recovered from an uploaded file yet. Recover the run from its own storage, or retry it." When the storage holds no result from the GPU machine, as when the time limit came during training, there is nothing to recover, and Recover from storage says "The run's storage holds no result from its GPU machine, so there is nothing to recover. Retry the run, or contact support if it happens again.": choose Cancel run, then Retry. The form applies a longer Time limit (hours). A decision run can't continue from a checkpoint, so the new run starts from the beginning. A recovery whose evaluation report still fails the checks says "The run's evaluation report could not be recorded: reason. Retry the run, or contact support if it happens again.", and the run keeps waiting with its model in your storage: contact support with the run's ID before you cancel it, or cancel it and retry. See Needs recovery.
When you download or publish
| Problem | What to do |
|---|---|
| "No verified model is available" | The run has no model yet. Download a finished training run's model. |
| "An evaluate run scores a model and makes none, so there is nothing to download" | An evaluate run makes no model. Download the model of the training run it scored, or open its evaluation. |
| "Model is missing from the configured storage" | The model file is gone from your storage. Train again, or use a copy you downloaded earlier. |
| "This run has no verified model to publish yet." | Wait until the run shows Model ready. |
| "An evaluate run scores a model and makes none, so there is nothing to publish." | Publish the model of the training run it scored. |
| "This model is being published to repository. Wait for that to finish." | Wait for that upload to finish in Activity. |
| "The model is missing from storage, so it was not published.", "The model in storage is not the one this run verified, so it was not published." or "The model in storage is not a valid decision model, so it was not published." | The model in your storage is gone, changed or unreadable. Train again, or upload a copy you downloaded earlier yourself. |
| "Hugging Face did not accept the model (HTTP code). Try again later." | Hugging Face had a problem. Try again later. |
| Anything about the token or the repository | As for an adapter: see Publishing adapters to Hugging Face. |
In evaluations
| Problem | What to do |
|---|---|
| "Choose two decision evaluations or two chat evaluations" | A decision evaluation compares only with another decision evaluation of the same version. |
| "Group this evaluation's decisions by category, question or question_type" | A request sent with the API asked for a grouping of answers. Group decisions by Category, Question or Question type. |
| "A likely range needs at least 10 test cases." | Import more test cases, from states of their own. |
| "Every decision changed the same way, so there is no range." or "No decisions of both models have this metric." | There is no range to give. Read the decisions that changed. |
Need a hand? Visit troubleshooting