Distillazione della conoscenza

La distillazione aggiunge un secondo termine di loss che avvicina le feature map intermedie dello student a quelle di un teacher congelato. LibreYOLO preleva le feature con i forward hook, quindi la testa e la loss del teacher stesso non intervengono mai.

Distillare da un checkpoint più grande

Impostare distill_model attiva la distillazione. Il valore è un checkpoint di teacher, caricato con la stessa factory di qualsiasi altro modello.

Python
from libreyolo import LibreYOLO # Un checkpoint più grande della stessa famiglia supervisiona quello piccolo.model = LibreYOLO("LibreYOLO9s.pt")model.train(    data="my-dataset.yaml",    epochs=100,    distill_model="LibreYOLO9c.pt",    distill_loss_type="mgd",)
CLI
libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \  epochs=100 distill_model=LibreYOLO9c.pt distill_loss_type=mgd

Il teacher esegue il forward sotto no_grad, e sotto autocast quando AMP è attivo, così il modello congelato non paga il costo del calcolo a precisione piena a ogni passo. I forward hook catturano le sue feature map nei punti di prelievo indicati per nome, la loss le confronta con quelle dello student, e il risultato si somma alla loss di addestramento e viene riportato come componente di nome distill.

Distillare da un backbone foundation congelato

In alternativa, un ViT auto-supervisionato può supervisionare un solo stadio del backbone dello student. Le feature del teacher arrivano dal suo estrattore di feature invece che dagli hook, e la loss gestisce il disallineamento tra una griglia di patch e uno stride convoluzionale.

Python
from libreyolo import LibreYOLO # Un ViT auto-supervisionato e congelato supervisiona uno stadio del backbone.model = LibreYOLO("LibreYOLO9s.pt")model.train(    data="my-dataset.yaml",    epochs=100,    distill_model="dinov2",)
CLI
libreyolo train model=LibreYOLO9s.pt data=my-dataset.yaml \  epochs=100 distill_model=dinov2

distill_model riconosce dinov2, che è DINOv2-base, più dinov2_vits14, dinov2_vitb14, dinov2_vitl14, dinov2-small, dinov2-base, dinov2-large, e qualsiasi id dell'hub che inizi con facebook/dinov2. Tutto il resto viene trattato come il percorso di un checkpoint di teacher.

Questa modalità usa feat_mse a prescindere da distill_loss_type, e richiede transformers installato. Se il teacher si carica con chiavi dei pesi mancanti, l'esecuzione si interrompe invece di distillare contro un backbone in parte casuale.

Quali famiglie

Il supporto alla distillazione è un metodo del modello student, e ce ne sono due.

get_distill_config() fornisce i punti di prelievo multi-scala che supervisiona un teacher detector. YOLOv9, YOLOX e RF-DETR lo implementano.

get_backbone_distill_config() fornisce il singolo stadio del backbone che supervisiona un teacher foundation. YOLOv9 lo implementa, ed è l'unica famiglia a farlo.

Tutto il resto solleva un errore invece di addestrare senza la loss:

LibreDFINE does not implement get_distill_config(). Distillation is not yet
supported for the 'dfine' family.
Foundation-model distillation into the 'yolox' family is not supported yet
(no get_backbone_distill_config()).

Punti di prelievo

I punti di prelievo sono fissi per famiglia e per ruolo, quindi teacher e student non devono essere la stessa architettura; devono avere stride delle feature che coincidono.

FamigliaRuoloPunti di prelievoStride
YOLOv9teacher o studentneck.elan_up2, neck.elan_down1, neck.elan_down28, 16, 32
YOLOv9student foundationbackbone.elan316
YOLOXteacher o studentbackbone.C3_p3, backbone.C3_n3, backbone.C3_n48, 16, 32
RF-DETRteacher o studentmodel.backbone.0.projector.stages.0rilevato durante il setup

Gli stride che non coincidono sollevano un errore prima che l'addestramento inizi:

Teacher and student must have matching strides. Teacher: [8, 16, 32],
Student: [16]

Quel controllo viene saltato per i teacher foundation, il cui senso è proprio che le griglie siano diverse.

Le tre loss

distill_loss_type seleziona la loss sulle feature per un teacher detector. Un teacher foundation usa sempre feat_mse.

mgd, masked generative distillation, maschera una frazione delle posizioni spaziali dello student e addestra un piccolo generatore a due convoluzioni per ricostruire l'intera feature map del teacher a partire da ciò che resta. distill_mask_ratio imposta la frazione mascherata, di default 0.65.

cwd, channel-wise distillation, trasforma le attivazioni spaziali di ogni canale in una distribuzione di probabilità e minimizza la divergenza KL canale per canale. distill_tau è la temperatura del softmax, di default 1.0.

feat_mse allinea i canali dello student a quelli del teacher con una convoluzione 1x1, ridimensiona la griglia del teacher a quella dello student in modo bilineare, e prende l'errore quadratico medio. distill_normalize=True normalizza prima entrambe le feature map con L2 sulla dimensione dei canali, il che rende il confronto puramente angolare e invariante alla scala. Di default vale False.

dis è il peso globale applicato al di sopra. Se non lo imposti, ogni loss usa il proprio valore predefinito pubblicato: 2e-5 per MGD, 1.0 per CWD e 1.0 per feature MSE. Differiscono di cinque ordini di grandezza, quindi un peso regolato per un tipo di loss non significa nulla per un altro.

Regolare la loss
from libreyolo import LibreYOLO model = LibreYOLO("LibreYOLO9s.pt")model.train(    data="my-dataset.yaml",    distill_model="LibreYOLO9c.pt",    distill_loss_type="cwd",    dis=1.0,           # peso globale della distillazione    distill_tau=1.0,   # temperatura del softmax di CWD)

distill_mask_ratio, distill_tau e distill_normalize non hanno flag da CLI. Sono argomenti Python o chiavi YAML di cfg=. Anche RF-DETR è solo Python per la distillazione nel suo complesso, perché la sua mappatura degli argomenti della CLI non include le chiavi della distillazione.

Adattatori, checkpoint e multi-GPU

Ogni loss costruisce piccoli moduli addestrabili che vivono fuori dallo student: gli adattatori di canale 1x1, e il generatore di MGD. Ricevono un proprio gruppo di parametri dell'ottimizzatore al learning rate effettivo dell'esecuzione.

Quei moduli vengono scritti nel checkpoint sotto una chiave distiller e ripristinati alla ripresa, così un'esecuzione ripresa non riparte con i proiettori azzerati.

Sotto DDP gli adattatori stanno fuori dallo student incapsulato, il che significa che il reducer di DDP non vede mai i loro gradienti. Il trainer esegue un all-reduce esplicito su di essi a ogni passo, così ogni rank addestra gli stessi adattatori.

La cattura dei CUDA graph non è disponibile in un'esecuzione con distillazione. Passare cuda_graph=True registra una riga e addestra in modalità eager. Vedi Prestazioni dell'addestramento.

Correlati

Verificato con LibreYOLO v1.5.0.