GLiNER2.5-Decide and Jev:
a decision model you run, and one you call.
Both models answer a narrow question about some text with a label and a probability, instead of generating a paragraph you have to parse. GLiNER2.5-Decide is open weights that we ported to MLX Swift, so it runs on a Mac. Jev is TypeSafe's hosted API. This post compares what each one offers, looks at what the published benchmark actually tested, and reports what we measured locally, failures included.
Typed answers instead of generated text.
An app often needs a small judgment inside a larger program: which handler gets this request, is this message urgent, which words in it are a time. Asking a chat model for JSON works, but the output is text that still needs parsing and can drift off the allowed labels. Both models here skip generation. You supply the candidate labels and get back a probability for each one.
Fastino released GLiNER2.5-Decide on September 24, 2026: a 340M-parameter encoder on DeBERTa-v3-large, Apache-2.0, English. TypeSafe describes Jev as a “System One” model that evaluates typed questions against a state and returns choices, scores or yes/no probabilities. The current version is jev-1.13.0.
Three ways to get a decision out of a model.
The same request, "Remind me to call Dad at six PM," routed to one of a few actions. What differs is what the model reads, and how many steps it takes to answer.
- PromptInstructions, allowed labels and the text, as one prompt.
- Decoder generatesOne token at a time, left to right. Each output token is another model step.
- JSON text{"action": "create_reminder"}
- Parse and validateYour code checks the label is allowed. There is no score for the alternatives.
The familiar baseline. Flexible, but the answer is text, and cost grows with output length.
- State + typed questionsOne HTTPS request. A question is a Choice, Score or Noul.
- System One modelTypeSafe reads the state once and evaluates each question against it, in parallel and in isolation.
- Typed answerschoice, probabilities, confidence
The steps above describe documented behavior only. TypeSafe does not publish model size or internals.
- Schema and text in one sequence( [P] action ( [L] create_reminder [L] create_calendar_event [L] send_message [L] search_notes [L] set_timer [L] other ) ) [SEP_TEXT] remind me to call dad at six pm .
- DeBERTa-v3-large encoderOne bidirectional pass. Every token sees every other token, labels included.
- Small headsEach [L] marker is scored against the others, giving a probability per label. Word positions score spans for extraction.
- Scores and spanscreate_reminder 0.55 · send_message 0.14 · … | time: "six PM" [25, 31) 0.999
One encoder pass per call, however many labels there are. Nothing is generated, so the output cannot drift off the label list.
Fastino's benchmark compares against JevK5, an open reproduction that Fastino says uses a 4B-class Qwen3.5 decoder, read out as label probabilities instead of generated text. The GLiNER scores are measured FP32 outputs of the Swift port for this sentence. Note that 0.55 is the top choice among six labels, not a confident one; a threshold in your code decides whether that is enough to act on.
What each one offers today.
Jev column: TypeSafe’s public documentation, read September 26, 2026. GLiNER column: the Soniqo Swift port and the pinned upstream model card.
| GLiNER2.5-Decide (Swift port) | Jev 1.13 (TypeSafe) | |
|---|---|---|
| Where it runs | On your Mac, native MLX Swift. Upstream Python also runs on CPU or GPU. | Hosted API, POST /v1/systemone. |
| Weights | Open, Apache-2.0. MLX conversions in FP32, FP16 and INT8, pinned to a commit hash. | Not publicly available. The docs describe API access only, with the same weights serving every account. |
| Cost per request | Local compute only. | $42 per billion input tokens. Output tokens are free. |
| Question types | Single-label classification and entity spans in the Swift port. Upstream also has multi-label, relations, records and constraints. | Choice, Score (rubric levels) and Noul (probability of yes). All three can be mixed in one call. |
| Spans from the text | Yes, with character offsets. | Not an extraction model. The docs recommend finding candidates in code and letting Jev choose between them. |
| Input size | 512 encoded tokens per request in the Swift port. Longer input is rejected. | 64k tokens per request, 32k for the state plus the longest question. |
| Languages | English. Fastino ships a separate multilingual model. | English is primary. Other languages work, but the docs say not equally well. |
| Versioning | You choose when to upgrade the weights. | Versioned IDs, or aliases like jev-latest that move with each release. |
| Where the text goes | Stays on the device. | Sent to TypeSafe. It is not used for training, and zero data retention is available on enterprise plans. |
Some upstream GLiNER features, such as relations and constrained records, are not yet in the Swift port. The table describes what you can call from Swift today.
The published comparison is not against TypeSafe’s Jev.
Fastino reports exact-match accuracy on its own 17-dataset suite, fastino/fast-decisions, with 300 held-out examples per domain. GLiNER2.5-Decide averages 60.2% and JevK5 averages 57.6% (model card at the pinned revision; the launch post gives 60.1% and 57.5%).
As reported by Fastino in the model card at the pinned revision. Bars start at zero. JevK5 is an open reproduction, not TypeSafe's Jev.
Fastino states the scope itself: this is an internal benchmark, not JevBench, and JevK5 is an open reproduction, not TypeSafe's Jev. The post says JevK5 uses a 4B-class Qwen3.5 decoder. The result is a comparison between an encoder and a reproduction of the approach. It does not measure the commercial API.
Neither vendor's latency figure transfers to a Mac. Fastino measured 38.3 ms p50 on a V100 and 167.3 ms on a 48-vCPU Xeon, for a 64-token input with two heads and 15 labels. TypeSafe publishes speed and cost multiples measured against LLM workflows. We don't put either set of numbers in a table with our own.
On an Apple M5 Pro.
Median full request including tokenization, model already loaded, on an idle machine. 16 routing cases with six labels and 8 extraction cases, five timed calls each. Memory is the peak footprint of the whole process.
| Runtime | Routing | Extraction | Peak memory |
|---|---|---|---|
| Python gliner2-mlx 0.1.2 (FP32) | 13.7 ms | 15.0 ms | |
| Swift port, FP32 | 11.1 ms | 12.6 ms | 2.55 GB |
| Swift port, FP16 | 8.8 ms | 10.0 ms | 1.58 GB |
| Swift port, INT8 (default) | 7.6 ms | 8.9 ms | 0.85 GB |
The Swift port computes the encoder's relative-position projections once at load instead of on every request. INT8 keeps the encoder matrices packed at 8 bits and needs a third of the FP32 memory.
All three precisions reproduce the upstream PyTorch model on 24 reference cases: the same labels, spans and offsets, with confidence within 0.006 for INT8 and 0.0005 for FP32. On our small handwritten set, 12 of 16 routing cases and 7 of 8 extraction cases matched expectations, identically across runtimes. That checks behavior; it is not an accuracy benchmark. The full method, per-variant memory options and reproduction steps are in the benchmark report in speech-swift.
Two cases worth knowing about.
A high score on the wrong action. The model matched the topic and ignored the negation. For Jev, TypeSafe publishes its own list of known jev-1.13 weaknesses, linked in the sources below.
Our expectation listed both names as mentions, and the model returned only Alice. That is arguably the intended recipient. It is also not what a mention extractor should return. Decide which question you are asking, and resolve recipients in application logic.
Where each one fits.
- Text that should not leave the device, or apps that must work offline.
- High request volume, where per-token billing adds up.
- You need the exact span in the source text, with offsets.
- You want to pin weights and upgrade when you choose.
- Short inputs: commands, messages, ticket titles.
- Long context: up to 64k tokens of state per request.
- Rubric scores and yes/no probabilities as documented primitives.
- Many questions fanned out over the same state in one call.
- No model memory budget on the client.
- You can depend on a network service and its data terms.
With either model, your application still owns the parts that are not a judgment: normalizing “six PM” into a timestamp, executing the tool, and asking for confirmation before anything irreversible. A probability tells you what the model thinks. It does not tell you the model is right.
The Swift port.
The speech gliner command and the GLiNER library are a development preview in speech-swift. The first run downloads the MLX weights from Hugging Face; after that everything runs offline, without Python. The model documentation covers the full API, CLI flags and the three precisions.
# Development preview: build speech-swift from source
swift build -c release --product speech --disable-sandbox
scripts/build_mlx_metallib.sh release
.build/release/speech gliner classify "Remind me to call Dad at six PM." \
--labels create_reminder,send_message,set_timer,other
.build/release/speech gliner extract "Remind me to call Dad at six PM." \
--labels person,time --jsonimport GLiNER
let model = try await GLiNER.fromPretrained()
let choices = try model.classify(
"Remind me to call Dad at six PM.",
labels: ["create_reminder", "send_message", "set_timer", "other"]
)
let spans = try model.extractEntities(
"Remind me to call Dad at six PM.",
labels: ["person", "time"]
)Primary references.
- Fastino: GLiNER2.5-Decide release post
- fastino/GLiNER2.5-Decide model card (Apache-2.0)
- GLiNER2 library
- gliner2-mlx by Andrew Chen Wang (MIT), reference for the Swift port
- TypeSafe documentation: Jev models, pricing and limits
- TypeSafe documentation: Jev 1.13 known limitations
- Soniqo guide: GLiNER in speech-swift
- speech-swift: GLiNER model documentation
- speech-swift: GLiNER2.5-Decide benchmark report
- aufklarer/GLiNER2.5-Decide-340M-MLX-8bit on Hugging Face (also -fp16 and FP32)
