News & Updates8 min read

OpenJev Is Live on an OpenAI-Compatible API: an Open Jev Alternative You Can Call Today

TypeSafe's Jev is hosted-only and behind a waitlist. OpenJev, the open NLI cross-encoder built on Qwen3.5, is now served on ParalonCloud behind POST /v1/classify: a label and calibrated probabilities per input, 3 ms per item in a batch, no generated text. Measured against a 27B LLM judge on the same pairs, with the vLLM recipe so you can run it yourself.

The Paralon capybara at a glowing emerald lever switch under holographic panels: one decision, no text

OpenJev is live on the ParalonCloud API. POST /v1/classify takes a premise and a hypothesis and returns entailment, contradiction or neutral with calibrated probabilities, in one forward pass, no generated text. It runs on the same prlc_ key as chat, embeddings and images, with the same free trial. Model id: openjev-4b.

If you have been following the last week, you know why this exists. On 15 September TypeSafe AI launched Jev, the first of what they call System One models: instead of writing text, the model reads a state and answers typed questions with probabilities, 40 to 200 times faster than a frontier LLM on the same decision. Jev is hosted-only, closed weights, behind a waitlist. Within three days several open projects calling themselves OpenJev appeared, and the Hacker News thread on one of them went past 500 points. The one we serve is AlexWortega/openjev (MIT): Qwen3.5-4B with the language-model head replaced by a three-class head, trained as a natural language inference cross-encoder.

You still cannot run Jev locally. You can call this today, and you can run it yourself with the recipe at the end.

What it does, in one primitive

The model answers exactly one question: given the premise, is the hypothesis entailed, contradicted, or undetermined? Everything else is phrasing.

you wantpremisehypothesis
rerank search resultsthe queryThe correct answer is: {passage}
grade an answer{question}\nReference answer: {reference}Answer: {candidate}
guardrail a replythe model's replyThis text reveals a customer's personal data
check RAG against sourcesthe retrieved documenteach sentence of the generated answer
route a messagethe user's messageThe user wants a refund / …reports a bug / …asks about pricing
classify without trainingthe documenteach label, written as a sentence

Take the highest entailment probability, or threshold it. No prompt engineering for output format, no JSON to parse, no retries on malformed text.

Call it

curl https://paraloncloud.com/v1/classify \
  -H "Authorization: Bearer $PARALON_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openjev-4b",
    "pairs": [
      {"premise": "The invoice was paid on March 3rd by bank transfer.",
       "hypothesis": "The invoice has been settled."},
      {"premise": "The invoice was paid on March 3rd by bank transfer.",
       "hypothesis": "The invoice is still open."}
    ]
  }'
{
  "object": "list",
  "model": "openjev-4b",
  "data": [
    {"index": 0, "label": "entailment",    "probs": [0.0004, 0.9871, 0.0125], "num_classes": 3},
    {"index": 1, "label": "contradiction", "probs": [0.9612, 0.0031, 0.0357], "num_classes": 3}
  ],
  "usage": {"prompt_tokens": 58, "total_tokens": 58, "completion_tokens": 0}
}

probs are [contradiction, entailment, neutral]. You can also send input as raw strings if you want to format the pair yourself; the model's own template is Premise: …\nHypothesis: …. Up to 256 items per request, 4,096 tokens each. In Python it is one requests.post; there is no SDK method to learn.

Measured

Everything below was run on 21 September 2026 against the public endpoint, from outside our network, with a premium key. The worker is a single RTX 4090 running vLLM 0.29 with the weights in FP8.

Latency through the public API

requesttime
one pair, p50 of 20180 ms
16 pairs in one request198 ms (12 ms per item)
64 pairs322 ms (5 ms per item)
256 pairs784 ms (3.1 ms per item)
one 533-token premise213 ms

On the worker itself a single pair is 18 ms. The other ~160 ms of a single-item call is the round trip: edge, gateway, tunnel to the node and back. So the rule is simple: batch. 256 pairs in 784 ms is about 10,000 tokens per second through the public API, and a client that sends one item per request is paying for the network, not the model.

Accuracy on a 20-pair smoke set, against an LLM judge

We wrote 20 pairs that a naive classifier gets wrong: negations, a changed meeting day, a price that is off by 10×, a drug dose, a grading pair with a reference answer, a refund complaint against three routing hypotheses, a credential-leak guardrail, and one French premise with an English hypothesis. Then we ran the same 20 through qwen3.8-27b as a judge, with a short rubric and temperature: 0, one pair per request, the way people actually use an LLM as a judge.

OpenJev 4BQwen 3.8 27B as judge
correct18 / 2018 / 20
time for all 20245 ms, one request5,765 ms, 20 requests
per item12 ms288 ms
tokens545 in, 0 out2,025 in, 74 out
list price for 1,000 verdicts$0.0014$0.018

Same score. Both models called "the user reports a bug in the app" a contradiction of a refund complaint where we had written neutral; on reflection they have a point. The two real misses differ: OpenJev failed the cross-lingual pair (French premise, English hypothesis: contradiction at 0.61 where entailment was right), and the 27B judge missed the credential guardrail in the negative case (called "sunny skies all week" neutral for "reveals a credential" instead of contradiction). Twenty pairs is a smoke test, not a benchmark; the point is the shape of the trade: the same answers, 24× faster and 13× cheaper, for questions that have a closed answer.

Reranking, the case most people will use it for: five passages from our docs against "How do I stop billing on a GPU rental?" came back in the right order in 193 ms, with the DELETE /rentals/{id} passage first. The absolute entailment probability of the winner was only 0.12, though. On technical text the ordering is reliable and the raw number is not a confidence you should show a user.

