Instructions to use spybyscript/gliner25-base-litert with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- LiteRT
How to use spybyscript/gliner25-base-litert with LiteRT:
# No code snippets available yet for this library. # To use this model, check the repository files and the library's documentation. # Want to help? PRs adding snippets are welcome at: # https://github.com/huggingface/huggingface.js
- GLiNER2
How to use spybyscript/gliner25-base-litert with GLiNER2:
from gliner2 import AutoExtractor extractor = AutoExtractor.from_pretrained("spybyscript/gliner25-base-litert") # Extract entities text = "Apple CEO Tim Cook announced iPhone 15 in Cupertino yesterday." result = extractor.extract_entities(text, ["company", "person", "product", "location"]) print(result) - Notebooks
- Google Colab
- Kaggle
A concise card: the files, use, validation and the Galaxy S23 Ultra results
Browse files- README.md +78 -125
- SHA256SUMS +1 -1
README.md
CHANGED
|
@@ -14,47 +14,29 @@ tags:
|
|
| 14 |
|
| 15 |
# GLiNER2.5 base (gliner2.5-base-v1) — LiteRT (Android)
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
|
|
|
|
|
|
|
|
|
| 20 |
|
| 21 |
-
|
| 22 |
-
The split into graphs follows FluidInference's Core ML port ([gliner2-5-base-coreml](https://huggingface.co/FluidInference/gliner2-5-base-coreml), Apache-2.0),
|
| 23 |
-
with the token table on the host. `config.json` is the full contract.
|
| 24 |
|
| 25 |
| File | Size | Contents |
|
| 26 |
|---|---|---|
|
| 27 |
-
| `gliner2_base_encoder_wfp16.tflite` | 189 MB | encoder (`inputs_embeds`, `attention_mask` → `hidden_states`)
|
| 28 |
-
| `gliner2_base_encoder_fp16hw.tflite` | 189 MB | the same encoder rewritten for FP16 hardware: LayerNorm power-of-two pre-scale
|
| 29 |
-
| `gliner2_base_head_fp32.tflite` | 8.5 MB | boundary head: routed
|
| 30 |
-
| `gliner2_base_scorer_fp32.tflite` | 2.1 MB | candidate scorer and
|
| 31 |
-
| `gliner2_base_explicit_fp32.tflite` | 2.1 MB | explicit-span scorer
|
| 32 |
| `gliner2_base_relation_fp32.tflite` | 23.7 MB | relation scorer over head/tail pairs |
|
| 33 |
| `gliner2_base_record_assignment_fp32.tflite` | 1.2 MB | record decoder: instance-to-field assignment, object and latent-seed scores |
|
| 34 |
-
| `gliner2_base_record_anchorless_fp32.tflite` | 2.9 MB | record decoder
|
| 35 |
-
| `gliner2_base_embeddings_f16.bin` | 197 MB | float16 [128011, 768], little-endian, row-major |
|
| 36 |
-
| `runtime/` | | `litert_boundary_runtime.py` (
|
| 37 |
-
|
| 38 |
-
## What it runs
|
| 39 |
-
|
| 40 |
-
`runtime/litert_boundary_runtime.py` is gliner2's BoundaryExtractor with every trained module on LiteRT: the schema
|
| 41 |
-
handling, the candidate pool and the decoders are the library's own code, and no PyTorch weights are loaded. Every
|
| 42 |
-
public call works: `extract`, `extract_entities`, `classify_text`, `extract_json`, `extract_relations`, and their
|
| 43 |
-
`batch_*` and `*_long` forms.
|
| 44 |
-
|
| 45 |
-
- Entities, with label descriptions, thresholds and the null head's abstention; entity attributes.
|
| 46 |
-
- Classification, single- and multi-label.
|
| 47 |
-
- Structures (`extract_json`), with choice fields and the natural, latent and anchorless record modes.
|
| 48 |
-
- Relations.
|
| 49 |
-
|
| 50 |
-
**Fixed sizes.** One request holds at most 128 subword tokens (schema and text), 64 text words, 8 queries (entity
|
| 51 |
-
labels, structure fields, relation roles) and 8 classification choices, with a candidate pool of 192 (the checkpoint's
|
| 52 |
-
own pool size). Relations take up to 4 types and 256 head/tail pairs per request; explicit spans up to 64 per query;
|
| 53 |
-
records up to 8 fields with 192 candidates each. These are FluidInference's bucket sizes. A larger request is refused
|
| 54 |
-
with a ValueError, never truncated: run long text through the `*_long` calls with a chunk that fits, e.g.
|
| 55 |
-
`extract_entities_long(text, labels, chunk_size=40, chunk_overlap=8)`. The original runs with dynamic shapes.
|
| 56 |
|
| 57 |
-
|
| 58 |
|
| 59 |
## Use
|
| 60 |
|
|
@@ -71,101 +53,72 @@ schema = Schema().entities(["person", "organization"]).relations(["works_for"])
|
|
| 71 |
model.extract("Ravi Shah is an engineer at Tidewater Systems.", schema, include_confidence=True)
|
| 72 |
```
|
| 73 |
|
| 74 |
-
|
| 75 |
-
|
|
|
|
| 76 |
|
| 77 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 78 |
|
| 79 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
`runtime/verify_parity.py` runs each request through gliner2 with the original weights and through the reference runtime
|
| 82 |
-
(LiteRT
|
| 83 |
-
(`runtime/parity_corpus.json`)
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
|
| 97 |
-
|
|
| 98 |
-
|
|
| 99 |
-
|
|
| 100 |
-
|
|
| 101 |
-
|
|
| 102 |
-
|
|
| 103 |
-
|
| 104 |
-
|
| 105 |
-
|
| 106 |
-
|
| 107 |
-
|
| 108 |
-
|
| 109 |
-
|
| 110 |
-
|
| 111 |
-
|
| 112 |
-
|
| 113 |
-
|
| 114 |
-
|
| 115 |
-
|
| 116 |
-
| Encoder | Runtime | Same answers as the library | Span F1 (min) | Drift p99 (max) | Mac ms p50 per graph | Gate |
|
| 117 |
-
|---|---|---|---|---|---|---|
|
| 118 |
-
| `wfp16` | CPU (XNNPACK; encoder 2 threads, head and scorer 1) | facts 287/287, keywords.a 287/287, keywords.b 285/287, relation 1660/1660 | 0.9966 | 0.00135 | encoder 26.28, head 0.52, scorer 2.13 | pass |
|
| 119 |
-
| `wfp16` | Mac GPU (Metal, ML Drift), FP32 precision | facts 287/287, keywords.a 287/287, keywords.b 285/287, relation 1660/1660 | 0.9966 | 0.00135 | encoder 10.03, head 0.65, scorer 2.49 | pass |
|
| 120 |
-
| `wfp16` | Mac GPU (Metal, ML Drift), default precision (FP16) | facts 13/287, keywords.a 112/287, keywords.b 68/287, relation 1259/1660 | 0.0 | 0.58571 | encoder 8.09, head 0.72, scorer 3.47 | fail |
|
| 121 |
-
| `fp16hw` | CPU (XNNPACK; encoder 2 threads, head and scorer 1) | facts 287/287, keywords.a 287/287, keywords.b 285/287, relation 1660/1660 | 0.9966 | 0.00135 | encoder 25.4, head 0.5, scorer 2.44 | pass |
|
| 122 |
-
| `fp16hw` | Mac GPU (Metal, ML Drift), FP32 precision | facts 287/287, keywords.a 287/287, keywords.b 285/287, relation 1660/1660 | 0.9966 | 0.00135 | encoder 10.33, head 0.61, scorer 3.54 | pass |
|
| 123 |
-
| `fp16hw` | Mac GPU (Metal, ML Drift), default precision (FP16) | facts 286/287, keywords.a 286/287, keywords.b 283/287, relation 1654/1660 | 0.9932 | 0.03023 | encoder 8.35, head 1.96, scorer 4.3 | pass |
|
| 124 |
-
| `int8` | CPU (XNNPACK; encoder 2 threads, head and scorer 1) | facts 207/287, keywords.a 229/287, keywords.b 205/287, relation 1488/1660 | 0.8348 | 0.38601 | encoder 29.58, head 0.76, scorer 3.43 | fail |
|
| 125 |
-
|
| 126 |
-
The acceptance gate: per call type, same answers ≥ 95 %, span F1 ≥ 0.95, confidence drift p99 ≤ 0.05. `validation.json` holds every number.
|
| 127 |
-
|
| 128 |
-
|
| 129 |
-
## On phones
|
| 130 |
-
|
| 131 |
-
### Galaxy S23 Ultra (SM8550, 2026-11-02)
|
| 132 |
-
|
| 133 |
-
Android 16, LiteRT 2.3.2 with `qnn-runtime` 2.50.0; each graph on a request recorded from the corpus, 10 calls after a
|
| 134 |
-
30 s rest, thermal status 0 throughout; 4 CPU threads (XNNPACK). For the GPU the time is the whole call (it runs
|
| 135 |
-
asynchronously).
|
| 136 |
-
|
| 137 |
-
| Graph | CPU | GPU FP32, LOW priority | GPU FP32, NORMAL priority | NPU (compiled on the phone) |
|
| 138 |
-
|---|---|---|---|---|
|
| 139 |
-
| encoder, 128 tokens | 143 ms | 156 ms, 0.85 GB dirty | 67 ms, 0.85 GB dirty | 13 ms (`fp16hw`, 5.7 s compile) |
|
| 140 |
-
| head | 1.2 ms | does not compile | does not compile | 1.2 ms |
|
| 141 |
-
| scorer | 2.9 ms | does not compile | does not compile | 3.4 ms |
|
| 142 |
-
| explicit spans | 5.6 ms | does not compile | does not compile | fails to run |
|
| 143 |
-
| relations | 16 ms | does not compile | does not compile | 2.8 ms |
|
| 144 |
-
| record assignment | 8.9 ms | 21.5 ms | not measured | 4.0 ms |
|
| 145 |
-
| anchorless records | 10.8 ms | does not compile | does not compile | 1.3 ms |
|
| 146 |
-
|
| 147 |
-
- **The encoder is the cost:** a request on the CPU takes about 150 ms (relations add 16 ms); with the encoder on the NPU,
|
| 148 |
-
about 20 ms.
|
| 149 |
-
- **Answers on the phone's accelerators** (32 recorded requests, two per call type; the phone's encoder outputs run
|
| 150 |
-
through the rest of the pipeline): the GPU at FP32 changed none; the NPU changed two, both latent-record requests (span
|
| 151 |
-
F1 0.98, confidence up to 0.28), and none of the other call types.
|
| 152 |
-
- **`fp16hw` on this phone's GPU at FP16 gives non-finite outputs** (LiteRT 2.3.2, Adreno 740), with or without FP32
|
| 153 |
-
accumulation, so it is not an accumulation overflow: use the CPU, the GPU at FP32 or the NPU there.
|
| 154 |
-
- **GPU priority:** LOW is meant to let other GPU work go first, but on this phone and LiteRT version it does not let an app's
|
| 155 |
-
rendering in. An app rendering on the same GPU stopped for each whole call at either priority, and LOW made each call
|
| 156 |
-
2–3 times longer. That was measured with GLiNER2.5-Decide's encoder: see `spybyscript/gliner25-decide-litert`, "GPU
|
| 157 |
-
priority beside a rendering app". On the GPU use NORMAL; the NPU keeps an app's frames.
|
| 158 |
-
|
| 159 |
-
### Galaxy Z Fold 8 (SM8850, 2026-10-29)
|
| 160 |
-
|
| 161 |
-
Snapdragon 8 Elite Gen 5 (SM8850), Android 17, LiteRT 2.2.0. The encoder runs wfp16 on 4 CPU threads (XNNPACK weight cache); the head and the scorer run on one thread each:
|
| 162 |
-
|
| 163 |
-
- the feature outputs and pair logits equal the Mac's LiteRT run (difference 0.0), with the same candidate pools (3 / 3);
|
| 164 |
-
- the graphs take 39–61 ms a call, against 70 ms for the same call on ONNX Runtime (an FP32 export with an int8 token table);
|
| 165 |
-
- a whole entity call through the host takes 46 ms.
|
| 166 |
|
| 167 |
## Files
|
| 168 |
|
| 169 |
-
`LICENSE` (Apache-2.0)
|
| 170 |
-
|
| 171 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 14 |
|
| 15 |
# GLiNER2.5 base (gliner2.5-base-v1) — LiteRT (Android)
|
| 16 |
|
| 17 |
+
A LiteRT conversion of [fastino/gliner2.5-base-v1](https://huggingface.co/fastino/gliner2.5-base-v1) (revision
|
| 18 |
+
`1a8bc24e00dc7300b9017c81d63e3dcdabb26596`, Apache-2.0, by Fastino), converted by spybyscript. It carries every trained head:
|
| 19 |
+
entities, classification, structures, relations and records. gliner2's own code decodes the outputs. For the model itself
|
| 20 |
+
(training, labels, benchmarks, intended use), see the [original model card](https://huggingface.co/fastino/gliner2.5-base-v1),
|
| 21 |
+
copied here as `model-card.md`. The split into graphs follows FluidInference's Core ML port
|
| 22 |
+
([gliner2-5-base-coreml](https://huggingface.co/FluidInference/gliner2-5-base-coreml), Apache-2.0).
|
| 23 |
|
| 24 |
+
## Files
|
|
|
|
|
|
|
| 25 |
|
| 26 |
| File | Size | Contents |
|
| 27 |
|---|---|---|
|
| 28 |
+
| `gliner2_base_encoder_wfp16.tflite` | 189 MB | encoder for the CPU and the GPU at FP32 (`inputs_embeds`, `attention_mask` → `hidden_states`), float16-stored weights |
|
| 29 |
+
| `gliner2_base_encoder_fp16hw.tflite` | 189 MB | the same encoder rewritten for FP16 hardware (NPU): LayerNorm power-of-two pre-scale, first feed-forward layer split in two |
|
| 30 |
+
| `gliner2_base_head_fp32.tflite` | 8.5 MB | boundary head: routed states, boundary marginals, pool projections, null and count heads, classification logits |
|
| 31 |
+
| `gliner2_base_scorer_fp32.tflite` | 2.1 MB | candidate scorer and record candidate states |
|
| 32 |
+
| `gliner2_base_explicit_fp32.tflite` | 2.1 MB | explicit-span scorer (entity attributes, choice fields) |
|
| 33 |
| `gliner2_base_relation_fp32.tflite` | 23.7 MB | relation scorer over head/tail pairs |
|
| 34 |
| `gliner2_base_record_assignment_fp32.tflite` | 1.2 MB | record decoder: instance-to-field assignment, object and latent-seed scores |
|
| 35 |
+
| `gliner2_base_record_anchorless_fp32.tflite` | 2.9 MB | record decoder for anchorless records |
|
| 36 |
+
| `gliner2_base_embeddings_f16.bin` | 197 MB | token table, float16 [128011, 768], little-endian, row-major |
|
| 37 |
+
| `runtime/` | | `litert_boundary_runtime.py` (reference runtime), `verify_parity.py`, `parity_corpus.json` |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
+
`config.json` lists every graph's signatures and shapes.
|
| 40 |
|
| 41 |
## Use
|
| 42 |
|
|
|
|
| 53 |
model.extract("Ravi Shah is an engineer at Tidewater Systems.", schema, include_confidence=True)
|
| 54 |
```
|
| 55 |
|
| 56 |
+
Every public gliner2 call works: `extract`, `extract_entities`, `classify_text`, `extract_json` and `extract_relations`,
|
| 57 |
+
plus their `batch_*` and `*_long` forms. The runtime runs gliner2's BoundaryExtractor with every trained module on
|
| 58 |
+
LiteRT. Schema handling, the candidate pool and the decoders are the library's own code.
|
| 59 |
|
| 60 |
+
**On a phone,** run the same graphs with LiteRT's `CompiledModel`; the runtime shows the host steps.
|
| 61 |
+
- **The encoder** is the only graph worth an accelerator: the NPU with `fp16hw`, the GPU at FP32 with `wfp16` (NORMAL
|
| 62 |
+
priority), or the CPU.
|
| 63 |
+
- **The six head graphs** run on the CPU in 1–16 ms each.
|
| 64 |
+
|
| 65 |
+
**Fixed sizes.** The original runs with dynamic shapes; these are FluidInference's bucket sizes. One request holds at most:
|
| 66 |
+
- 128 subword tokens (schema and text) and 64 text words;
|
| 67 |
+
- 8 queries (entity labels, structure fields, relation roles) and 8 classification choices;
|
| 68 |
+
- a candidate pool of 192 (the checkpoint's own);
|
| 69 |
+
- 4 relation types with 256 head/tail pairs;
|
| 70 |
+
- 64 explicit spans per query;
|
| 71 |
+
- records of up to 8 fields with 192 candidates each.
|
| 72 |
|
| 73 |
+
A larger request is refused with a ValueError, never truncated. Run long text through the `*_long` calls, for example
|
| 74 |
+
`extract_entities_long(text, labels, chunk_size=40, chunk_overlap=8)`. The weights change only in storage and compute
|
| 75 |
+
precision.
|
| 76 |
+
|
| 77 |
+
## Validation
|
| 78 |
|
| 79 |
`runtime/verify_parity.py` runs each request through gliner2 with the original weights and through the reference runtime
|
| 80 |
+
(LiteRT CPU), then compares the structured results:
|
| 81 |
+
- **The corpus** (`runtime/parity_corpus.json`): 296 requests over 16 call types (entities, relations, structures, the
|
| 82 |
+
three record modes, attributes, single- and multi-label classification, mixed schemas). All 296 are identical, with
|
| 83 |
+
span F1 1.0 and confidences within 0.0014.
|
| 84 |
+
- **FluidInference's eleven schema-path fixtures:** 11 of 11.
|
| 85 |
+
|
| 86 |
+
`validation-full.json` and `validation.json` hold the numbers.
|
| 87 |
+
|
| 88 |
+
## Galaxy S23 Ultra (SM8550)
|
| 89 |
+
|
| 90 |
+
Snapdragon 8 Gen 2, Android 16, LiteRT 2.3.2 with `qnn-runtime` 2.50.0. Each graph ran on a request recorded from the
|
| 91 |
+
corpus: 10 calls after a 30 s rest, at thermal status 0. The CPU ran 4 threads; the GPU ran at NORMAL priority, timed as
|
| 92 |
+
whole calls. The NPU compiled the graphs on the phone; for the encoder that takes 5.7 s, once.
|
| 93 |
+
|
| 94 |
+
| Graph | CPU | GPU FP32 | NPU |
|
| 95 |
+
|---|---|---|---|
|
| 96 |
+
| encoder, 128 tokens | 143 ms | 67 ms (0.85 GB dirty) | 13 ms (`fp16hw`) |
|
| 97 |
+
| head | 1.2 ms | not supported by LiteRT's GPU | 1.2 ms |
|
| 98 |
+
| scorer | 2.9 ms | not supported | 3.4 ms |
|
| 99 |
+
| explicit spans | 5.6 ms | not supported | does not run |
|
| 100 |
+
| relations | 16 ms | not supported | 2.8 ms |
|
| 101 |
+
| record assignment | 8.9 ms | runs (21.5 ms at LOW priority) | 4.0 ms |
|
| 102 |
+
| anchorless records | 10.8 ms | not supported | 1.3 ms |
|
| 103 |
+
|
| 104 |
+
- **A request** takes about 150 ms on the CPU. With the encoder on the NPU and the heads on the CPU, it takes about
|
| 105 |
+
20 ms; relations add 16 ms on the CPU, or 3 ms on the NPU.
|
| 106 |
+
- **Answers with the phone's encoder outputs.** 32 recorded requests, two per call type, ran through the rest of the
|
| 107 |
+
pipeline. At GPU FP32 they were all unchanged. On the NPU, 30 were unchanged; the two that changed were latent-record
|
| 108 |
+
requests (span F1 0.98).
|
| 109 |
+
- **`fp16hw` at GPU FP16 gives non-finite outputs on this phone's Adreno 740**, with or without FP32 accumulation. Use
|
| 110 |
+
the GPU at FP32 there.
|
| 111 |
+
- **GPU priority:** use NORMAL. On this phone, LOW priority does not let an app's rendering run any sooner; it only makes
|
| 112 |
+
each call 2–3 times longer. The measurement is with GLiNER2.5-Decide's encoder: see
|
| 113 |
+
[spybyscript/gliner25-decide-litert](https://huggingface.co/spybyscript/gliner25-decide-litert).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 114 |
|
| 115 |
## Files
|
| 116 |
|
| 117 |
+
- `LICENSE` (Apache-2.0) and `NOTICE.txt`
|
| 118 |
+
- `model-card.md`, the original card
|
| 119 |
+
- `config.json`, the contract
|
| 120 |
+
- `validation.json` and `validation-full.json`
|
| 121 |
+
- `SHA256SUMS`
|
| 122 |
+
- `tokenizer/`
|
| 123 |
+
- `source/` (the checkpoint's configs)
|
| 124 |
+
- `runtime/`
|
SHA256SUMS
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 LICENSE
|
| 2 |
a4134d01e6b89380d84cfcde424328aaa717edadef0a6958c3129f206d91dc37 NOTICE.txt
|
| 3 |
-
|
| 4 |
251e71c11dd57b4106d0d5eb102a984abebc5415f4e0eb392a4966e3293b189f config.json
|
| 5 |
22c2e937cfc17e1ee9c8f3ec6f1449d44dc9230cfcbb8737c9bae8492628a3e8 gliner2_base_embeddings_f16.bin
|
| 6 |
6f5241586176d6b123f75392bedd66a24c63f4105f8a45181dbc02385e95e5bb gliner2_base_encoder_fp16hw.tflite
|
|
|
|
| 1 |
cfc7749b96f63bd31c3c42b5c471bf756814053e847c10f3eb003417bc523d30 LICENSE
|
| 2 |
a4134d01e6b89380d84cfcde424328aaa717edadef0a6958c3129f206d91dc37 NOTICE.txt
|
| 3 |
+
de378412e30d392c2437c17ab94c8a953cd192d4d8c2e7e8e93fd2a57d025b7d README.md
|
| 4 |
251e71c11dd57b4106d0d5eb102a984abebc5415f4e0eb392a4966e3293b189f config.json
|
| 5 |
22c2e937cfc17e1ee9c8f3ec6f1449d44dc9230cfcbb8737c9bae8492628a3e8 gliner2_base_embeddings_f16.bin
|
| 6 |
6f5241586176d6b123f75392bedd66a24c63f4105f8a45181dbc02385e95e5bb gliner2_base_encoder_fp16hw.tflite
|