Instructions to use haohan84/v-jev1.4 with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Transformers
How to use haohan84/v-jev1.4 with Transformers:
# pip install -U transformers accelerate # Load model directly from transformers import AutoModel model = AutoModel.from_pretrained("haohan84/v-jev1.4", device_map="auto") - Notebooks
- Google Colab
- Kaggle
v-jev 1.4
v-jev is a decision model in the Jev style. It turns a state and a set of typed questions into decisions in a single forward pass: a probability for every allowed option of every question. Version 1.4 adds value extraction (copy a date, amount, id, name, address, url β¦ out of the state, or say there is none) and decisions about an image in the state. Nothing is generated and nothing needs parsing.
This repo holds v-jev 1.4 in several sizes, each in its own folder and post-trained the same way from its own backbone. Decisions are trained only on that backbone's own answers, so they show what the backbone itself thinks: what it is sure of, where it doubts, and where its answer moves with the way the question is asked. Reads are trained on exact labels only (human annotations and documents whose values are known by construction), never on a model's answers. No benchmark data was used for training.
Research release Β· one training run and one seed per size Β· only English was tested.
Sizes
| 0.8b/ | 4b/ | |
|---|---|---|
| Backbone | Qwen3.5-0.8B (2fc0636) |
Qwen3.5-4B (851bf6e) |
| Weights (one file, with the vision encoder) | 1.7 GB | 9.1 GB |
| GPU memory, text / image request | 1.5 / 1.8 GB | 8.0 / 9.1 GB |
| 6 decisions + 2 reads, warm, RTX 5090 | 36.6 ms | 51.3 ms |
| typed-decisions, five per request: accuracy / KL from gold | 48.1 / 0.372 | 63.8 / 0.272 |
| JevBench-mini coherence | 62.4 | 69.7 |
| Images (A-OKVQA + ScienceQA): accuracy (the backbone's own) | 75.3 (74.6) | 91.9 (91.8) |
| Reads on SGD dialogues: exact / right among given answers | 95.5 / 94.3 | 96.2 / 95.2 |
Reads on pandas issues with lock=True: right among given answers |
77 | 76 |
Each folder's card has the full results; both sizes on the public leaderboards are below. The smaller model is faster and shows a backbone that knows less; the larger one is the more accurate.
Leaderboards
Both sizes placed in the two public decision leaderboards. All numbers for our rows are our own runs; our rows are not on the leaderboards, and neither benchmark was trained on. Each size's card has its other results.
typed-decisions
Placed in the zero-shot table of the typed-decisions dataset card as read on Nov 11, 2026 (43 entries; selected rows below: the top, and most of the models of about 4B and under). The card scores each case's five questions in one request, as we did. Our rows are not on the leaderboard; v-jev never trained on typed-decisions. The card's gold is the mean of three samples from a 4B-class teacher, so a score measures agreement with that teacher. ECE is left out: our definition differs from the card's.
| # | Model | Size | Accuracy β | KL from gold β | Brier β |
|---|---|---|---|---|---|
| 1 | Quyet-1.0-Large | 31B | 0.791 | 0.281 | 0.114 |
| 2 | meraGPT Decider 1 | 0.768 | 0.096 | 0.052 | |
| 4 | Amos 1 medium | 9B | 0.765 | 0.151 | 0.080 |
| 7 | FastBrain-9B | 9.4B | 0.753 | 0.151 | 0.080 |
| 11 | d3-mini | 4B | 0.743 | 0.319 | 0.123 |
| 23 | signpost-d-4b | 4.5B | 0.712 | 0.162 | 0.085 |
| β | v-jev-1.0-high-base | 4B | 0.685 | 1.375 | 0.300 |
| 29 | OpenDecider-small | 0.671 | 0.211 | 0.117 | |
| β | v-jev-1.0-base | 4B | 0.668 | 0.451 | 0.210 |
| 31 | d1-3B | 3B | 0.656 | 0.286 | 0.144 |
| β | v-jev 1.4 | 4B | 0.638 | 0.272 | 0.148 |
| 33 | d1-2B | 2B | 0.637 | 0.282 | 0.137 |
| 34 | d3-nano | 2B | 0.629 | 0.545 | 0.211 |
| 37 | d3-lite | 0.8B | 0.531 | 0.518 | 0.244 |
| 39 | Jeff-Qwen3.5-2B | 2B | 0.511 | 0.460 | 0.237 |
| 41 | Jeff-Qwen3.5-0.8B | 0.8B | 0.483 | 0.679 | 0.313 |
| β | v-jev 1.4 | 0.8B | 0.481 | 0.372 | 0.201 |
| 42 | d3-edge | 0.6B | 0.425 | 1.176 | 0.456 |
| 43 | THX-01 | 0.3B | 0.377 | 0.620 | 0.320 |
| β | Prior (ignores the input) | 0.470 | 0.347 | 0.189 |
v-jev 1.4 (4B) is in the middle of the 2β4B models on accuracy, below the 1.0 base on the same backbone, and v-jev 1.4 (0.8B) is near the bottom, at the prior's accuracy: each shows its backbone's own knowledge rather than adding to it. Both keep the backbone's doubt instead of committing to one answer: the 4B's probabilities (KL 0.272) are closer to the gold than those of the other 2β4B models listed here except signpost-d-4b (0.162) and OpenDecider-small (size not listed, 0.211), and among the models of about 0.8B the 0.8B's are the closest (KL 0.372; Jeff-Qwen3.5-0.8B, on the same backbone and at the same accuracy, 0.679).
JevBench-mini
All 21 entries of JevBench-mini 0.1.0 (leaderboard.json read on Nov 11,
2026), with our rows placed by coherence. Our rows are not on the leaderboard. Ranks are the ranks the leaderboard's
intervals allow. Columns: wording, batch independence, probability measure, logical order and choice set.
| Ranks | Model | Size | Coherence (95% interval) | REP | BAT | MEA | LOG | CHO | Accuracy |
|---|---|---|---|---|---|---|---|---|---|
| 1β2 | Open-Jev-9B | 9.7B | 83.9 (82.5β85.2) | 81.9 | 100.0 | 50.2 | 87.1 | 100.0 | 88.4 |
| 1β7 | JevAny-Gemma-4B (pointer) | E4B | 81.2 (79.0β83.2) | 81.4 | 100.0 | 52.0 | 83.8 | 88.9 | 87.6 |
| 2β7 | JevAny-Qwen-4B (pointer) | 4B | 79.4 (77.2β81.4) | 81.7 | 100.0 | 52.2 | 78.3 | 84.7 | 88.8 |
| 2β8 | decider-4b v2.1 | 4.2B | 78.4 (76.0β80.7) | 80.3 | 100.0 | 52.5 | 78.8 | 80.6 | 88.6 |
| 2β8 | JevAny-Qwen-4B (direct token) | 4B | 77.8 (75.4β80.2) | 81.4 | 100.0 | 50.2 | 80.8 | 76.4 | 88.6 |
| 2β8 | TinyJev-4B | 4.0B | 77.3 (75.4β79.2) | 78.3 | 100.0 | 42.2 | 75.8 | 90.3 | 86.6 |
| 2β11 | Jebadiah 9B v2 | 9.65B | 76.9 (74.4β79.3) | 79.2 | 100.0 | 48.0 | 83.8 | 73.6 | 89.1 |
| β | v-jev-1.0-high-base | 4B | 76.1 (73.0β78.9) | 86.9 | 73.3 | 64.0 | 81.2 | 75.0 | 89.4 |
| 4β10 | Von 1.3 | 395M | 75.9 (74.7β77.1) | 83.1 | 100.0 | 16.4 | 80.0 | 100.0 | 72.2 |
| 7β15 | JevK5 v0.3 | 4.2B | 72.8 (70.4β75.3) | 76.1 | 100.0 | 43.6 | 76.2 | 68.1 | 88.1 |
| 7β15 | OneJev-4B | 5.2B | 72.5 (69.9β74.7) | 79.7 | 100.0 | 43.6 | 71.2 | 68.1 | 89.2 |
| 8β15 | RSI-Jev v3.0 2B | 2.3B | 72.2 (70.1β74.4) | 73.1 | 100.0 | 32.1 | 73.8 | 81.9 | 85.2 |
| 9β15 | Kev-4B | 4.7B | 71.9 (69.8β73.9) | 74.4 | 100.0 | 30.1 | 67.5 | 87.5 | 87.9 |
| 9β15 | decider-2b v10 | 1.9B | 71.7 (69.2β74.4) | 78.6 | 100.0 | 38.0 | 67.1 | 75.0 | 84.9 |
| β | v-jev 1.4 | 4B | 69.7 (67.6β71.8) | 76.1 | 68.3 | 39.2 | 71.7 | 93.1 | 88.1 |
| 9β15 | jevhome-E | 48M | 69.6 (68.1β71.3) | 69.2 | 100.0 | 25.2 | 84.2 | 69.4 | 55.8 |
| 9β17 | Bespoke-Nimble-9B | 9.7B | 69.2 (66.5β72.1) | 76.4 | 68.3 | 50.5 | 87.1 | 63.9 | 89.1 |
| 15β19 | CLM v0.1 | 8.2B + 20M | 66.8 (65.5β68.1) | 59.2 | 100.0 | 25.5 | 49.6 | 100.0 | 63.5 |
| β | v-jev-1.0-base | 4B | 66.4 (63.4β69.4) | 79.4 | 65.0 | 51.5 | 69.6 | 66.7 | 89.2 |
| 15β20 | OpenThai-SystemOne | 0.75B | 64.2 (61.2β67.0) | 76.9 | 70.8 | 39.7 | 61.3 | 72.2 | 82.4 |
| 16β19 | jevhome-ettin-1b | 1.0B | 64.1 (61.8β66.2) | 70.3 | 100.0 | 29.2 | 70.8 | 50.0 | 82.3 |
| 16β20 | Laya (typed-decisions) | 421M | 63.9 (61.4β66.3) | 55.0 | 100.0 | 14.5 | 73.8 | 76.4 | 71.0 |
| β | v-jev 1.4 | 0.8B | 62.4 (60β65) | 68.6 | 57.5 | 20.3 | 69.6 | 95.8 | 74.9 |
| 18β21 | Verdict 1.4 | 151M | 59.4 (57.0β61.8) | 66.1 | 100.0 | 19.9 | 77.9 | 33.3 | 64.2 |
| 20β21 | Laya (english) | 421M | 56.5 (53.8β59.2) | 52.5 | 100.0 | 16.4 | 67.9 | 45.8 | 70.8 |
v-jev 1.4 (4B) would place between ranks 9 and 17, with an interval that overlaps those of the entries from JevK5 v0.3 down to CLM v0.1, above v-jev 1.0 base on the same backbone (66.4); v-jev 1.4 (0.8B) would place between ranks 17 and 21, overlapping the 0.75Bβ1B entries above it. At both sizes the choices barely depend on which other options are listed (choice set 93.1 and 95.8). The 0.8B's probabilities over related answers add up less well (probability measure 20.3 against 39.2). Batch independence is low because all questions of a request share one prompt; most entries answer each question in its own pass and score 100 there.
Repo layout
| Path | Purpose |
|---|---|
inference.py |
Prompt building, the model, the heads, and VJev.ask (one file for all sizes) |
LICENSE |
Apache-2.0 license |
<size>/model.safetensors |
Everything of that size in one file: bf16 weights with the LoRA merged, fp32 heads, the vision encoder |
<size>/config.json, generation_config.json, preprocessor_config.json, video_preprocessor_config.json |
The backbone's configuration and image processor |
<size>/tokenizer.json, tokenizer_config.json, chat_template.jinja |
Tokenizer with the 78 added tokens, and the chat template |
<size>/vjev.json |
The read head's middle layer and the read threshold |
<size>/README.md |
That size's card |
What it does
| Question type | Answer | Read at |
|---|---|---|
noul (yes/no) |
p(yes) | the answer rows of <no>, <yes> |
choice (2β64 named options) |
a probability per option | a pointer from the <ans> slot to each option's line |
score (2β10 ordered levels) |
a probability per level | the answer rows of <lvl_0>β¦<lvl_9> |
read (a value of the state) |
the value as written in the state, or None |
a span head: the value's first and last token in the state, or "nothing" |
All questions of a request go into one prompt with one <ans> placeholder per decision and a start and end slot per
read; the model runs once. With an image, the image goes into the state through the backbone's own vision encoder.
Usage
Tested with torch 2.14 and transformers 5.x (with Qwen3.5 support) on a single RTX 5090. Install
flash-linear-attention and causal-conv1d for the backbone's linear-attention layers; without them transformers
falls back to a much slower pure-PyTorch path.
from inference import VJev
jev = VJev(size="4b") # the 4b/ folder next to inference.py; size="0.8b" for the small one
# or: VJev(repo="haohan84/v-jev1.4", size="4b") downloads only that size's folder from the Hub
answers = jev.ask(
"INVOICE INV-2026-0412\nIssued: March 4, 2026\nDue: April 3, 2026\nBill to: Amara Okafor, Cobalt Labs\nTotal: $1,240.50\n"
"Note from the customer: the March delivery arrived damaged and we would like a refund before we pay.",
{
"refund_requested": {"type": "noul", "instructions": "Does the customer ask for a refund?"},
"team": {"type": "choice", "instructions": "Which team should handle this?",
"criteria": {"billing": "Invoices, charges and refunds", "logistics": "Deliveries and damaged goods"}},
"urgency": {"type": "score", "instructions": "How urgent is this?",
"criteria": ["Not urgent", "Within a week", "Within a day", "Immediately"]},
"due_date": {"type": "read", "kind": "date", "instructions": "When is the invoice due?"},
"po_number": {"type": "read", "kind": "id", "instructions": "What is the purchase order number?"},
},
lock=True,
)
# 4B: {"refund_requested": {"type": "noul", "noul": 0.987},
# "team": {"type": "choice", "probabilities": {"billing": 0.493, "logistics": 0.507}},
# "urgency": {"type": "score", "probabilities": {"0": 0.260, "1": 0.408, "2": 0.174, "3": 0.157}},
# "due_date": {"type": "read", "value": "April 3, 2026", "parsed": "2026-04-03", "found": 1.0, "locked": true},
# "po_number": {"type": "read", "value": null, "found": 0.000002, "locked": true}}
# The invoice has no purchase order number. The 4B says so even without lock=True; the 0.8B reads the invoice number
# "INV-2026-0412" there unless lock=True, which refuses it because the span moves when the read is asked another way.
jev.ask("A photo from the warehouse.", {"damaged": {"type": "noul", "instructions": "Is the box in the photo damaged?"}},
image="box.jpg")
python inference.py --size 4b (or --size 0.8b) runs an example; add an image path for three questions about it.
Input format
| Field | Description |
|---|---|
state |
Any string or JSON value describing the situation |
questions |
Mapping of question ID to question |
image |
Optional: an image path or PIL image, placed in the state (decision questions only) |
lock |
Optional: reads answer only when their value is stable (see below) |
Each question has type and instructions, and:
choice:criteria, a mapping of option ID to description, 2 to 64 options (the model trained on at most 16 per question, andinference.pywarns above 16; the benchmarks ask longer lists in rounds of 16 plus "none of these");score:criteria, a list of 2 to 10 level descriptions, lowest first (or an object of them, and the answer is keyed by its IDs);noul: optionallycriteriawithtrueandfalsedescriptions;read: optionallykind, the kind of value:person,org,address,place,geo,date,time,duration,money,quantity,percent,email,phone,url,id,category,attribute,numberortext(default). The value comes back as written in the state; number and date reads also giveparsed(a number, orYYYY-MM-DD).
Reads must not answer when the value is not there. A read returns None when the model finds no value above the
threshold. With lock=True each read is asked three ways that should not move it, in the same batch: as served (with the
request's other questions), alone, and alone with the state's first line dropped; it returns a value only when all
three agree, and says "locked".
On pandas GitHub issues (real technical text, never trained on) the lock raises the share of right answers
to 76β77% at both sizes, at the cost of answering less often. A read may come
back a little longer or shorter than a person would mark it.
Reads are value extraction, not reading comprehension: on SQuAD 2.0 (a test only, never trained on) the 4B model refuses 74% of the unanswerable questions and gets 21% of the answerable ones exactly (0.8B: 45% and 22%). Use it to pull values out of records, documents and messages.
The state and the question texts are treated as data: inference.py breaks up every added token written out in
them. The state is otherwise inserted as is, so it can sway the answers; do not rely on the model to resist
instructions written into the state. Training used prompts of at most 4,608 tokens.
Training
Decisions (per size: one anchor model, trained once on text and images together):
- Questions: 21,491 text questions (9,758 with up to 16 options, from 34 sources of BEV texts and Open-Jev states; 11,733 from 3,000 lists of 17 to 64 options, asked in rounds of up to 16 with a final "none of these") and 22,674 image questions (A-OKVQA and ScienceQA).
- Answers: the frozen backbone's own direct answers (thinking off). Each choice question was asked in 4 option orders and each yes/no in both, and the orders were kept apart: the training target is their average (what the backbone believes), and the spread between orders (whether it is locked on an answer or moved by the order) is kept beside it. A score question was read as the probability that the backbone replies with each level's own words, with the levels listed both ways, so that no letter, number or yes/no adds a format bias. The datasets' own answers were not used.
- Score scales flipped in training (half the time the levels go to the level tokens top-down), so the model cannot learn a preference for a level token that the backbone does not have.
- Trained parts: a rank-16 LoRA and the 78 answer rows, 2 epochs; the vision encoder frozen.
Reads (then, on the frozen anchor, a span head; then the LoRA and the head once together, with the decisions held to the anchor's own answers):
- Exact labels only: human slot annotations from the Schema-Guided Dialogue dataset (SGD); synthetic documents whose values were drawn first (20 kinds, laid out by code or written around the values by Qwen3.5-4B, a value kept only where it appears verbatim), with questions phrased several ways; the real JSON records of the decision data; values that occur exactly once in real long text (CFPB complaints, Amazon ESCI product texts, When2Call requests, and 993 pandas GitHub issues, none of them in the test); encyclopedia-style articles about fictional entities.
- Absent values are exact too: fields a record does not have, a value's sentence removed from a document, or a type of value the text does not contain.
- Holding the decisions: while the reads train, every text decision keeps the anchor's own answer as its target (a KL term, weight 6). Where the anchor is sure (top probability β₯ 0.6), the final model gives the same answer on 100% of the checks at 0.8B and 99.5% at 4B.
Limitations
- The backbone's knowledge is the ceiling for decisions. Each size shows what its backbone believes, including where it is wrong; it is not trained to be right on any benchmark.
- Reads are text only. The models do not read values out of images.
- Reads are extraction, not comprehension. Questions that need reasoning over prose are answered poorly; with
lock=Truethe models answer less often instead of guessing, but the lock does not catch every wrong read. - "None of these" is rarely chosen for lists of options (CLINC150 out of scope 0% at both sizes).
- Not verified: one seed per size; English only; prompts longer than 4,608 tokens are untested.
License and data
The model is released under Apache-2.0, as its backbone. Training data: BEV and Open-Jev (questions only), A-OKVQA and ScienceQA images and questions, the Schema-Guided Dialogue dataset (CC BY-SA 4.0, slot annotations used as read labels), CFPB consumer complaints, Amazon ESCI, When2Call and pandas GitHub issues (texts for one-value reads), and documents generated by Qwen3.5-4B. Check each dataset's terms for your use.