Содержание
  1. Что такое GLiNER и где проходят границы задачи
  2. Полный исходный набор и ручной эталон
  3. Копируемый маршрут запуска
  4. Ручной эталон и результаты реального запуска
  5. Отрицательные случаи и неизвестные значения
  6. Условия доступа и справочный слой
  7. Частые вопросы
Обзоры

GLiNER: извлечение сущностей по заданным меткам

7 ноября 2026 · 9 минут чтения

GLiNER: извлечение сущностей по заданным меткам работает так — метки задаются в момент вызова, а модель ищет их в тексте. По документации проекта это framework для обучения и развёртывания небольших NER-моделей с zero-shot возможностями. Ниже — полный вход, ручной эталон границ и маршрут запуска.

Что такое GLiNER и где проходят границы задачи

В README проекта GLiNER описан как framework для обучения и развёртывания небольших моделей распознавания именованных сущностей с zero-shot возможностями. Там же перечислены дополнительные режимы: инкрементальный потоковый NER, совместное извлечение сущностей и отношений, многозадачная классификация токенов. Классификация текста, связывание сущностей и извлечение по схеме вынесены в разделы экосистемы.

Граница задачи проходит по моменту, когда читатель называет метки. Классические NER-модели обучены на фиксированном наборе типов. GLiNER принимает список меток во время inference, и этот список определяет, что модель будет искать. В карточке модели urchade/gliner_multi-v2.1 на Hugging Face сказано, что модель определяет любой тип сущности через двунаправленный трансформерный энкодер.

В README приведена таблица архитектур. Uni-encoder — исходная архитектура с сильными zero-shot возможностями и поддержкой примерно 50 типов сущностей. Bi-encoder масштабируется на большое число типов через раздельное кодирование текста и меток. RelEx объединяет NER и извлечение отношений в одной модели. GLiNER Decoder генерирует типы сущностей небольшим декодером. StreamingSpan переиспользует кэши декодера, меток и слов для инкрементального NER.

Отдельно стоит развести продукты. GLiNER2 в таблице экосистемы README описан как унифицированная многозадачная модель для NER, классификации текста и извлечения структурированных данных. Это отдельный проект со своим репозиторием. Сторонние обёртки — gliner-spacy для spaCy, GLiNER.cpp, gline-rs, vllm-factory — дают собственные пути интеграции. Материал ниже описывает исходный Python-пакет gliner и модель urchade/gliner_multi-v2.1.

Установка в README дана двумя командами: pip install gliner и uv pip install gliner. Для serving-режима на Ray Serve указан вариант uv pip install gliner[serve]. Базовый пример из README загружает модель gliner-community/gliner_small-v2.5 и вызывает predict_entities с порогом 0.5.

Полный исходный набор и ручной эталон

Возьмём короткий английский вход и зафиксируем его целиком. Текст: Mira joined Atlas Labs in Oslo. Разрешённые метки: person, organization, location. Это условный учебный вход.

Ручной эталон строится по индексам Python. Правая граница среза исключается. Разберём посимвольно:

Сущность Метка Срез Что попадает в срез
Mira person [0:4] четыре символа имени
Atlas Labs organization [12:22] название целиком с пробелом
Oslo location [26:30] четыре символа города

Проверим арифметику. Строка начинается с Mira — позиции 0, 1, 2, 3. Дальше пробел на позиции 4, joined занимает 5–10, пробел на 11. Atlas Labs начинается с 12 и заканчивается на 21, поэтому срез [12:22] захватывает ровно десять символов. Пробел на 22, in на 23–24, пробел на 25. Oslo занимает 26–29, срез [26:30] даёт четыре символа. Точка стоит на позиции 30 и в срез не входит.

Этот эталон задаёт, что читатель готов принять. Он не гарантирует, что модель вернёт все три сущности. Извлечение вероятностное: модель выдаёт свои спаны и свои score, а эталон служит планкой приёмки.

Три механические проверки применяются к каждому спану. Первая: text[start:end] == entity_text — срез строки совпадает с текстом сущности. Вторая: метка входит в разрешённый список labels. Третья: 0 <= start < end <= len(text) — границы лежат внутри строки и не перевёрнуты. Эти проверки выполняются локально над строками и не требуют запуска инференса.

Копируемый маршрут запуска

Маршрут повторяет базовый пример из README проекта и карточки модели. Загрузка идёт через GLiNER.from_pretrained, предсказание — через predict_entities.

PYTHON13 строк
from gliner import GLiNER

text = "Mira joined Atlas Labs in Oslo."
labels = ["person", "organization", "location"]

model = GLiNER.from_pretrained("urchade/gliner_multi-v2.1")
entities = model.predict_entities(text, labels)

for entity in entities:
    assert text[entity["start"]:entity["end"]] == entity["text"]
    assert entity["label"] in labels
    assert 0 <= entity["start"] < entity["end"] <= len(text)
    print(entity["text"], entity["label"], entity["score"])

Порядок действий. Установите пакет командой pip install gliner. Сохраните скрипт в файл. Запустите его в окружении с доступом к Hugging Face. Модель скачается при первом вызове from_pretrained. Строки assert проверяют каждый спан до печати. Если проверка падает, вы видите, какой именно спан нарушил контракт.

Порог срабатывания в этом маршруте оставлен по умолчанию. В README базовый пример передаёт threshold=0.5 третьим аргументом predict_entities. Порог отсекает спаны с низким score. Значение порога подбирается под задачу читателя.

Для русского текста выберите совместимую модель по её карточке и повторите собственную разметку. Английский пример показывает маршрут вызова. Качество на другом языке он не доказывает.

