qwen3-0.6b-rlcd

This model scores options. You give the model a state and a list of typed questions. For each question, the model returns a calibrated probability distribution over your options. The model also returns a separate signal when the answer is not in your options. The model does this in one forward pass. The model generates no tokens.

The model has no chat interface. The model gives no free text. The model cannot answer off-list. The softmax includes only the options in your request. The model has 0.6B parameters. The model can run on a CPU.

RLCD

This model is an RLCD model. RLCD means Reinforcement Learning for Calibrated Decisions. The name covers models that read one state and a list of typed questions. These models return a calibrated probability over the options of each question. They do not generate free text.

This implementation uses supervised training. It uses no reinforcement learning. The loss is a strictly proper scoring rule against observed outcome frequencies. This card calls the method PSR-FT. Other models in the same family also use supervised training.

One warning about the name. An alignment method uses the same acronym for Reinforcement Learning from Contrastive Distillation. That method is not related to this model. This model uses no reinforcement learning and no distillation.

How it works

Prefill-only The model does one forward pass. The model uses no decode loop. output_tokens is always 0.
Parallel sampler A block-diagonal mask separates the questions. Each question attends to the state. No question attends to a different question. If you add, remove or move a question, the logits of the other questions do not change.
Restricted softmax The model scores each option from the hidden state of that option. The distribution includes only your options. The model cannot emit an off-list token.
PSR-FT Training uses a strictly proper scoring rule. The loss is cross-entropy against observed outcome frequencies, not against one hard label. Therefore the optimum of the loss is the true probability. Training uses no RL, no reward model and no preference pairs.
Criteria as input The option key is an arbitrary identifier. The description holds the meaning. In part of the training data, every key becomes opt_0 to opt_k. Therefore the model must read the description.
A separate ignorance signal confidence is a separate head. It is not a statistic of the distribution. Temperature scaling keeps the rank order. Therefore temperature scaling cannot show that the answer is not in the option list.

The adaptation is LoRA with r=32, alpha=64 and dropout 0.05. The base model is Qwen/Qwen3-0.6B-Base. The release merges the adapter into the backbone. In bouncy.json, lora_r: 0 shows that the adapter is merged. It does not show that the adapter is absent.

Interface

The model has three question types:

  • noul asks if a statement is true.
  • choice asks which option is correct.
  • score asks for a position on a scale.

The model never sees the question ID. Put the full question in instructions. The choice type and the score type return a confidence value. The noul type returns no confidence value.

{
  "state": {"channel": "email",
            "subject": "Deploy failing since 4.2.1",
            "body": "Since upgrading to 4.2.1 our nightly deploy fails at the migration step with 'relation users_pkey already exists'. Rolling back to 4.2.0 fixes it. We have 200 seats and this blocks our release on Friday.",
            "plan": "enterprise"},
  "questions": {
    "kind": {
      "type": "choice",
      "instructions": "What kind of request is this?",
      "criteria": {"bug":      "Reports something that is broken",
                   "question": "Asks how to do something",
                   "feature":  "Requests new functionality",
                   "billing":  "About payment or invoices"}},
    "team": {
      "type": "choice",
      "instructions": "Which team should own this ticket?",
      "criteria": {"billing":  "Charges, invoices, refunds, subscription changes",
                   "platform": "Deploys, migrations, infrastructure, upgrades",
                   "design":   "Visual design, layout and copy",
                   "sales":    "Pricing questions, contracts, seat expansion"}},
    "needs_engineer": {
      "type": "noul",
      "instructions": "Does resolving this require someone who can read the codebase?",
      "criteria": {"true":  "Requires engineering investigation",
                   "false": "A support agent can resolve it from documentation"}}
  }
}

The response from this checkpoint has three questions and 230 tokens in one forward pass:

{
  "answers": {
    "kind":           {"choice": "bug",
                       "probabilities": {"bug": 0.910, "question": 0.055,
                                         "billing": 0.020, "feature": 0.016},
                       "confidence": 0.457},
    "team":           {"choice": "platform",
                       "probabilities": {"platform": 0.970, "sales": 0.014,
                                         "billing": 0.010, "design": 0.006},
                       "confidence": 0.691},
    "needs_engineer": {"noul": 0.785}
  },
  "usage": {"input_tokens": 230, "output_tokens": 0}
}

The model gives bug a probability of 0.910. The confidence value for the same question is 0.457. The two numbers are separate signals. The probability ranks the options. The confidence value reports how sure the model is. Gate on the confidence value.

The model has these limits:

  • 8,192 tokens in total, for the state and all questions, with the code in this repository. The model has a 32,768-token window, but it trained on states of up to 4,002 tokens. See Run the model and the limitations.
  • 255 options for a choice question.
  • 2 to 10 levels for a score question.

