Сегментация по промпту
Сегментация по промпту превращает клик в маску: вы указываете на объект или обводите его рамкой, а модель возвращает его контур. В LibreYOLO это не отдельный ключ задачи, а группа моделей, которая загружается через фабрику LibreSAM и выдаёт обычные Results сегментации.
Определение
Сегментация по промпту принимает изображение и пространственный промпт и
возвращает маску того, на что этот промпт указывает. Никакой классификации не
происходит: списка классов нет, а result.boxes содержит рамки, плотно
описанные вокруг масок, а не самостоятельные детекции. result.masks несёт
данные масок, а result.masks.xy — их полигоны.
Интерфейс — это сам промпт. points — пиксельные координаты [x, y], по
одному набору на объект, а labels помечает каждую точку как положительную
(1, включить) или отрицательную (0, исключить). bboxes — это
[x1, y1, x2, y2], одна маска на рамку. Точки и рамки можно комбинировать,
тогда они соединяются попарно по объектам и должны быть одной длины. Если не
передать ни одного промпта, запускается путь сегментации всего — сетка точек по
изображению.
Одна точка неоднозначна по своей природе. Клик по рукаву может означать рукав,
рубашку или человека, поэтому multimask=True возвращает на каждый промпт все
три маски «целое против части» вместо одной лучшей. conf фильтрует по
предсказанному моделью значению IoU — это оценка качества маски, а не
уверенность детекции.
В LibreYOLO нет ключа задачи promptable. Группа регистрируется как segment —
тот же ключ, что использует сегментация экземпляров. Отличается форма вызова, и
поэтому у неё своя фабрика LibreSAM(), родственная LibreYOLO(),
LibreOpenVocab() и LibreVLM(). Одной сигнатурой predict(image) не выразить
тот цикл, ради которого эти модели и сделаны: set_image() один раз прогоняет
кодировщик изображения и кэширует эмбеддинги, каждый следующий вызов
predict() с source=None платит только за декодирование промпта, а
reset_image() очищает кэш. Основные затраты приходятся на кодировщик
изображения, а он выполняется один раз на изображение, так что второй промпт по
тому же изображению пропускает его полностью.
Модели
Через LibreSAM по алиасу загружаются шесть семейств.
SAM — вариант по умолчанию, в размерах base, large и
huge, они же b, l и h.
SAM 2 — как sam2-tiny, sam2-small, sam2-base-plus и
sam2-large. LibreYOLO поддерживает его путь для изображений.
SAM 3, как sam3, — единственное семейство, которое
принимает текстовый промпт-понятие: text="yellow school bus" возвращает все
подходящие экземпляры. Передача text= любому другому семейству вызывает
ошибку с сообщением, где названа модель SAM 3. Веса распространяет Meta под
собственной лицензией SAM License, а не под MIT-лицензией LibreYOLO, и доступ к
репозиторию ограничен: примите условия на странице модели и авторизуйтесь через
hf auth login перед первой загрузкой. Прочитайте SAM 3, прежде чем
разворачивать модель.
EdgeTAM, как edgetam, — вариант SAM 2 для работы на
устройстве. LibreYOLO поддерживает его путь для изображений.
MobileSAM, как mobilesam, заменяет кодировщик ViT-H
из SAM на дистиллированный TinyViT.
PicoSAM3, как picosam3, — компактная CNN для
областей по промпту-рамке на периферийных сенсорах. Промпты рамкой здесь и есть
весь контракт: точки, текст, маска, multimask и сегментация всего вызывают
ошибку с сообщением, указывающим на SAM 2 или SAM 3.
Дополнительный набор зависимостей (extra) для этой группы охватывает четыре
семейства, которые загружаются через transformers:
pip install "libreyolo[sam]"MobileSAM и PicoSAM3 — нативные порты в LibreYOLO, и для их запуска установка
transformers не нужна.
Предсказание
from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Точка — это [x, y] в пикселях; labels: 1 — положительная, 0 — отрицательная.result = model.predict(SAMPLE_IMAGE, points=[640, 420], labels=[1])print(result.masks.xy) # полигоныprint(result.boxes.xyxy) # рамки, плотно описанные вокруг масок # Промпт рамкой даёт одну маску на рамку.result = model.predict(SAMPLE_IMAGE, bboxes=[300, 200, 900, 700])from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # set_image один раз прогоняет тяжёлый кодировщик изображения и кэширует его.model.set_image(SAMPLE_IMAGE)first = model.predict(points=[640, 420], labels=[1])second = model.predict(bboxes=[300, 200, 900, 700])model.reset_image()from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Без промпта берётся сетка точек по всему изображению. Сетка по# умолчанию 32 на сторону — это ~1024 прохода декодера, медленно на CPU.result = model.predict(SAMPLE_IMAGE, points_per_side=8)print(len(result.masks))from libreyolo import LibreSAM, SAMPLE_IMAGE model = LibreSAM("base") # Одна точка может означать рукав, рубашку или человека. multimask=True# возвращает все три маски «целое против части» вместо одной лучшей.result = model.predict( SAMPLE_IMAGE, points=[640, 420], labels=[1], multimask=True)print(len(result.masks))source и set_image() — альтернативы, а не последовательность: передайте
изображение в predict() для разового вызова или сначала вызовите
set_image(), а затем predict(source=None) на каждый промпт. Передача
device= в predict() переносит модель для этого и всех последующих вызовов и
делает недействительными закэшированные эмбеддинги.
Сегментация всего — дорогой режим. points_per_side по умолчанию равен 32, а
это примерно 1024 прохода декодера по изображению; для интерактивных сценариев
на CPU его стоит уменьшить. В этом режиме, если conf не задан, применяется
пороговое значение сетки, принятое в этом семействе, а на пути с промптом
незаданный conf оставляет все маски. Передайте conf=0.0, чтобы отключить фильтрацию в любом из
режимов, и max_det, чтобы ограничить число возвращаемых масок.
Промпты маской в этой версии не поддерживаются, и masks= вызывает ошибку, а не
игнорируется. track() тоже вызывает ошибку во всей группе: это сегментаторы
изображений, поэтому запускайте predict() покадрово. Про источники и работу с
результатами см. предсказание.
Обучение
Ни одно семейство этой группы не обучается внутри LibreYOLO. train() вызывает
ошибку: дообучайте модель в исходном проекте и загружайте полученные веса.
Валидация
Валидатора для этой группы нет, и val() вызывает ошибку. У маски по промпту
нет фиксированного набора классов, по которому её можно оценить, поэтому
обычным метрикам детекции и сегментации не за что зацепиться. Оценить маску по
промпту — значит сравнить её с эталонной маской, которую вы задаёте сами, на
тех промптах, которые вам важны.
Экспорт
Экспорт для группы в целом не предусмотрен, и export() вызывает
ошибку — с одним исключением. PicoSAM3 экспортирует в
ONNX саму CNN для областей 96x96 как roi_image -> mask_logits;
обрезка по рамке и обратное масштабирование маски в координаты изображения
остаются в Python. Все остальные семейства работают через predict() в
PyTorch. Про форматы, доступные в остальной библиотеке, см.
экспорт.