Ручной эталон и результаты реального запуска

Эти две вещи нужно держать раздельно. Ручной эталон — это ваш список ожидаемых спанов с индексами. Результат запуска — это то, что вернула модель в конкретном окружении. Совпадение проверяется сопоставлением полученных спанов с эталоном.

Порядок сверки:

  1. Зафиксируйте вход и список меток.
  2. Выпишите ожидаемые спаны с индексами.
  3. Запустите модель и соберите вывод.
  4. Сопоставьте каждый возвращённый спан с эталоном по тексту и метке.
  5. Отметьте спаны, которых нет в эталоне, и спаны эталона, которых нет в выводе.

Score в выводе — это значение, которое вернула модель. Заранее оно неизвестно. Не вписывайте ожидаемое число в эталон: эталон описывает границы и метки, а score приходит из запуска.

Таблица разводит роли:

Артефакт Кто задаёт Что фиксирует Меняется ли
Вход читатель текст и список меток по задаче
Ручной эталон читатель спаны, метки, индексы по задаче
Вывод модели модель спаны, метки, score от запуска к запуску

Практический смысл разделения — приёмка. Вы принимаете вывод по своим правилам: какие метки разрешены, какие границы считаются верными, какой порог отсекает слабые спаны. Модель эти правила не знает.

Отрицательные случаи и неизвестные значения

Отрицательные проверки показывают, что эталон отклоняет. Разберём четыре случая.

Запрос только метки date при отсутствии даты во входе. Ручной эталон пуст: в тексте нет даты. Пустой вывод модели совпадает с эталоном. Появление любого спана с меткой date — расхождение.

Спан Madrid в выводе. Такой строки во входе нет. Проверка text[start:end] == entity_text не найдёт для неё совпадения, и спан отклоняется.

Срез text[26:] для Oslo. Позиция 30 — это точка. Срез захватывает лишний символ, и сравнение с текстом сущности падает. Верный срез — [26:30].

Метка city в выводе. Такой метки нет в списке labels. Проверка членства отклоняет спан, даже если границы верны.

Неизвестные значения перечислим явно. Score каждого спана определяется запуском. Полный набор возвращённых сущностей определяется запуском. Поведение на русском тексте определяется выбранной моделью. Точность, скорость и расход памяти в эталон не входят: это свойства конкретного запуска на конкретном железе.

Условия доступа и справочный слой

Пакет gliner ставится из PyPI командой pip install gliner. Модель urchade/gliner_multi-v2.1 опубликована на Hugging Face с лицензией apache-2.0 и меткой multilingual. В карточке модели приведена таблица релизов: у семейства v2.1 модели small, medium, large и multi имеют 166M, 209M, 459M и 209M параметров соответственно. У релизов v0 и v1 указана лицензия cc-by-nc-4.0.

Документация проекта доступна по адресу urchade.github.io/GLiNER. Там же опубликованы разделы по архитектурам, обучению и serving. Serving-слой на Ray Serve описан в README: динамическая батчинг-группировка запросов, подбор размера батча с оглядкой на память GPU, предкомпилированные ядра для типовых размеров батча, горизонтальное масштабирование через реплики Ray и HTTP API.

Оптимизации из README: torch.compile даёт ускорение примерно до 1.5x, FP16-квантизация вдвое сокращает память модели, а вместе с компиляцией даёт ускорение GPU-инференса примерно до 1.9x. INT8-квантизация сокращает память ещё вдвое относительно FP16 и требует обучения с учётом квантизации для сохранения точности.

Обучение на своих данных в README показано двумя путями: скриптом python train.py --config configs/config.yaml и программно через model.train_model с параметрами max_steps, per_device_train_batch_size, learning_rate, bf16. Примеры ноутбуков вынесены в каталог examples репозитория.

Сторонние проекты дают собственные пути. Label Studio в своей документации описывает использование GLiNER для разметки NER. inference4j в своём руководстве по zero-shot NER показывает Java-путь через ONNX. Их ограничения и тайминги относятся к их окружениям.

Частые вопросы

Что такое GLiNER простыми словами?
Это framework для распознавания именованных сущностей, где список меток задаётся при вызове модели. По README проекта он поддерживает zero-shot NER, потоковый NER, извлечение отношений и классификацию токенов. Модель принимает текст и список меток, возвращает найденные спаны с метками и score.

Чем GLiNER отличается от обычного NER?
Классические NER-модели обучены на фиксированном наборе типов сущностей. GLiNER принимает метки во время inference, и этот список определяет поиск. В карточке модели сказано, что она определяет любой тип сущности через двунаправленный трансформерный энкодер.

Как задать свои метки?
Передайте список строк вторым аргументом predict_entities. В примере это ["person", "organization", "location"]. Метка из вывода обязана входить в этот список — проверка членства отсекает лишнее. Для русского текста выберите совместимую модель по карточке и повторите свою разметку.

Почему границы сущности не совпадают с ожидаемыми?
Индексы в Python считаются с нуля, а правая граница среза исключается. Для Oslo в строке Mira joined Atlas Labs in Oslo. верный срез — [26:30], точка на позиции 30 остаётся снаружи. Проверка text[start:end] == entity_text показывает расхождение сразу.

Можно ли использовать GLiNER на русском языке?
В карточке модели urchade/gliner_multi-v2.1 указана метка multilingual и лицензия apache-2.0. Выбирайте модель по её карточке и повторяйте собственную разметку на своих текстах. Английский пример показывает маршрут вызова и качество на другом языке не доказывает.

Читайте также

3 материала