Этот раздел пока доступен только на английском языке.
Основная документация
Экспериментальный уровень

LibreVLM

Передайте визуально-языковой модели изображение и список слов, чтобы получить рамки. LibreVLM превращает Qwen3-VL, Florence-2 и похожие модели в детекторы объектов с открытым словарём, которые используют тот же API Results, что и остальные модели LibreYOLO.

Введение

Классический детектор поставляется с фиксированным списком классов, встроенным в его голову. LibreVLM снимает это ограничение. Он оборачивает современные визуально-языковые модели, настроенные на выполнение инструкций, запрашивает у них ограничивающие рамки, разбирает сгенерированный текст и возвращает тот же объект Results, который используется для YOLO9 и RF-DETR. Список классов — это просто список слов, передаваемый во время выполнения, поэтому новую категорию можно добавить без затрат и обучения.

  • Открытый словарь. Детектируйте "pink car", "license plate" или "the small island", не обучая для них голову.
  • Одна фабрика, один контракт. LibreVLM(...) возвращает стандартный объект Results с boxes.xyxy, boxes.cls, boxes.conf, а также .plot() и .save().
  • Взаимозаменяемые бэкенды. Шесть семейств моделей за одной строкой псевдонима, от Florence-2 с 230 млн параметров до Qwen3-VL с 8 млрд.
  • Прямой доступ. chat() позволяет задавать произвольные вопросы об изображении, когда одних рамок недостаточно.

Зачем нужен отдельный уровень и отдельная страница

LibreVLM намеренно не входит в фабрику LibreYOLO(...) с закрытым словарём и её реестр .pt. Эти модели управляются промптами, используют открытый словарь и сообщают синтетическую уверенность, поэтому работают по другому контракту. Отдельный уровень сохраняет основную документацию по детекции ясной и точно описывает, что именно измеряется.

В ветке dev

Сейчас LibreVLM находится в ветке dev и планируется для релиза v1.3, но не входит в v1.2.0. Этот уровень предназначен только для инференса через Python: обучение, валидация, экспорт и CLI пока недоступны, а оценки уверенности служат заглушками. Перед началом работы прочитайте раздел Ограничения.

Установка

LibreVLM доступен через необязательное дополнение vlm. Оно устанавливает свежую версию transformers и вспомогательные пакеты, необходимые нескольким процессорам. Без дополнения импорт семейства VLM вызывает ImportError со ссылкой на эту страницу.

bash
1pip install 'libreyolo[vlm]'

При первом использовании веса скачиваются из Hugging Face Hub в локальную папку weights/. Некоторые семейства распространяются по лицензиям, не одобренным OSI, и перед скачиванием один раз выводят уведомление. Для крупных бэкендов рекомендуется GPU, но все модели также работают на CPU с device="cpu".

Быстрый старт

Создайте модель, укажите нужные слова и запустите предсказание. По умолчанию используется Qwen3-VL-4B, самый сильный детектор уровня под лицензией Apache-2.0.

python
1from libreyolo import LibreVLM
2
3# Qwen3-VL-4B by default; weights autodownload on first use
4model = LibreVLM()
5
6# The vocabulary is just words. Any words.
7model.set_classes(["pink car", "wheel"])
8
9result = model.predict("street.jpg")
10
11print(result.boxes.xyxy) # pixel [x1, y1, x2, y2]
12print(result.boxes.cls) # ids into ["pink car", "wheel"]
13result.plot() # same drawing helpers as any LibreYOLO model
14result.save("out.jpg")

Это весь цикл. Всё после predict() работает как с обычным детектором, поэтому существующий код визуализации, обрезки и трекинга продолжает работать.

Поддерживаемые модели

Выберите бэкенд с помощью псевдонима, передаваемого в LibreVLM(...). Имя семейства без размера разрешается в размер по умолчанию. Общий бэкенд по умолчанию — qwen3-vl-4b. На практике самые сильные детекторы — Qwen3-VL, LFM2-VL и Florence-2.

