NER Guide 2026: GLiNER, spaCy, Transformers en LLMs

Automatische vertaling Dit artikel is automatisch vertaald vanuit de oorspronkelijke Engelse versie.

Named entity recognition (NER) omvat inmiddels compacte encoders, open-vocabulary models en op LLM gebaseerde extractie. In de aangehaalde CrossNER-evaluatie overtreft een GLiNER-model met 300M parameters de gerapporteerde zero-shot F1 van UniNER met 13B parameters. Een nieuwere bi-encoder rapporteert tot 130 keer de throughput van de vergelijkbare gliner_small-v2.5 uni-encoder bij 1.024 entity types wanneer labels vooraf zijn berekend. Het paper mat dit op één H100 met batch size 1 voor inputs van 64, 256 en 512 tokens. Deze resultaten rechtvaardigen experimenten, maar geen universele productieranglijst.

De bijbehorende repository bevat uitvoerbare voorbeelden voor GLiNER, ONNX-export, door LLMs gegenereerde training labels en structured extraction. Voor workloads die vooral uit expliciete spans bestaan, zijn compacte encoders doorgaans de snellere en goedkopere optie. LLMs blijven nuttig voor het genereren van training data en voor gevallen die inference of normalisatie vereisen.

Deze guide is bedoeld voor engineers die NER-architecturen kiezen en evalueren voor RAG-, agent-, document- of privacy-pipelines. Je houdt er een modelselectiepad, een afgebakend evaluatieplan en een three-tier design aan over voor het combineren van encoders met LLM-extractie.

Companion repo: ner-field-guide, met uitvoerbare demo’s voor GLiNER, ONNX-export, de LLM-as-teacher-pipeline en structured extraction met Instructor.

Zie Best NER Models in 2026 voor de korte modelvergelijking.

Wat is named entity recognition?

Named entity recognition vindt spans in tekst en wijst daaraan types toe, zoals person, organization, date, product of domain-specific labels. NER identificeert de mention. Entity linking is de afzonderlijke stap waarin een mention wordt gekoppeld aan een canonical record of ontology concept.

WorkloadEerste model om te testenEscaleren wanneer
Stabiele labels en voldoende training dataspaCy of een fine-tuned encoderDe labelset verandert of recall stagneert bij zeldzame types.
Veranderende labels; kleine type-inventoryGLiNER cross-encoderDe inventory groeit of labels worden hergebruikt voor veel documenten.
Grote, herbruikbare type-inventoryGLiNER bi-encoderDe domain set een regressie in quality of calibration laat zien.
Meerdere extraction-taken in één text-pipelineGLiNER2De joint-task quality de target per task niet haalt.
Impliciete feiten of schema reasoningStructured LLM extractionLatency, cost of unsupported claims het productbudget overschrijdt.

Waar moderne systemen NER gebruiken

NER vindt nog steeds spans in tekst en wijst daaraan labels toe. Wat is veranderd, is de positie ervan in het systeem. NER levert nu filters voor RAG, structured arguments voor agent tools en velden voor document-processing pipelines. Daardoor zijn latency, cost en schema flexibility net zo belangrijk geworden als benchmark accuracy.

RAG: betere retrieval door entity extraction

Similarity search alleen heeft moeite met vragen die exacte entities bevatten. Bij “what did Anthropic say about model safety in Q4 2024?” moet het systeem “Anthropic” en “Q4 2024” als metadata filters extraheren, in plaats van uitsluitend op embeddings te vertrouwen.

Tijdens indexing extraheer je entities uit elke chunk en sla je ze op als metadata: {"organizations": ["Anthropic"], "dates": ["Q4 2024"], ...}. Zo kun je eerst op entity filteren en daarna vector search uitvoeren. Knowledge graph RAG (GraphRAG, LlamaIndex property graphs) gaat verder: NER plus relation extraction bouwt een graph die multi-hop-vragen kan beantwoorden waar flat embeddings niet mee overweg kunnen.

Op query time sturen uit de vraag geëxtraheerde entities de routing aan. Een vraag met een bedrijfsnaam gaat naar een finance index; een vraag met drug names naar een clinical knowledge base. GLiNER is nuttig wanneer het query-time schema of de entity types veranderen. Onbekende bedrijfs- of drug names vereisen op zichzelf geen open-vocabulary labels; een closed-label model kan nieuwe mentions van bekende types nog steeds herkennen.

AI agents: tekst omzetten in structured facts

Agents ontvangen unstructured text, zoals webpagina’s, API-responses en user messages. NER zet die tekst om in structured facts waarover de agent kan redeneren en die hij kan opslaan of aan tools kan doorgeven.

Voor tool routing vereist een verzoek zoals “schedule a meeting with Sarah Chen from Accenture on Thursday at 2pm” eerst PERSON: Sarah Chen, ORGANIZATION: Accenture en DATETIME: Thursday 2pm voordat de agent de calendar API aanroept. Een lokale encoder vermijdt de API round trip en is vaak aanzienlijk sneller, maar latency hangt af van het model, de runtime, de hardware, de batch size en het aantal labels. Meet beide routes op de calendar workload in plaats van uit te gaan van een vast verschil in milliseconden.

NER ondersteunt ook entity tracking over gesprekken heen. Agent memory-systemen moeten weten dat “Sarah” in beurt 3 en “Ms. Chen” in beurt 12 dezelfde persoon zijn. NER identificeert de spans; entity linking koppelt ze aan dezelfde ID.

De beperking in beide gevallen is latency. Als elk van tien sequential steps een NER-call van 200 ms uitvoert, voegen die NER-calls 2 seconden perceived delay toe. Eén call voegt 200 ms toe. Encoder models passen doorgaans beter in agent loops dan LLM-based extraction.

Document intelligence: van images naar structured data

OCR zet images om in tekst. NER zet die tekst om in structured fields.

Een standaardpipeline gebruikt eerst OCR, zoals Tesseract, Azure Document Intelligence of AWS Textract, om tekst en bounding boxes te produceren. NER extraheert vervolgens velden zoals invoice_number, vendor_name, line_items, total en due_date. Dezelfde volgorde geldt voor contracten, medical records en regulatory filings.

