GLiNER Documentation

repository·main·Indexed 25 days ago

https://github.com/urchade/gliner

A framework for training and deploying small, lightweight Named Entity Recognition (NER) models with zero-shot capabilities. GLiNER supports streaming NER, relation extraction, and multi-task token classification, with optimizations for CPU and GPU deployment including FP16 quantization and torch.compile. It provides a production-ready serving layer via Ray Serve and Docker Compose, and supports multiple architecture variants such as UniEncoderSpan, BiEncoder, and StreamingSpan.

Tokens
52.8K
Snippets
118
Records
210
Agent score
83%

What's inside GLiNER

  1. Overview of GLiNER

    main

    GLiNER (Generalist and Lightweight Model for Named Entity Recognition) is a framework for training and deploying Named Entity Recognition (NER) models capable of identifying any arbitrary entity type.

    It serves as a middle ground between:

    1. Traditional NER models: Which are limited to a fixed set of predefined entity types.
    2. Large Language Models (LLMs): Which offer high flexibility but require significant computational resources.

    Supported architectures include bidirectional transformer encoders, scalable bi-encoders, relation extraction models, and a causal StreamingSpan model for incremental text processing.

  2. Overview of GLiNER Architecture Components

    main

    A complete GLiNER architecture is composed of five main components that work together to handle everything from configuration to user-facing inference. To extend GLiNER, you may need to implement one or more of these components by inheriting from their respective base classes.

    | Component | Purpose | Base Class |
    |-----------|---------|------------|
    | **Configuration** | Store model hyperparameters and settings | `BaseGLiNERConfig` |
    | **Model** | Neural network architecture (forward pass, loss) | `BaseModel` |
    | **Processor** | Data preprocessing and tokenization | `BaseProcessor` |
    | **Decoder** | Convert model outputs to entity predictions | `BaseDecoder` |
    | **High-Level Wrapper** | User-facing API and orchestration | `BaseGLiNER` |
  3. GLiNER Bi-encoder Architecture Overview

    main

    The Bi-encoder architecture (including BiEncoderSpan and BiEncoderToken variants) decouples the encoding of entity labels from the input sequence. This addresses performance bottlenecks in the original GLiNER architecture, such as positional encoding constraints and performance degradation when using more than 30 entity labels.

    Variants:

    • BiEncoderSpan: Uses span-level predictions; best for standard NER with discrete entity mentions.
    • BiEncoderToken: Uses token-level predictions; better for long-form entities and efficient with pre-computed label embeddings.

    Advantages:

    • Supports large numbers of entities (50-200+) without performance loss.
    • Faster inference via pre-computed and cached label embeddings.
    • Improved zero-shot performance and robustness.
  4. Identify GLiNER Architecture Variants and Config Classes

    main

    GLiNER supports several architecture variants, each requiring a specific configuration class. Choose the architecture based on your use case:

    ArchitectureConfig ClassUse Case
    UniEncoderSpanUniEncoderSpanConfigStandard span-based NER (original GLiNER)
    UniEncoderTokenUniEncoderTokenConfigToken-level NER, long-form extraction
    BiEncoderSpanBiEncoderSpanConfigSpan NER with separate label encoder
    BiEncoderTokenBiEncoderTokenConfigToken NER with separate label encoder
    UniEncoderSpanDecoderUniEncoderSpanDecoderConfigGenerative label prediction
    UniEncoderSpanRelexUniEncoderSpanRelexConfigJoint entity and relation extraction
  5. Understand Batch-Level Decoding Performance

    main

    GLiNER uses a batch-level decoding approach to replace per-item loops with batch-wide tensor operations. This optimization significantly reduces CUDA kernel launches and GPU-to-CPU transfers.

    Performance Characteristics

    GPU

    • Batch Size (bs) >= 8: Expect a 63-95% speedup (median 85%) compared to per-item decoding. The decoder time remains nearly constant across batch sizes for short/medium inputs because the fixed overhead is paid only once.
    • Batch Size (bs) = 1: Performance is neutral. A fast path detects bs=1 and delegates to the original per-item decoder to avoid the overhead of 4D torch.where operations.

    CPU

    • Short/Medium Inputs: You may experience regressions (3-5ms absolute increase) because the 4D torch.where implementation on CPU has a higher fixed overhead than multiple 3D calls on small tensors.
    • Very Long Inputs: Batching provides a 24-42% improvement as the per-item cost becomes high enough to justify the batching overhead.
  6. Use BiEncoder models for large label sets

    main

    BiEncoder models are optimized for handling many entity types (50-200+). To maximize performance in production, you can pre-compute label embeddings using encode_labels and then use predict_with_embeds for faster inference.

    from gliner import GLiNER
    
    model = GLiNER.from_pretrained("knowledgator/gliner-bi-small-v1.0")
    labels = ["person", "organization", "location", "date", "product", "event"] # ... can be 100+
    text = "Python is a programming language created by Guido van Rossum."
    
    # 1. Pre-compute label embeddings
    label_embeddings = model.encode_labels(labels, batch_size=16)
    
    # 2. Use cached embeddings for faster inference
    entities = model.predict_with_embeds(
        text, 
        label_embeddings, 
        labels,
        threshold=0.5
    )
  7. Convert GLiNER models to ONNX format

    main

    You can convert GLiNER models (from HuggingFace or local paths) to ONNX format using the export_to_onnx method on a GLiNER instance. This allows for cross-platform deployment and optimized inference.

    CLI Usage

    If using the provided convert_to_onnx.py script, use the following flags:

    • --model_path: Path to local model or HuggingFace model ID (Required).
    • --save_path: Directory to save ONNX files (Default: ./onnx_models).
    • --file_name: Name of the ONNX model file (Default: model.onnx).
    • --quantized_file_name: Name of the quantized model file (Default: model_quantized.onnx).
    • --opset: ONNX opset version (14-19 supported, Default: 19).
    • --quantize: Flag to create an INT8 quantized version.

    Programmatic Export

    from gliner import GLiNER
    
    model = GLiNER.from_pretrained("urchade/gliner_small-v2.1")
    
    # Export with all options
    paths = model.export_to_onnx(
        save_dir="./models",
        onnx_filename="gliner.onnx",
        quantized_filename="gliner_int8.onnx",
        quantize=True,
        opset=19
    )
    
    print(f"Standard model: {paths['onnx_path']}")
    print(f"Quantized model: {paths['quantized_path']}")
  8. Use explicit labels and negatives in NER training

    main

    To improve training control and handle hard negatives, you can add optional keys to your NER training dictionaries:

    • ner_labels: A list of entity types present in the example. Useful for fixed label set use cases.
    • ner_negatives: A list of entity types to use as negative examples (e.g., including "company" as a negative when training for "organization" to help the model distinguish similar types).
    train_data = [
        {
            "tokenized_text": ["Apple", "Inc.", "hired", "Tim", "Cook", "in", "1998"],
            "ner": [
                [0, 1, "organization"],
                [3, 4, "person"],
                [6, 6, "date"]
            ],
            "ner_labels": ["organization", "person", "date", "location"],
            "ner_negatives": ["product", "event", "money"]
        }
    ]
  9. Perform joint entity and relation extraction with UniEncoderSpanRelex

    main

    The UniEncoderSpanRelex architecture allows for joint entity and relation extraction in a single forward pass. It is suitable for Knowledge Graph construction and general Information Extraction tasks where entities and their relationships (e.g., 'works_for', 'located_in') need to be captured simultaneously.

    Inference API

    Use the .inference() method, providing both labels (for entities) and relations (for relation types).

    Output Formats

    • Entities: Standard GLiNER format containing start, end, text, label, and score.
    • Relations: Triplets containing head and tail (which include entity metadata and entity_idx) and the relation type with a score.
    from gliner import GLiNER
    
    # Load a relation extraction model
    model = GLiNER.from_pretrained("knowledgator/gliner-relex-large-v0.5")
    
    text = "John Smith works at Microsoft in Seattle."
    
    # Define both entity types and relation types
    entity_labels = ["person", "organization", "location"]
    relation_labels = ["works_at", "located_in"]
    
    # Extract entities and relations
    entities, relations = model.inference(
        [text],
        labels=entity_labels,
        relations=relation_labels,
        threshold=0.5,
        relation_threshold=0.5
    )
    
    # Display entities
    print("Entities:")
    for entity in entities[0]:
        print(f"  {entity['text']} ({entity['label']})")
    
    # Display relations
    print("\nRelations:")
    for relation in relations[0]:
        head = entities[0][relation['head']['entity_idx']]
        tail = entities[0][relation['tail']['entity_idx']]
        print(f"  {head['text']} --[{relation['relation']}]--> {tail['text']}")
  10. Build and run GLiNER with Docker

    main

    You can containerize the GLiNER server using the provided Containerfile.

    Build the image:

    docker build -t gliner-serve -f gliner/serve/Containerfile .

    Run the container:

    docker run --gpus all -p 8000:8000 gliner-serve

    Run with custom configuration via environment variables:

    docker run --gpus all -p 8000:8000 \
      -e GLINER_MODEL=urchade/gliner_medium-v2.1 \
      -e GLINER_ENABLE_FLASHDEBERTA=true \
      gliner-serve
  11. Enable FlashDeBERTa for faster inference

    main

    FlashDeBERTa can provide up to a 3× speed boost for GLiNER models using DeBERTa encoders.

    Prerequisites:

    • Install flashdeberta: pip install flashdeberta -U
    • Ensure transformers>=4.51.3 is installed.

    Activation: You must set the USE_FLASHDEBERTA environment variable to 1 before loading the model. You can do this via the shell or directly in Python.

    # Via shell
    export USE_FLASHDEBERTA=1
    import os
    os.environ["USE_FLASHDEBERTA"] = "1"
    
    from gliner import GLiNER
    model = GLiNER.from_pretrained("urchade/gliner_mediumv2.1")
  12. Use Sequence Packing for higher throughput

    main

    Sequence packing combines multiple short requests into a single transformer pass using a block-diagonal attention mask. This reduces padding and increases throughput.

    1. Create an InferencePackingConfig.
    2. Apply it to the model using model.configure_inference_packing(packing_cfg).
    3. You can override this on a per-call basis using the packing_config argument in model.inference or model.predict_entities.
    from gliner import GLiNER, InferencePackingConfig
    
    model = GLiNER.from_pretrained("urchade/gliner_medium-v2.1", map_location="cuda")
    
    packing_cfg = InferencePackingConfig(
        max_length=512,
        sep_token_id=model.data_processor.transformer_tokenizer.sep_token_id,
        streams_per_batch=1,
    )
    
    # Enable packing for all subsequent calls
    model.configure_inference_packing(packing_cfg)
    
    texts = ["Email CEO to approve budget", "Schedule yearly medical checkup"]
    labels = ["person", "organization", "action"]
    
    predictions = model.inference(texts, labels, batch_size=16)