selfjev/GitHub
GET STARTED / SELFJEV

Hardware & sizing

GPU, CPU, memory, and what is actually tested.

Use an NVIDIA GPU for the supported server. selfjev serve selects CUDA by default and does not offer a CPU or MPS device flag. A full-model Apple Silicon experiment is measured below through the lower-level tree engine; it is not a validated Mac serving setup.

A practical starting point

WorkloadGPU / VRAMSystem RAMCPUStatus
Light inferenceNVIDIA, 24 GB16–32 GB4 vCPUsMeasured on an A10G: texts up to 32K tokens with 50 questions fit (21.1 GB peak)
8 GB card (RTX 4060 class)NVIDIA, 8 GB16 GB4 vCPUs4-bit build measured: texts up to 16K tokens fit (6.0 GiB peak); see below
Smaller-memory experimentNVIDIA, 16 GB16–32 GB4+ vCPUsDocumented floor; workload-dependent, not a measured minimum
Long inputs or more concurrencyNVIDIA, 48 GB32 GB+8 vCPUsConservative starting point; measure your workload
Fine-tuningL40S, 48 GB64 GB used on g6e.2xlarge8 vCPUsTraining recipe run on this class of machine
CPU-onlyNone32 GB budget for an experimentModern multicore CPUUnsupported CLI path; no measured latency or minimum
Marketing and docs siteNoneNo dedicated runtime requiredNone at runtimeStatic Next.js export

System RAM and GPU VRAM are separate resources. Extra system RAM does not automatically compensate for too little VRAM in this engine.

Compare measured GPU response times

The interactive hardware comparison shows how long one request takes with SelfJev-4B on A10G, L40S, and H100: texts from 512 to 32,000 tokens, with 1 to 50 questions about the same text. It runs the native tree engine that selfjev serve uses, version 0.4.2, measured on October 5, 2026; the fainter bar in the chart is version 0.4.1, measured on September 30. Each value is the median of up to 20 warmed requests (at least 3), with three answer options per question. The times are measured inside the process, without HTTP or network time. The chart links each GPU to its raw benchmark; the full tables add decisions per second and the cost of each extra question.

Version 0.4.2 against 0.4.1

Version 0.4.2 (October 5, 2026) changed the engine, not the model: the same weights answer faster. One request with one question, median time:

Text tokensA10G 0.4.1A10G 0.4.2L40S 0.4.1L40S 0.4.2H100 0.4.1H100 0.4.2
512241 ms158 ms145 ms93 ms146 ms94 ms
2,048584 ms434 ms243 ms146 ms166 ms99 ms
8,1922,558 ms1,545 ms1,173 ms624 ms506 ms244 ms
16,3847,157 ms3,159 ms3,129 ms1,334 ms1,290 ms494 ms
32,00022,019 ms6,721 ms9,146 ms2,739 ms4,033 ms1,055 ms
0.4.2 is faster by1.3–3.3×1.6–3.3×1.5–3.8×
Same weights, two engine versions0.4.10.4.2
Text Decisions, all 1,991 questions, four requests in flight on one L40S167 s100 s
AI Response Review, all 946 questions, same setup68 s41 s
Accuracy, Text Decisions96.1%96.2%
Accuracy, AI Response Review92.6%92.6%
Accuracy, image test (2,002 questions)90.5%90.5%
  • Long texts gain the most. A 32,000-token text takes 2.7 s on an L40S instead of 9.1 s, and uses less memory (15.5 GB reserved instead of 20.2 GB).
  • The answers are the same. Each test set differs by a handful of near-tie questions, none of it significant.
  • Many questions about a short text did not get faster. With 25 or 50 questions on a text of 2,048 tokens or less, the A10G and the L40S take about as long as before; the answer branches are most of the work there.

Many questions about one text

The shared-prefix tree reads the text once. Each question then adds only its own short branch. On a 24 GB A10G with version 0.4.2:

Text tokens1 question510255050 questions with 0.4.1Peak GPU memory, 1 → 50 questions
512158 ms2653497111,4441,4708.1 → 10.3 GB
2,048434 ms5195981,0191,7301,9458.5 → 10.5 GB
8,1921,545 ms1,6401,7402,1973,0164,5769.9 → 11.5 GB
16,3843,159 ms3,2643,3923,9595,1129,60711.8 → 12.6 GB
32,0006,721 ms6,8567,1237,8849,46027,76015.5–18.0 GB
  • Memory follows the text, not the questions. The weights take about 8 GB, and 50 questions add at most 2.5 GB. Every workload above fits on the 24 GB card.
  • Latency grows far more slowly than the number of questions. Fifty questions take 1.4–9.1× as long as one. One request with 50 questions is 5–36× faster than 50 requests with one question each.
  • Faster GPUs cut the time, not the memory. Fifty questions about a 2,048-token text take 1,730 ms on the A10G, 804 ms on an L40S and 334 ms on an H100. Memory use is the same on all three.