Moderne document pipelines kunnen layout understanding, entity extraction en relation extraction combineren. OCR of een layout-aware document model levert nog steeds tekst, reading order, tabellen en bounding boxes. GLiNER 2 kan daarna entity-, relation-, classification- en hierarchical structured extraction over die tekst combineren in één schema-driven pass.

Cost bepaalt veel van deze pipelines. Bereken je kosten op basis van het werkelijke maandelijkse documentvolume, inclusief retries en review. Een compacte encoder kan op CPU draaien, terwijl een API-based LLM per-document inference cost en latency toevoegt. Een praktische test is om een representatieve invoice set met een LLM te labelen. Fine-tune GLiNER op de gereviewde records en vergelijk daarna beide routes op field-level F1, latency en total cost.

PII-detectie en LLM guardrails

De data-protection principles en security duties van de GDPR (Articles 5, 25, and 32), de technology-neutral Security Rule van HIPAA (HHS guidance) en de Californische CCPA, zoals gewijzigd door CPRA, leggen verschillende rechten en risk-based safeguards op. De aangehaalde bepalingen schrijven geen NER of specifieke pre-model scanning architecture voor. Dit is geen juridisch advies; laat counsel de vereisten beoordelen die op jouw data en jurisdictie van toepassing zijn. NER kan data inventory, minimization of de-identification ondersteunen, maar het is één control waarvan recall moet worden gevalideerd voor de relevante data en jurisdictie.

NER verwerkt dit rechtstreeks. De-identification models vinden spans zoals PERSON, SSN, PHONE, EMAIL en ADDRESS en redigeren deze of vervangen ze door synthetische equivalenten. Microsoft Presidio combineert recognizers met anonymization operators, en de voorbeelden bevatten GLiNER als recognizer. De 0.3B-parameter GLiNER2-PII is een andere kandidaat: het paper behandelt 42 PII types op character-span resolution. Geen van beide vormt compliance evidence. Valideer recall per dataformaat, jurisdictie, taal en PII class voordat je een detector als control inzet.

In de vendor-run vergelijking van John Snow Labs op 48 expert-geannoteerde open-source documenten met zes PHI classes rapporteerde de token-level evaluation 96% F1. De studie rapporteerde 91% voor Azure, 83% voor AWS en 79% voor GPT-4o. De studie mapte provider labels naar het ground-truth schema en sloot predictions uit die niet konden worden gemapt. Beschouw dit als een beperkte provider comparison, niet als compliance evidence. Een afzonderlijk deployment report beschrijft dat Providence meer dan 100.000 clinical notes per dag verwerkt.

Voor LLM guardrails werkt NER als een pre-screening layer: scan user input op PII voordat je die naar een external API stuurt en blokkeer of anonymiseer de input vervolgens. Dit kan sneller of eenvoudiger zijn dan de LLM vragen zichzelf te modereren. Behandel dit als een deployment hypothesis: meet beide routes op jouw model, hardware, inputmix en recall target. False negatives blijven mogelijk; voeg daarom een extra control toe voor de PII exposure die je systeem niet kan accepteren. GLiNER is hier vooral nuttig omdat PII categories per jurisdictie verschillen. Je kunt nieuwe entity types toevoegen, zoals “genetic information” onder een nieuwe regulation, zonder retraining.

GLiNER: span-to-label matching voor open-vocabulary NER

GLiNER (NAACL 2024, Zaratiana et al.) maakte encoder-based NER competitief met LLMs tegen een fractie van de cost. In plaats van NER te behandelen als sequence labeling of text generation, behandelt GLiNER het als een matching problem. Het scoort elke candidate text span (elke aaneengesloten reeks woorden, zoals “Bill Gates” of “Microsoft”) tegen elk entity-type label en behoudt vervolgens de pairs met hoge scores.

Het model ontvangt entity-type labels en input text als één sequence: [ENT] person [ENT] organization [ENT] date [SEP] Bill Gates founded Microsoft.... Een bidirectional transformer (DeBERTa-v3) encodeert alles gezamenlijk.

Uit de output bouwt het model twee sets representations. De ene representeert entity types vanuit [ENT] token positions. De andere representeert text spans door start- en end-tokenvectors te combineren via een kleine FFN. Een dot product tussen een span representation en een entity-type representation levert een score op.

Pas sigmoid toe en je krijgt de probability dat de span van token ii tot token jj tot entity type tt behoort: ϕ(i,j,t)=σ(SijTqt)\phi(i, j, t) = \sigma(S_{ij}^T \cdot q_t). Hier is SijS_{ij} de span vector die door de FFN is geproduceerd en qtq_t de entity-type embedding van de corresponderende [ENT] token (Zaratiana et al., 2024, Eqs. 1–2). Spans zijn begrensd op 12 tokens om het systeem snel te houden.

GLiNER architecture: entity type tokens and text tokens are jointly encoded by DeBERTa, then span representations are scored against entity type embeddings via dot productGLiNER architecture: entity type tokens and text tokens are jointly encoded by DeBERTa, then span representations are scored against entity type embeddings via dot product

GLiNER accepteert tijdens inference natural-language label descriptions zonder retraining, maar extraction quality hangt af van de formulering van labels en de fit met het domain. Je geeft entity types door zoals “person”, “adverse drug reaction” of “financial instrument”, waarna het model spans daartegen scoort. De 50M-, 90M- en 300M-configuraties hieronder zijn de oorspronkelijke paper models. De huidige v2.1 model card vermeldt in plaats daarvan 166M-, 209M- en 459M English checkpoints, plus een 209M multilingual checkpoint, allemaal onder Apache 2.0. Vergelijk latency of memory tussen die generaties niet alsof de parameternamen identiek zijn (GLiNER v2.1 model card).

Voor een echte hard zero-shot test houd je zowel target types als target examples buiten de training. Een typebeschrijving zoals “a medically confirmed adverse effect caused by a treatment” geeft het model meer informatie dan alleen adverse event. Dat garandeert geen transfer, maar description-driven ZeroNER presteerde beter dan name-only baselines op benchmarks met held-out types (Cocchieri et al., 2025).

De training data voor het oorspronkelijke model kwam uit de Pile-NER dataset: 44.889 passages met 240K entity spans over 13K entity types, allemaal gelabeld door ChatGPT. GLiNER-L trainen duurde ongeveer 5 uur op één A100 (Zaratiana et al., 2024).

Benchmarkresultaten