The options of a question share the token budget with the state. A request with many long options leaves less room for the state. A request over the budget raises an error. The model does not cut the state. The returned input_tokens value shows how many tokens the model read.

Run the model

The model needs only torch and transformers. The scoring code ships in this repository, so you must set trust_remote_code=True.

pip install torch transformers
from transformers import AutoModel

model = AutoModel.from_pretrained("thefloydd/qwen3-0.6b-rlcd",
                                  trust_remote_code=True).eval()

response = model.score(
    state={"channel": "email",
           "subject": "Deploy failing since 4.2.1",
           "body": "Since upgrading to 4.2.1 our nightly deploy fails at the migration "
                   "step with 'relation users_pkey already exists'. Rolling back to "
                   "4.2.0 fixes it. We have 200 seats and this blocks our release on "
                   "Friday.",
           "plan": "enterprise"},
    questions={
        "kind": {
            "type": "choice",
            "instructions": "What kind of request is this?",
            "criteria": {"bug":      "Reports something that is broken",
                         "question": "Asks how to do something",
                         "feature":  "Requests new functionality",
                         "billing":  "About payment or invoices"}},
        "needs_engineer": {
            "type": "noul",
            "instructions": "Does resolving this require someone who can read the codebase?",
            "criteria": {"true":  "Requires engineering investigation",
                         "false": "A support agent can resolve it from documentation"}},
    },
)

kind = response["answers"]["kind"]
print(kind["choice"], round(kind["probabilities"]["bug"], 3), round(kind["confidence"], 3))
# bug 0.91 0.457
print(round(response["answers"]["needs_engineer"]["noul"], 3))
# 0.785

score() takes the state and questions of the request above and returns the response above. To use a GPU, call model.to("cuda") before score(). The model loads in fp32 by default. Add dtype=torch.bfloat16 to from_pretrained to halve the memory. The two heads stay in fp32. In bf16 the numbers above move a little: bug 0.908 0.449 and 0.781.

score() builds a dense attention mask with T squared entries. Therefore it refuses a request longer than 8,192 tokens, and it does not cut the request to fit. Shorten the state, or send the questions in several requests. The questions are independent, so a split request gives the same answers.

config.json holds the fitted temperature of 0.9903 and confidence_mode: head. score() applies both.

Evaluation

These numbers come from an internal held-out split. The split has 477 task schemas and 50,923 questions. The model did not train on these schemas. The split divides the data by whole task. Therefore the numbers show transfer to new schemas. The numbers do not show transfer to new rows of a known schema. The evaluation read the split one time, at the end. The confidence intervals are 95 % bootstrap intervals over questions, from 2,000 draws.

metric value 95 % CI
accuracy (micro) 0.7128 [0.7090, 0.7167]
NLL vs soft targets (micro) 0.7326 [0.7227, 0.7421]
Brier (micro) 0.3293 [0.3248, 0.3336]
ECE after temperature (micro) 0.0599 [0.0563, 0.0633]
accuracy (macro, over tasks) 0.6023 [0.5709, 0.6349]
NLL (macro, over tasks) 1.1760 [1.0790, 1.2700]

The split includes families that the model did not train on. These families are four rule-application families and one set of invented entities. They hold 14,706 of the 50,923 questions. These families are the most difficult part of the split. They also hold most of the calibration error.

subset questions NLL accuracy ECE
whole split 50,923 0.7326 0.7128 0.0599
families with trained analogues 36,217 0.7360 0.6747 0.0330
families never trained on 14,706 0.7240 0.8067 0.1451

On the families that the model did not train on, the accuracy is higher. On the same families, the calibration is worse. The model is accurate and too confident.

Structure. A test packs the same question in six different ways. In fp32, the maximum absolute change of a logit is 2.563e-06. The score value equals the sum of i multiplied by p[i]. Over 49,178 checks, the maximum absolute error is 0.0.

Selective prediction

The confidence head is separate. Training used a frozen scoring model. Use the confidence value as a gate:

  1. Accept the answer if the confidence value is high.
  2. Send the question to a person if the confidence value is low.
value
AURC, confidence head 0.0769
AURC, raw max-probability 0.1170
ratio 0.657. The head is 34 % better than the free baseline.
head ECE against correctness 0.0305
max-probability ECE against correctness 0.0553
mean confidence, answer present in the options 0.772
mean confidence, correct option withheld 0.371
mean confidence, families never trained on 0.652 (0.808 on familiar families)

Rule application

You can write a rule in the criteria. An example rule is: the gross weight is more than 12 kg and the carrier is kestrel. The model applies the rule to a record. The model trained on nine rule forms. On these nine forms, the mean accuracy is 0.978. The lowest form is 0.920. The highest form is 1.000. The model did not train on four other forms. On these four forms, the mean accuracy is 0.598.

