Configuration Parsing Warning:In adapter_config.json: "peft.task_type" must be a string

jev-lite

A QLoRA adapter that turns Gemma 4 E4B into a System One decision model: it reads a state, reads a typed question about it, and returns a calibrated probability distribution over the allowed answers from a single forward pass, with no generation.

Since the answer is read from the logits at the option letters, it cannot answer outside the options it was given. There is no parsing, no retry loop, and no "as an AI language model".

It implements the three TypeSafe primitives:

type question returns
choice pick one of several named options the option, probabilities, confidence
score rate against ordered levels expected level, legend, probabilities, confidence
noul is this true? a single probability

Usage

The adapter is only meaningful with the exact prompt format it was trained on, so primitives.py is included in this repo and must be used to render questions. Criteria descriptions are part of that format.

import torch, primitives
from peft import PeftModel
from transformers import AutoModelForImageTextToText, AutoTokenizer, BitsAndBytesConfig

tok = AutoTokenizer.from_pretrained("vagmi/jev-lite")
base = AutoModelForImageTextToText.from_pretrained(
    "google/gemma-4-E4B-it", device_map={"": 0}, dtype=torch.bfloat16,
    quantization_config=BitsAndBytesConfig(
        load_in_4bit=True, bnb_4bit_quant_type="nf4",
        bnb_4bit_compute_dtype=torch.bfloat16, bnb_4bit_use_double_quant=True))
model = PeftModel.from_pretrained(base, "vagmi/jev-lite").eval()

row = primitives.normalize({
    "type": "choice",
    "state": "Help! My payouts have been failing for 3 days.",
    "question": "Which team should handle this?",
    "options": ["billing", "technical", "sales"],
    "criteria": {"billing": "Payments, invoicing, refunds",
                 "technical": "Bugs, outages, integrations",
                 "sales": "Pricing, upgrades, new accounts"},
})

prompt = primitives.PREFIX + row["state"] + "\n</state>\n\n" + \
    primitives.question_block(row) + "\nAnswer:"
ids = torch.tensor([[tok.bos_token_id] + tok.encode(prompt, add_special_tokens=False)])
letters = [tok.encode(" " + c, add_special_tokens=False)[0] for c in primitives.LETTERS]

with torch.no_grad():
    logits = model(input_ids=ids.to(model.device)).logits[0, -1].float()
probs = torch.softmax(logits[letters[:len(row["options"])]], -1).tolist()
print(primitives.answer(row, probs))
# {'type': 'choice', 'choice': 'billing', 'probabilities': {...}, 'confidence': 0.58}

A server speaking the TypeSafe System One wire API (POST /v1/systemone), for both transformers and vLLM backends, is at github.com/vagmi/jevlite.

Training

QLoRA on google/gemma-4-E4B-it, 4-bit NF4 base with bf16 compute.

LoRA rank / alpha 16 / 32, dropout 0.05
target modules q, k, v, o, gate, up, down
trainable params 34.9M of 7.98B (0.44%)
objective soft-label cross-entropy over option letters
epochs / LR / schedule 1 / 2e-4 / cosine, 3% warmup
effective batch 16 (grad accum)
hardware one RTX 4090 (24 GB), ~1h40m

Options are shuffled every epoch so the model cannot learn "A is usually right" — except for score, where the order of levels carries meaning and is preserved.

Training data

23,632 rows across 301 tasks: 13,492 choice, 6,368 noul, 3,772 score. 92% carry criteria descriptions; 35.5% carry soft labels.

source rows labels
Super-NaturalInstructions (288 tasks) 8,629 gold, with criteria written by the teacher
MNLI / ANLI / BoolQ / RACE / Yelp 9,605 gold, hand-written criteria
synthetic states (978, 8 domains) 5,398 soft labels from the teacher

Soft labels came from Qwen3.6-35B-A3B read at the answer token with option order reversed and averaged to cancel position bias. Reasoning was deliberately left off: with a thinking budget the teacher commits to its answer with probability 1.0 on essentially every row, which is useless for distillation — the measured mean entropy was 0.000 with reasoning versus 0.211 without.