Zero-shot-resultaten uit Zaratiana et al. (2024), Tables 1 and 2:

ModelParamsCrossNER F1Avg (20 datasets)
GLiNER-L300M60.9%47.8%
GoLLIE7B58.0%
UniNER-13B13B55.6%
GLiNER-M90M55.4%
UniNER-7B7B53.7%45.7%
GLiNER-S50M52.7%
ChatGPT (GPT-3.5)47.5%36.5%

GLiNER-M met 90M parameters benadert UniNER-13B bijna in de CrossNER-tabel van het paper (55.4% versus 55.6% F1), terwijl het ongeveer 140 keer minder parameters gebruikt. GLiNER-S met 50M overtreft het gerapporteerde ChatGPT-resultaat (GPT-3.5) met 5 F1-punten. De multilingual variant, die uitsluitend op English data is getraind, overtreft dezelfde ChatGPT-baseline in 8 van 10 non-English languages (Zaratiana et al., 2024). Deze vergelijkingen gebruiken de modelversies en evaluation harness van het paper; ze stellen geen ranking vast tegenover nieuwere LLMs.

GLiNER-varianten omvatten biomedical text, PII-detectie, nieuws en multilingual support.

Uit scripts/01_gliner_quickstart.py:

from gliner import GLiNER

model = GLiNER.from_pretrained("urchade/gliner_medium-v2.1")
text = "Bill Gates founded Microsoft on April 4, 1975."
labels = ["person", "organization", "date"]
entities = model.predict_entities(text, labels, threshold=0.5)

for entity in entities:
    print(f"  {entity['text']} => {entity['label']}")
# Bill Gates => person
# Microsoft => organization
# April 4, 1975 => date

Hoe GLiNER zich verhoudt tot spaCy

spaCy is een van de meest gevestigde NLP-libraries in production. Het werkt ook onder andere architectural constraints dan GLiNER.

De pipelines van spaCy (en_core_web_sm, en_core_web_trf) doen closed-vocabulary NER: een vaste set entity types (PERSON, ORG, GPE, DATE enzovoort) die tijdens training wordt gedefinieerd. Een nieuw entity type? Verzamel gelabelde data en retrain. Pin het onderhouden 3.8 model package in plaats van aan te nemen dat een niet-uitgebrachte major line een production upgrade is. De model card van en_core_web_trf 3.8.0 rapporteert 90.19 NER F1 op OntoNotes 5.0, maar alleen voor de 18 predefined types (spaCy model card).

GLiNER doet open-vocabulary NER: elk label werkt tijdens inference, zonder retraining. Dat maakt het de betere keuze wanneer entity types vooraf onbekend zijn, vaak veranderen of domain-specific zijn (“adverse drug reaction”, “financial instrument”, “threat indicator”).

Mijn aanbeveling: gebruik spaCy voor standard entity types waarvoor pretrained pipelines goed zijn gevalideerd. Gebruik GLiNER wanneer je flexibele, zero-shot types nodig hebt of wanneer je pipeline zich zonder retraining moet kunnen aanpassen. Ze kunnen één pipeline delen, waarbij spaCy tokenization en sentence splitting afhandelt en GLiNER entity extraction.

Een supervised Transformer-baseline

Begin bij stabiele labels met representatieve annotated spans met een fine-tuned token classifier zoals RoBERTa of DeBERTa als supervised baseline. Deze ruilt label flexibility in voor task-specific accuracy. Vergelijk het model met spaCy en GLiNER op exact-span F1, recall per label, calibration, latency en cost binnen dezelfde domain set.

UniNER en NuNER: hoe klein kun je gaan?

UniNER (ICLR 2024, Zhou et al.) en NuNER (EMNLP 2024, Bogdanov et al.) distilleren allebei LLM annotations naar kleinere NER models — maar ze verschillen van mening over hoe klein je kunt gaan.

UniNER: de maximalistische route

UniNER fine-tunet LLaMA-7B/13B op 45.889 input-output pairs die door ChatGPT zijn gegenereerd. Voor elk entity type beantwoordt het model de vraag “What describes [type] in the text?” en produceert het JSON-lijsten. Een belangrijke training trick: frequency-based negative sampling verhoogt F1 van 31.5% naar 53.4% (Zhou et al., 2024).

UniNER-7B bereikt 41.7% zero-shot F1 over 43 datasets — 7 punten beter dan ChatGPT met 34.9%. De 13B-variant bereikt 43.4%, slechts 1.7 punten meer voor bijna tweemaal zoveel compute (Zhou et al., 2024).

De production trade-off: de UniNER-type setup met hogere scores bevraagt elk entity type sequentially. De all-in-one variant gebruikt één response, maar lag gemiddeld 3.3% lager. Bij FP16 heeft een 7B checkpoint ongeveer 14GB nodig alleen voor de weights; lower-bit quantization kan die footprint verkleinen. Het model heeft bovendien een beperkende CC BY-NC 4.0-licentie.

NuNER: de minimalistische route

NuNER begint met RoBERTa-base (125M parameters) en gebruikt contrastive training met 4,38 miljoen GPT-3.5 annotations over 200K concepts. Na training wordt de concept encoder verwijderd; de text encoder past in elke standaard NER-pipeline als vervanging voor RoBERTa (Bogdanov et al., 2024).

NuNER verslaat plain RoBERTa met 6–15 F1-punten voor alle few-shot sizes. Met slechts een dozijn voorbeelden per entity type matcht NuNER UniNER-7B, ondanks dat het 56 keer kleiner is (Bogdanov et al., 2024).

Beide papers ondersteunen het distilleren van LLM annotations naar kleinere NER models. NuNER laat zien dat een encoder met 125M parameters het gerapporteerde UniNER-7B-resultaat kan evenaren wanneer task-specific fine-tuning data beschikbaar is, met MIT-licensing en CPU-friendly inference.

GLiNER 2: één model, vier taken

Het oorspronkelijke GLiNER-ecosysteem verdeelde NER, relation extraction, classification en document-level extraction over afzonderlijke models. Het GLiNER2-paper uit EMNLP 2025 verenigde NER, classification en hierarchical extraction in één model met 205M parameters; latere current releases voegden relation extraction toe aan dezelfde schema interface.

