Контрольні точки upstream-проєктів
Сімейства LibreYOLO портовано з upstream-проєктів, опубліковані контрольні точки яких майже готові до завантаження, але не містять метаданих LibreYOLO. Автоматичне перетворення розпізнає ці файли, загортає їх у схему v1.0 і записує результат поруч із джерелом.
Що відбувається під час завантаження
Коли LibreYOLO() отримує файл .pt, який ще не є повною контрольною точкою
v1.0, він викликає засіб автоматичного перетворення, який:
- розпаковує словник тензорів із поширених upstream-структур;
- запитує кожне зареєстроване сімейство, чи розпізнає воно структуру, і перепризначає ключі, якщо upstream-назви відрізняються від нативного порту;
- загортає переможця у строгу контрольну точку з метаданими v1.0, зчитуючи розмір, задачу й кількість класів із самих тензорів, щоб донавчені контрольні точки перетворювалися правильно;
- записує її поруч із джерелом як
<source>-<Prefix><size>[-task].ptі повертає цей шлях, після чого фабрика завантажує файл звичайним способом.
Від коду виклику нічого не потрібно. Якщо жодне сімейство не заявляє про підтримку файла, засіб нічого не повертає, а фабрика повідомляє, що не змогла його завантажити.
from libreyolo import LibreYOLO # Розпізнаний upstream-файл перетворюється під час завантаження, а# перетворена контрольна точка записується поруч із ним.# model = LibreYOLO("yolov9-t-converted.pt") # Будь-яка контрольна точка LibreYOLO завантажується без змін.model = LibreYOLO("LibreYOLO9t.pt")print(model.family, model.size, model.task, model.nb_classes)Структури, які розпаковуються
Словник тензорів шукається в наведеному нижче порядку пріоритету, починаючи з EMA, і кожен кандидат перевіряється, доки один із них справді не міститиме тензори. Тому порожній блок EMA або блок лише з метаданими не приховує коректних ваг під ним.
| Ключ | Примітка |
|---|---|
ema.module | Поширена обгортка EMA |
ema | Застарілі плоскі обгортки EMA, що зберігають тензори безпосередньо |
ema_state_dict | Префікс module. у записах видаляється |
params_ema | |
params | |
ema_net | |
net | |
model | |
state_dict | |
| Сам файл | Звичайний словник стану |
Потім кожного кандидата звужують до записів із тензорними значеннями та
нормалізують: початковий префікс module. або _orig_mod. видаляється, а зі
словника, у якому всі ключі починаються з model.model., видаляється цей
префікс.
Які сімейства що розпізнають
Розпізнавання реалізовано окремим методом класу для кожного сімейства. Типова реалізація заявляє про підтримку структури, ключі якої вже відповідають нативному порту. Сімейство з іншими назвами upstream-ключів перевизначає метод із перепризначенням і нічого не повертає для структур, які не розпізнає.
Сімейства, що постачають засіб розпізнавання з перепризначенням: centernet,
deeplabv3, deformable_detr, dexined, moge2, picodet, rtdetr,
rtdetrv2, rtdetrv4, rtmdet, segformer, swin, teed, yolo7,
yolo9, yolo9_e2e, yolo9_p2.
Сімейства, що повністю відмовляються від автоматичного перетворення:
efficientdet, eomt і pidnet нічого не повертають із засобу розпізнавання,
тому їхні upstream-файли проходять через скрипт перетворення. Сімейство l2cs
вилучено із загального засобу розпізнавання, оскільки воно призначене лише для
інференсу та має ваги з обмеженим розповсюдженням.
RF-DETR має власний засіб розпізнавання, оскільки йому потрібна вся контрольна точка, а не лише словник тензорів, щоб визначити розмір і перепризначити класи COCO. Він реєструється лише тоді, коли встановлено його необов'язкові залежності.
Усі інші зареєстровані сімейства використовують типову поведінку: заявляють про підтримку файла, коли їхній власний завантажувач уже розпізнає ці ключі.
Яке сімейство перемагає
Один файл можуть розпізнати кілька сімейств, тому вибір відтворює правила маршрутизації фабрики.
Заява підкласу має перевагу над його базовим класом. Порядок реєстрації відповідає порядку створення класів, тож похідне сімейство реєструється після базового, яке воно уточнює, а його позитивні маркери не повинні програти ширшому прямому пропусканню базового класу.
Далі рішення визначає порядок у реєстрі, оскільки він кодує специфічність: найраніша заява є найточнішим збігом.
Єдиний конфлікт, якого не може розв'язати порядок у реєстрі, виникає між DEIM і D-FINE, оскільки їхні архітектурні ключі ідентичні. Лише в цьому випадку вирішальним сигналом стає назва файла, а файл без підказки в назві відхиляється замість вгадування. В усіх інших випадках назва файла навмисно не враховується, тому широка хибнопозитивна заява ніколи не отримає перевагу над точнішою лише через назву файла.
Безпечне завантаження
Upstream-файли завантажуються засобом десеріалізації лише ваг. Деякі upstream-контрольні точки навчання містять об'єкти бібліотек, які цей засіб відхиляє. Такі об'єкти є метаданими навчання, а не вагами, тому кожен заблокований глобальний об'єкт повторно обробляється з інертним підставним класом, який задовольняє засіб десеріалізації, не виконуючи нічого. Отримана назва використовується лише як текстова мітка, її ніколи не імпортують, не обчислюють і не викликають.
Чутливі назви модулів відхиляються повністю та ніколи не підміняються:
builtins, os, sys, posix, nt і subprocess. Цикл повторних спроб
обмежено 32 ітераціями, тому файл, спеціально створений для необмеженої
послідовності різних глобальних об'єктів, завершує роботу безпечно, а не
зациклюється. До перетвореної контрольної точки потрапляють лише тензори.
Розташування перетвореного файла
Вихідні дані записуються поруч із джерелом під назвою
<source>-<Prefix><size>[-task].pt. Файл завжди записується наново, а не
використовується повторно, що підтримує актуальність повторних завантажень того
самого джерела та водночас запобігає конфліктам з офіційними вагами або іншим
донавчанням того самого сімейства, розміру й задачі в тому самому каталозі.
Якщо каталог джерела доступний лише для читання, перетворення використовує новий приватний тимчасовий каталог, створений для кожного виклику, а рядок журналу вказує використаний шлях. Лише якщо й це не вдається, перетворення відкидається з попередженням.
Наявні контрольні точки LibreYOLO
Файл із маркером LibreYOLO, libreyolo_version або model_family, належить до
звичайного шляху завантаження й не перетворюється повторно. Пропуск застосовується
лише до заяви з прямим пропусканням, тобто коли набір ключів не змінився. Заява,
у якій перетворення змінило набір ключів, доводить наявність сторонньої
upstream-структури й приймається навіть для позначеного файла.
schema_version навмисно не вважається маркером, оскільки інші інструменти
навчання й експорту використовують цю загальну назву. Маркерами також не є
names, nc, size, task або imgsz, оскільки upstream-донавчання теж
може їх містити. Тому стороннє донавчання лише із загальним ключем names не
вважається позначеним, його заява з нативними ключами перетворюється звичайним
способом, а кількість класів визначається з тензорної голови замість помилкового
завантаження як моделі на 80 класів.
Метадані, які читає засіб перетворення
Назви класів беруться з ключа верхнього рівня names або з class_names у
блоці args чи hyper_parameters. Карта назв із ключами-мітками замість
індексів класів непридатна й замінюється згенерованими типовими назвами. Список
назв, довший за виявлену кількість класів, обрізається, оскільки індекси поза
діапазоном не пройдуть строгий валідатор і непомітно перервуть перетворення.
Upstream-параметри args переносяться як звичайні метадані, а всі значення,
що не є рядком, числом, булевим значенням, списком або словником, відкидаються,
тому до збереженого файла не потрапляють небезпечні дані.
Нормалізація COCO для RF-DETR
Upstream-контрольні точки RF-DETR мають класифікаційну голову з 91 виходом, що відповідає 90 класам COCO разом із тлом. Автоматичне перетворення нормалізує RF-DETR для COCO до домовленості COCO-80, застосовуючи перепризначення під час постоброблення.
Контрольна точка вважається призначеною для COCO, якщо вона містить рівно 80
назв, оголошує 80 класів, має підказку датасету coco або взагалі не має
метаданих класу чи датасету. Останній випадок важливий: звичайний upstream-словник
стану є канонічною контрольною точкою, попередньо навченою на COCO, і єдиною
розповсюджуваною контрольною точкою RF-DETR із 91 виходом без метаданих.
Справжня користувацька модель RF-DETR на 90 класів зберігається з 90 класами. Її визначають за списком назв, явно вказаною кількістю класів, що не дорівнює 80, або підказкою датасету, відмінного від COCO, тож резервне правило для контрольної точки без метаданих до неї не застосовується. Порожні заповнювачі не враховуються під час визначення наявності підказки датасету.
Обмеження
Автоматичне перетворення розпізнає опубліковані upstream-структури. Воно не
переписує архітектуру й не робить непортовану модель придатною до завантаження.
Якщо жодне сімейство не заявляє про підтримку файла, слід застосувати скрипт
перетворення, а не аргумент фабрики: репозиторій постачає weights/convert_*.py
для сімейств, яким він потрібний, зокрема EoMT, PIDNet і EfficientDet.
Перетворення також не вигадує метадані, які неможливо прочитати. Розмір, задача
й кількість класів визначаються з тензорів; назви беруться з файла, якщо вони
наявні, і генеруються як class_i, якщо їх немає.