gliner-extract: the GLiNER zero-shot extraction lane, planned as a metered API
GLiNER is an open-source model for zero-shot named entity recognition: you send text and a list of entity types in plain language. It returns the matching pieces of the text, each typed with one of your labels. No training step, no annotation pass, and the open model runs on CPU-class hardware. Search results describe GLiNER as a local tool. Google's own summary of the space, read on 24 September 2026, takes a clear side. It says GLiNER is "typically deployed locally as your own API using the python package rather than consumed through a third-party paid service". The summary then shows the pip install. That summary is accurate. No vendor serves general zero-shot GLiNER over HTTP today.
gliner-extract is this platform's name for the lane that changes the answer: GLiNER extraction as one metered API call. The lane is written, not open. The platform's model data carries this alias's row behind the public list. Nothing answers it today, and no date is promised. What this page publishes is the capability record. It holds the model's identity from its official sources, and the request contract the lane is designed to accept. The integration can be written before the switch flips.
Last verified: 2026-09-25
What it is
GLiNER is the model published in the paper GLiNER: Generalist Model for Named Entity Recognition using Bidirectional Transformer. It is an encoder model, not a chat model. A chat model generates text token by token. An encoder reads its input. It assigns labels to pieces of that input. For extraction that difference is the product: GLiNER labels spans. A span is a run of text with a start and an end, a person's name, a drug name, a clause. It produces nothing else. There is no generated prose to parse and no answer format that can drift between calls.
The zero-shot part is what separates it from older NER services. Classic NER APIs ship a fixed schema: person, location, organization, and a short tail. GLiNER takes the type list as an input. If your types are medication, dosage, and adverse event, you send those three phrases as the label list. The model matches them against the text. Its training relates type names to spans rather than memorizing a fixed category set.
The identity facts, with the owner of each claim named:
| Fact | Value | Where the claim comes from |
|---|---|---|
| What it is | a generalist, lightweight model for NER that extracts any entity types from texts | the official repository's own title and description |
| Inputs | text plus a user-supplied list of entity types | official repository and docs |
| Hardware | runs on CPU and consumer hardware | the project's README, the project's own claim |
| Quality position | competitive with LLMs like ChatGPT and UniNER on entity extraction | the project's README; the project's words, not this platform's |
| License | Apache 2.0 on the official repository | the repository's license file |
| Package | pip install gliner | the official python package |
| Alias on this platform | gliner-extract, row behind the public list | the platform's model data, checked 2026-09-25 |
The project around the model has grown wider than NER, and that growth is the second identity fact. The official repository describes a framework. It now covers streaming extraction, joint entity and relation extraction, and token classification across tasks. A sibling project, GLiClass, handles classification. A PII-tuned model in the family, gliner_multi_pii-v1, covers 100+ languages. The 2025 paper GLiNER2 extends the line into schema-driven structured extraction. It also ranks in the top results for the hosted-API query itself. One ranking story in the model's search results tracks the whole arc: how GLiNER grew from NER into structured extraction. That arc is the trajectory this lane rides. The lane is extraction with a user-supplied type list rather than the classic entity categories alone.
GLiNER, gliner-extract, and the PII derivative
Three names sit close together and the search results mix them freely.
GLiNER is the open-source project: the model, the documentation, the python package, and the papers.
gliner-extract is this platform's alias for its planned lane: the same model family behind a metered HTTP route with a custom type list. Its row sits behind the public list. The lane is planned as part of the same classification family as the platform's IAB text-classification lanes, iab-2x and iab-3x. GLiNER itself needs only roughly 0.6 GB of GPU memory. That small footprint is why it runs on consumer hardware. No date is promised, and nothing on this page should be read as a launch date.
One hosted GLiNER-class endpoint exists today: NVIDIA's gliner-pii on its NIM service. It deserves the honest mention because it is the one hosted result a searcher will find. It is a PII-tuned derivative that detects personal and health information spans with a fixed label set. It is not general zero-shot extraction with your own types. If the whole job is PII detection, that route, or the project's own PII model self-hosted, is the shorter path. This lane is the general one: any type list, one call.
Use cases
The lane's profile is typed extraction at request scale: text in, typed spans out, one request one bill. The type list can change per request without a retraining round.
- Types a fixed schema cannot give you. Medication and adverse event in pharmacovigilance (drug-safety monitoring) text, clause types in contracts, component and fault codes in maintenance logs, ingredient and allergen in food copy: none of these are person, location, organization. With a zero-shot type list, the vocabulary is yours.
- Document and page intake. Pages parsed earlier in your pipeline, or any text corpus, get entity fields attached at ingestion, before storage.
- Knowledge graphs and retrieval enrichment. Extraction finds the entities. An embedding model such as bge-m3 puts them into the vector index. The two calls are the halves of one enrichment pipeline.
- Content operations and ad tech. The IAB lanes in the same family classify pages into the advertising taxonomy; this lane pulls the named entities out of them. Classification answers what a page is about, extraction answers who and what it names.
- Annotation acceleration. The model's ecosystem includes an annotation-tool integration for pre-labeling; teams label with GLiNER first and correct by hand, which is faster than labeling from zero.
GLiNER or an LLM doing NER
The how-to results for zero-shot custom entity extraction are mostly one shape: prompt a chat model, ask for JSON, parse the answer. It works, and for one-off extraction it is fine. At request scale that shape has costs the how-tos do not carry:
- Parse fragility. The answer is generated text that must parse back into structure. A malformed array, an invented field, or a chatty preface breaks the parser, and the failure class follows the model, not your code.
- Cost shape. A chat model bills by the token, prompt and completion both, and the type list rides the prompt on every call. An encoder pass is metered per request and moves only the text and the labels.
- Output contract. GLiNER's answer is spans, matched text typed with a label from your list, with position and score information. That is data. A generated JSON answer is data-shaped only until the model decides otherwise.
The quality claim in that comparison belongs to the project, not this platform. The project's README describes GLiNER as competitive with LLMs like ChatGPT and UniNER on entity extraction. That is the claim. It runs on CPU and consumer hardware. Test both routes on your own text before committing. That is the honest form of every model comparison.
Self-host, or wait for the lane
GLiNER is open source and CPU-capable, so self-hosting is a real road, not a consolation. pip install gliner is the official package, and the project's documentation covers training-free use on CPU-class hardware. The package ships a serve extra, gliner[serve]. It wraps the model in an HTTP server of its own: the project's own answer to the hosted question, on your machine. Self-host fits when the text cannot leave your boundary, when the machine is already there, or when the volume is a research batch.
A metered lane earns its rent when you would rather not own a model process. You get per-request billing against a prepaid wallet, a key that can be revoked the moment one leaks, and no runtime to patch. On this platform that lane is designed but not open. The contract below is what it answers to when it is.
API usage
Google's related-questions box for GLiNER asks its own version of the hosted question. Would you like a Python code example to run GLiNER, or do you want to know how to fine-tune it? The premise inside the question is the one this page flips. New entity types need neither a pip install nor a fine-tune. Here is the code example, as one HTTP call.
The lane is designed to ride a new lightweight classification route on the platform's gateway. The shape follows the embeddings route, not a chat adapter. It is one JSON POST with a Bearer key from the console. Text and type list go in; typed spans come out. The design path is POST /v1/classifications, the same route family the taxonomy lanes ride. That name is the design's, and nothing answers under it today. The alias gliner-extract sits behind the public list. A call to the route today returns the gateway's not-found answer and bills nothing.
| Field | Required | Meaning |
|---|---|---|
model | yes | gliner-extract on this platform |
input | yes | one string or an array of strings, the text to extract from |
labels | yes | the type list, an array of plain-language type names sent with the request |
Three design laws, so the contract can be written against now:
- Unknown keys fail loudly. The platform's JSON routes reject a request carrying a key outside the accepted set, with an error that names the key, rather than ignoring it, and this route is designed to the same law. A silent ignore answers a different question than the one you asked.
- Metering is per request. The unit is the request, the same unit class the platform's rerank lane uses per search; the tokens of text do not multiply the bill. A request refused at the door bills nothing, and the wallet balance is the stop: once it is spent, the next request is refused rather than billed.
- Input caps arrive from measurement. The maximum text length and the maximum number of labels per request are sized from measurement before the row lands, the platform's standing law for every input cap. The design target for a single request is a p50 under 150 milliseconds, and any latency figure publishes on this page only if the measured rounds hold it.
curl
curl -X POST "https://api.ironstratum.com/v1/classifications" \
-H "Authorization: Bearer $KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "gliner-extract",
"input": "The patient was started on metformin 500 mg twice daily after the April visit to Riverside Clinic.",
"labels": ["medication", "dosage", "facility", "date"]
}'
python
import os
import requests
resp = requests.post(
"https://api.ironstratum.com/v1/classifications",
headers={"Authorization": "Bearer " + os.environ["KEY"]},
json={
"model": "gliner-extract",
"input": [
"The patient was started on metformin 500 mg twice daily.",
"Contract terminated under clause 14.2 on 3 March.",
],
"labels": ["medication", "dosage", "facility", "date", "clause"],
},
timeout=30,
)
resp.raise_for_status()
print(resp.json())
The answer is designed as typed spans. For each match you get the matched text, the type from your list, position information, and a score. Print it and read it once before you connect a parser. The exact response envelope publishes with the row.
openai-sdk
The OpenAI SDK has no typed resource for a custom classification route, and this tab will not pretend otherwise. The SDK's generic request method reaches any JSON route on the platform's base URL. That was checked against the current SDK (3.19.2):
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.ironstratum.com/v1",
api_key=os.environ["KEY"],
)
answer = client.post(
"/classification",
cast_to=dict,
body={
"model": "gliner-extract",
"input": "The patient was started on metformin 500 mg twice daily.",
"labels": ["medication", "dosage", "facility"],
},
)
print(answer)
Code written against the OpenAI SDK migrates with two changes: the base URL and the model id. Key creation and the auth contract are documented in the platform API reference.
Benchmarks
This platform has run no measurements on GLiNER: no lane serves it, so there is nothing to measure against. No benchmark number on this page is borrowed from memory either. When the lane lands, this section carries the platform's own dated measurements, or the project's dated tables, and nothing else.
What exists today is the project's own record, quoted as theirs. The project's README describes GLiNER as competitive with LLMs like ChatGPT and UniNER on entity extraction while running on CPU and consumer hardware. The paper carries the evaluation behind that claim, and GLiNER2 extends the line with a schema-driven multi-task interface. Treat all of it as the authors measuring their own model: direction, not audit. Your acceptance test is your own text with your own type lists.
The platform-side numbers are design targets with a publication law. The plan sets a p50 target of under 150 milliseconds per request, measured under real load before any figure publishes here. If the measured rounds miss the target, the target stays off this page. The metering does not change.
Getting started
- Try the model itself. The repository, the documentation, and the paper are the official record. pip install gliner runs on CPU-class hardware, so the model can be tested on a laptop before any commitment.
- Write the integration now. The contract above is the design the lane answers to: one POST, model, input, labels. A client written against it changes nothing when the row lands.
- Be there when the row lands. The console's invite flow starts at signup; an account opens the wallet and the keys. A key is created per project and revoked alone, and the wallet balance, not a per-key cap, is the spending boundary.
- Read the neighbors. The classification category maps the lane family this model belongs to, iab-2x and iab-3x are the IAB siblings in the same family, bge-m3 is the embeddings half of an extraction-plus-indexing pipeline, the models index carries the catalog's current state, and the API reference documents keys and auth.