De architecture behoudt het cross-encoder design, maar breidt de context uit naar 2.048 tokens (4x het origineel) en voegt declarative schemas toe voor het definiëren van extraction-taken. Training gebruikt 135.698 real documents die met GPT-4o zijn geannoteerd, plus 118.636 synthetic examples (Zaratiana et al., 2025).

Op zero-shot CrossNER behaalt GLiNER 2 0.590 F1, dicht bij GPT-4o’s 0.599 in de mid-2025 benchmark van het paper. Voor classification is het gemiddelde 0.72 over 7 benchmarks, tegenover 0.69 voor DeBERTa-v3-large. Op CPU rapporteert het paper 130–208 ms classification latency over de geteste aantallen labels. De DeBERTa-baseline stijgt van 1.714 ms voor 5 labels naar 16.897 ms voor 50 (Zaratiana et al., 2025).

from gliner2 import GLiNER2
extractor = GLiNER2.from_pretrained("fastino/gliner2-base-v1")

# Multi-task composition in ONE forward pass
schema = (extractor.create_schema()
    .entities({"person": "Names of people", "company": "Organization names"})
    .classification("sentiment", ["positive", "negative", "neutral"])
    .relations(["works_for", "founded", "located_in"])
    .structure("product_info")
        .field("name", dtype="str")
        .field("price", dtype="str"))
text = "Acme launched a $19 widget in Berlin."
results = extractor.extract(text, schema)

Huidige GLiNER2-releases bieden entity recognition, classification, hierarchical extraction en relation extraction via één schema. Het EMNLP-paper evalueert NER en classification; het rapporteert geen hierarchical-extraction benchmark en behandelt de latere relation API niet. Beschouw de four-task route als een deployment capability die je moet benchmarken, niet als bewijs dat één model de accuracy van vier gespecialiseerde models behoudt.

Toevoegingen voor 2026: kies de architecture die bij de bottleneck past

Het GLiNER-ecosysteem beschikt nu over verschillende architectures. Het zijn kandidaten voor een domain comparison, geen enkele leaderboard.

NeedCandidateWhat to verify
Veel herbruikbare entity typesGLiNER bi-encoderExact-span F1 en calibration na caching van type embeddings.
Entities en relations in één passGLiNER-RelexZowel span- als relation F1 op dezelfde documenten.
Lokale PII-kandidaatGLiNER2-PIIRecall per taal, documentformat en PII type.
Multilingual open-vocabulary kandidaatGLiNER-XQuality per taal; de card vermeldt 23 languages.
Gegenereerde of veranderende typesGLiNER DecoderOf gegenereerde types stabiel en downstream bruikbaar zijn.

Het oorspronkelijke GLiNER-paper, het bi-encoder-paper en GLiNER-Relex gebruiken elk hun eigen models en harnesses. De model cards van GLiNER-X en GLiNER Decoder beschrijven uitgebrachte checkpoints, maar dit is geen peer-reviewed, vergelijkbare benchmark. Leg dat onderscheid vast in een architecture decision record.

Checkpoint-licenties maken deel uit van de modelkeuze

Controleer vóór deployment de exacte voorwaarden voor code, weights en datasets. De huidige aangehaalde releases zijn niet uitwisselbaar:

ReleasePublished licensePractical consequence
GLiNER v2.1 en GLiNER biApache 2.0Permissive voorwaarden in de model card; review dependencies en data nog steeds.
GLiNER2 en GLiNER2-PIIApache 2.0Bevestig het geselecteerde checkpoint, niet alleen de library.
UniNER-7B-allCC BY-NC 4.0Gebruik dit niet voor een commercial path zonder afzonderlijke toestemming.
NuNERMITHet uitgebrachte model en de dataset vermelden MIT-voorwaarden.

Licentielabels zijn geen juridisch advies. Een production review moet voorwaarden voor het base model, de training data en de provider omvatten.

De bi-encoder: opschalen naar NER met miljoenen labels

De oorspronkelijke GLiNER encodeert labels en tekst gezamenlijk. Joint encoding wordt geleidelijk duurder naarmate labeltekst context inneemt en voor elk document opnieuw moet worden ge-encodeerd. Het crossover point hangt af van het checkpoint, de label descriptions en de hardware. Wanneer dezelfde grote type-inventory voor veel documenten wordt hergebruikt, moet je de GLiNER bi-encoder als default comparison nemen. Deze splitst text- en label-encoding op in twee afzonderlijke transformers (Stepanov et al., 2026).

Cross-encoder versus bi-encoder: de cross-encoder encodeert labels en tekst gezamenlijk, terwijl de bi-encoder afzonderlijke encoders gebruikt met vooraf berekende label embeddingsCross-encoder versus bi-encoder: de cross-encoder encodeert labels en tekst gezamenlijk, terwijl de bi-encoder afzonderlijke encoders gebruikt met vooraf berekende label embeddings

De text encoder gebruikt ModernBERT (Ettin family); de label encoder gebruikt sentence transformers (BGE of MiniLM). Spans en labels worden gescoord via dot product. Door die split kunnen entity-type embeddings één keer vooraf worden berekend en gecachet. Tijdens inference hoeft alleen de tekst te worden ge-encodeerd; de labelzijde wordt een cache read.

Er zijn vier model sizes beschikbaar, allemaal gebenchmarkt op CrossNER (Stepanov et al., 2026, Table 1):

ModelParametersCrossNER F1Throughput (H100)With Pre-computed Labels
gliner-bi-edge-v2.060M54.0%13.64 ex/s24.62 ex/s
gliner-bi-small-v2.0108M57.2%7.99 ex/s15.22 ex/s
gliner-bi-base-v2.0194M60.3%5.91 ex/s9.51 ex/s
gliner-bi-large-v2.0530M61.5%2.68 ex/s3.60 ex/s

Bij 1.024 entity types verliest de pre-computed gliner-bi-edge-v2.0 bi-encoder slechts 5.2% throughput ten opzichte van één label (19.3 → 18.3 ex/s). De vergelijkbare gliner_small-v2.5 uni-encoder verliest 98.7% (10.7 → 0.14 ex/s). In de single-H100-tests van het paper met batch size 1 voor inputs van 64, 256 en 512 tokens bereikt de pre-computed bi-encoder een tot 130× throughput advantage ten opzichte van gliner_small-v2.5. Met 100 entity types op één H100 verwerkt de bi-encoder 1,96 miljoen predictions per dag, tegenover 368K voor de cross-encoder (Stepanov et al., 2026).

