Skip to main content

llm_decision_sft: decide in one pass

The first, and often the only, stage of a decision model. The backbone reads the state and the question, a head scores every option, and cross-entropy over the options trains both. With method.think_fraction: 0 the result is a one-pass decision model: one forward pass a question, as a router on every request needs. Above 0, that share of the questions gets a reasoning chain sampled from the base model and inserted as context, so the head also learns to decide after reasoning (the start of llm_decision_cispo).

Rows​

Jev records (state, questions), as on the family page. training.batch_size counts questions, however many a record holds.

Config​

configs/llm/decision_readout.yaml
# One-pass decision model (Jev, jeff): describe the situation and the options, get a calibrated probability per
# option from a single forward pass. Every weight is trained; the readout head scores one-token option codes.
pipeline:
recipe: llm_decision_sft
name: decision-readout-qwen3.5-0.8b
seed: 20260920
output_dir: ./output

model:
architecture: hybrid
name: Qwen/Qwen3.5-0.8B # or Qwen/Qwen3.5-2B @ 15852e8c16360a2fea060d615a32b45270f8a8fc
revision: 2fc06364715b967f1860aea9cf38778875588b17
head: readout # or pointer

data:
sources:
- name: local_jsonl
path: samples/llm_decision.jsonl # rows: {"state": ..., "questions": {id: {type, instructions, criteria, label}}}
limit: 48 # pilot size; drop for a real run
validation: 0.15

method:
think_fraction: 0.0 # no reasoning: the model decides straight from the prompt
head_lr: 1.0e-4
calibration: 0.15 # share of training rows kept aside to fit the temperature

training: {epochs: 1, lr: 5.0e-6, batch_size: 12, max_length: 768, max_steps: 8} # batch_size counts questions

validation:
min: {accuracy: 0.3} # accuracy, nll and ece are measured on the held-out rows

Other shipped configs: configs/llm/decision_pointer.yaml (LoRA, pointer head, reasoning chains as context: stage 1 of a reasoning decision model) and configs/llm/route.yaml (the inner-thought router, trained on rows from configs/data/route.yaml).

Use​

uv run llmclick run configs/llm/decision_readout.yaml
  • Head: readout scores one-token option codes (A, B, ...); pointer compares the decide position with each option's end, so options need no codes and their meanings are read.
  • Gate: calibrated accuracy, nll and ece on the held-out questions; method.calibration of the training records is kept aside to fit the temperature.
  • Output: output/<name>-<hash>/validate/checkpoint with head.safetensors and head.json next to the weights. Measure it with evaluation_decision: accuracy, calibration and latency.

Source: configs/llm/decision_readout.yaml. This page is generated; edit the source and run npm run sync.