These requests use synthetic text and are sent one at a time. The 32K rows measure time and memory only: the model was trained on texts up to 16K tokens.

Apple Silicon experiment

We also ran SelfJev-4B on a local M5 Pro with a 20-core GPU and 48 GB of unified memory (September 28, 2026, with the engine before version 0.4.2). The adapter was merged into Qwen3.5-4B in bf16 and scored through TreeServer on PyTorch MPS. The test used synthetic repeated text and three answer options per question. These are local call times, including tokenization but excluding HTTP and network time; each cell is the median of 10 calls after two warm-ups.

Text length1 question16 questions
8 tokens688 ms6,786 ms
512 tokens2,018 ms8,599 ms

The MPS path uses PyTorch's slower reference implementation for the model's gated recurrent operation. The raw samples and benchmark script make this small experiment reproducible. The supported CLI still requires CUDA.

An 8 GB GPU: 4-bit and 8-bit builds

The full model needs about 9 GB for bf16 weights alone, so it does not load on an 8 GB card such as an RTX 4060. Two pre-quantized builds do: 4-bit (NF4) and 8-bit, both made with bitsandbytes from the same merged weights.

bash
pip install "selfjev[serve,gpu,quant]"
selfjev serve --quantized-model Jwuthrich/selfjev-4b-vision-4bit

We scored them on all 3,657 Decision Bench questions on an A10G whose memory we capped at 7.2 GiB, the usable memory of an 8 GB card.

BuildDecision Bench (3,657)eval2 (1,991)eval_llm (946)compact (720)
bf16 (full model)95.9%96.1%92.5%100%
8-bit95.3%95.2%92.0%100%
4-bit (NF4)95.0%94.7%92.0%100%

Peak GPU memory and median time for one question with version 0.4.2 (memory in GiB allocated; the weights alone are 8 for bf16 and about 3 for 4-bit):

Text lengthbf168-bit4-bit
2,048 tokens8.3, 434 ms4.8, 558 ms3.4, 454 ms
8,192 tokens9.2, 1,545 ms5.8, 1,767 ms4.3, 1,565 ms
16,384 tokens10.4, 3,159 msout of memory at 7.2 GiB5.6, 3,193 ms
  • Use 4-bit on an 8 GB card. It costs about one point against bf16, reads texts up to 16K tokens, and one 2K-token request takes 454 ms on the A10G (bf16: 434 ms; with version 0.4.1 it took 604 ms). Most of its eval2 loss is in multi-select questions, where the exact set of answers must match.
  • 8-bit is slightly more accurate but needs about 10 GB for long texts. It also runs slower (558 ms for the same request).
  • Measured on text. Images use the same vision tower as the full model (loaded from the Qwen3.5-4B base on the first image); the quantized path was not scored on images.
  • bitsandbytes needs an NVIDIA GPU with CUDA (Linux or Windows). The raw reports are in the repository.

A 16 GB RAM CPU machine is not a supported minimum. No CPU artifact or llama.cpp/GGUF serving path is provided on this page.

Context length and concurrency matter

SelfJev's context limit is configurable with --max-length; the default is 32,768 tokens for the formatted document plus the longest question/candidate path. Prompt formatting and options also consume this budget.

The underlying Qwen3.5-4B configuration has a native 262,144-token context window. That is base-model capacity, not a validated SelfJev serving limit: training used texts up to 16K, and we have not validated full-window inference or accuracy in this engine. Raising the flag alone does not establish usable capacity.

For comparison, Jev's published limits are 32K tokens for state plus the longest question, and 64K tokens for state plus all questions combined (checked September 28, 2026). Self-hosting lets you experiment with a larger budget, subject to memory and validation on your documents.

Memory use grows mainly with document length, as measured above; question and candidate branches add little, and batching adds more. Since version 0.4.2 the text is read without an attention mask; only question and answer tokens carry one, so a request with very many questions and options is what costs extra.

Start with short inputs and conservative batching. The controls are:

bash
uv run --no-sync selfjev serve \
  --max-length 4096 \
  --max-batch-tokens 4096

--max-length limits the state plus the longest question/candidate path. --max-batch-tokens controls packing; it is not a hard memory cap for a single large request tree. Reduce question and candidate counts as well if you run out of memory. Longer-than-allowed input is rejected, not silently truncated.

Disk and first startup

Budget 50 GB of free disk for the checkout, Python/CUDA dependencies, adapter, model cache, and temporary files. This is a planning allowance, not a measured minimum. Building a Docker image with baked-in weights may require additional space.

What has actually been measured?

The current model's latency and memory are measured on A10G, L40S and H100, and a smaller experiment ran on an M5 Pro. The native tree engine also has an A10G correctness check, and the training recipe ran on an L40S. L4 latency, Mac serving and full-model CPU inference remain unvalidated. See the linked reports for the configuration and scope of each measurement.

Sources: question sweep, the 0.4.2 engine report, deployment notes, engine loader, tree packing, GPU engine check, and latency methodology.