Ook de accuracy blijft overeind. Bi-encoder-large behaalt 61.5% CrossNER F1, iets hoger dan de 60.9% van de cross-encoder. De auteurs bevelen bi-base-v2.0 (194M) aan als sweet spot: 98% van de accuracy van het large model bij 2,6x de speed (Stepanov et al., 2026).

from gliner import GLiNER

model = GLiNER.from_pretrained("knowledgator/gliner-bi-base-v2.0")

# Pre-compute embeddings for massive label sets — encode once, use forever
entity_types = ["person", "organization", "date"]  # Can be thousands or millions
entity_embeddings = model.encode_labels(entity_types, batch_size=8)

# Inference only encodes text — labels are a cached lookup
outputs = model.batch_predict_with_embeds(texts, entity_embeddings, entity_types)

Toepassingen omvatten biomedical NER tegen de UMLS ontology (4M+ concepts), enterprise taxonomies die zonder model retraining evolueren en entity linking via het bijbehorende GLiNKER-framework.

LLMs als teachers: een $70-case study en een deployable pipeline

Het LLM-as-teacher pattern scheidt dure annotation van goedkopere inference. Twee gepubliceerde case studies laten zien hoe teams dit onder verschillende omstandigheden hebben toegepast.

CFM's LLM-as-teacher-pipeline: een LLM labelt ongeveer 900.000 headlines, mensen reviewen een subset in Argilla en een fine-tuned encoder wordt vergeleken op basis van gerapporteerde prijzen per uur, zonder normalisatie voor throughputCFM's LLM-as-teacher-pipeline: een LLM labelt ongeveer 900.000 headlines, mensen reviewen een subset in Argilla en een fine-tuned encoder wordt vergeleken op basis van gerapporteerde prijzen per uur, zonder normalisatie voor throughput

De CFM-case study

In een Hugging Face-case study extraheerde Capital Fund Management company names uit ongeveer 900.000 financial-news headlines. Zero-shot GLiNER scoorde 87.0% F1. Het team gebruikte Llama 3.1-70B om de dataset in ongeveer 8 uur te annoteren voor ongeveer $70 en reviewde vervolgens 2.714 samples via Argilla in nog eens 8 uur.

Fine-tuning van GLiNER op deze data bereikte in de case study 93.4% F1, tegenover 92.7% voor de Llama-70B teacher. De auteurs rapporteren $0.10 per uur op CPU voor het fine-tuned model en $8 per uur voor de teacher (CFM case study). Deze cijfers beschrijven één financial-news-taak en één infrastructure setup.

De Refuel AI-studie

Het technical report van Refuel AI benchmarkt LLM-labeling op 8 NLP-datasets, waaronder CoNLL-2003. Het rapporteert 88.4% agreement with ground truth voor GPT-4 (maart 2023) en 86.2% voor de human annotators in hun setup, samen met 20 keer snellere en 7 keer goedkopere labeling. Hun ensemble routeert eenvoudige voorbeelden naar goedkopere models en moeilijke voorbeelden naar GPT-4, en bereikt in de gerapporteerde experimenten meer dan 95% agreement (Refuel AI technical report). Behandel dit als vendor-reported results volgens het annotation protocol van die studie.

Een production pipeline

Een praktische production flow bestaat uit zes stappen:

  1. Schrijf annotation guidelines in natural language
  2. Maak human-labeled validation- en held-out test sets waarvan de omvang is gebaseerd op entity prevalence, vereisten voor slices per label en de gewenste breedte van confidence intervals. Een pilot met 50–200 documenten kan de guidelines calibreren, maar is geen standaardomvang voor production evaluation.
  3. Gebruik een LLM met een versioned prompt en expliciet output schema om bulk training data te labelen; bewaar de modelversie, prompt en source text bij elk label
  4. Review een subset via Argilla of Label Studio
  5. Fine-tune een compacte encoder (GLiNER, SpanMarker, RoBERTa)
  6. Deploy alleen als de encoder de quality gate haalt en de gemeten total cost verlaagt. CFM rapporteerde in de eigen setup 16–80x lagere hourly infrastructure cost; neem annotation-, review-, serving- en retrainingkosten mee in je vergelijking.

De LLM kan het volume handmatige annotation verlagen, maar het team blijft verantwoordelijk voor de validation set, annotation guidelines, targeted review en error analysis.

Waar GLiNER faalt en LLMs nuttig blijven

De Sease-benchmark (oktober 2025) testte GLiNER tegenover GPT-4.1-mini op 30 query-parsing-taken. GPT-4.1-mini behaalde 100% fully correct. GLiNER behaalde 53% (16 van 30). GLiNER reageerde echter in 0,08 seconden, tegenover 1,21 seconden voor de LLM — 15x sneller.

In deze benchmark met 30 taken faalde GLiNER volgens drie terugkerende patterns:

  1. Implicit entities: “event” extraheren uit “Elton John performed at Madison Square Garden” — nergens staat letterlijk “event”, maar de LLM leidt “concert” af
  2. Label phrasing sensitivity: “2022” scoort 0.388 tegen “date”, maar 0.958 tegen “year” — kleine labelwijzigingen veroorzaken grote scoreverschillen
  3. Value mapping: GLiNER retourneert de exacte surface text (“family houses”) in plaats van de canonical value (“Single family house”). Een LLM kan deze normalisatie uitvoeren wanneer de prompt en het schema de target values definiëren.

Nested en overlapping entities

GLiNER gebruikt standaard flat decoding, waarmee overlapping spans worden onderdrukt. De API ondersteunt ook flat_ner=False, waardoor nested predictions mogelijk zijn, hoewel de quality afhangt van het checkpoint, de labels en de domain data. Benchmark beide decoding modes op een nested, span-level test set voordat je een gespecialiseerd model kiest.

Gebruik GLiNER voor explicit entity extraction en routeer gevallen die inference, reasoning of mapping naar predefined ontologies vereisen naar een LLM. De routing threshold moet afkomstig zijn uit een gelabelde domain set.

NER evalueren: metrics, valkuilen en testsets

