This note summarizes how to train a smaller GazeLLE variant (e.g. gazelle_dinov3_vit_tiny) under a teacher such as gazelle_dinov3_vits16plus using the distillation hooks wired into the training scripts.
--distill_weight is set to a positive value.scripts/train_gazefollow.py and scripts/train_vat.py now expose a common set of knobs:--distill_teacher: teacher model name (defaults to gazelle_dinov3_vits16plus).--distill_weight: scalar weight applied to the auxiliary KL loss.--distill_temp_start: temperature used at the beginning of training (default 1.0).--distill_temp_end: temperature reached at the last training step via cosine annealing (default 4.0).--distill_teacher_ckpt: optional override pointing to the teacher’s checkpoint (defaults to a lookup in ./ckpts/).torch.no_grad() contexts during training.# Example: distilling the ViT-Tiny student on GazeFollow
uv run python scripts/train_gazefollow.py \
--model_name gazelle_dinov3_vit_tiny \
--distill_teacher gazelle_dinov3_vits16plus \
--distill_weight 0.3 \
--distill_temp_end 4.0
# Example: distilling the in/out model on VAT
uv run python scripts/train_vat.py \
--model gazelle_dinov3_vit_tinyplus \
--distill_teacher gazelle_dinov3_vits16plus \
--distill_weight 0.3 \
--distill_temp_end 4.0
Passing --distill_weight 0 (or omitting the flag) keeps the previous training behaviour.
gazelle_dinov3_vits16plus: it offers a strong signal while remaining light enough to co-train with the student.gazelle_dinov3_vitb16 for potential accuracy gains. Expect to revisit loss weights because the representational gap grows with the larger teacher.The training scripts try to locate pretrained heads for the most common teachers automatically:
gazelle_dinov3_vit_tiny → ./ckpts/gazelle_dinov3_vit_tiny.ptgazelle_dinov3_vit_tinyplus → ./ckpts/gazelle_dinov3_vit_tinyplus.ptgazelle_dinov3_vits16 → ./ckpts/gazelle_dinov3_vits16.ptgazelle_dinov3_vits16plus → ./ckpts/gazelle_dinov3_vits16plus.ptgazelle_dinov3_vitb16 → ./ckpts/gazelle_dinov3_vitb16.ptgazelle_dinov2_vitb14 → ./ckpts/gazelle_dinov2_vitb14.ptgazelle_dinov2_vitl14 → ./ckpts/gazelle_dinov2_vitl14.ptgazelle_dinov2_vitb14_inout → ./ckpts/gazelle_dinov2_vitb14_inout.ptgazelle_dinov2_vitl14_inout → ./ckpts/gazelle_dinov2_vitl14_inout.ptIf a teacher name is missing or you keep checkpoints elsewhere, pass --distill_teacher_ckpt /path/to/file.pt.
torch.logit when they arrive as probabilities).torch.log_softmax + torch.softmax produce log-probabilities/probabilities over the flattened heatmap.nn.KLDivLoss(reduction='batchmean') is multiplied by temperature² (standard KD normalisation).L_total = L_supervised + distill_weight * KL_T.distill_temp_start to distill_temp_end across all training steps:
T(s) = T_start + 0.5 * (1 - cos(pi * s)) * (T_end - T_start), where s is the normalised step counter.1.0 → 4.0) work well as a first attempt. If the teacher is noisy, keep the end temperature smaller; if the student underfits the teacher, raise it.distill_weight0.1, 0.3, 0.5, 1.0) and watch:distill_weight from 0 during the first epoch if you still observe instability.train/distill_loss reports the KL term.train/distill_temperature tracks the cosine schedule.--distill_teacher_ckpt and the loader will hydrate both backbone and head. By default the scripts still fall back to the curated files in ./ckpts/ (e.g. gazelle_dinov3_vits16plus.pt, gazelle_dinov3_vitb16.pt).--use_amp) or smaller batch sizes if you encounter OOM errors.--distill_weight to a very large value (e.g. 10) for a few iterations; the student heatmaps should quickly mimic the teacher. Revert afterwards.--distill_weight 0 and confirm the loss matches the historical baseline.--distill_weight 0.3 to confirm the pipeline works end-to-end.With these pieces in place, you can iterate on teacher choices, loss weighting, and additional hints to tailor the distillation strategy to your needs.
$ claude mcp add gazelle-dinov3 \
-- python -m otcore.mcp_server <graph>