held-out rule form accuracy
a trained range, with a negation 0.982
set membership 0.616
disjunction 0.527
a comparison of one field across records 0.267

The results show a clear pattern. One held-out rule is a trained rule with a negation. The model transfers to this rule almost perfectly. One held-out rule compares a field across several records. This shape is new to the model. On this rule, the model performs at chance. The model learned the rule forms in its training data. The model did not learn rule application in general.

Abstention

This test uses the same request, the same state and the same real options. Only the words of one extra option change. This extra option has the meaning of "none of the above". The correct answer is in the option list in every test. The model selects the correct answer in every test.

words of the extra option p(that option)
"None of the above" 0.110
"Anything else", "Other" and similar words 0.060
24 generated wordings from the training data 0.0968
24 generated wordings not in the training data 0.0966

The difference between trained words and new words is 2e-04. On the new words, the wrong-answer rate is 0.0. Therefore the model makes a decision. The model does not match a string.

This test uses 600 claims about invented entities. The test randomises every attribute. Therefore the model cannot answer from memory.

condition mean confidence
The record states the claim. 0.997
The record contradicts the claim. 0.828
The record does not mention the claim. 0.264

Limitations

  • New rule forms. The accuracy is 0.978 on trained forms and 0.598 on held-out forms. On a fully new shape, the accuracy is 0.267. Every trained rule gives the name of its field. A rule can point to a field indirectly. An example is "outside its required temperature range". Such a rule is out of distribution. On such a rule, the model can be wrong and confident at the same time. Write criteria that give the name of each field. Read the confidence value.
  • Calibration out of distribution. The ECE is 0.0330 on families with trained analogues. The ECE is 0.1451 on families that the model did not train on. A development split sets the temperature of 0.9903. That split does not contain these families. For the test split, the best temperature is 1.765. Trust the calibration only for task families near the training distribution.
  • Probability recovery for new forecast families. In distribution, the MAE is 0.056 and r is 0.917. On forecast families that the model did not train on, the MAE is 0.246 and r is 0.425.
  • Option order in one question. Independence between questions is exact, and a test measures it. Invariance to option order inside one question is not exact. Training includes this property, but the model does not guarantee it. A reversed option list moved one probability by up to 0.06. The argmax did not change.
  • The model cannot answer off-list. This is by design. If the correct answer is not in your option list, the distribution has no meaning. In that condition, read only the confidence value.
  • Long states are untested. The model window is 32,768 tokens, and the code in this repository accepts 8,192. In the training data the 99th percentile was 1,147 state tokens, and the longest was 4,002. Above that range the model extrapolates, and the quality there has no measurement.
  • The evaluation used English. Other languages have no test results.

Training

Training used these settings:

  • Base model: Qwen/Qwen3-0.6B-Base.
  • Adaptation: LoRA with r=32, alpha=64, dropout 0.05.
  • Precision: bf16.
  • Attention: FlexAttention with a block-diagonal mask.
  • Memory: gradient checkpointing and a compiled backbone.
  • Schedule: 8,000 steps, batch 32, lr 2e-4, 300 warmup steps, cosine decay.
  • Hardware: one RTX PRO 6000.

Selection used the lowest development NLL out of distribution. This value is 1.0489 at step 7,500. A second stage trained the confidence head against the frozen scoring model. This stage used detached hidden states. A final stage fitted the temperature on the development split with LBFGS.

Comparison with other models

These numbers come from an internal held-out split. You cannot compare them to published results for other models. A public benchmark and evaluation set for this class of model is in preparation. Then you can compare this model to other models on equal terms. Until then, read these numbers as internal measurements.

Citation

@software{qwen3_0_6b_rlcd_2026,
  title  = {qwen3-0.6b-rlcd: a prefill-only option-scoring model for calibrated decisions},
  year   = {2026},
  note   = {Qwen3-0.6B-Base + LoRA, block-diagonal question independence,
            proper-scoring fine-tuning, separate confidence head}
}
Downloads last month
-
Safetensors
Model size
0.6B params
Tensor type
F32
·
BF16
·
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for thefloydd/qwen3-0.6b-rlcd

Finetuned
(707)
this model

Evaluation results

  • Accuracy (micro) on Internal held-out split (477 unseen task schemas)
    self-reported
    0.713
  • NLL vs soft targets (micro) on Internal held-out split (477 unseen task schemas)
    self-reported
    0.733
  • Expected calibration error, after temperature on Internal held-out split (477 unseen task schemas)
    self-reported
    0.060
  • AURC, confidence head on Internal held-out split (477 unseen task schemas)
    self-reported
    0.077