Een model kan 95% F1 scoren op een gecureerde testset en toch falen op de documentmix die het na deployment ziet. Bouw de evaluation set op basis van de production distribution en houd slices bij voor zeldzame formats en entity types die aggregate F1 kan verbergen.

De kernmetrics

  • Entity-level F1: De standaardmetric. Een prediction is alleen correct wanneer zowel de span boundaries als het type exact overeenkomen met de ground truth. Dit rapporteren de meeste papers.
  • Token-level F1: Scoort elke token afzonderlijk. Dit overschat resultaten omdat gedeeltelijk correct zijn van een lange entity gedeeltelijke credit oplevert. Geef de voorkeur aan entity-level F1.
  • Precision versus Recall: Deze hebben vaak asymmetrische costs. Voor de-identification is recall belangrijker — een naam missen is erger dan te veel redigeren. Voor database extraction is precision belangrijker — false entries vervuilen downstream analysis.

Veelvoorkomende evaluatievalkuilen

  1. Partial match inflation: “Bill” extraheren wanneer het gold label “Bill Gates” is — sommige scripts tellen dit als een partial match. Gebruik exact span matching tenzij je een reden hebt om dat niet te doen.
  2. Type confusion: “Microsoft” correct als span identificeren maar als PERSON in plaats van ORG labelen, moet nul scoren. Controleer of je evaluation code dit correct verwerkt.
  3. Test set leakage: Als test entities overlappen met training entities, worden scores opgeblazen. Zero-shot benchmarks (CrossNER, Few-NERD) bestaan om generalization te testen.
  4. Uncontrolled label prompts: Een korte type name en een geteste type description zijn verschillende inputs. Versioneer label descriptions, thresholds, checkpoint revisions en decoding mode samen met de score.
  5. One-language zero-shot claims: Leid geen multilingual quality af uit English. OpenNER omvat 36 corpora en 52 languages, en de baselines vonden geen enkel model dat in elke taal het beste was (Palen-Michel et al., 2025). In FiNERweb-experimenten veranderde het wisselen van English naar target-language labels de F1 met 0.02–0.09, afhankelijk van de setting (Golde et al., 2026). Test beide labeltalen wanneer het product lokale terminologie gebruikt.
  6. One run is a verdict: Rapporteer waar van toepassing variatie over random seeds, threshold sweeps en herhaalde production samples. Kleine slice counts maken een modelranking instabiel.

Een domain-testset bouwen

Voor production evaluation raad ik aan:

  1. Sample uit production data, niet uit gecureerde voorbeelden. Neem de rommelige documenten op die je model daadwerkelijk zal zien.
  2. Maak de testset groot genoeg voor de schatting die je nodig hebt. Kies het aantal op basis van entity prevalence, slice sizes per label en de gewenste breedte van confidence intervals. Rapporteer bootstrap- of analytische confidence intervals.
  3. Gebruik ten minste twee annotators op een calibration subset. Adjudiceer meningsverschillen en rapporteer een span-aware agreement measure. Agreement diagnosticeert ambiguïteit en de quality van de guidelines; het vormt geen bovengrens voor model performance.
  4. Stratificeer op difficulty — eenvoudige gevallen (schone tekst, standard types) en moeilijke gevallen (ambiguous entities, jargon, noisy text).
  5. Behoud privacy- en fairness-slices. Rapporteer voor PII recall per PII type, taal, locale, document format en relevante demographic- of name-origin-slices. Beperk evaluator access tot raw sensitive text, stel retention limits in en review false negatives.

Continual NER vereist een immutable regression set

Production taxonomies veranderen. Voeg nieuwe types toe zonder stilzwijgend de betekenis van een oud type te wijzigen. Houd een versioned, immutable regression set voor bestaande types, een afzonderlijke testset voor het nieuwe type en een changelog voor wijzigingen in annotation guidelines. Rapporteer scores voor oude en nieuwe types afzonderlijk voordat je een checkpoint vervangt. Dit is de eenvoudigste manier om forgetting en taxonomy drift te detecteren.

Production NER in vier sectoren

Dit zijn geselecteerde industry examples met specifieke cijfers onder de gerapporteerde omstandigheden. De bronnen combineren vendor-reported comparisons, door bedrijven of projecten gerapporteerde case studies en peer-reviewed papers of preprints. Beschouw ze als praktische voorbeelden, niet als maturity ranking.

Healthcare

John Snow Labs biedt clinical entity models die zijn gemapt naar ICD-10, SNOMED CT, LOINC en RxNorm. In de vendor-reported vergelijking van 48 documenten en zes classes rapporteerde de token-level evaluation 96% F1, tegenover 91% voor Azure, 83% voor AWS en 79% voor GPT-4o. De vergelijking remapte labels en sloot predictions uit die niet konden worden gemapt. Een afzonderlijke provider-reported case study beschrijft Providence St. Joseph Health processing 100,000-500,000 clinical notes daily.

In de in 2025 gerapporteerde project review meldt het open-source OpenMed project meer dan 380 biomedical NER models, 29,7 miljoen Hugging Face-downloads en toonaangevende resultaten op 10 van 12 publieke biomedical benchmarks.

Financial NER

De belangrijkste use case: SEC filing extraction. John Snow Labs’ Finance NLP extraheert 11+ entity types uit 10-K/10-Q filings (addresses, tickers, fiscal years, stock exchanges). Peer-reviewed FinBERT-MRC-varianten behalen 0.87–0.93 F1 op financial entity-taken. De moeilijke punten zijn lange documenten en nested entities in complexe financial instruments.

E-commerce

Peer-reviewed papers rapporteren dat Walmart’s EAMT system (KDD 2023) traint op 965 miljoen queries met ongeveer 60 entity labels en een 0.51% GMV lift in A/B-tests produceerde. Home Depot’s TripleLearn-framework (AAAI 2021) verhoogde NER F1 van 69.5 naar 93.3 via iterative training.

Cybersecurity

Het peer-reviewed iACE system (CCS 2016) verwerkte 71.000 artikelen uit 45 security blogs en extraheerde 900K OpenIOC-items met 95% precision en meer dan 90% coverage. Een project report voor moderne systemen zoals CyNER beschrijft het combineren van DeBERTa (F1 >91%) met regex-based IOC heuristics. De CyberNER-preprint bevat een in 2025 gepubliceerde unified dataset die vier datasets harmoniseert tot 21 STIX 2.1-aligned entity types; RoBERTa behaalt daar 0.736 F1.