СемействоПсевдонимРазмеры (параметры)ЛицензияПримечания
Qwen3-VLqwen3-vl-2b / -4b / -8b2B / 4B / 8BApache-2.0Модель по умолчанию и самая сильная. Рекомендуемая отправная точка.
LFM2-VLlfm2-vl-450m / -1.6b450M / 1.6BLFM Open LicenseКомпактный размер для edge-устройств и неожиданно сильная детекция. Требует подтверждения уведомления.
InternVL3internvl3-1b / -2b / -8b1B / 2B / 8BQwen LicenseХорошая привязка у версии 8B, малые размеры слабее. Требует подтверждения уведомления.
Florence-2florence-2-base / -large0.23B / 0.77BMITСпециализированная модель привязки. Точные рамки, без chat().
SmolVLM2smolvlm2-500m / -2.2b500M / 2.2BApache-2.0Очень компактная и быстрая, но слабее в детекции. Подходит для быстрых проб.
Kosmos-2kosmos-2~1.6BMITМодель привязки 2023 года. Менее точные рамки, без chat().

Выбор бэкенда

  • Лучшее качество: qwen3-vl-8b или qwen3-vl-4b (по умолчанию).
  • Точные рамки и малый размер: florence-2-large.
  • Edge-устройства и CPU: lfm2-vl-450m или smolvlm2-500m.
  • Полностью разрешительная лицензия: любой размер Qwen3-VL, SmolVLM2, Florence-2 или Kosmos-2.

Лицензирование

Qwen3-VL и SmolVLM2 распространяются по Apache-2.0, а Florence-2 и Kosmos-2 — по MIT. У LFM2-VL и InternVL3 лицензии, не одобренные OSI, поэтому перед первым скачиванием они выводят однократное уведомление, чтобы решение о коммерческом использовании было осознанным.

Настройка словаря

Словарь — основа детекции с открытым словарём. Вызовите set_classes() со списком строковых меток. Он сохраняется для всех последующих вызовов predict() и track(), пока не будет задан снова. Метод возвращает self, поэтому вызовы можно объединять в цепочку.

python
1# Sticky and chainable
2model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"])
3
4# Set it once at construction instead
5model = LibreVLM("lfm2-vl-450m", names=["boat"], device="cpu")
6
7# Re-set any time to change what you are looking for
8model.set_classes(["a red car", "a blue truck"])

Метки могут быть любыми фразами. Они должны быть уникальными без учёта регистра, и передавать нужно список, а не отдельную строку. Если set_classes() ни разу не вызывался, модель использует словарь COCO-80, поэтому вызов predict() без дополнительных настроек всё равно даёт осмысленный результат.

Предсказание

predict() и эквивалентный вызов model(...) принимают те же типы источников, что и любой детектор LibreYOLO: путь, изображение PIL, массив NumPy, URL, папку или видео. stream=True и track() также работают.

python
1result = model.predict(
2 source="image.jpg", # path | PIL | ndarray | URL | folder | video
3 conf=0.25, # see note below: scoring is synthetic
4 classes=[0], # optional: keep only these vocabulary ids
5 max_det=300,
6)

Форма результата

Возвращается стандартный объект Results, такой же, как у детектора с закрытым словарём:

ПолеФорма / типЗначение
result.boxes.xyxyN x 4Пиксельные рамки [x1, y1, x2, y2], масштабированные до исходного изображения.
result.boxes.clsNИдентификаторы классов, ссылающиеся на словарь из set_classes().
result.boxes.confNСинтетическая уверенность: 1.0 для каждой рамки (см. раздел «Ограничения»).
result.plot() / .save()-Обычные вспомогательные методы для отрисовки и сохранения.

Внутри LibreVLM устойчиво разбирает вывод модели, обрабатывая ограждения Markdown, посторонний текст, повторяющиеся рамки и обрезанные массивы, сопоставляет произвольные текстовые метки с идентификаторами классов и отбрасывает метки, которых нет в словаре. Именно последний шаг заставляет генератор произвольного текста работать как детектор с закрытым набором классов.

Примеры

Детекция объекта заданного цвета

python
1from libreyolo import LibreVLM
2
3model = LibreVLM("qwen3-vl-4b")
4model.set_classes(["red car"])
5
6result = model.predict("parking_lot.jpg")
7print(f"Found {len(result.boxes.cls)} red car(s)")
8result.save("red_cars.jpg")

Точные рамки с Florence-2

