Model reference · open weights
LemonDecider is an open-weight embedding model from inclusionAI. LemonDecider (BF16) weighs 9.1 GB; the smallest configuration that runs it is RTX 3060 12 GB.
For self-hosting, compare this build's requirements below with the GPU you plan to rent.
Summary of the inclusionAI/LemonDecider model card, 2026-10-13
What it is
| Released by | inclusionAI |
|---|---|
| Released | 2026-10-05 |
| Parameters | 4.5B |
| VRAM | 9.1 GB for the weights |
What it runs on
| Card | Runs | Memory |
|---|---|---|
| RTX 3060 12 GB | tight | 11.6 GB |
| RTX 4060 Ti 16 GB | fits | 15.4 GB |
| RTX 3090 24 GB | fits | 23.4 GB |
| RTX 4090 24 GB | fits | 23.4 GB |
| RTX 5090 32 GB | fits | 31.0 GB |
| L40S 48 GB | fits | 44.0 GB |
| A100 80 GB | fits | 78.2 GB |
| H100 80 GB | fits | 78.1 GB |
| RTX PRO 6000 Blackwell 96 GB | fits | 93.8 GB |
| DGX Spark (GB10) 128 GB unified | fits | 107 GB |
| H200 141 GB | fits | 138 GB |
| B200 180 GB | fits | 176 GB |
From the model card
A typed decision engine derived from Qwen/Qwen3.5-4B: it answers structured choice / noul / score questions in a single forward pass with an explicit unknown (abstention) candidate. There is no autoregressive generation head — the backbone is kept full-weight, and a 255-way single-token readout replaces the LM head.
| Property | Value |
|---|---|
| Architecture | AutoJevForDecisionClassification (custom code, trust_remote_code=True) |
| Base model | Qwen/Qwen3.5-4B (Qwen3.5 text + vision backbones) |
| Parameters | ~4B backbone + 255×2560 readout head |
| Readout | 255 single-token answer codes (A … JT), initialized from the Qwen LM-head rows of those tokens |
| Decision head | Linear(hidden_size=2560, 255, bias=False) over the last prompt position |
| Dtype / context | bfloat16; max_input_length = 8192 (no silent truncation) |
| Options per question | 1–255 (option_counts required per row; invalid option logits are masked) |
| Multimodal | Optional images (PIL, decoded) via the Qwen3 vision processor |
| Serving temperature | 1.0 (post-processing softmax only; not used in CE loss) |
Each input is rendered as one user message (state + instructions + options + an appended __unknown__ slot), then scored in one forward pass. The forward pass rejects KV-cache decoding and right padding (left padding is required).
decision_utils.py implements the native _known() semantics: probabilities over known candidates are renormalized, and the unknown slot gets its own probability.
question.type | Candidates | Output |
|---|---|---|
choice | 1–254 named options (+unknown) | choice (argmax key), per-option probabilities, confidence |
noul | true, false (+unknown) | noul = P(true) + 0.5 * P(unknown) |
score | 2–10 ordered descriptions (+unknown) | score = Σ i · P(i) plus legend and probabilities |
| — | — | abstained = True iff the raw argmax lands on unknown; unknown_probability is always returned |
confidence = concentration · (1 − P(unknown)), where concentration = (n·p_max − 1)/(n − 1) (1 for single-candidate questions).
Standalone CLI (bundled model.py):
python model.py --checkpoint . \
--input inputs.json \
--device cuda:0
With transformers:
import torch
from transformers import AutoModel, AutoProcessor
from decision_utils import predict_batch
model = AutoModel.from_pretrained(
"inclusionAI/LemonDecider",
trust_remote_code=True,
dtype=torch.bfloat16,
device_map="cuda:0",
attn_implementation="sdpa",
).eval()
processor = AutoProcessor.from_pretrained(
"inclusionAI/LemonDecider", trust_remote_code=True
)
processor.tokenizer.padding_side = "left"
rows = [{
"state": "我想申请退款。",
"question": {
"type": "choice",
"instructions": "判断主要诉求",
"criteria": {
"refund": "退款相关",
"delivery": "物流相关",
"account": "账户相关",
},
},
}]
result = predict_batch(model, processor, rows)
print(result["answers"][0])
# {"type": "choice", "choice": "refund", "probabilities": {...},
# "confidence": ..., "unknown_probability": ..., "abstained": ...}
Images are passed as decoded PIL.Image objects in row["images"]; paths/URLs are not fetched.
Distilled via supervised fine-tuning from imajev-4b, a larger Jev-class decision model:
0.7735 (best step: 3, 0.7805)Temperature fit (not applied): an NLL scan over T ∈ [0.30, 5.00] on the dev set found T = 0.60 (NLL 0.56265, Brier 0.28261, vs 0.6016 / 0.29885 at T=1). The checkpoint still serves at T = 1.0; adopting T* is deliberately blocked until the public evaluation suite is re-evaluated (argmax is invariant at T* except at the noul decision boundary).
choice / noul / score) rendered through decision_utils.decision_messages(); prompt-layout divergence will degrade results.| File | Purpose |
|---|---|
model-00001/2-of-00002.safetensors(+index) | Weights (bfloat16) |
configuration_autojev.py / modeling_autojev.py | Custom architecture (decision forward, option masking, hard/soft-target loss) |
decision_utils.py | Prompt rendering, _known() scoring, batching (prepare_batch / predict_batch) |
model.py | Standalone inference CLI |
chat_template.jinja, processor_config.json | Qwen3-style chat template and image processor |
sft_receipt.json | Training artifact receipt (step, dev metrics, temperature fit) |
Apache-2.0 (see LICENSE / LICENSE.code).
Quoted from the model card on Hugging Face. The full card is behind the Hugging Face link above.