Deployment optimization: van Python naar lower-latency inference

De companion repo demonstreert GLiNER ONNX-export en INT8-packaging. De repository legt artifact sizes vast, maar reproduceert niet de latency- of F1-cijfers die door externe projecten zijn gerapporteerd.

Native GLiNER serving

Test voordat je naar een nieuwe runtime overstapt de Ray Serve path van het project. gliner[serve] biedt dynamic batching, memory-aware batch sizing, multi-replica scaling en een HTTP client. Dit kan queueing overhead voor een multi-user service verwijderen terwijl dezelfde modelcode behouden blijft. Benchmark queue latency, warm latency, throughput en exact-span F1 onder jouw request mix voordat je de route vergelijkt met ONNX of Rust.

ONNX-export

GLiNER heeft native ONNX-conversion en pre-converted models bestaan op Hugging Face (onnx-community/gliner_small-v2.1). Meet latency met hetzelfde PyTorch-checkpoint, dezelfde batch size, hardware en warm-up protocol.

Uit scripts/02_onnx_export.py:

# Export with quantization
# python convert_to_onnx.py --model_path model/ --save_path onnx/ --quantize True

# Load the exported ONNX model
from gliner import GLiNER
model = GLiNER.from_pretrained("path/to/model", load_onnx_model=True)

entities = model.predict_entities(text, labels, threshold=0.5)

INT8 quantization

Dynamic quantization kan de storage- en memory requirements van een ONNX-model verminderen. Het effect op latency en F1 per label hangt af van het checkpoint en de CPU; het export script is daarom packaging evidence en geen deployment benchmark.

from onnxruntime.quantization import quantize_dynamic, QuantType

# Quantize weights dynamically, then evaluate the result
quantize_dynamic("gliner.onnx", "gliner_int8.onnx", weight_type=QuantType.QInt8)

gline-rs: Rust-reimplementation

gline-rs (Apache 2.0) verwijdert de Python runtime uit het inference path. De token-mode benchmark van v0.9.0 op een Intel i9 met drie labels rapporteert 6.67 seq/s tegenover 1.61 voor Python; het resultaat op een RTX 4080 bedraagt 248.75 seq/s. Dit zijn de eigen omstandigheden van het project, niet door de companion repo gereproduceerde resultaten. Het ondersteunt span- en token models, GPU/NPU via ONNX Runtime en wordt als crate op crates.io geleverd.

use gliner::{GLiNER, TokenMode, Parameters, RuntimeParameters, TextInput};

let model = GLiNER::<TokenMode>::new(
    Parameters::default(), RuntimeParameters::default(),
    "tokenizer.json", "model.onnx")?;

let input = TextInput::from_str(
    &["My name is James Bond."], &["person", "vehicle"])?;
let output = model.inference(input)?;
// => "James Bond" : "person" (99.7%)

Het package fast-gliner biedt Python bindings via PyO3.

Wat het optimization evidence omvat

PathEvidence availableMeasure before deployment
ONNX exportCompanion script exporteert een GLiNER-checkpointWarm latency, throughput en exact-span F1
INT8 packageCompanion script maakt een dynamically quantized modelArtifact size, latency en recall per label
gline-rsProject benchmark met gedocumenteerde hardware/setupJouw model mode, labels, hardware en batch

Structured extraction: native schemas, Instructor en lokale decoders

Wanneer je meer flexibility nodig hebt dan encoder models bieden — implicit entities, reasoning, ontology mapping — begin je met het native schema mechanism van de provider. OpenAI ondersteunt strict json_schema response formats, Anthropic structured outputs ondersteunt JSON outputs en strict tool inputs, en de Gemini API ondersteunt een subset van JSON Schema. Een gedeeld Pydantic- of Zod-model kan het contract beschrijven, maar elke provider accepteert een andere schema subset en heeft ander refusal- en complexity behavior.

Schema conformance maakt parsing betrouwbaar. Het bewijst niet dat een geëxtraheerde span in de source text bestaat of dat een normalized value correct is. Valideer field values, bewaar offsets of quotations waar mogelijk en score semantic accuracy op een gelabelde set.

Instructor wikkelt provider clients in met Pydantic validation en optionele retries na validation failures.

Aangepast van het Instructor-pattern in scripts/05_structured_extraction.py:

import instructor
from pydantic import BaseModel
from typing import List, Literal
from openai import OpenAI

class Entity(BaseModel):
    name: str
    label: Literal["PERSON", "ORGANIZATION", "LOCATION"]

class ExtractEntities(BaseModel):
    entities: List[Entity]

client = instructor.from_openai(OpenAI())
result = client.chat.completions.create(
    model="gpt-5.4-mini", temperature=0.0,
    response_model=ExtractEntities,
    messages=[{"role": "user", "content": "BioNTech SE acquired InstaDeep in the U.K."}])
# entities=[Entity(name='BioNTech SE', label='ORGANIZATION'), ...]

Outlines van dottxt kiest een andere aanpak: constrained token generation via finite-state machines. De decoder maskeert tokens die de target grammar zouden schenden, in plaats van te wachten op een validation failure en daarna te retrien. Een AWS-overview citeert 98% schema adherence tegenover 76% voor post-generation validation. De pagina herhaalt afzonderlijk de claim van .txt Engineering dat generation door de coalescence approach tot 5 keer sneller kan zijn; de pagina publiceert onvoldoende methodologie om beide cijfers als één controlled benchmark te beschouwen.

import outlines
from transformers import AutoModelForCausalLM, AutoTokenizer

model_id = "microsoft/Phi-3-mini-4k-instruct"
model = outlines.from_transformers(
    AutoModelForCausalLM.from_pretrained(model_id),
    AutoTokenizer.from_pretrained(model_id),
)
result = model(
    "Extract entities from: BioNTech SE acquired InstaDeep in the U.K.",
    ExtractEntities,
)

LangExtract is nuttig wanneer een gegenereerd field in de source moet worden ge-ground: het retourneert character intervals en ondersteunt hosted of local LLM backends. Voor self-hosted document extraction zet NuExtract JSON schemas om in templates en bevat het multimodal document models. Beschouw beide als structured-extraction systems, niet als automatische replacements voor span NER. Hun targets voor fields, offsets, document layout en latency vereisen eigen tests.

