Ядра
Кожна прискорена операція в LibreYOLO має переносну типову реалізацію, а іноді й швидший варіант, зареєстрований поверх неї. Вибір відбувається під час виконання за предикатом, відсутня необов'язкова залежність спричиняє перехід до резервного шляху, а не помилку, а експортований граф завжди використовує переносний шлях.
- Пакет
libreyolo.kernels- Додатковий пакет за згодою
libreyolo[hub-kernels]- Примусовий еталонний шлях
LIBREYOLO_KERNELS=off
Реєстр
libreyolo/kernels/ є невеликим реєстром під'єднуваних реалізацій під час
виконання. Слот операції має назву на кшталт fake_quant_fp8 або
ms_deform_attn. Код запитує слот у реєстру й отримує першу зареєстровану
реалізацію, що проходить власний предикат, з перевагою найновішої реєстрації.
Якщо жодна не підходить, використовується еталонна реалізація.
Така структура потрібна, щоб необов'язкова залежність ніколи не ставала
жорсткою вимогою. Машина без Triton, CUDA чи пакета kernels запускає той
самий код і отримує ті самі числа, лише повільніше.
| Функція | Призначення |
|---|---|
active() | Відповідність слота операції назві вибраної реалізації або "unavailable" |
resolve(op) | Викликаний об'єкт, що буде запущений, або None |
register(op, impl, *, name, predicate=None) | Додавання реалізації на початок |
unregister(op, name) | Вилучення однієї реалізації |
clear_cache() | Очищення кешованого визначення |
import libreyolo.kernels as kernels # Відповідність слота операції назві вибраної реалізації або "unavailable".print(kernels.active())# off і reference означають те саме, а також повністю пропускають# імпорт прискорених провайдерів.LIBREYOLO_KERNELS=off python train.pyLIBREYOLO_HUB_KERNELS=0 python predict.pyfrom libreyolo import LibreYOLOfrom libreyolo.kernels.attention import set_fused_attention model = LibreYOLO("LibreSwinIRs.pt") # Повертає кількість перемкнених модулів уваги.print(set_fused_attention(model))import libreyolo.kernels as kernels kernels.register( "fake_quant_fp8", my_impl, name="mybackend", predicate=my_check,)Виняток із предиката перехоплюється й спричиняє попередження, а не поширюється, тому несправна стороння реалізація переходить до переносного шляху замість порушення передбачення.
Структура
Дерево впорядковано спочатку за призначенням, а потім за бекендом, тому слот знаходиться за обчисленням, а не за бібліотекою, яка випадково реалізує його зараз.
| Каталог | Вміст |
|---|---|
kernels/quant/simulate/ | Ядра Triton для імітації квантування з прямим оцінюванням зворотного проходу на будь-якому пристрої. Використовуються як для QAT, так і для імітованого квантування після навчання |
kernels/quant/execute/ | Шляхи справжньої точності лише для фіналізованих моделей без зворотного проходу: GEMM на тензорних ядрах FP8, його злиті пролог та епілог Triton і ядра розпакування упакованих ваг |
kernels/attention/ | Операції уваги, спільні для сімейств: слот ms_deform_attn і політика злитого SDPA |
Межа між simulate та execute визначається фіналізацією моделі, а не
навчанням чи розгортанням. Еталонні реалізації залишаються в libreyolo/quant/,
який визначає значення чисел; kernels/ лише прискорює їх. Пакування ваг узагалі
не має варіантів, оскільки є контрактом контрольної точки.
Слоти GEMM і уваги не мають еталонної реалізації. Код виклику повинен перевірити,
що resolve() щось повернув, і зберігати власний переносний шлях. Тому графи
ONNX, TensorRT і torch.export завжди містять переносну математику.
Перевизначення вибору
LIBREYOLO_KERNELS=off або =reference примусово використовує еталонні
реалізації й повністю зупиняє імпорт прискорених провайдерів. Будь-яке інше
значення обмежує вибір реалізаціями, зареєстрованими під цією назвою.
LIBREYOLO_QUANT_KERNELS підтримується як застарілий псевдонім із часу, коли
реєстр розташовувався в libreyolo/quant/, і зчитується лише за відсутності
LIBREYOLO_KERNELS. Обидві змінні наведено разом з іншими в розділі
налаштування.
Ядра Hub
Скомпільовані ядра CUDA, опубліковані на Hugging Face Hub, завантажуються під
час виконання через необов'язковий пакет kernels. Нічого не вбудовується в
LibreYOLO; артефакт отримує й кешує цей пакет, а кожен провайдер закріплює
перевірену ревізію коміту. Тому оновлення закріпленої версії потребує перевірки
відповідності на GPU до прийняття.
Додатковий пакет установлюється за явною згодою:
pip install "libreyolo[hub-kernels]"Без пакета нічого не змінюється й мережевий запит не виконується.
LIBREYOLO_HUB_KERNELS=0 вимикає отримання без видалення пакета. Ядро, яке не
вдалося завантажити чи запустити, вимикає себе до завершення процесу й переходить
до резервного шляху з одним попередженням.
Зараз Hub підтримує один слот: ms_deform_attn, скомпільовані прямий і зворотний
проходи багатомасштабної деформівної уваги з Deformable DETR під ліцензією
Apache 2.0. Він під'єднаний до всієї деформівної лінії: RF-DETR, Deformable DETR,
DINO-DETR, LW-DETR, Grounding DINO, RT-DETR, RT-DETRv2, D-FINE, RT-DETRv4, DEIM,
DEIMv2, EC і OV-DEIM. Оскільки зворотний прохід також скомпільовано, це покращує
і навчання, і передбачення.
Придатність навмисно вузька. Вхідні дані мають бути CUDA та float32, а виконання
має бути негайним: провайдер відмовляється за torch.jit.is_tracing(),
torch.compiler.is_compiling(), torch.compiler.is_exporting() і
torch.onnx.is_in_onnx_export(). Дві структури вхідних даних також переходять
до переносного шляху: кількість точок на рівень, яка відрізняється між рівнями,
і дискретна вибірка за цілочисловими індексами. Варіант пози EC не під'єднано.
Це ядро стало доступним нещодавно
Прочитайте цей розділ перед установленням додаткового пакета в наявному проєкті.
У v1.4.0 слот запитувався всередині допоміжної функції за умовою, що вимагала відсутності пар просторових форм. RF-DETR завжди передає ці пари через свій декодер, тому умова ніколи не виконувалася, а ядро не запускалося в жодному негайному прямому проході. У v1.5.0 запит переміщено, і тепер ядро справді працює.
Практичний наслідок полягає в тому, що після оновлення до v1.5.0 та встановлення
libreyolo[hub-kernels] у CUDA сімейства RF-DETR уперше виконують прямий прохід
зі скомпільованого бінарного файла. Через це передбачення та метрики можуть
змінитися в межах допуску рухомої коми. Звичайне встановлення без додаткового
пакета не змінюється. Під час порівняння метрик до й після оновлення зберігайте
однаковий стан додаткового пакета або задайте LIBREYOLO_HUB_KERNELS=0 з обох боків.
Злита увага
Для злитої масштабованої уваги за скалярним добутком не потрібна необов'язкова залежність, лише стандартний PyTorch, тому нею керує політика, а не доступність. Діють два правила.
По-перше, захоплення графа ніколи її не використовує. Кожне замінене місце
виклику зберігає рівняння на примітивних операціях за перевіркою експорту. Це
охоплює експорт ONNX, типовий opset якого не має символу SDPA, і
torch.jit.trace, через який проходять TorchScript, CoreML та NCNN. Захоплення
Dynamo навмисно не входять до шлюзу, оскільки torch.compile знижує SDPA краще
за ручну математику, а Core AI та ExecuTorch самостійно розкладають SDPA до
базового ATen.
По-друге, вимогою для типового використання є побітова точність. Сімейства, що
її виконують, типово використовують SDPA: SegFormer, Depth Anything і MoGe-2,
BERT, Grounding DINO, SwinIR і PP-OCR. Сімейства, що не виконують вимогу,
зберігають ручну математику й натомість надають прапорець fused_attn, який
перемикає set_fused_attention(model): Swin, бекбон Swin моделі DINO-DETR,
BiRefNet і FeyNobg, OWLv2, LW-DETR, SigLIP 2, ZipDepth та MobileSAM. ViT і DeiT
мають той самий прапорець, але типово вмикають його відповідно до оригінальної
реалізації, тому той самий виклик з enabled=False вимикає функцію.
Там, де це застосовується, функція корисна. На RTX 5070 Ti з автоперетворенням fp16 віконна увага Swin скорочується з 1.278 мс до 0.721 мс, що дає виграш 1.77x, а візуальна увага OWLv2 з 6.483 мс до 1.735 мс, що дає 3.74x.
Обладнання
| Платформа | Поведінка |
|---|---|
| CPU та MPS | Кожен предикат CUDA і Triton не виконується, тому все працює через еталонний шлях |
| NVIDIA CUDA | Вмикаються ядра Triton і придатні ядра Hub та GEMM |
| AMD ROCm | Triton може ввімкнутися, оскільки пакети ROCm містять бекенд AMD для Triton, але відповідність у CI перевіряється лише на NVIDIA |
Додавання реалізації
Викличте register() з назвою та предикатом. Зовнішні скомпільовані ядра можуть
постачатися як окремий пакет libreyolo_kernels, який реєструє себе під час
імпорту. Це повністю зберігає приватний бекенд поза деревом LibreYOLO.
Для будь-якої реалізації всередині дерева шлюзом є відповідність: точний збіг прямого проходу з еталонним і градієнти в межах 1e-6 від оцінювача з прямим проходженням для набору форм із тестового набору.
Вибір ядра взаємодіє з графами CUDA: матриця
відповідності інференсу запускалася без установленого пакета kernels, тому
безпека захоплення з активним скомпільованим ядром не охоплена.