Донавчання LoRA
LoRA заморожує важкі попередньо навчені частини моделі та навчає поруч із ними невеликі низькорангові адаптери разом із шарами, які мають залишатися щільними. У LibreYOLO весь загальнодоступний інтерфейс зводиться до одного логічного значення.
Встановлення
LoRA працює на необов'язковій залежності peft.
pip install "libreyolo[lora]"Без неї lora=True спричиняє ImportError із назвою цієї команди,
а не випадково запускає повне донавчання.
Використання
from libreyolo import LibreYOLO model = LibreYOLO("LibreRFDETRs.pt")model.train(data="my-dataset.yaml", epochs=50, lora=True)libreyolo train model=LibreRFDETRs.pt data=my-dataset.yaml \ epochs=50 lora=truelora=True, це весь інтерфейс. Ранг, alpha, dropout і цільові модулі
зафіксовано для кожного сімейства відповідно до upstream-реалізації, і
користувач не може їх налаштовувати.
Сімейство без підтримки LoRA спричиняє помилку під час налаштування, а не ігнорує прапорець:
LoRA fine-tuning (lora=True) is not supported for yolo9. LoRA targets
transformer components with nn.Linear layers (e.g. RF-DETR, D-FINE, DEIM).CLI відхиляє його раніше, ще до побудови моделі, використовуючи власний дозвільний список тих самих дев'яти сімейств.
Підтримувані сімейства
RF-DETR, D-FINE, DEIM, DEIMv2, RT-DETR v1, v2 і v4, EC та ConvNeXt. Умовою є
атрибут supports_lora класу тренера кожного сімейства, а CLI має
відповідний дозвільний список.
Покриття задач вужче за покриття сімейств. D-FINE і EC підтримують лише виявлення, а їхні шляхи сегментації та пози спричиняють помилку. Семантичний шлях RF-DETR також спричиняє помилку. ConvNeXt виконує класифікацію.
Усі інші варіанти спричиняють помилку. Часткового або прихованого режиму немає.
Дія кожного рецепта
Рецепти відрізняються через відмінності архітектур, а рецепту, який працює для бекбона ViT, немає до чого приєднатися в згортковому бекбоні.
RF-DETR використовує DoRA, LoRA з розкладеними вагами, із рангом 16 і alpha
16 для проєкцій уваги query, key і value бекбона DINOv2
відповідно до еталона RF-DETR. Бекбон ViT заморожується, а проєктор, декодер
і голова виявлення навчаються як звичайно.
D-FINE, DEIM і RT-DETR v1, v2 та v4 поєднують згортковий бекбон із гібридним
енкодером-трансформером і деформованим декодером, тому межа зміщується.
Згортковий бекбон повністю заморожується, що також пропускає його зворотний
прохід. Блоки трансформера заморожують базові ваги й навчають звичайні
адаптери LoRA з тим самим рангом 16 і alpha 16 на лінійних шарах:
feed-forward linear1 і linear2, gate та проєкції деформованої уваги.
Усе інше, згорткове злиття енкодера, вхідні проєкції, голови передбачення й
ембединги запитів, навчається щільно.
Дві деталі цього рецепта навмисні. Самоувага декодера залишається замороженою
без адаптерів, оскільки nn.MultiheadAttention PyTorch читає
out_proj.weight безпосередньо й непомітно обходила б вставлений адаптер.
Використовується звичайна LoRA, а не DoRA, оскільки кілька лінійних шарів
декодера навмисно ініціалізовано нулями, а нормалізація величини DoRA ділить
на норму ваг.
DEIMv2 використовує той самий рецепт із feed-forward шарами SwiGLU w12
і w3 як цілями. Її розміри S, M, L і X також мають бекбон ViT DINOv3,
базова частина якого заморожується, а злиті шари уваги qkv отримують
адаптери; водночас згорткова піраміда Spatial Tuning Adapter продовжує
навчатися як аналог проєктора. Ці адаптери qkv додаються навіть тоді,
коли конфігурація вже постачала заморожений ViT, оскільки сенс полягає саме
в адаптації замороженого бекбона. Розміри менші за S мають згортковий бекбон
і використовують звичайний рецепт.
EC, це DETR із бекбоном ViT, оточеним згортковою пірамідою проєктора, яка
навчається. Базова частина ViT заморожується, а її шари qkv отримують
адаптери; блоки трансформера використовують спільний рецепт, а проєктор і
голови залишаються щільними.
Блоки ConvNeXt мають лінійні MLP із каналами в останньому вимірі, fc1
і fc2, які отримують звичайні адаптери. Глибинні згортки, нормалізації
та параметри масштабу шарів заморожуються. Голова класифікації залишається
щільною, щоб працювала власна кількість класів.
Голови виявлення й класифікації завжди залишаються доступними для навчання в кожному рецепті, оскільки для власної кількості класів потрібна заново навчена голова.
Контрольні точки та експорт
best.pt і last.pt зберігають тензори адаптерів, тому запуск LoRA
відновлюється й перевіряється як будь-який інший. Для завантаження однієї з
цих контрольних точок потрібна встановлена додаткова залежність lora,
оскільки завантажувач повторює вставлення адаптерів для узгодження ключів.
export() зливає адаптери в щільні ваги, тому експортований артефакт не
залежить від peft. Таке саме злиття доступне безпосередньо для моделі
в пам'яті.
from libreyolo import LibreYOLO model = LibreYOLO("runs/train/exp/weights/best.pt")model.export(format="onnx")from libreyolo import LibreYOLOfrom libreyolo.training.lora import merge_lora_adapters model = LibreYOLO("runs/train/exp/weights/best.pt")merged = merge_lora_adapters(model.model) print(f"{merged} adapter layers folded into dense weights")Після злиття дерево модулів повністю щільне, а друге злиття нічого не робить.
Що заощаджується, а що ні
LoRA зменшує пам'ять оптимізатора й градієнтів, а в сімействах, що повністю заморожують бекбон, також пропускає його зворотний прохід.
Пам'ять активацій не змінюється. Активації прямого проходу й далі потрібно
зберігати для всіх частин, що навчаються, і саме вони зазвичай визначають
пікове споживання. За найсуворішого обмеження VRAM також зменште batch
або imgsz.
Пов'язані матеріали
- Заморожування шарів для іншого способу
навчати підмножину ваг, який працює з кожним сімейством і не потребує
додаткової залежності.
freezeіlora=Trueпоєднуються: параметри адаптерів залишаються доступними для навчання, навіть коли їхню батьківську групу бекбона заморожено. - Гіперпараметри для
batch,imgszі решти аргументівtrain().