De keuze hangt af van waar je models runt. Native schemas zijn de route met de minste frictie voor een ondersteunde provider. Instructor voegt een provider-agnostic Pydantic validation- en retry-layer toe. Outlines constrained lokale generation tegen een schema. LangExtract geeft prioriteit aan source grounding, terwijl NuExtract zich richt op self-hosted document extraction. Alle LLM-routes omvatten nog steeds autoregressive generation. Benchmark elke route tegen een encoder met dezelfde batch size, hardware, entity schema en semantic-accuracy rubric.

De three-tier production architecture

Ik zou production NER routeren op basis van de task shape, niet op basis van één modelranking.

Three-tier NER architecture die expliciete spans naar encoders routeert, multi-task- of gezamenlijke relation extraction naar GLiNER-modellen en reasoning-heavy fields naar schema-constrained LLMsThree-tier NER architecture die expliciete spans naar encoders routeert, multi-task- of gezamenlijke relation extraction naar GLiNER-modellen en reasoning-heavy fields naar schema-constrained LLMs

Tier 1: encoder models voor expliciete spans. Gebruik een GLiNER cross-encoder voor een kleine type-inventory. Wanneer een grote inventory wordt hergebruikt, vergelijk je de bi-encoder met gecachete type embeddings. Fine-tune via de LLM-as-teacher-pipeline en deploy vervolgens met native serving, ONNX, INT8 of gline-rs, maar alleen wanneer die route de domain benchmark haalt.

Tier 2: multi-task of relation extraction. Wanneer één request NER, classification en hierarchical fields nodig heeft, test je GLiNER2’s shared model met 205M parameters. Wanneer de centrale vereiste gezamenlijke spans plus relations zijn, test je GLiNER-Relex. Het GLiNER2-paper rapporteert 130–208 ms CPU classification latency voor de geteste aantallen labels; dit is geen bewijs voor de latere relation API of een andere deployment.

Tier 3: LLMs voor reasoning-heavy extraction. Routeer implicit entities, contextual inference en ontology mapping naar een native schema API of Instructor voor cloud APIs, en naar Outlines voor lokale constrained output. Gebruik LangExtract wanneer source intervals essentieel zijn en NuExtract wanneer het document zelf de input is. Log deze gevallen, want ze zijn kandidaten voor de volgende Tier 1 training set.

De CFM-case study geeft één cost reference voor Tier 1: 93.4% F1 tegen een gerapporteerde $0.10 per uur op CPU, tegenover 92.7% F1 en $8 per uur voor de Llama-70B teacher. Bereken die vergelijking opnieuw met jouw hardware, teachermodel, labelset en review cost.

Trade-offs en limitations

Voor elk van de onderstaande trade-offs zijn de nuttige vragen waar deze zichtbaar wordt en of je hem vóór deployment kunt meten.

LLM-as-teacher errors propageren. Als de LLM een specifiek entity type consequent verkeerd herkent (bijvoorbeeld subsidiary names verwart met parent companies), neemt de fine-tuned encoder die bias over. De oplossing is targeted human review — richt de inspanning op entity types waarvoor de confidence van de LLM laag of inconsistent is, niet op random sampling.

Een geldig schema kan false facts bevatten. Native structured output, Instructor en constrained decoders kunnen een response parseable maken. Ze garanderen niet dat elk field ge-ground is, dat een span boundary correct is of dat een normalized value naar het juiste record verwijst. Bewaar source evidence en valideer semantics afzonderlijk.

Quantization losses zijn checkpoint- en data-dependent. De companion maakt een dynamically quantized INT8-artifact, maar meet de F1 niet. De huidige GLiNER-guidance adviseert quantization-aware training wanneer INT8 accuracy behouden moet blijven. Vergelijk quantized en originele checkpoints op exact-span F1 en recall per label vóór deployment.

Wanneer de three-tier architecture overkill is. Eén domain met stabiele entity types en voldoende labeled examples heeft mogelijk alleen een fine-tuned RoBERTa- of spaCy-pipeline nodig. Het three-tier pattern past bij meerdere domains, evoluerende entity types of een gemeten mix van expliciete en reasoning-heavy extraction. Een smalle invoice pipeline die names en dates extraheert, kan bij Tier 1 stoppen.

Bi-encoder quality varieert per dataset. Joint encoding kan op sommige datasets helpen, terwijl de bi-encoder de CrossNER-vergelijking in het paper wint en de uni-encoder op CoNLL-2003 nipt beter is. Benchmark beide op de domain set; kies op basis van gemeten exact-span quality, calibration, label count en throughput, niet door “high stakes” als regel voor de model family te gebruiken.

PII- en multilingual claims vereisen slices. Een hoge aggregate score kan een gevaarlijke recall loss voor een locale, name form, document layout of zeldzame PII class verbergen. Behandel een privacy model als één defense-in-depth-maatregel, definieer een false-negative response process en evalueer opnieuw wanneer de taxonomy, language mix of data source verandert.

Belangrijkste conclusies

  1. Gebruik een compacte encoder voor expliciete spans pas nadat deze een domain test set met support per type en confidence intervals heeft doorstaan.
  2. Gebruik GLiNER voor veranderende labelvocabularies. Vergelijk eerst de bi-encoder wanneer een grote type-inventory wordt hergebruikt; schakel flat_ner=False alleen in nadat je de quality van nested spans hebt gemeten.
  3. Gebruik geteste type descriptions voor harde zero-shot claims en test English en localized label wording afzonderlijk voor multilingual products.
  4. Houd OCR, NER, relation extraction en entity linking als afzonderlijke evaluation stages, ook wanneer één model meerdere tasks exposeert.
  5. Beschouw een LLM-teacher als een systeem dat annotation proposals genereert. Human guidelines, adjudication, immutable regression sets en een held-out test set blijven vereist.
  6. Gebruik native schemas voor ondersteunde LLM-providers, maar valideer semantic correctness en source grounding afzonderlijk van JSON-validity.
  7. Benchmark native serving, ONNX, quantization en Rust paths afzonderlijk én gecombineerd. Vermenigvuldig nooit niet-gemeten speedups.

References

Papers

Industry papers

Case studies

Tools en frameworks