Jeeves – Redeneren verbetert Jev-achtige beslissingsmodellen

Erkenningen Geïnspireerd door Kev.

Belangrijkste kenmerken

  • Model: Een Jev-achtig 9B model (Qwen3.5-9B, LoRA, pointer head) dat redeneert voordat het een beslissing neemt. Het project bevat een block-4 diffusion drafter, de volledige trainingscode en train/dev/test-data.
  • Prestaties: Verslaat Kev-9B en Jev op testdata waar het niet op is getraind (0,889 vs. 0,822 en 0,857) en op de publieke niveaus van JevBench (0,935 vs. 0,866 voor Jev).
  • Flexibiliteit: Ondersteunt ja/nee-vragen (noul), meerkeuzevragen (choice) en waarderingsvragen (score) in één enkel verzoek via een Jev-compatibele API.
  • Snelheid: Ongeveer 0,3 seconden per verzoek zonder redenering, en een mediaan van 3,3 seconden met redenering op één H100. De snelheid kan worden verhoogd door de lengte van de redeneringsketen (chain length) in te korten.
  • Hardware: Draait op CUDA (Hopper voor de FP8-kernel).

Het probleem

Jev-achtige modellen leveren goed gekalibreerde beslissingskansen, maar de nauwkeurigheid is laag. Veel pipelines vertrouwen daarom op een redeneermodel als fallback. Jeeves traint een Jev-achtig Qwen3.5-9B model (via LoRA en een pointer head) met behulp van CISPO, zodat het model redeneert voordat het een besluit neemt.

Dit resulteert in betere prestaties bij taken buiten het trainingsdomein (out-of-domain) en overtreft Jev in de 'hard' categorie van JevBench (publiek).

Resultaten

Nauwkeurigheid met redenering, greedy decoding, en een limiet van 2.560 tokens. De kolommen voor Kev-9B en Jev bevatten de door Kev gepubliceerde cijfers.

BenchmarkKev-9BJevJeeves
Test overall (out-of-domain en held-out, item-weighted)0,8220,8570,889
Transfer overall (MMLU-Pro en buried state)0,5790,8000,746
JevBench overall (231 publieke items)0,715*0,8660,935
QNLI0,9250,9250,913
SciQ0,9630,9880,991
TweetEval offensive0,7750,8130,813
PAWS0,7630,7880,875
MMLU0,7380,9000,793
Emotion0,6000,5880,647
Held-out rule structures0,8960,8851,000
Contrastive policies0,9000,9631,000
MMLU-Pro (10-way)0,5150,8400,739
Buried state0,7400,7000,759
Unknowable answered at p ≥ 0.9 (lager is beter)0,0000,0900,055
JevBench hard (111 publieke items)0,451*0,7300,865
JevBench ECE (publieke items)0,0490,037-

\ Geen Kev-9B JevBench resultaat gepubliceerd. Dit zijn Kev-8B (Qwen3) resultaten.*

Alle JevBench-cijfers hebben betrekking op de publieke 'easy', 'standard' en 'hard' niveaus (231 items). De 'sealed judge' tier is niet inbegrepen. Zonder redenering scoort hetzelfde checkpoint 0,804 op onze test split (2.962 items), tegenover 0,840 met redenering.

Snelstart

Vereisten

Python 3.12 en een CUDA GPU.

pip install -r requirements.txt

Installatie en uitvoering

Download de released weights en start de server:

hf download PostHog/jeeves --local-dir jeeves-weights
python -m inference.serve --model jeeves-weights --drafter jeeves-weights/drafter_k4.safetensors --port 8009

Of fuseer een eigen getraind checkpoint tot een standalone model en serveer dit met een drafter:

python export.py runs/cispo/final --out runs/fused
python -m inference.serve --model runs/fused --drafter runs/drafter_k4/drafter.safetensors --port 8009

Verzoek versturen

Stuur een verzoek in het Jev-formaat:

curl -s localhost:8009/v1/systemone -H 'content-type: application/json' -d '{
"state": "Shoes arrived two weeks late and in the wrong size. Also I see two charges on my card.",
"questions": {
"department":  {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"returns": "Exchanges, refunds, wrong or damaged items",
"shipping": "Delivery status, delays, lost packages",
"billing": "Charges, invoices, payment problems"}},
"escalate":    {"type": "noul", "instructions": "Does this need urgent human attention?"},
"frustration": {"type": "score", "instructions": "How frustrated is the customer?",
"criteria": ["Calm", "Frustrated", "Very angry"]}
},
"options": {"max_think": 512}}'