python
1# Florence-2 is a purpose-built grounder: very tight pixel boxes.
2model = LibreVLM("florence-2-large")
3model.set_classes(["a red car", "license plate"])
4
5result = model.predict("car.jpg")
6result.plot()

Фильтрация до одного класса на лету

python
1model = LibreVLM("qwen3-vl-2b").set_classes(["person", "dog", "cat"])
2
3# classes= filters the configured vocabulary by id
4people_only = model.predict("street.jpg", classes=[0])

Запуск на CPU со встроенным примером изображения

python
1from libreyolo import LibreVLM, SAMPLE_IMAGE
2
3model = LibreVLM("lfm2-vl-450m", device="cpu")
4# No set_classes() -> falls back to the COCO-80 vocabulary
5result = model.predict(SAMPLE_IMAGE)
6print(model.names[result.boxes.cls[0]]) # e.g. "person"

Батчи, папки и видео

python
1model = LibreVLM().set_classes(["forklift", "pallet"])
2
3# A whole folder
4for result in model.predict("warehouse_frames/", stream=True):
5 result.save()
6
7# A video file (frames are processed one at a time)
8model.predict("warehouse.mp4", save=True)

Прямой доступ к чату

Иногда нужна сама модель, а не детектор. Семейства с шаблонами чата предоставляют chat(), который принимает изображение и произвольный промпт, а затем дословно возвращает декодированный текст. Используйте его для подсчёта, создания подписей или быстрых вопросов об изображении.

python
1model = LibreVLM("qwen3-vl-4b")
2
3answer = model.chat("harbor.jpg", "How many boats are docked? Answer with a number.")
4print(answer)

chat() доступен в семействах с шаблонами чата (Qwen3-VL, LFM2-VL, SmolVLM2, InternVL3). Florence-2 и Kosmos-2 используют токены задач для привязки и вызывают NotImplementedError. Для них используйте predict().

Различия бэкендов

Все семейства возвращают одинаковый объект Results, но получают его по-разному. Обычно это неважно, однако различия объясняют поведение некоторых бэкендов. У семейств с чатом запрашивается JSON-массив рамок, а модели привязки используют специальные токены задач.

СемействоПромптПространство координатchat()
Qwen3-VLJSON-промпт с рамкамиОт 0 до 1000, масштабированныеДа
LFM2-VLJSON-промпт с рамкамиНормализованные от 0 до 1Да
SmolVLM2JSON-промпт с рамкамиНормализованные от 0 до 1Да
InternVL3JSON-промпт с рамкамиОт 0 до 1000, масштабированныеДа
Florence-2Токен задачиИсходные пикселиНет
Kosmos-2Промпт привязкиНормализованные, масштабированныеНет

Для семейств с чатом промпт детекции можно переопределить аргументом конструктора prompt=, а длину генерации ограничить с помощью max_new_tokens=. Устройство и dtype определяются автоматически: bf16 или fp16 на CUDA, fp32 на CPU.

Ограничения

LibreVLM обладает широкими возможностями, но всё ещё молод. Знание ограничений заранее поможет избежать неожиданностей.

  • Синтетическая уверенность. Каждая рамка получает оценку 1.0. Поэтому фильтр conf= работает по принципу «всё или ничего», а не как настоящий порог.
  • Нет mAP и валидации. val() вызывает исключение, поскольку синтетические оценки сделали бы COCO mAP недостоверным.
  • Нет обучения и экспорта. train() и export() вызывают исключение. Вместо этого дообучите VLM в исходном проекте и загрузите полученные веса.
  • Качество трекинга снижено. track() работает, но одинаковые оценки делают неактивным этап восстановления трекера при низкой уверенности.
  • По одному изображению. В v1 генерация выполняется последовательно, поэтому увеличение batch= не ускоряет работу.
  • Только Python API. CLI libreyolo пока не разрешает псевдонимы VLM.

Где LibreVLM особенно полезен

Используйте LibreVLM, когда набор классов открыт, часто меняется или его трудно разметить заранее: для быстрого прототипирования, редких категорий или сценариев «найти то, что описано словами». Если нужны откалиброванная уверенность, пропускная способность или готовый к развёртыванию артефакт, обучите YOLO9 или RF-DETR с закрытым словарём по основной документации.

Только инференсветка dev / цель: v1.3Исходный код на GitHub