DEIM
Детекционный трансформер, обученный плотным взаимно однозначным сопоставлением: он сходится за куда меньшее число эпох, чем рецепты DETR, на которых он построен. LibreYOLO несёт две его версии, а различают их по загружаемому чекпойнту.
- Задачи
- detection
- Размеры
- deim: n, s, m, l, x at 640 px
- Установка
pip install libreyolo- Уровень поддержки
- Основной, начиная с v1.2.0. Основные обучаемые детекторы: функции появляются вслед за флагманами в той же волне релиза.
- Исходный проект
- DEIM and DEIMv2 от Intellindust AI Lab, Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License. Статья, исходный код
- Лицензии
- Код: Apache-2.0, веса: Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License. Коммерческое использование
Установка
Ни одной из версий не нужен дополнительный extra. Всё, что они импортируют, входит в базовую установку.
pip install libreyoloИсключение — дообучение адаптерами через lora=True: ему нужен extra lora.
pip install "libreyolo[lora]"Предсказание
Веса скачиваются с Hugging Face при первом запуске и кэшируются локально.
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("LibreDEIMn.pt")result = model(SAMPLE_IMAGE, save=True) for box in result.boxes: print(box.cls, box.conf, box.xyxy)libreyolo predict model=LibreDEIMn.pt save=True \ source=https://raw.githubusercontent.com/LibreYOLO/libreyolo/release/libreyolo/assets/parkour.jpgfrom libreyolo import LibreYOLO # Версия входит в имя файла, а фабрика выбирает по чекпойнту, поэтому# обе загружаются одинаково.model = LibreYOLO("LibreDEIMv2pico.pt") # Любой источник, который принимает библиотека: файл, папка, URL, индекс# веб-камеры, RTSP-поток или список .streamsfor result in model.predict("clip.mp4", stream=True, save=True): print(len(result.boxes))Возвращаемый объект Results — тот же, что возвращает любое семейство, поэтому
подменить детектор на другой можно одной строкой. conf и max_det фильтруют
top-k-декодирование по запросам и классам; шага NMS, который нужно было бы
настраивать, здесь нет, а iou принимается, но не используется. Про источники,
стриминг и обработку результатов — предсказание.
DEIM принимает прямоугольный imgsz=(height, width) для предсказания. DEIMv2 явно отклоняет прямоугольные входы при предсказании и валидации. Это не означает поддержку прямоугольных входов при обучении или экспорте.
Варианты
Версия 1 поставляется в пяти размерах, все с одинаковым входным разрешением.
Версия 2 сохраняет эти пять названий и добавляет три меньших — atto, femto
и pico, — первые два из которых нативно работают на меньшем входном
разрешении, чем остальные. Поэтому пять кодов размеров существуют в обеих
версиях и обозначают разные модели; версия записана в имя файла чекпойнта.
| Чекпойнт | Вход (пикс.) | mAP 50-95 | Параметры (млн) |
|---|---|---|---|
| LibreDEIMl | 640 | 57.8 | 31.24 |
| LibreDEIMm | 640 | 55.4 | 19.59 |
| LibreDEIMn | 640 | 46.8 | 3.78 |
| LibreDEIMs | 640 | 52.1 | 10.32 |
| LibreDEIMx | 640 | 59.6 | 62.62 |
| LibreDEIMv2atto | 320 | 27.5 | 0.51 |
| LibreDEIMv2femto | 416 | 34.5 | 0.98 |
| LibreDEIMv2l | 640 | 58.6 | 32.55 |
| LibreDEIMv2m | 640 | 56.0 | 18.36 |
| LibreDEIMv2n | 640 | 46.7 | 3.6 |
| LibreDEIMv2pico | 640 | 42.2 | 1.54 |
| LibreDEIMv2s | 640 | 53.0 | 9.78 |
| LibreDEIMv2x | 640 | 61.3 | 51.21 |
COCO val2017, 500 images. Измерено системой бенчмарков LibreYOLO и опубликовано на Vision Analysis, где сравниваются задержки на разном оборудовании и в разных средах выполнения и хранятся полные записи запусков.
Версия 1 сохраняет архитектуру D-FINE и заменяет её целевую функцию
классификации на функцию потерь с учётом сопоставимости из рецепта плотного
взаимно однозначного сопоставления, поэтому у двух семейств совпадают почти все
ключи state dict, и различают их по метаданным в чекпойнте. Версия 2 сохраняет
этот контракт обучения и смешивает бэкбоны: HGNetv2 ниже s и vision
transformer DINOv3 с адаптером пространственной подстройки на s и выше.
Именно из-за этого бэкбона на этих четырёх чекпойнтах появляется вторая
лицензия, так что прежде чем выкатывать такой чекпойнт, прочитайте
лицензирование.
Обучение
Обучение начинается с опубликованного чекпойнта. pretrained до обучения не
доходит: версия 1 предупреждает, что ключ неизвестен, и игнорирует его, версия
2 его удаляет. Ни та, ни другая не дадут модель со случайной инициализацией.
from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt") # coco128.yaml при первом запуске скачивает выборку из 128 изображений.# Для реального запуска укажите в `data` YAML своего датасета.model.train(data="coco128.yaml", epochs=50, batch=8, lr0=1e-4)libreyolo train model=LibreDEIMn.pt data=coco128.yaml \ epochs=50 batch=8 lr0=1e-4from libreyolo import LibreYOLO # Если epochs, batch, imgsz и lr0 не заданы, они берутся из# опубликованного рецепта для загруженного размера.model = LibreYOLO("LibreDEIMv2pico.pt")model.train(data="coco128.yaml", epochs=50)# Требуется extra lora: pip install "libreyolo[lora]"from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt")model.train(data="coco128.yaml", epochs=50, lora=True)libreyolo train model=LibreDEIMn.pt data=coco128.yaml \ epochs=50 device=0,1На версии 1 задавайте lr0 сами. В сигнатуре Python-метода train() по
умолчанию стоит 4e-4 — скорость обучения из опубликованного рецепта для COCO,
— тогда как в конфиге обучения этого семейства значением по умолчанию для
дообучения записано 1e-4, и именно это меньшее значение подставляет CLI, если
аргумент не передан. В конфиге записано и измерение, которое за этим стоит: при
размерах батча, которые реально используются при дообучении, на небольших
датасетах скорость обучения из рецепта COCO заметно ухудшала перенос.
Версия 2 разрешает эти значения по умолчанию сама. Если epochs, batch,
imgsz и lr0 не заданы, каждое из них читается из опубликованного рецепта
для загруженного размера, поэтому маленькие размеры обучаются на своём входном
разрешении без дополнительных указаний, а переданное вами значение перекрывает
рецепт. Ограничение накладывается на imgsz: он должен быть положительным
числом, кратным 32, иначе версия 2 выбросит ошибку ещё до старта запуска.
Про датасеты, аугментацию, обучение на нескольких GPU и логгеры — обучение.
DEIM по умолчанию включает AMP с amp_dtype="float16". Для обучения в FP32 передайте amp=False.
Валидация
val() возвращает словарь с ключами metrics/, которые покрывают точность,
полноту, mAP 50 и mAP 50-95, посчитанные на любом датасете в том формате, на
котором вы обучались.
from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt") # val() возвращает обычный dict, а не объектmetrics = model.val(data="coco128.yaml") print(metrics["metrics/mAP50-95"])print(metrics["metrics/mAP50"])print(metrics["metrics/precision"], metrics["metrics/recall"])libreyolo val model=LibreDEIMn.pt data=coco128.yaml# coco-val-only.yaml скачивает 5000 изображений val2017 и пропускает# обучающий набор. Внутри него есть встроенный скрипт загрузки, поэтому# нужно явное разрешение, если датасета ещё нет локально.libreyolo val model=LibreDEIMn.pt data=coco-val-only.yaml \ allow_download_scripts=TrueСтроки в таблице бенчмарков выше получены на бенчмарк-стенде LibreYOLO; в примечании под этой таблицей указано, на каком датасете они получены, и даны ссылки на записи о запусках.
Экспорт
| Задача | ONNX | TorchScript | ExecuTorch | TensorRT | OpenVINO | Paddle | MNN | RKNN | ncnn | TFLite | CoreML | Core AI |
|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Detection | Detection to ONNX: поддерживается | Detection to TorchScript: поддерживается | Detection to ExecuTorch: не поддерживается | Detection to TensorRT: поддерживается | Detection to OpenVINO: поддерживается | Detection to Paddle: поддерживается | Detection to MNN: поддерживается | Detection to RKNN: не поддерживается | Detection to ncnn: не поддерживается | Detection to TFLite: не поддерживается | Detection to CoreML: не поддерживается | Detection to Core AI: поддерживается |
Матрица описывает обе версии на одной странице: там, где они расходятся по формату, в ячейке показан более слабый из двух вариантов, так что здесь ничего не приукрашено — какую бы версию вы ни загрузили.
Экспортированный артефакт загружается обратно через LibreYOLO() по суффиксу
файла, поэтому файл .onnx или .engine ведёт себя как чекпойнт и возвращает
тот же Results.
# Требуется extra onnx: pip install "libreyolo[onnx]"from libreyolo import LibreYOLO model = LibreYOLO("LibreDEIMn.pt")path = model.export(format="onnx")print(path)libreyolo export model=LibreDEIMn.pt format=onnxfrom libreyolo import LibreYOLO, SAMPLE_IMAGE # Фабрика выбирает по суффиксу файла, поэтому экспортированный артефакт# загружается как обычный чекпойнт и возвращает тот же объект Results.model = LibreYOLO("LibreDEIMn.onnx")result = model(SAMPLE_IMAGE) print(result.boxes.xyxy)Входы и выходы ONNX
LibreDEIM, and LibreDEIMv2 atto, femto, pico and n
| Тензор | images float32 [batch, 3, height, width] |
|---|---|
| Цвет | RGB |
| Масштабирование | пиксель / 255 |
| Нормализация | нет |
| Изменение размера | растянуть до ширины x высоты (без заполнения, соотношение сторон не сохраняется), Pillow bilinear |
Как воспроизвести билинейное изменение размера Pillow
LibreYOLO меняет размер фильтром BILINEAR из Pillow (Image.resize). Это не OpenCV INTER_LINEAR и не INTER_AREA: при уменьшении Pillow расширяет фильтр на коэффициент уменьшения, а изменение размера в OpenCV меняет детекции и сдвигает рамки на несколько пикселей. Чтобы воспроизвести его без Pillow, измените размер по одной оси, округлите до 8 бит, затем измените размер по другой оси и округлите снова. Для каждой оси пусть s = in_size / out_size и f = max(s, 1). Выходной пиксель i имеет центр c = (i + 0.5) * s и читает исходные пиксели j от int(c - f + 0.5) до int(c + f + 0.5) - 1, ограниченные изображением, каждый с весом max(0, 1 - |j + 0.5 - c| / f), деленным на сумму весов. Pillow считает в фиксированной точке и выбирает порядок осей по форме изображения, поэтому веса с плавающей точкой могут отличаться от него на один уровень на нескольких пикселях. Это не меняет результаты в наших проверках.
Square input only. Export rejects a non-square imgsz. height and width equal the imgsz metadata key: 640 by default, 320 for DEIMv2 atto and 416 for DEIMv2 femto.
Batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0.
To run several images per call, export with batch=2. That graph takes any batch size and gives the same results per image.
Divide by 255 after the resize. There is no mean or std normalization for these sizes.
Only the default export exists. nms=True raises NotImplementedError for this family.
Detection, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
pred_logits | [batch, queries, nc] | One logit per query and class. Sigmoid is not applied, and there is no background class. 300 queries, except DEIMv2 atto with 100 queries, femto with 150 queries and pico with 200 queries. |
pred_boxes | [batch, queries, 4] | cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image. |
Постобработка
- Apply sigmoid to pred_logits.
- Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
- Keep the pairs whose score is above the confidence threshold (0.25 by default).
- Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
- There is no NMS and the iou threshold is not used. DEIM predicts a set of boxes.
- LibreYOLO does not clip these boxes, so an edge can sit slightly outside the image.
LibreDEIMv2 s, m, l and x
| Тензор | images float32 [batch, 3, height, width] |
|---|---|
| Цвет | RGB |
| Масштабирование | пиксель / 255 |
| Нормализация | среднее [0.485,0.456,0.406], стандартное отклонение [0.229,0.224,0.225] |
| Изменение размера | растянуть до ширины x высоты (без заполнения, соотношение сторон не сохраняется), Pillow bilinear |
Как воспроизвести билинейное изменение размера Pillow
LibreYOLO меняет размер фильтром BILINEAR из Pillow (Image.resize). Это не OpenCV INTER_LINEAR и не INTER_AREA: при уменьшении Pillow расширяет фильтр на коэффициент уменьшения, а изменение размера в OpenCV меняет детекции и сдвигает рамки на несколько пикселей. Чтобы воспроизвести его без Pillow, измените размер по одной оси, округлите до 8 бит, затем измените размер по другой оси и округлите снова. Для каждой оси пусть s = in_size / out_size и f = max(s, 1). Выходной пиксель i имеет центр c = (i + 0.5) * s и читает исходные пиксели j от int(c - f + 0.5) до int(c + f + 0.5) - 1, ограниченные изображением, каждый с весом max(0, 1 - |j + 0.5 - c| / f), деленным на сумму весов. Pillow считает в фиксированной точке и выбирает порядок осей по форме изображения, поэтому веса с плавающей точкой могут отличаться от него на один уровень на нескольких пикселях. Это не меняет результаты в наших проверках.
These sizes use a DINOv3 backbone, so they take ImageNet mean and std. The atto, femto, pico and n sizes do not.
Square input only. Export rejects a non-square imgsz. height and width equal the imgsz metadata key, 640 by default.
Batch size 1 only. The graph declares a dynamic batch axis, but batches of 2 or more fail in 1.7.0.
To run several images per call, export with batch=2. That graph takes any batch size and gives the same results per image.
After the resize, divide by 255, then subtract the ImageNet mean and divide by the ImageNet std, per channel in RGB order.
Only the default export exists. nms=True raises NotImplementedError for this family.
Detection, экспорт по умолчанию
| Выход | Форма | Смысл |
|---|---|---|
pred_logits | [batch, queries, nc] | One logit per query and class. Sigmoid is not applied, and there is no background class. 300 queries. |
pred_boxes | [batch, queries, 4] | cx, cy, w, h of each query, normalized 0 to 1 of the input. The input is the whole image stretched, so these are also fractions of the original image. |
Постобработка
- Apply sigmoid to pred_logits.
- Flatten the [queries, nc] scores and take the top 300 (max_det, 300 by default). For flat index k, the query is k // nc and the class is k % nc. One query can yield several classes.
- Keep the pairs whose score is above the confidence threshold (0.25 by default).
- Convert the query's box to x1 = cx - w / 2, y1 = cy - h / 2, x2 = cx + w / 2, y2 = cy + h / 2. Multiply x by the original image width and y by the original image height.
- There is no NMS and the iou threshold is not used. DEIM predicts a set of boxes.
- LibreYOLO does not clip these boxes, so an edge can sit slightly outside the image.
Чтобы проверить собственную реализацию, пропустите тот же файл через LibreYOLO: LibreYOLO("model.onnx").predict("image.jpg") возвращает эталонные результаты. Проверено на LibreYOLO 1.7.0.
Чекпойнты
Все опубликованные файлы весов этого семейства.
| Файл | Вход (пикс.) | Лицензия весов |
|---|---|---|
| Detection | ||
| LibreDEIMn.pt | 640 | apache-2.0 |
| LibreDEIMs.pt | 640 | apache-2.0 |
| LibreDEIMm.pt | 640 | apache-2.0 |
| LibreDEIMl.pt | 640 | apache-2.0 |
| LibreDEIMx.pt | 640 | apache-2.0 |
| LibreDEIMv2n.pt | 640 | apache-2.0 |
| LibreDEIMv2s.pt | 640 | other |
| LibreDEIMv2m.pt | 640 | other |
| LibreDEIMv2l.pt | 640 | other |
| LibreDEIMv2x.pt | 640 | other |
| LibreDEIMv2atto.pt | apache-2.0 | |
| LibreDEIMv2femto.pt | apache-2.0 | |
| LibreDEIMv2pico.pt | apache-2.0 | |
Все перечисленные выше файлы уже доступны в организации LibreYOLO и скачиваются при первом использовании.
Лицензирование
Проверяйте лицензию в репозитории конкретных весов на Hugging Face. Она указана для каждого чекпойнта в организации LibreYOLO и может различаться даже внутри одного семейства. Этот репозиторий считается авторитетным источником, а сводка ниже описывает условия на момент последней проверки страницы.
Это описание соответствующих лицензий, а не юридическая консультация. Если ответ важен для коммерческого использования, прочитайте лицензии самостоятельно и проконсультируйтесь с юристом.
- Оригинальная работа
- DEIM and DEIMv2, Intellindust AI Lab
- Лицензия исходного проекта
- Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License
- Исходный код проекта
- github.com/Intellindust-AI-Lab/DEIM
- Код LibreYOLO
- MIT
- Веса
- Apache-2.0; the DEIMv2 DINOv3 backbone adds Meta's DINOv3 License, повторно опубликованы на huggingface.co/LibreYOLO
- Толкование
- Apache-2.0 is a permissive license, so these weights can be used in commercial and closed-source products. It asks you to keep its license text and attribution notices with any copy of the weights you redistribute, and it grants a patent license. It places no obligation on your own application code, and weights you train yourself on your own data are yours. DEIM is Apache-2.0 throughout, and so are the DEIMv2 sizes below S, which use an HGNetv2 backbone. The DEIMv2 S, M, L and X sizes take their backbone from DINOv3, so both their weights and the backbone source vendored in LibreYOLO are additionally governed by Meta's DINOv3 License Agreement, which is not an OSI license: redistribution has to carry the agreement with it, and it forbids use for military or warfare purposes, weapons development, espionage, nuclear industries and anything subject to ITAR. Their Hugging Face repositories declare both licenses, and DEIMv2 is also cited separately (arXiv 2509.20787).
Цитирование
@misc{huang2024deim,
title={DEIM: DETR with Improved Matching for Fast Convergence},
author={Shihua, Huang and Zhichao, Lu and Xiaodong, Cun and Yongjun, Yu and Xiao, Zhou and Xi, Shen},
booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},
year={2025},
}Скопировано из блока цитирования авторов на странице github.com/Intellindust-AI-Lab/DEIM#5-citation.
DEIMv2 — отдельная статья, и у неё свой блок цитирования на github.com/Intellindust-AI-Lab/DEIMv2; ссылайтесь на него, если использовали чекпойнт версии 2.