ONNX

ONNX є переносним форматом графа. LibreYOLO трасує модель за допомогою torch.onnx.export, за потреби спрощує граф і записує сімейство, завдання, назви класів та розмір вхідних даних у власні метадані файлу, щоб будь-який бекенд LibreYOLO міг відтворити подальшу обробку.

Параметр
export(format="onnx")
Результат
Один файл .onnx із метаданими, вбудованими у граф
Додатково
pip install "libreyolo[onnx]"
Повторне завантаження
LibreYOLO("weights/LibreYOLO9t.onnx")
Форми
Типово динамічний батч у Python; винятки для завдань наведено нижче
Точність
FP32, FP16 (half=True), INT8 (int8=True, виявлення YOLO9)

Встановлення

Встановлення
pip install "libreyolo[onnx]"

Додатковий пакет встановлює onnx, onnxsim та onnxruntime. Для запису файлу достатньо лише onnx; onnxsim виконує прохід спрощення, а onnxruntime запускає артефакт і виконує калібрування INT8.

Експорт

Python
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9t.pt") # Записує weights/LibreYOLO9t.onnxpath = model.export(format="onnx")print(path)
CLI
libreyolo export --model LibreYOLO9t.pt --format onnx
Аргументи
model.export(    format="onnx",    imgsz=640,        # ціле число або (висота, ширина)    batch=1,    dynamic=True,     # типове значення Python; у CLI типовим є False    simplify=True,    # запуск onnxsim для графа    opset=None,       # None вибирає 13 або 17 для сімейств у стилі DETR    half=False,       # ваги та активації FP16    int8=False,       # QDQ INT8, лише виявлення YOLO9    data=None,        # калібрувальний data.yaml, лише INT8    device=None,      # пристрій трасування; None використовує пристрій моделі    output_path=None, # None записує weights/<stem>.onnx)

Без output_path файл потрапляє до weights/ із основою назви контрольної точки, до якої додається _fp16 або _int8, якщо запитано відповідну точність.

Типовим значенням dynamic є True у Python і False у CLI. Коли параметр увімкнено, вісь батча стає символьною, а кілька завдань отримують додаткову динамічність: для семантичної сегментації змінними стають також висота й ширина маски, для відновлення Real-ESRGAN змінними стають просторові осі, а двостадійні детектори зберігають динамічними початкові висоту й ширину, оскільки змінюють розмір усередині графа.

Якщо opset не зазначено, його вибирають для кожного сімейства окремо. Сімейства у стилі DETR (detr, deformable_detr, dinodetr, dfine, deim, deimv2, ec, lwdetr, rfdetr, rtdetr, rtdetrv2, rtdetrv4), а також deit, midas і moge2 отримують opset 17, де знижується aten::scaled_dot_product. Усі інші отримують 13. Для matting незалежно від налаштувань вибирається 19, оскільки декодеру BiRefNet потрібен оператор DeformConv, визначений у ONNX починаючи з opset 19.

Параметр simplify=True запускає onnxsim і в разі невдачі зберігає початковий граф, тому помилка спрощення створює попередження, а не зупиняє експорт. У macOS arm64 із onnx 1.22 або новішим та onnxsim 0.6.5 або старішим прохід повністю пропускається, оскільки це поєднання може аварійно завершити процес Python.

Вбудований NMS

Вбудувати NMS у граф
from libreyolo import LibreYOLO # Лише виявлення YOLO9, батч 1. dynamic примусово стає False.LibreYOLO("LibreYOLO9t.pt").export(    format="onnx",    nms=True,    conf=0.25,    iou=0.45,    max_det=300,)
CLI
libreyolo export --model LibreYOLO9t.pt --format onnx --nms \  --conf 0.25 --iou 0.45 --max-det 300

Параметр nms=True підтримується лише для виявлення YOLO9 і потребує батча 1; якщо запитати його з dynamic=True, буде записано попередження й вимкнено динамічність. Після цього граф має два виходи: output форми (batch, max_det, 6) і raw, недекодований тензор детектора, який використовує власний бекенд LibreYOLO, щоб подальша обробка залишалася ідентичною шляху PyTorch.

DeepStream

Параметр deepstream=True доступний лише для ONNX. Він експортує граф у компонуванні, якого очікує синтаксичний аналізатор NVIDIA DeepStream, і записує поряд два допоміжні файли, config_infer_primary_<stem>.txt та <stem>_labels.txt, щоб артефакт можна було додати до пайплайна без написаної вручну конфігурації.

Він несумісний із nms=True, а запит обох параметрів спричиняє ValueError: DeepStream виконує пригнічення на власному етапі кластеризації. Передавання цього параметра до будь-якого формату, крім ONNX, також спричиняє помилку. Сітку підтримуваних сімейств і завдань та збирання аналізатора наведено на сторінці DeepStream.

INT8

INT8 із калібрувальними даними
from libreyolo import LibreYOLO LibreYOLO("LibreYOLO9t.pt").export(    format="onnx",    int8=True,    data="coco128.yaml",   # кількасот репрезентативних зображень    fraction=1.0,)

Параметр int8=True запускає статичне квантування ONNX Runtime та записує граф QDQ із вхідними й вихідними даними float32. Квантуються лише вузли Conv і Gemm. Декодування голови детектора навмисно залишається у float32: ця конкатенація поєднує координати рамок у масштабі пікселів з оцінками класів у діапазоні від 0 до 1, а єдиний масштаб активації для тензора, у якому переважає величина координат рамки, звів би всі оцінки до нуля.

Наразі цей параметр застосовується лише до виявлення YOLO9, а для всього іншого попередня перевірка спричиняє NotImplementedError. Якщо data не зазначено, із попередженням використовується coco8.yaml; вісім зображень не є репрезентативним калібрувальним набором. Модель, яку вже квантовано в PyTorch, використовує інший шлях, описаний на сторінці Квантування.

Запуск артефакту

Через LibreYOLO
from libreyolo import LibreYOLO, SAMPLE_IMAGE model = LibreYOLO("weights/LibreYOLO9t.onnx")result = model.predict(SAMPLE_IMAGE)print(result.boxes.xyxy[:3])
Безпосередньо в ONNX Runtime
import numpy as npimport onnximport onnxruntime as ort session = ort.InferenceSession(    "weights/LibreYOLO9t.onnx",    providers=["CPUExecutionProvider"],) # На цьому шляху попередня та подальша обробка покладаються на вас.batch = np.zeros((1, 3, 640, 640), dtype=np.float32)outputs = session.run(None, {session.get_inputs()[0].name: batch})print([out.shape for out in outputs]) # Граф містить сімейство, завдання, назви класів і розмір вхідних даних.meta = {p.key: p.value for p in onnx.load("weights/LibreYOLO9t.onnx").metadata_props}print(meta["model_family"], meta["task"], meta["imgsz"])

LibreYOLO() виконує диспетчеризацію за суфіксом .onnx і повертає такий самий об'єкт Results, як контрольна точка .pt, оскільки під час експорту назви класів, завдання, розмір вхідних даних і схему пози записано у metadata_props графа. З device="auto" сеанс використовує CUDAExecutionProvider, якщо про нього повідомляє ONNX Runtime, а інакше переходить на CPU.

Другий фрагмент призначено для читачів без встановленої LibreYOLO. На цьому шляху попередня обробка, декодування, NMS і повторне масштабування координат покладаються на вас; блок метаданих усе одно доступний для читання.

Обмеження

Назви вихідних тензорів фіксовані для кожного завдання, і споживач без метаданих має зіставити саме їх:

ЗавданняНазви виходів
Виявлення, сіткові та якірні головиoutput
Виявлення, стиль DETRpred_logits, pred_boxes
Виявлення, RF-DETRdets, labels
Класифікаціяoutput
Семантична сегментаціяsemantic_logits
Глибинаdepth
Нормалі поверхніnormal
Контуриedges
Відновленняrestored
Mattingmatte
Поглядyaw_logits, pitch_logits

RF-DETR також є єдиним сімейством, вхідний тензор якого називається input, а не images.

У цій версії кілька завдань мають контракт середовища виконання з фіксованою роздільною здатністю. Завдання глибини, нормалей поверхні та контурів відхиляють batch != 1 і примусово встановлюють dynamic=False. Matting вимагає початкового квадратного розміру 1024, оскільки таблиці відносних позицій Swin у BiRefNet прив'язані до своєї роздільної здатності. Відновлення вимагає фіксованого полотна для всіх сімейств, крім Real-ESRGAN, генератор якого є повністю згортковим.

Прямокутний imgsz працює для сімейств YOLO9, HRNet, NAFNet та Real-ESRGAN. Сімейства з контрактом фіксованої квадратної форми (clip, deformable_detr, detr, dinodetr, dfine, deim, deimv2, ec, lwdetr, moge2, rtdetr, rtdetrv2, rtdetrv4, rfdetr, siglip2, ssd) одразу його відхиляють.

Два поєднання відхиляються ще до трасування: сегментація YOLO9, оскільки YOLO9 підтримує в LibreYOLO лише виявлення, і сегментація RTMDet-Ins, декодування масок із динамічним ядром якої не має контракту експортованого середовища виконання.

Повну сітку сімейств і завдань наведено в матриці експорту. Для окремого поєднання можна запитати безпосередньо бібліотеку:

Перевірити сімейство й завдання перед експортом
libreyolo formats --family yolo9 --task detect

Перевірено за файлами libreyolo/export/onnx.py, libreyolo/export/exporter.py, libreyolo/export/support.py, libreyolo/backends/onnx.py та libreyolo/cli/commands/export.py у гілці dev.