Where it is honest about its limits

  • English. The base model is multilingual, the NLI training is not. Our one cross-lingual pair failed; do not send it French and expect entailment.
  • It decides, it does not explain. No reasoning, no "why". If you need the why, that is a chat model's job.
  • Single items are network-bound. 180 ms of which 18 is inference. Batch.
  • Text only. The v2 checkpoint can read images; we serve a text-only copy (see below). If image NLI matters to you, tell us.
  • 4,096-token input, no Batch API line type yet, and the same rate limits as chat.

We have not measured it against Jev itself. TypeSafe's model is hosted behind a waitlist and, as commenters on Hacker News pointed out, its terms reportedly restrict public benchmarking. "OpenJev" is a name several projects share; this article is about the AlexWortega checkpoint served on our network, nothing else.

How we got it onto vLLM (and how you can)

This is the part that cost a day, so here it is for free. vLLM has no Qwen3_5ForSequenceClassification in its registry, but its _normalize_arch falls back to Qwen3_5ForCausalLM and the as_seq_cls_model adapter loads the score head from the checkpoint, so --runner pooling --convert classify is enough… almost. The v2 checkpoint carries the Qwen3.5 vision tower, and the text-only class has nowhere to put those 297 model.visual.* tensors:

ValueError: There is no module or parameter named 'visual' in Qwen3_5Model

The fix is a text-only copy. Download only the subfolder, drop the vision tensors, rename the language-model prefix, and declare the text architecture:

from huggingface_hub import snapshot_download
from safetensors import safe_open
from safetensors.torch import save_file
import json, shutil

snapshot_download("AlexWortega/openjev", allow_patterns=["qwen3.5-4b-nli-v2/*"], local_dir="oj")
src, dst = "oj/qwen3.5-4b-nli-v2", "openjev-text"
out = {}
with safe_open(f"{src}/model.safetensors", "pt") as f:
    for k in f.keys():
        if ".visual." in k:
            continue
        out[k.replace("model.language_model.", "model.")] = f.get_tensor(k)
save_file(out, f"{dst}/model.safetensors", metadata={"format": "pt"})
for fn in ("tokenizer.json", "tokenizer_config.json", "chat_template.jinja"):
    shutil.copy(f"{src}/{fn}", f"{dst}/{fn}")
cfg = json.load(open(f"{src}/config.json")); cfg["architectures"] = ["Qwen3_5ForCausalLM"]
json.dump(cfg, open(f"{dst}/config.json", "w"))
vllm serve ./openjev-text --served-model-name openjev-4b \
  --runner pooling --convert classify --quantization fp8 \
  --max-model-len 4096 --max-num-seqs 16 --gpu-memory-utilization 0.8

curl localhost:8000/classify -H 'Content-Type: application/json' \
  -d '{"model":"openjev-4b","input":["Premise: A man is playing a guitar.\nHypothesis: Someone is making music."]}'

7.9 GB in bf16, about 4 GB with --quantization fp8 at load, which is what lets it share a 16 GB card. On a 4090 in bf16 we measured 18 ms for one pair, 2.8 ms per pair in a batch of 64, and 74 ms for a 533-token premise. On our network this exact script runs once per node inside the worker's start command, then every restart goes straight to vllm serve.

Price and how to start

openjev-4b is billed per input token at $0.05 per million, nothing for output, from prepaid credits on a premium key. A free key's 250,000-token trial covers it too: that is roughly 9,000 pairs of the size above, no card. Sign in to the Console, create a key, and point at https://paraloncloud.com/v1/classify. The Classify docs have the full request shape and errors; if you are building RAG, it sits next to embeddings on the same key.

If you want a second model behind /v1/classify, the 0.8B checkpoint for phones and edge, or the image-capable variant, say so on Discord. The endpoint is model-agnostic; the model is the part we can change in an afternoon.

On the network

A GPU with JupyterLab on it, in about a minute

Billed for the minutes it runs, on a machine we benchmarked before listing it. Or call open models through an OpenAI-compatible API.

Keep reading

Related articles

The Paralon capybara measuring three holographic bar columns with an emerald caliper, red cubes on the bench as the planted errors
Benchmarks & Comparisons

8 min read

OpenJev vs an LLM Judge on 990 Planted Errors: Recall, Calibration, Cost

The same 990 support tickets with 495 deliberately wrong labels, judged two ways: OpenJev over /v1/classify and Qwen 3.8 27B as an LLM judge. Asked one pair at a time OpenJev catches 82.6% of the planted errors; asked to pick among all twelve intents it catches 98.2%, rejects the same 33 mislabelled 'complaint' rows the 27B judge rejected, and its probabilities are calibrated to within 3 points. Every number is exact because we planted the errors.

Read
The Paralon capybara reading a glowing document through a magnifying glass, one line red among green ones
Guides & Tutorials

7 min read

Catch RAG Hallucinations Sentence by Sentence with an NLI Classifier: 74 Planted Errors, 93% Caught, $0.013

A RAG pipeline on one API key: embeddings for retrieval, a 27B chat model for the answer, and OpenJev over /v1/classify to check every sentence of the answer against the passages it came from. We planted 74 wrong sentences in 148 answers so recall is exact: 93.2% caught at a 0.7 threshold, 4.6% of clean sentences flagged, 49 seconds and 1.3 cents for 463 sentences. The 27B used as a judge caught the same 69 for 2.4× the money and 3× the time. Script included.

Read