A typed-decision model built by a self-improving loop of AI agents. It reads a decision at layers
16, 20 and 32 of Qwen/Qwen3.5-4B-Base and answers each question at the first depth that is
confident enough: easy questions stop early, hard ones use every layer. It answers choice / noul /
score questions about a document and up to four images, and speaks the
Jev HTTP API.
v6.0-VL is a System One model: one forward pass, no generated reasoning, a probability for every option. effort sets how many layers that one pass uses (16, 20 or 32), not how many tokens it writes; it writes none.
pip install "rsi-jev[fast,vision] @ git+https://github.com/Shanghua-Gao/RSI-Jev"
rsi-jev serve v6.0-vl-4b
Everything below is the version record from the project repository.
Describes release v6.0-VL Β· updated 2026-10-06
Each question picks its own depth. v6.0-VL reads a decision at three depths of one model β after layer 16, 20 and 32 of Qwen3.5-4B-Base β and answers at the first one that is confident enough. Easy questions stop early; hard ones go to the last layer. It takes the same typed questions as before β yes/no, pick-one-of-k, rate-on-a-rubric, about text and up to four images β and returns a calibrated probability for every option, plus the depth it answered at.
v6.0-VL is a System One model: one forward pass, no generated reasoning, a probability for every option. effort sets how many layers that one pass uses (16, 20 or 32), not how many tokens it writes; it writes none.
It is a 4B model, named as Qwen names the 4.66B Qwen3.5-4B-Base: 4.69B parameters β the 32 decoder layers (3.57B), the token embeddings (0.64B), the vision tower (0.33B), the main decision head (0.05B) and the two early-exit heads (0.10B). The checkpoint is self-contained.
Checkpoint: shgao/rsi-jev-v6.0-vl-4b Β· this record: versions/v6.0-vl.md
Unchanged from v5.0-VL: a state (text, optionally images), one or more typed questions, a
probability for every option in one forward pass. New in the response: usage.depth, the layer each
question was answered at.
Full fine-tuning throughout (no LoRA), from Qwen/Qwen3.5-4B-Base, seed 17 unless noted, own-token option readout
(specs in data/v6.0-vl_recipe/).
Two findings shaped the recipe: retuning heads on a trunk trained with attached early exits did not recover the deep layers' accuracy, so the early exits are detached; and 10,000 steps on the cleaned corpus beat 40,000 on the older one on the held-out set (+0.026) and MMLU-Pro (+0.043).
Image sources and their licences. Stage 3 uses v5.0-VL's image corpus: the image sources of v4.0-VL and four sets generated by code. The images are the original datasets', under their own terms. Five sources are non-commercial or research-only, and several others carry no clear grant for their images:
| source | licence |
|---|---|
| DocVQA | DocVQA terms; UCSF Industry Documents images β unclear |
| ChartQA | GPL-3.0 (repository); charts from Statista, Pew, OWID, OECD β unclear |
| VQAv2, TallyQA, A-OKVQA | annotations CC BY 4.0 / Apache-2.0; COCO images under Flickr terms β unclear |
| NLVR2 | annotations CC BY 4.0; web images β unclear |
| Hateful Memes | Facebook licence, research only |
| Screen2Words (RICO) | CC BY 4.0; RICO screenshots β unclear |
| AI2D | CC BY-SA 4.0 |
| ScienceQA | CC BY-NC-SA 4.0 |
| TQA | CC BY-NC 3.0 |
| RVL-CDIP | IIT-CDIP / Legacy Tobacco terms β unclear |
| IconQA | CC BY-NC-SA 4.0 |
| OCR-VQA | non-commercial |
| TextVQA | CC BY 4.0; OpenImages images |
| Visual7W | none found β unclear |
| six synthetic generators (v4.0-VL), spatial relations, joint reasoning, recasts, sokoban states | generated by code |
The weights are released under Apache-2.0, as earlier releases were. Whether weights trained on non-commercial data inherit those terms is not settled; check the sources above against your use.
Exits. Decision heads read layers 16 and 20 as well as the last layer (32). Each exit has
its own scalar temperature, fitted on held-out DEV rows (T = 1.88 at layer 16, 1.97 at layer 20, 1.65 at layer 32; the layer-32 value is the one in calibration.safetensors).
Choosing the exit. With auto, a question answers at the first exit whose calibrated top probability
reaches that exit's threshold, 0.95 at layer 16 and 0.59 at layer 20, else at layer 32. With no effort set, one
threshold, Ο = 0.59, applies at both exits (multi-question requests). The thresholds were picked on one half of a held-out development set weighted like our test suite and confirmed on the other half, then read once on test; nothing was tuned on test or Decision Index rows.
Mean depth on the suite: 23.3 with auto (20.9 with the single threshold).
| Hugging Face | shgao/rsi-jev-v6.0-vl-4b |
| alias | v6.0-vl-4b (rsi-jev serve v6.0-vl-4b, Decider("v6.0-vl-4b")) |
| size | 4.69B parameters, 9.7 GB (bf16) |
| file | what it holds |
|---|---|
tower.safetensors | decoder layers 1β32 (bf16) and the token embeddings |
visual.safetensors | the vision tower |
scorer.safetensors | the main decision head (layer 32) |
aux_scorers.safetensors | the decision heads at layers 16 and 20 |
calibration.json, calibration.safetensors | the main head's temperature and the per-exit temperatures ("exits") |
config.json, tokenizer and image-processor files | the base's |
meta.json | training spec, serving settings (adaptive: exits and Ο), parameter counts |
pip install "rsi-jev[fast,vision] @ git+https://github.com/Shanghua-Gao/RSI-Jev"
rsi-jev serve v6.0-vl-4b # default: single questions at 32, auto on multi-question requests
rsi-jev serve v6.0-vl-4b --effort medium # a server default; a request's own "effort" field wins
| model | base | 15-benchmark suite | held-out (eval_final_v2) | suite ECEΒ² | images | download |
|---|---|---|---|---|---|---|
| RSI-Jev-v6.0-VL-4B | Qwen3.5-4B-Base, exits at layers 16 / 20 / 32 | 0.770ΒΉ | 0.698 | β | yes | π€ download |
| RSI-Jev-v5.0-VL-3B | Qwen3.5-4B-Base, layers 1β20 | 0.764 | 0.689 | 0.050 | yes | π€ download |
| RSI-Jev-v4.0-VL-2B | Qwen3.5-2B-Base | 0.756 | 0.653 | 0.043 | yes | π€ download |
| RSI-Jev-v3.0-2B | Qwen3.5-2B-Base | 0.756 | 0.649 | 0.066 | no | π€ download |
| RSI-Jev-v2.1-2B | Qwen3.5-2B-Base | 0.736 | 0.633 | 0.059 | no | π€ download |
| RSI-Jev-v1.0-2B | Qwen3.5-2B-Base | 0.622 | 0.604 | β | no | π€ download |
ΒΉ Without open_jev_ood (see Β§8); the earlier rows include it. Β² v6.0-VL's suite calibration is not compared with earlier releases' (Β§4.1); its final-set ECE is 0.036 as served.
The package was checked against the training checkpoint: in fp32 the package matches the training checkpoint at every exit (logits within 0.021, the same top answer on every question), and on 1,000 held-out questions every question takes the same exit as in training. Served in bf16 (the default on GPU), 1β2% of questions take a different exit than in fp32; accuracy on those rows is unchanged.
Four ways to run the same weights, set per server (--effort) or per request ("effort" in the body): low stops at layer 16, medium at 20, high at 32, and auto answers at the first exit that is confident enough, with its own threshold at each exit (0.95 at layer 16, 0.59 at layer 20). With no effort set, single questions run at layer 32 and multi-question requests use a cascade with one threshold, 0.59, at both exits. Images always run all 32 layers. Suite is the fifteen-benchmark mean without open_jev_ood (see Β§8).
| default | auto | low (16) | medium (20) | high (32) | v5.0-VL 3B | |
|---|---|---|---|---|---|---|
| 15-benchmark suite, without open_jev_ood | 0.770 | 0.771 | 0.753 | 0.768 | 0.770 | 0.763 |
| held-out set (eval_final_v2) | 0.698 | 0.696 | 0.670 | 0.702 | 0.695 | 0.689 |
| MMLU-Pro 1k | 0.440 | 0.444 | 0.401 | 0.430 | 0.443 | 0.429 |
| final ECE after calibration | 0.036 | 0.024 | 0.029 | 0.037 | 0.033 | 0.042 |
| held-out images (eval_vision_v1) | 0.825 | 0.825 | 0.825 | 0.825 | 0.825 | 0.829 |
| KoBBQ accuracy / "unknown" when ambiguous | 0.918 / 0.939 | 0.925 / 0.941 | 0.925 / 0.941 | 0.923 / 0.932Β³ | ||
| CLINC150, 151 numbered options: accuracy / picks the option after the right one | 0.833 / 0.3% | β / 0.3% | 0.843 / 0.3% | 0.757 / 2.0%Β³ |
Default and auto are the bf16 package as served (auto: one pre-registered test read); low, medium and high are our fp32 reads of the same weights (text in fp32). Images are slightly below v5.0-VL (0.825 vs 0.829), within the release tolerance. Calibration is compared on the held-out final set only (0.036 as served by default and 0.024 with auto, against 0.042). The suite's calibration error is not compared with v5.0-VL's: it was not computed the same way for both.
Β³ v5.0-VL scored by its own evaluation script on the same item files. With auto, 20% of suite questions stop at layer 16, 46% at 20 and 34% go to 32: 23.3 layers on average (24.0 on the held-out set).
Which tasks need which depth (Decision Index sample, skill by exit; differences under 0.03 are noise):
Full run, as served by default (every request of the suite, all 150,759 answered, nothing cut, the unset effort): Decision Index 0.2.1 46.24 (knowledge 28.8, language 46.2, retrieval 55.5, tools 65.8, arts 37.1), with the rows that also appear in our training data left out (46.25 with them). On the public board of 2026-09-28 that is the highest score among 4B models and anything smaller (14th of 71 overall). Nearby entries: JPT-4B 43.04 (the next of our size), Jet v6.2 42.60, Decider 4B 40.70, Intern-Decision-4B 37.81; for context, JPT-9B 46.89 and Lux 9B 43.49. v5.0-VL's full run scored 38.38.
By effort level (a 16k-question stratified sample of the suite, the kit's own sampler, the same rows for every level; a sample read, not a full run):
| default | auto | low (16) | medium (20) | high (32) | v5.0-VL 3B | |
|---|---|---|---|---|---|---|
| Decision Index 0.2.1, 16k-sample read | 45.70 | 45.81 | 43.25 | 45.89 | 45.91 | 37.39 |
| knowledge | 29.0 | 25.1 | 28.5 | 29.2 | 25.8 | |
| language | 45.7 | 43.5 | 46.7 | 45.7 | 42.4 | |
| retrieval | 53.3 | 53.4 | 53.7 | 53.3 | 41.8 | |
| tools | 66.5 | 63.5 | 66.0 | 67.0 | 51.7 | |
| arts | 36.6 | 32.3 | 36.5 | 36.2 | 19.5 |
On this index, stopping at layer 20 scores the same as all 32. An earlier auto with one threshold of 0.59 at both exits read 44.89 here, 1.0 below both: it stopped 78% of questions at layer 16, and most of the loss was on two-option judgement tasks, where 0.59 is barely above chance. That is why auto now has a threshold per exit: 0.95 at layer 16, 0.59 at 20, chosen on our development sets (picked on one half, confirmed on the other, depth capped at 24 layers on average), then read once on test. On this sample the new auto reads 45.81 at 22.1 layers on average (15% of questions stop at layer 16, 62% at 20, 23% at 32). medium ties high on this sample but is not a better default in general. A pre-registered check on fresh
held-out sets, read once, found layer 20 ahead of auto on Decision Index-like questions (+0.107), level with
layer 32 there within noise (β0.018, interval β0.069 to +0.036), and behind auto on questions like our suite
(0.711 vs 0.756). No single effort wins every workload, so the default stays as verified and the effort level is
the user's choice. Leaving out the questions that also appear in our training data moves these numbers by at most 0.02.
Choosing a single threshold (confidence_threshold as one number applies it at both exits; range (0, 1]; an object such as {"16": 0.95, "20": 0.59} sets each exit, and that is auto's default). Dev sets, descriptive,
not used for any selection: a suite-like dev set, a held-out dev set, and a dev set rendered like the Decision Index.
| setting | layers, suite-like | stops at 16 / 20 / 32 | suite-like score | layers, held-out | held-out accuracy | layers, Decision-Index-style | Decision-Index-style skill |
|---|---|---|---|---|---|---|---|
| layer 16 | 16.0 | 100 / 0 / 0 % | 0.752 | 16.0 | 0.697 | 16.0 | 0.521 |
| layer 20 | 20.0 | 0 / 100 / 0 % | 0.760 | 20.0 | 0.703 | 20.0 | 0.550 |
| layer 32 | 32.0 | 0 / 0 / 100 % | 0.765 | 32.0 | 0.697 | 32.0 | 0.555 |
| threshold 0.50 | 19.4 | 76 / 4 / 20 % | 0.758 | 19.2 | 0.705 | 18.9 | 0.532 |
| threshold 0.59 | 20.9 | 65 / 5 / 30 % | 0.765 | 20.8 | 0.705 | 20.2 | 0.535 |
| threshold 0.70 | 22.9 | 52 / 6 / 42 % | 0.766 | 23.1 | 0.698 | 22.2 | 0.542 |
| threshold 0.80 | 24.8 | 40 / 6 / 54 % | 0.765 | 25.2 | 0.697 | 24.0 | 0.544 |
| threshold 0.90 | 26.9 | 29 / 5 / 67 % | 0.765 | 27.3 | 0.697 | 26.1 | 0.551 |
| threshold 0.95 | 28.3 | 21 / 4 / 76 % | 0.765 | 28.6 | 0.697 | 27.5 | 0.555 |
On suite-like and held-out text, every threshold from 0.59 up matches layer 32 within about 0.005, and 0.59 does
so at about 21 layers. On questions rendered unlike the training data, a low threshold costs quality (0.535 vs
0.555); it comes back only from about 0.9 (26β28 layers). Layer 20 is within about 0.005 of layer 32 on all three.
If inputs may be unusual, use a threshold of 0.9 or more, or medium.
Each exit has its own scalar temperature, fitted so that confidence matches accuracy at that exit: final-set ECE after calibration 0.036 as served by default, 0.024 with auto (v5.0-VL: 0.042).
What the deeper layers buy on Decision Index 0.2.1, measured on the released package (bf16, one H200) on the same 16,000-row sample as the effort table in 4.2, with the 57 rows that overlap our training data removed. Fixed exits were forced with variants that share the released weights. A plain-language walk-through of these results is in docs/effort-depth.md.
By benchmark.
Skill at layer 16 / 20 / 32. About 315 questions per benchmark in the sample (standard error about 0.03), so only gaps of 0.03 or more count.
Smaller gains from 20 to 32 show on GSM8K, WinoGrande and Habermas. BANKING77 (β.035), New Yorker (β.060) and ESCI (β.037) get worse with depth. HLE, RAGTruth and iSarcasm score zero at every exit.
By question.
Per-question correctness at layers 16, 20 and 32, on the 27 benchmarks that Decision Index scores by per-question accuracy (10,232 questions; our per-question accuracy matches the kit's own score within 0.02 at every exit). Ranking, F1 and case-level benchmarks are covered only in the section above, because per-question accuracy does not measure them. Rescued is wrong at 16 and right at 32; harmed is the reverse.
By layer 16's own confidence (calibrated top-option probability):
| layer-16 confidence | questions | acc 16 | acc 20 | acc 32 | rescued | harmed | net |
|---|---|---|---|---|---|---|---|
| below 0.50 | 2,323 | .331 | .354 | .363 | 11.5% | 8.4% | +3.1 |
| 0.50β0.59 | 1,546 | .537 | .673 | .671 | 22.5% | 9.1% | +13.5 |
| 0.59β0.70 | 1,717 | .643 | .690 | .695 | 12.1% | 6.9% | +5.2 |
| 0.70β0.80 | 1,529 | .767 | .763 | .774 | 2.9% | 2.2% | +0.7 |
| 0.80β0.90 | 1,520 | .872 | .876 | .877 | 1.1% | 0.6% | +0.5 |
| 0.90β0.97 | 1,067 | .906 | .907 | .909 | 0.3% | 0.0% | +0.3 |
| 0.97 and above | 530 | .949 | .949 | .949 | 0.0% | 0.0% | 0.0 |
By question shape:
| slice | questions | benchmarks | acc 16 | acc 20 | acc 32 | net 16β32 |
|---|---|---|---|---|---|---|
| 2 options | 3,797 | 11 | .694 | .759 | .762 | +6.8 |
| 3β4 options | 4,083 | 16 | .735 | .752 | .760 | +2.4 |
| 5β10 options | 1,404 | 10 | .462 | .467 | .449 | β1.4 |
| 11β50 options | 314 | 3 | .080 | .080 | .089 | +1.0 |
| more than 50 options | 634 | 3 | .568 | .607 | .645 | +7.7 |
| input under 256 tokens | 7,096 | 23 | .673 | .714 | .718 | +4.5 |
| input 256β1k | 1,980 | 18 | .607 | .620 | .619 | +1.2 |
| input 1kβ4k | 839 | 7 | .601 | .628 | .638 | +3.7 |
| input 4kβ16k | 317 | 3 | .606 | .621 | .666 | +6.0 |
| all accuracy-scored | 10,232 | 27 | .652 | .686 | .690 | +3.8 |
Most of the gain happens between layers 16 and 20 (.652 β .686). From 20 to 32 the average moves by .004, which hides the knowledge and multi-step reasoning benchmarks above that keep gaining.
Choosing an effort level.
low for intent, routing, retrieval and sentiment, where layer 16 is already saturated
(57% of full latency).medium for classification and judgement workloads: the same Decision Index score as high at
about 70% of the latency.high for knowledge, multi-step reasoning, code and tool documentation.auto for mixed workloads: its default thresholds (0.95 at 16, 0.59 at 20) match high on our
suite at about 23 layers. Every response
reports each question's exit (usage.depth) and calibrated confidence (usage.confidence), so
the routing can be checked.Limits of this analysis.
Median latency per request on the Decision Index sample, one NVIDIA H200, bf16:
| default | auto | low (16) | medium (20) | high (32) |
|---|---|---|---|---|
| 40 ms | β | 23 ms | 27 ms | 40 ms |
auto was read on a different GPU; at 22 layers on average it sits between medium and high.
medium matches high on the Decision Index at about 70% of the latency; low takes 57%.
Inputs up to 32,768 tokens, nothing cut (longer gets a 422); up to 5,120 options.
The API returns a probability and a confidence, and they are different numbers: confidence
is the peak statistic Jev documents, (K * p_max - 1) / (K - 1). Route on the probability of the
option you intend to act on. The response also carries usage.depth, the layer each question was
answered at.
auto's thresholds were chosen on our development sets; on workloads unlike them, check usage.depth and usage.confidence in the responses, or set an effort.97 arms ran on this line: one per distinct experiment id with a run record, first recorded from 2026-10-03
through the run that chose auto's thresholds, a rerun counted once; 93 if the four data audits are left out. This window
is counted by a different rule than the earlier sections, so the totals are not strictly comparable.
The full list of arms on the released line is in EXPLORE.md.
The training code, the stage specs and the commands are in
data/v6.0-vl_recipe/; D is the data directory. The
training corpora and the policy development sets are not public (listed in the recipe README),
so the stages cannot be rerun from this repository alone. Serving the released model needs only
the public code.
# stage 1: trunk, main head and early exits at 12 / 16 / 20 reading detached layers
python scripts/release_train.py --model Qwen/Qwen3.5-4B-Base --seed 17 --root D \
--spec data/v6.0-vl_recipe/1-trunk-exits.json --corpus D/text-corpus --save-dir D/trunk/s17
# stage 2: the early-exit heads refit on the frozen trunk, distilled from the main exit at 0.5
python scripts/refit_exit_heads.py --ckpt D/trunk/s17 --corpus D/text-corpus --out D/refit \
--exclude-public --exclude D/eval_suite_v2 --exclude D/eval_final_v2 --link-into D/trunk-refit/s17
# stage 3: images, from stage 2
python scripts/release_train.py --model Qwen/Qwen3.5-4B-Base --seed 17 --root D \
--spec data/v6.0-vl_recipe/3-images.json --corpus D/image-corpus --save-dir D/images/s17
# stage 4: all four heads under the own-token readout, tower frozen (seed 1 shipped)
RSIJEV_OPTION_POOL_OWN_TOKENS=1 python scripts/fit_head.py --ckpt D/images/s17 --corpus D/image-corpus \
--dev-corpus D/text-corpus --out D/heads-s1 --heads all --sdpa-math --max-length 4096 --skip-prefix vis --seed 1
# stages 5-6: per-exit dumps, the policy and auto's thresholds, the package (full commands in the recipe README)
python scripts/dump_exits.py dev --ckpt D/heads-s1 --corpus D/image-corpus --out D/dumps/s1 # and eval / cases / vision
python scripts/select_exit_policy.py policy ... # temperatures per exit, cascade 16 -> 20 -> 32 at 0.59
python scripts/select_exit_policy.py thresholds ... # auto: 0.95 at 16, 0.59 at 20
python scripts/package_multiexit.py --ckpt D/heads-s1 --seed-metric D/policy/seed.json --seed s1 \
--policy D/policy/cascade.json --drop-exit 12 --thresholds D/policy/auto.json --out D/package
The v5.0-VL record is left as published; these are its errata.
open_jev_ood overlapped 579 training rows, so the
15-benchmark suite (0.764) is inflated by an unknown amount; from this release the suite is
reported without it. MMLU-Pro, BBH and the held-out final set have no overlap.A typed-decision model built by a self-improving loop of AI agents. It reads a decision at layers
16, 20 and 32 of Qwen/Qwen3.5-4B-Base and answers each question at the first depth that is
confident enough: easy questions stop early, hard ones use every layer. It answers choice / noul /
score questions about a document and up to four images, and speaks the
Jev HTTP API.
v6.0-VL is a System One model: one forward pass, no generated reasoning, a probability for every option. effort sets how many layers that one pass uses (16, 20 or 32), not how many tokens it writes; it writes none.
pip install "rsi-jev[fast,vision] @ git+https://github.com/Shanghua-Gao/RSI-Jev"
rsi-jev serve v6.0-vl-4b
Everything below is the version record from the project repository.
Describes release v6.0-VL Β· updated 2026-10-06
Each question picks its own depth. v6.0-VL reads a decision at three depths of one model β after layer 16, 20 and 32 of Qwen3.5-4B-Base β and answers at the first one that is confident enough. Easy questions stop early; hard ones go to the last layer. It takes the same typed questions as before β yes/no, pick-one-of-k, rate-on-a-rubric, about text and up to four images β and returns a calibrated probability for every option, plus the depth it answered at.
v6.0-VL is a System One model: one forward pass, no generated reasoning, a probability for every option. effort sets how many layers that one pass uses (16, 20 or 32), not how many tokens it writes; it writes none.
It is a 4B model, named as Qwen names the 4.66B Qwen3.5-4B-Base: 4.69B parameters β the 32 decoder layers (3.57B), the token embeddings (0.64B), the vision tower (0.33B), the main decision head (0.05B) and the two early-exit heads (0.10B). The checkpoint is self-contained.
Checkpoint: shgao/rsi-jev-v6.0-vl-4b Β· this record: versions/v6.0-vl.md
Unchanged from v5.0-VL: a state (text, optionally images), one or more typed questions, a
probability for every option in one forward pass. New in the response: usage.depth, the layer each
question was answered at.
Full fine-tuning throughout (no LoRA), from Qwen/Qwen3.5-4B-Base, seed 17 unless noted, own-token option readout
(specs in data/v6.0-vl_recipe/).
Two findings shaped the recipe: retuning heads on a trunk trained with attached early exits did not recover the deep layers' accuracy, so the early exits are detached; and 10,000 steps on the cleaned corpus beat 40,000 on the older one on the held-out set (+0.026) and MMLU-Pro (+0.043).
Image sources and their licences. Stage 3 uses v5.0-VL's image corpus: the image sources of v4.0-VL and four sets generated by code. The images are the original datasets', under their own terms. Five sources are non-commercial or research-only, and several others carry no clear grant for their images:
| source | licence |
|---|---|
| DocVQA | DocVQA terms; UCSF Industry Documents images β unclear |
| ChartQA | GPL-3.0 (repository); charts from Statista, Pew, OWID, OECD β unclear |
| VQAv2, TallyQA, A-OKVQA | annotations CC BY 4.0 / Apache-2.0; COCO images under Flickr terms β unclear |
| NLVR2 | annotations CC BY 4.0; web images β unclear |
| Hateful Memes | Facebook licence, research only |
| Screen2Words (RICO) | CC BY 4.0; RICO screenshots β unclear |
| AI2D | CC BY-SA 4.0 |
| ScienceQA | CC BY-NC-SA 4.0 |
| TQA | CC BY-NC 3.0 |
| RVL-CDIP | IIT-CDIP / Legacy Tobacco terms β unclear |
| IconQA | CC BY-NC-SA 4.0 |
| OCR-VQA | non-commercial |
| TextVQA | CC BY 4.0; OpenImages images |
| Visual7W | none found β unclear |
| six synthetic generators (v4.0-VL), spatial relations, joint reasoning, recasts, sokoban states | generated by code |
The weights are released under Apache-2.0, as earlier releases were. Whether weights trained on non-commercial data inherit those terms is not settled; check the sources above against your use.
Exits. Decision heads read layers 16 and 20 as well as the last layer (32). Each exit has
its own scalar temperature, fitted on held-out DEV rows (T = 1.88 at layer 16, 1.97 at layer 20, 1.65 at layer 32; the layer-32 value is the one in calibration.safetensors).
Choosing the exit. With auto, a question answers at the first exit whose calibrated top probability
reaches that exit's threshold, 0.95 at layer 16 and 0.59 at layer 20, else at layer 32. With no effort set, one
threshold, Ο = 0.59, applies at both exits (multi-question requests). The thresholds were picked on one half of a held-out development set weighted like our test suite and confirmed on the other half, then read once on test; nothing was tuned on test or Decision Index rows.
Mean depth on the suite: 23.3 with auto (20.9 with the single threshold).
| Hugging Face | shgao/rsi-jev-v6.0-vl-4b |
| alias | v6.0-vl-4b (rsi-jev serve v6.0-vl-4b, Decider("v6.0-vl-4b")) |
| size | 4.69B parameters, 9.7 GB (bf16) |
| file | what it holds |
|---|---|
tower.safetensors | decoder layers 1β32 (bf16) and the token embeddings |
visual.safetensors | the vision tower |
scorer.safetensors | the main decision head (layer 32) |
aux_scorers.safetensors | the decision heads at layers 16 and 20 |
calibration.json, calibration.safetensors | the main head's temperature and the per-exit temperatures ("exits") |
config.json, tokenizer and image-processor files | the base's |
meta.json | training spec, serving settings (adaptive: exits and Ο), parameter counts |
pip install "rsi-jev[fast,vision] @ git+https://github.com/Shanghua-Gao/RSI-Jev"
rsi-jev serve v6.0-vl-4b # default: single questions at 32, auto on multi-question requests
rsi-jev serve v6.0-vl-4b --effort medium # a server default; a request's own "effort" field wins
| model | base | 15-benchmark suite | held-out (eval_final_v2) | suite ECEΒ² | images | download |
|---|---|---|---|---|---|---|
| RSI-Jev-v6.0-VL-4B | Qwen3.5-4B-Base, exits at layers 16 / 20 / 32 | 0.770ΒΉ | 0.698 | β | yes | π€ download |
| RSI-Jev-v5.0-VL-3B | Qwen3.5-4B-Base, layers 1β20 | 0.764 | 0.689 | 0.050 | yes | π€ download |
| RSI-Jev-v4.0-VL-2B | Qwen3.5-2B-Base | 0.756 | 0.653 | 0.043 | yes | π€ download |
| RSI-Jev-v3.0-2B | Qwen3.5-2B-Base | 0.756 | 0.649 | 0.066 | no | π€ download |
| RSI-Jev-v2.1-2B | Qwen3.5-2B-Base | 0.736 | 0.633 | 0.059 | no | π€ download |
| RSI-Jev-v1.0-2B | Qwen3.5-2B-Base | 0.622 | 0.604 | β | no | π€ download |
ΒΉ Without open_jev_ood (see Β§8); the earlier rows include it. Β² v6.0-VL's suite calibration is not compared with earlier releases' (Β§4.1); its final-set ECE is 0.036 as served.
The package was checked against the training checkpoint: in fp32 the package matches the training checkpoint at every exit (logits within 0.021, the same top answer on every question), and on 1,000 held-out questions every question takes the same exit as in training. Served in bf16 (the default on GPU), 1β2% of questions take a different exit than in fp32; accuracy on those rows is unchanged.
Four ways to run the same weights, set per server (--effort) or per request ("effort" in the body): low stops at layer 16, medium at 20, high at 32, and auto answers at the first exit that is confident enough, with its own threshold at each exit (0.95 at layer 16, 0.59 at layer 20). With no effort set, single questions run at layer 32 and multi-question requests use a cascade with one threshold, 0.59, at both exits. Images always run all 32 layers. Suite is the fifteen-benchmark mean without open_jev_ood (see Β§8).
| default | auto | low (16) | medium (20) | high (32) | v5.0-VL 3B | |
|---|---|---|---|---|---|---|
| 15-benchmark suite, without open_jev_ood | 0.770 | 0.771 | 0.753 | 0.768 | 0.770 | 0.763 |
| held-out set (eval_final_v2) | 0.698 | 0.696 | 0.670 | 0.702 | 0.695 | 0.689 |
| MMLU-Pro 1k | 0.440 | 0.444 | 0.401 | 0.430 | 0.443 | 0.429 |
| final ECE after calibration | 0.036 | 0.024 | 0.029 | 0.037 | 0.033 | 0.042 |
| held-out images (eval_vision_v1) | 0.825 | 0.825 | 0.825 | 0.825 | 0.825 | 0.829 |
| KoBBQ accuracy / "unknown" when ambiguous | 0.918 / 0.939 | 0.925 / 0.941 | 0.925 / 0.941 | 0.923 / 0.932Β³ | ||
| CLINC150, 151 numbered options: accuracy / picks the option after the right one | 0.833 / 0.3% | β / 0.3% | 0.843 / 0.3% | 0.757 / 2.0%Β³ |
Default and auto are the bf16 package as served (auto: one pre-registered test read); low, medium and high are our fp32 reads of the same weights (text in fp32). Images are slightly below v5.0-VL (0.825 vs 0.829), within the release tolerance. Calibration is compared on the held-out final set only (0.036 as served by default and 0.024 with auto, against 0.042). The suite's calibration error is not compared with v5.0-VL's: it was not computed the same way for both.
Β³ v5.0-VL scored by its own evaluation script on the same item files. With auto, 20% of suite questions stop at layer 16, 46% at 20 and 34% go to 32: 23.3 layers on average (24.0 on the held-out set).
Which tasks need which depth (Decision Index sample, skill by exit; differences under 0.03 are noise):
Full run, as served by default (every request of the suite, all 150,759 answered, nothing cut, the unset effort): Decision Index 0.2.1 46.24 (knowledge 28.8, language 46.2, retrieval 55.5, tools 65.8, arts 37.1), with the rows that also appear in our training data left out (46.25 with them). On the public board of 2026-09-28 that is the highest score among 4B models and anything smaller (14th of 71 overall). Nearby entries: JPT-4B 43.04 (the next of our size), Jet v6.2 42.60, Decider 4B 40.70, Intern-Decision-4B 37.81; for context, JPT-9B 46.89 and Lux 9B 43.49. v5.0-VL's full run scored 38.38.
By effort level (a 16k-question stratified sample of the suite, the kit's own sampler, the same rows for every level; a sample read, not a full run):
| default | auto | low (16) | medium (20) | high (32) | v5.0-VL 3B | |
|---|---|---|---|---|---|---|
| Decision Index 0.2.1, 16k-sample read | 45.70 | 45.81 | 43.25 | 45.89 | 45.91 | 37.39 |
| knowledge | 29.0 | 25.1 | 28.5 | 29.2 | 25.8 | |
| language | 45.7 | 43.5 | 46.7 | 45.7 | 42.4 | |
| retrieval | 53.3 | 53.4 | 53.7 | 53.3 | 41.8 | |
| tools | 66.5 | 63.5 | 66.0 | 67.0 | 51.7 | |
| arts | 36.6 | 32.3 | 36.5 | 36.2 | 19.5 |
On this index, stopping at layer 20 scores the same as all 32. An earlier auto with one threshold of 0.59 at both exits read 44.89 here, 1.0 below both: it stopped 78% of questions at layer 16, and most of the loss was on two-option judgement tasks, where 0.59 is barely above chance. That is why auto now has a threshold per exit: 0.95 at layer 16, 0.59 at 20, chosen on our development sets (picked on one half, confirmed on the other, depth capped at 24 layers on average), then read once on test. On this sample the new auto reads 45.81 at 22.1 layers on average (15% of questions stop at layer 16, 62% at 20, 23% at 32). medium ties high on this sample but is not a better default in general. A pre-registered check on fresh
held-out sets, read once, found layer 20 ahead of auto on Decision Index-like questions (+0.107), level with
layer 32 there within noise (β0.018, interval β0.069 to +0.036), and behind auto on questions like our suite
(0.711 vs 0.756). No single effort wins every workload, so the default stays as verified and the effort level is
the user's choice. Leaving out the questions that also appear in our training data moves these numbers by at most 0.02.
Choosing a single threshold (confidence_threshold as one number applies it at both exits; range (0, 1]; an object such as {"16": 0.95, "20": 0.59} sets each exit, and that is auto's default). Dev sets, descriptive,
not used for any selection: a suite-like dev set, a held-out dev set, and a dev set rendered like the Decision Index.
| setting | layers, suite-like | stops at 16 / 20 / 32 | suite-like score | layers, held-out | held-out accuracy | layers, Decision-Index-style | Decision-Index-style skill |
|---|---|---|---|---|---|---|---|
| layer 16 | 16.0 | 100 / 0 / 0 % | 0.752 | 16.0 | 0.697 | 16.0 | 0.521 |
| layer 20 | 20.0 | 0 / 100 / 0 % | 0.760 | 20.0 | 0.703 | 20.0 | 0.550 |
| layer 32 | 32.0 | 0 / 0 / 100 % | 0.765 | 32.0 | 0.697 | 32.0 | 0.555 |
| threshold 0.50 | 19.4 | 76 / 4 / 20 % | 0.758 | 19.2 | 0.705 | 18.9 | 0.532 |
| threshold 0.59 | 20.9 | 65 / 5 / 30 % | 0.765 | 20.8 | 0.705 | 20.2 | 0.535 |
| threshold 0.70 | 22.9 | 52 / 6 / 42 % | 0.766 | 23.1 | 0.698 | 22.2 | 0.542 |
| threshold 0.80 | 24.8 | 40 / 6 / 54 % | 0.765 | 25.2 | 0.697 | 24.0 | 0.544 |
| threshold 0.90 | 26.9 | 29 / 5 / 67 % | 0.765 | 27.3 | 0.697 | 26.1 | 0.551 |
| threshold 0.95 | 28.3 | 21 / 4 / 76 % | 0.765 | 28.6 | 0.697 | 27.5 | 0.555 |
On suite-like and held-out text, every threshold from 0.59 up matches layer 32 within about 0.005, and 0.59 does
so at about 21 layers. On questions rendered unlike the training data, a low threshold costs quality (0.535 vs
0.555); it comes back only from about 0.9 (26β28 layers). Layer 20 is within about 0.005 of layer 32 on all three.
If inputs may be unusual, use a threshold of 0.9 or more, or medium.
Each exit has its own scalar temperature, fitted so that confidence matches accuracy at that exit: final-set ECE after calibration 0.036 as served by default, 0.024 with auto (v5.0-VL: 0.042).
What the deeper layers buy on Decision Index 0.2.1, measured on the released package (bf16, one H200) on the same 16,000-row sample as the effort table in 4.2, with the 57 rows that overlap our training data removed. Fixed exits were forced with variants that share the released weights. A plain-language walk-through of these results is in docs/effort-depth.md.
By benchmark.
Skill at layer 16 / 20 / 32. About 315 questions per benchmark in the sample (standard error about 0.03), so only gaps of 0.03 or more count.
Smaller gains from 20 to 32 show on GSM8K, WinoGrande and Habermas. BANKING77 (β.035), New Yorker (β.060) and ESCI (β.037) get worse with depth. HLE, RAGTruth and iSarcasm score zero at every exit.
By question.
Per-question correctness at layers 16, 20 and 32, on the 27 benchmarks that Decision Index scores by per-question accuracy (10,232 questions; our per-question accuracy matches the kit's own score within 0.02 at every exit). Ranking, F1 and case-level benchmarks are covered only in the section above, because per-question accuracy does not measure them. Rescued is wrong at 16 and right at 32; harmed is the reverse.
By layer 16's own confidence (calibrated top-option probability):
| layer-16 confidence | questions | acc 16 | acc 20 | acc 32 | rescued | harmed | net |
|---|---|---|---|---|---|---|---|
| below 0.50 | 2,323 | .331 | .354 | .363 | 11.5% | 8.4% | +3.1 |
| 0.50β0.59 | 1,546 | .537 | .673 | .671 | 22.5% | 9.1% | +13.5 |
| 0.59β0.70 | 1,717 | .643 | .690 | .695 | 12.1% | 6.9% | +5.2 |
| 0.70β0.80 | 1,529 | .767 | .763 | .774 | 2.9% | 2.2% | +0.7 |
| 0.80β0.90 | 1,520 | .872 | .876 | .877 | 1.1% | 0.6% | +0.5 |
| 0.90β0.97 | 1,067 | .906 | .907 | .909 | 0.3% | 0.0% | +0.3 |
| 0.97 and above | 530 | .949 | .949 | .949 | 0.0% | 0.0% | 0.0 |
By question shape:
| slice | questions | benchmarks | acc 16 | acc 20 | acc 32 | net 16β32 |
|---|---|---|---|---|---|---|
| 2 options | 3,797 | 11 | .694 | .759 | .762 | +6.8 |
| 3β4 options | 4,083 | 16 | .735 | .752 | .760 | +2.4 |
| 5β10 options | 1,404 | 10 | .462 | .467 | .449 | β1.4 |
| 11β50 options | 314 | 3 | .080 | .080 | .089 | +1.0 |
| more than 50 options | 634 | 3 | .568 | .607 | .645 | +7.7 |
| input under 256 tokens | 7,096 | 23 | .673 | .714 | .718 | +4.5 |
| input 256β1k | 1,980 | 18 | .607 | .620 | .619 | +1.2 |
| input 1kβ4k | 839 | 7 | .601 | .628 | .638 | +3.7 |
| input 4kβ16k | 317 | 3 | .606 | .621 | .666 | +6.0 |
| all accuracy-scored | 10,232 | 27 | .652 | .686 | .690 | +3.8 |
Most of the gain happens between layers 16 and 20 (.652 β .686). From 20 to 32 the average moves by .004, which hides the knowledge and multi-step reasoning benchmarks above that keep gaining.
Choosing an effort level.
low for intent, routing, retrieval and sentiment, where layer 16 is already saturated
(57% of full latency).medium for classification and judgement workloads: the same Decision Index score as high at
about 70% of the latency.high for knowledge, multi-step reasoning, code and tool documentation.auto for mixed workloads: its default thresholds (0.95 at 16, 0.59 at 20) match high on our
suite at about 23 layers. Every response
reports each question's exit (usage.depth) and calibrated confidence (usage.confidence), so
the routing can be checked.Limits of this analysis.
Median latency per request on the Decision Index sample, one NVIDIA H200, bf16:
| default | auto | low (16) | medium (20) | high (32) |
|---|---|---|---|---|
| 40 ms | β | 23 ms | 27 ms | 40 ms |
auto was read on a different GPU; at 22 layers on average it sits between medium and high.
medium matches high on the Decision Index at about 70% of the latency; low takes 57%.
Inputs up to 32,768 tokens, nothing cut (longer gets a 422); up to 5,120 options.
The API returns a probability and a confidence, and they are different numbers: confidence
is the peak statistic Jev documents, (K * p_max - 1) / (K - 1). Route on the probability of the
option you intend to act on. The response also carries usage.depth, the layer each question was
answered at.
auto's thresholds were chosen on our development sets; on workloads unlike them, check usage.depth and usage.confidence in the responses, or set an effort.97 arms ran on this line: one per distinct experiment id with a run record, first recorded from 2026-10-03
through the run that chose auto's thresholds, a rerun counted once; 93 if the four data audits are left out. This window
is counted by a different rule than the earlier sections, so the totals are not strictly comparable.
The full list of arms on the released line is in EXPLORE.md.
The training code, the stage specs and the commands are in
data/v6.0-vl_recipe/; D is the data directory. The
training corpora and the policy development sets are not public (listed in the recipe README),
so the stages cannot be rerun from this repository alone. Serving the released model needs only
the public code.
# stage 1: trunk, main head and early exits at 12 / 16 / 20 reading detached layers
python scripts/release_train.py --model Qwen/Qwen3.5-4B-Base --seed 17 --root D \
--spec data/v6.0-vl_recipe/1-trunk-exits.json --corpus D/text-corpus --save-dir D/trunk/s17
# stage 2: the early-exit heads refit on the frozen trunk, distilled from the main exit at 0.5
python scripts/refit_exit_heads.py --ckpt D/trunk/s17 --corpus D/text-corpus --out D/refit \
--exclude-public --exclude D/eval_suite_v2 --exclude D/eval_final_v2 --link-into D/trunk-refit/s17
# stage 3: images, from stage 2
python scripts/release_train.py --model Qwen/Qwen3.5-4B-Base --seed 17 --root D \
--spec data/v6.0-vl_recipe/3-images.json --corpus D/image-corpus --save-dir D/images/s17
# stage 4: all four heads under the own-token readout, tower frozen (seed 1 shipped)
RSIJEV_OPTION_POOL_OWN_TOKENS=1 python scripts/fit_head.py --ckpt D/images/s17 --corpus D/image-corpus \
--dev-corpus D/text-corpus --out D/heads-s1 --heads all --sdpa-math --max-length 4096 --skip-prefix vis --seed 1
# stages 5-6: per-exit dumps, the policy and auto's thresholds, the package (full commands in the recipe README)
python scripts/dump_exits.py dev --ckpt D/heads-s1 --corpus D/image-corpus --out D/dumps/s1 # and eval / cases / vision
python scripts/select_exit_policy.py policy ... # temperatures per exit, cascade 16 -> 20 -> 32 at 0.59
python scripts/select_exit_policy.py thresholds ... # auto: 0.95 at 16, 0.59 at 20
python scripts/package_multiexit.py --ckpt D/heads-s1 --seed-metric D/policy/seed.json --seed s1 \
--policy D/policy/cascade.json --drop-exit 12 --thresholds D/policy/auto.json --out D/package
The v5.0-VL record is left as published; these are its errata.
open_jev_ood overlapped 579 training rows, so the
15-benchmark suite (0.764) is inflated by an unknown amount; from this release the suite is
reported without it. MMLU-Pro, BBH and the held-out final set have no overlap.