Results

Evaluated on 1,898 held-out rows — 31 Super-NaturalInstructions tasks the model never saw, 78 synthetic states it never saw, and SST-2 held out in its entirety.

accuracy ECE NLL Brier
overall 0.816 0.019 0.430 0.222
choice (n=1196) 0.809 0.431 0.238
noul (n=547) 0.819
score (n=155) 0.852

Score answers are off by 0.216 levels on average (mean absolute error of the expected level).

Calibration is the point. ECE of 0.019 means that when it reports 80% confidence it is right about 80% of the time. Accuracy was flat from step 250 to the end of training while ECE fell 0.086 → 0.019: the model did not learn to be right more often, it learned to be honest about when it isn't.

Operationally, gating on confidence:

band share of traffic accuracy
≥ 0.80 — act automatically 62% 93%
0.50–0.80 — confirm or review 36% 60%
< 0.50 — route to a human 2% 32%

Confidence

confidence is the model's probability that the answer it returned is the correct one:

  • choice — the probability of the selected option (p_max)
  • score — the probability mass that rounds to the reported expected level
  • noul — no confidence field; the probability is the answer

This was chosen by measurement, not taste. Over 1,430 gold-labelled held-out rows, p_max beat normalized entropy, margin, chance-corrected top and collision entropy on both AUROC (0.816, ranking right answers above wrong ones) and ECE (0.036). Normalized entropy — the obvious first guess — was the worst of the lot: it is dominated by small probabilities, so it reads a decisive 0.85/0.08/0.07 as low confidence and routes 45% of traffic to human review at 64% accuracy.

Limitations

  • English only.
  • Score evaluation rests on teacher labels, not gold. All 155 held-out score rows are synthetic; SNI has no rating scales and the HF eval split is SST-2. Choice and noul numbers (n=1,430) are against real gold labels.
  • Serving precision matters. The adapter was trained against a 4-bit NF4 base and learned to correct that quantization. Served in bf16 (e.g. vLLM), accuracy holds (0.807 vs 0.799) but ECE roughly doubles, 0.036 → 0.069. A single temperature of 1.4, fitted on half the eval set and measured on the other half, restores it to 0.033. Serve 4-bit, or apply the correction.
  • Tokenization is part of the contract. Feeding a differently-tokenized prompt (a missing BOS, say) moved 16% of argmaxes in testing. Build ids the way primitives.py does.
  • The teacher disagreed with gold on 24.9% of a 3,000-row sample — mostly noisy annotation in SBIC/civil-comments-style tasks plus adversarial ANLI. Those rows were blended toward gold at 0.5 rather than dropped.
  • Not evaluated for fairness, toxicity, or adversarial robustness. Several source tasks (stereotype and offensiveness classification) carry the biases of their annotators.

Licensing and provenance

The adapter is a derivative of Gemma and is governed by the Gemma Terms of Use, including its use restrictions.

Training data licenses are mixed, and some are non-commercial:

dataset license
Super-NaturalInstructions Apache-2.0
ANLI CC BY-NC 4.0 — non-commercial
RACE research use only — non-commercial
BoolQ CC BY-SA 3.0
MNLI (GLUE) mixed, per-genre
Yelp Review Full Yelp Dataset Terms of Use

Because ANLI and RACE rows are in the training mix, this adapter should be treated as non-commercial / research use unless retrained without them. build_data.py in the source repo takes --sets to select sources, so a commercially-clean rebuild is a flag change plus a retrain.

Synthetic rows and soft labels were generated with Qwen3.6-35B-A3B, an open-weight model whose license permits using outputs to train other models.

Downloads last month
20
Inference Providers NEW
This model isn't deployed by any Inference Provider. 🙋 Ask for provider support

Model tree for vagmi/jev-lite

Adapter
(355)
this model