Response op één H100 (FP8), waarbij de drie vragen parallel worden verwerkt:

{
"model": "jeeves-latest",
"answers": {
"department": {
"type": "choice",
"choice": "billing",
"confidence": 0.19,
"probabilities": { "returns": 0.4, "shipping": 0.14, "billing": 0.46 }
},
"escalate": { "type": "noul", "noul": 0.72 },
"frustration": {
"type": "score",
"score": 1.5,
"legend": { "0": "Calm", "1": "Frustrated", "2": "Very angry" },
"probabilities": { "0": 0.04, "1": 0.43, "2": 0.54 },
"confidence": 0.75
}
},
"usage": { "input_tokens": 129, "output_tokens": 160, "reasoning_tokens": 1536 },
"latency_ms": 8141.6
}

Python SDK

De map sdk/ is een vervanging voor de Python SDK van Jev (typesafe-sdk):

pip install ./sdk
from jeeves_sdk import Choice, Noul, Score, TypeSafeClient

with TypeSafeClient() as client:
    result = client.system_one(
        state="I was charged twice. Please help.",
        questions={
            "billing": Noul(instructions="Is this about billing?"),
            "tone": Choice(instructions="What is the tone?", criteria={"calm": None, "angry": None}),
            "urgency": Score(instructions="How urgent is this?", criteria=["can wait", "this week", "today"]),
        },
        max_think=768,
        return_reasoning=True,
    )
    print(result.nouls["billing"].noul, result.choices["tone"].choice, result.scores["urgency"].score)
    print(result.reasoning["tone"].text)

De client verbindt standaard met http://127.0.0.1:8009 (of JEEVESBASEURL), vereist geen API-key en wacht tot maximaal 120 seconden.

Opties

Het options veld is optioneel. Server-brede standaarden kunnen worden ingesteld via de serve flags.

OptieStandaardEffect
thinktrueGeeft antwoorden op basis van alleen de prompt (ca. 0,3 s) als false
max_think2560Kort elke redeneerketen af bij dit aantal tokens, geeft daarna antwoord
nothink_thresholdnullGeeft antwoord zonder te redeneren als de 'no-think confidence' minimaal deze waarde heeft
return_reasoningfalseVoegt de redeneringstekst van elke vraag toe aan de respons

Prestaties op 325 dev-vragen:

InstellingNauwkeurigheidGem. redeneertokensMediaan / p90 latentie
Volledige redenering0,8251.1383,3 s / 17,1 s
maxthink 768, nothinkthreshold 0,90,8063442,0 s / 5,6 s
Geen redenering0,7750ca. 0,3 s

Hoe het werkt

Vragen, statussen en antwoorden worden in de Qwen chat template geladen als volgt: <state> …state… <q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <think>

Het model genereert vervolgens zijn redeneerketen. Na de </think> token voegen we het volgende toe: </think> <q> instructions <opt> option 1 </opt> <opt> option 2 </opt> … <decide>

Een pointer head scoort elke optie met een scaled dot product tussen een query-projectie van de hidden state bij <decide> en een key-projectie van de hidden state bij de bijbehorende </opt>.

Hierbij worden de volgende tokens gebruikt: <state>, <q>, <opt>, </opt>, <decide> = "<|fimprefix|>", "<|fimmiddle|>", "<|boxstart|>", "<|boxend|>", "<|fim_suffix|>"

Dit zijn zeldzame tokens in de Qwen tokenizer. Uit tests bleek dat het gebruik van gewone tekst (zoals "State") in de prompt de prestaties verslechterde. Ook het weglaten van de herhaling van de vragen na het redeneringsblok verlaagde de nauwkeurigheid.

De uiteindelijke kansen zijn een softmax over de optie-scores, gedeeld door een temperatuur die is afgestemd op de dev-set.

Training

  1. SFT: 2 epochs, 596 stappen op 8 GPU's. LoRA r=16 op alle projecties van Qwen3.5-9B plus de pointer head, getraind op 19.126 vragen uit 12 publieke datasets en synthetische policy-data. De helft van de vragen bevat een redeneerketen gesampled van het basismodel.
  2. CISPO: Een schema van 624 stappen, gestopt bij stap 402. 9.992 RL-vragen, 8 rollouts per vraag bij temperatuur 1, begrensd op 2.560 redeneertokens.
  3. Calibratie: Een enkele temperatuur afgestemd op de dev-set, opgeslagen bij het checkpoint.

Stoppen bij stap 402 behoudt de beste calibratie en dev-score; daarna wordt de head te scherp gesteld op de verzadigde RL-pool.

Diffusion drafter

Een diffusion view van het bevroren model (drafter/), geïnspireerd door Orthrus. In tegenstelling tot Orthrus, dat alleen attention-only modellen ondersteunt, ondersteunt dit model de Gated DeltaNet-lagen van Qwen3.5 door mask-tokens cross-attend te laten doen naar de post-convolution keys en values van die lagen.

Tokens per seconde (greedy decoding, één vraag):

MethodeSnelheidVersnelling
Plain graphed109-
Block 41761,6×
Block 81931,76×
Block 4 (8 vragen gebatcht)ca. 960 (totaal)-

Block 4 is de standaardinstelling omdat deze goedkoop blijft wanneer meerdere vragen gebatcht worden.

Reproduceerbaarheid

Data

Datasets kunnen lokaal worden gebouwd met de prep scripts. Dit downloadt publieke datasets van Hugging Face:

python -m prep.prep

Elke publieke dataset behoudt zijn eigen licentie.

Training

Op 8 GPU's, met de data in data/, voert bash run.sh de volledige pipeline uit:

torchrun --nproc_per_node 8 train.py sft --run-dir runs/sft
torchrun --nproc_per_node 8 train.py cispo --run-dir runs/cispo --init runs/sft/final
torchrun --nproc_per_node 8 test.py runs/cispo/final
torchrun --nproc_per_node 8 jevbench.py runs/cispo/final
python export.py runs/cispo/final --out runs/fused
torchrun --nproc_per_node 8 -m drafter.gen --model runs/fused
torchrun --nproc_per_node 8 train.py drafter --model runs/fused --block 4 --run-dir runs/drafter_k4

Repository Structuur

PadInhoud
model/Qwen3.5 (Gated DeltaNet + gated attention), LoRA, pointer head
loader/Prompt-formaat, tokenisatie en batching
prep/Datasetconstructie (prep.py) en synthetische generators
trainer.py, train.pySFT, CISPO en drafter training
test.py, jevbench.py, calibrate.pyEvaluatie, JevBench, temperatuurfitting
export.pyFuseert LoRA in een standalone model inclusief head en temperatuur
drafter/Drafter model, chain sampling, fused speculative decoder
inference/FP8 kernel, batched speculative engine, Jev-compatibele server en benchmark
sdk/jeeves_sdk, een vervanging voor Jev's Python SDK met redeneeropties

Beperkingen

  • Kennisvragen: Scoort lager dan Jev (MMLU 0,793 vs 0,900, MMLU-Pro 0,739 vs 0,840).
  • Latentie: Redeneren is traag in de uitersten: 17 s bij p90 met volledige ketens. Gebruik maxthink en nothinkthreshold wanneer latentie kritiek is.
  • Vergelijkingen: Vergelijkingen met Kev en Jev buiten JevBench maken gebruik van verschillende items uit dezelfde bronnen.
  • Interpreteerbaarheid: Er is geen language consistency reward toegevoegd, waardoor de redeneerketens niet altijd goed interpreteerbaar zijn.

Citatie

Als u Jeeves, het trainingsrecept of de drafter gebruikt, citeer dan als volgt:

@software{waltz2026jeeves,
author = {Waltz, Nicholas P.},
title  = {Jeeves: Reasoning Improves Jev-like Decisions},
year   = {2026},
url    = {https://github.com/PostHog/jeeves},
note   = {Qwen3.5-9B decision model trained with SFT and CISPO, with a block-4 diffusion drafter}
}

Referenties

  • Jev's Architecture Unmasked: Het Jev-ontwerp dat Kev en Jeeves volgen.
  • Qwen Team: Qwen3.5-9B, het basismodel.
  • Yang, Kautz, Hatamizadeh: Gated Delta Networks: Improving Mamba2 with Delta Rule. ICLR 2025.
  • Hu et al.: LoRA: Low-Rank Adaptation of Large Language Models. ICLR 2022.
  • MiniMax: MiniMax-M1: Scaling Test-Time Compute Efficiently with Lightning Attention. 2025 (Introduceert CISPO).
  • Guo, Pleiss, Sun, Weinberger: On Calibration of Modern Neural Networks. ICML 2017 (Temperature scaling).
  • Orthrus: arXiv 2605.12825. De diffusion drafter die is aangepast voor Gated DeltaNet.
  • Leviathan, Kalman, Matias: Fast Inference from Transformers via Speculative Decoding. ICML 2023.