Skip to content

Advanced Finetuning#358

Open
kozlov721 wants to merge 33 commits into
mainfrom
feature/parameter-groups
Open

Advanced Finetuning#358
kozlov721 wants to merge 33 commits into
mainfrom
feature/parameter-groups

Conversation

@kozlov721

@kozlov721 kozlov721 commented Mar 17, 2026

Copy link
Copy Markdown
Collaborator

Purpose

Improves the control over the training process.

Specification

  • Adds new field finetuning to the NodeConfig
  • This field allows users to specify different parameter groups used for optimization
    • Allows to set different optimizer/scheduler parameters or different optimizers/schedulers altogether for different parameter groups of each node
    • For example allows to set lower learning rate for backbone vs head
  • Added finetuning argument to SimplePredefinedModel
  • Updated ocr_recognition_model.yaml to use different weight_decay for nn.Linear modules in the OCRCTCHead as per the reference implenentation

Example:

nodes:
  - name: CustomHead

    # Specifies custom value of `weight_decay` for all parameters
    # of `nn.Linear` modules in this head. Additionally sets
    # different optimizer and scheduler for the `aux_head` module. 
    finetuning:
      # Specifies different optimizer and scheduler for the `aux_head` module. 
      - parameters:
          name: aux_head
        optimizer:
          name: SGD
        scheduler:
          name: ConstantLR
      # Specifies different `weight_decay` for modules of type `nn.Linear` 
      # that were not included in the previous group.
      - parameters:
          module_type: Linear
        optimizer:
          params:
            weight_decay: 1e-4

# Optimizers and schedulers that are used for the rest of the model
trainer:
  optimizer:
    name: Adam
  scheduler:
    name: StepLR

Dependencies & Potential Impact

None / not applicable

Deployment Plan

None / not applicable

Testing & Validation

Added new test_finetunings.py test.

Summary by CodeRabbit

  • New Features

    • Per-node finetuning: select parameter groups and override optimizer/scheduler per node; improved multi-optimizer support with manual-optimization handling and optimizer/scheduler logging.
  • Bug Fixes

    • Removed implicit T_max auto-population for CosineAnnealingLR.
    • Improved ReduceLROnPlateau stepping and metric monitoring in manual mode.
  • Configuration

    • Removed legacy fc_decay parameter; finetuning config supports weight-decay overrides.
  • Documentation

    • Added finetuning docs and YAML examples.
  • Tests

    • Extensive finetuning unit tests covering selectors, grouping, inheritance, errors, and strategies.

@kozlov721
kozlov721 requested a review from a team as a code owner March 17, 2026 08:55
@kozlov721
kozlov721 requested review from conorsim, klemen1999 and tersekmatija and removed request for a team March 17, 2026 08:55
@github-actions github-actions Bot added documentation Improvements or additions to documentation enhancement New feature or request labels Mar 17, 2026
@klemen1999
klemen1999 requested a review from dtronmans March 17, 2026 08:57

@dtronmans dtronmans left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These are my comments so far regarding potential breaking changes or unexpected behavior, I will just take a quick look at the changes to ReduceLROnPlateau to note any changes to the scheduler

Comment thread luxonis_train/lightning/utils.py Outdated
Comment thread luxonis_train/config/config.py
Comment thread luxonis_train/lightning/luxonis_lightning.py Outdated
Comment thread luxonis_train/nodes/heads/ocr_ctc_head.py
for scheduler in schedulers:
if isinstance(scheduler, ReduceLROnPlateau):
if scheduler.mode == "min":
scheduler.step(loss)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In both modes, the validation results are needed. If the mode is "max" then the chosen val metric is taken into account, and if it is "min" then the val/loss is taken into account. But at this point (on the last batch of a training_step) the val metrics/loss are not computed yet so what is being taken into account? I cannot find any reference to scheduler.step() in the main branch so I assume that this was automatically handled by PyTorch Lightning before.

@coderabbitai

coderabbitai Bot commented May 28, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds per-node finetuning config types and schema, wires finetuning into predefined model NodeConfig creation, centralizes parameter-pattern-based optimizer/scheduler extraction and building in Nodes, updates Lightning for manual optimization and ReduceLROnPlateau handling, removes legacy fc_decay, and adds comprehensive finetuning unit tests and docs/examples.

Changes

Per-node Finetuning Implementation

Layer / File(s) Summary
Configuration types: ParameterPattern, OptimizerConfig, SchedulerConfig, FinetuningConfig
luxonis_train/config/config.py
New Pydantic config classes for regex-based parameter selection via name/module_type patterns, typed optimizer/scheduler configs with finetuning conversion, SequentialLRParams for composed schedulers, and FinetuningConfig with cached regex compilation. NodeConfig gains finetuning list; TrainerConfig narrows types and removes CosineAnnealingLR T_max auto-population logic.
Strategy framework: base contract and TripleLRSGD parameter exclusion
luxonis_train/strategies/base_strategy.py, luxonis_train/strategies/triple_lr_sgd.py
BaseTrainingStrategy.configure_optimizers() return typing updated and new get_base_configs() added. TripleLRSGD supports excluded_params and filters/builds param groups accordingly; TripleLRSGDStrategy persists hyperparameters, exposes base configs, and accepts exclusion sets.
SimplePredefinedModel: per-role finetuning support
luxonis_train/config/predefined_models/base_predefined_model.py
Constructor accepts optional finetuning dict mapping backbone/neck/head to parameter-spec lists; _get_finetuning() converts role dicts to FinetuningConfig; backbone/neck/head NodeConfig instances receive finetuning.
Nodes: parameter extraction and optimizer/scheduler materialization
luxonis_train/lightning/utils.py
Nodes stores top-level cfg and NodeConfig on wrappers, adds main_metric_reference, _extract_optimizer_params() to match trainable params against ParameterPatterns and deduplicate by id, build_optimizers() to materialize multiple optimizer/scheduler pairs, and build_callbacks() to centralize checkpoint/callback creation. Added merge_config_items() and build_optimizer_scheduler() with scheduler-specific handling.
Lightning module: optimizer/callback wiring and manual backward
luxonis_train/lightning/luxonis_lightning.py
configure_optimizers() now builds typed optimizer/scheduler sequences via training_strategy.get_base_configs() + self.nodes.build_optimizers() with optional strategy augmentation, disables automatic optimization for multiple optimizers, and logs optimizer/scheduler info. training_step() implements manual-optimization with manual_backward and steps non-ReduceLROnPlateau schedulers on last batch; _step_reduce_lr_on_plateau_schedulers() handles ReduceLROnPlateau stepping using loss or main metric extraction; _evaluation_epoch_end() invokes this helper for validation.
Configuration documentation and examples
configs/README.md, configs/complex_model.yaml, configs/ocr_recognition_light_model.yaml, luxonis_train/nodes/README.md
Docs updated with finetuning field description and Finetuning section explaining parameters selectors (regex support), optional optimizer/scheduler override blocks, and empty-name inheritance behavior. complex_model.yaml and ocr_recognition_light_model.yaml gain per-node/head finetuning examples; nodes/README.md updates OCRCTCHead parameters.
OCRCTCHead: remove legacy fc_decay parameter
luxonis_train/nodes/heads/ocr_ctc_head.py
Removed fc_decay constructor parameter and assignment; deleted docstring entry and per-layer regularizer initialization in initialize_weights.
Test helpers: model components and snapshot utilities
tests/unittests/test_finetuning/_helpers.py
Adds small BaseNode modules (Backbone, Neck, Head, TinyHead), OptimizerSnapshot dataclass, config builders, build_snapshot to capture optimizers/schedulers and parameter-name mapping, and utilities/assertions for optimizer-group inspection and validation.
Test coverage: error handling, inheritance, grouping, selectors, strategy
tests/unittests/test_finetuning/test_errors.py, test_inheritance.py, test_optimizer_groups.py, test_selectors.py, test_strategy.py
Adds comprehensive unit tests validating unknown optimizer/scheduler name errors, invalid param-group/scheduler params, selector validation errors, inheritance/override semantics for optimizer and scheduler, grouping/deduplication/fallback behavior, ReduceLROnPlateau monitor formatting, and strategy exclusion/inheritance behavior.
Test cleanup
tests/unittests/test_config.py
Removes assertions that depended on TrainerConfig-level CosineAnnealingLR T_max auto-population; defaulting moved to runtime build_optimizer_scheduler() behavior.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant Trainer as LuxonisLightningModule
  participant Nodes
  participant Builder as build_optimizer_scheduler
  Client->>Trainer: start training
  Trainer->>Nodes: nodes.build_optimizers(base_configs)
  Nodes->>Builder: build_optimizer_scheduler per group
  Builder-->>Nodes: Optimizer + Scheduler
  Nodes-->>Trainer: sequences of Optimizers/Schedulers
  Trainer->>Trainer: toggle automatic_optimization, training_step/manual_backward
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

tests

Suggested reviewers

  • klemen1999
  • tersekmatija
  • conorsim

Poem

🐰 I hopped through configs, regex in paw,
Matching parameters with nary a flaw,
Optimizers grouped, schedulers in tune,
Manual backward beneath the moon,
Tests all in rows — a celebratory tune!

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (1 warning, 1 inconclusive)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 4.30% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Title check ❓ Inconclusive The title 'Advanced Finetuning' is partially related to the changeset, referring to a real aspect of the change, but it is overly broad and does not clearly convey the specific primary change: adding per-node finetuning configuration with parameter group selection. Consider a more specific title such as 'Add per-node finetuning configuration with parameter groups' to better communicate the primary change to reviewers scanning the history.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/parameter-groups

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

coderabbitai[bot]

This comment was marked as outdated.

@kozlov721
kozlov721 force-pushed the feature/parameter-groups branch from fdf1ed4 to 83885f1 Compare June 3, 2026 19:30

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
luxonis_train/lightning/utils.py (1)

999-1017: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Use the formatted metric key for ReduceLROnPlateau(mode="max").

Lines 1007-1008 build val/metric/{main_metric.node_name}/{main_metric.metric_name}, but validation metrics are logged under val/metric/{formatted_node_name}/{metric_name}. For any node whose formatted name differs from its identifier, this scheduler will monitor a key that is never logged.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@luxonis_train/lightning/utils.py` around lines 999 - 1017, The
ReduceLROnPlateau branch builds a monitor key with main_metric.node_name which
can differ from the logged/formatted node name; update the monitor construction
to use the metric's formatted node name (e.g., main_metric.formatted_node_name)
or call the existing formatting helper (e.g.,
format_node_name(main_metric.node_name)) so the monitor string becomes
f"val/metric/{formatted_node_name}/{main_metric.metric_name}" when
cfg_scheduler.name == "ReduceLROnPlateau" and mode == "max".
♻️ Duplicate comments (1)
luxonis_train/lightning/luxonis_lightning.py (1)

485-501: ⚠️ Potential issue | 🟠 Major | 🏗️ Heavy lift

Move ReduceLROnPlateau stepping out of training_step.

Line 489 feeds the last train-batch loss into mode="min", and Line 491 reads the main metric before the current epoch's validation has run. In manual optimization this makes plateau decisions use the wrong signal and ignore the validation cadence.

#!/bin/bash
set -euo pipefail

printf "\n-- scheduler stepping in training_step --\n"
sed -n '480,502p' luxonis_train/lightning/luxonis_lightning.py

printf "\n-- metric updates / resets happen in evaluation hooks --\n"
rg -n -C2 'metric\.run_update|metric\.reset|main_metric_reference\.compute' luxonis_train/lightning/luxonis_lightning.py
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@luxonis_train/lightning/luxonis_lightning.py` around lines 485 - 501, The
ReduceLROnPlateau logic currently inside training_step (the block that checks
self.trainer.is_last_batch and calls scheduler.step(loss) or
scheduler.step(value) using nodes.main_metric_reference.compute()) must be
removed from training_step and moved to a post-validation hook where metrics
have been updated (e.g., on_validation_epoch_end or a dedicated end-of-epoch
method run after metric.run_update/metric.reset). Specifically, stop calling
ReduceLROnPlateau.step from training_step; instead iterate the same schedulers
list in the chosen validation-end hook, compute the main metric via
nodes.main_metric_reference.compute() there (ensuring it’s not called before
validation completes), and call scheduler.step(value) for non-loss modes or
scheduler.step(loss) only when you have the correct training loss signal; keep
other schedulers' scheduler.step() behavior unchanged. Ensure code references:
training_step (remove block), nodes.main_metric_reference.compute(), and the
schedulers iteration (re-add in the validation-end hook).
🧹 Nitpick comments (1)
tests/integration/test_finetuning.py (1)

552-553: 💤 Low value

Remove leftover # CHECK markers.

The # CHECK comments above test_inherits_omitted_optimizer_and_scheduler and test_inherits_name_and_merges_params_when_name_is_missing look like authoring reminders that should be resolved or dropped before merge.

Want me to confirm whether these tests need any follow-up before removing the markers?

Also applies to: 582-583

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@tests/integration/test_finetuning.py` around lines 552 - 553, Remove the
leftover authoring markers by deleting the stray "# CHECK" comments immediately
above the test functions test_inherits_omitted_optimizer_and_scheduler and
test_inherits_name_and_merges_params_when_name_is_missing; ensure no other
sentinel comments remain in that test file and run the test suite to confirm
nothing relied on those markers.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@luxonis_train/lightning/utils.py`:
- Around line 356-363: The grouping currently keys buckets by
(cfg_optimizer.name, cfg_scheduler.name) which collapses different scheduler
configs that share a name; change the key to include scheduler parameters as
well (for example include a stable representation such as
frozenset(cfg_scheduler.params.items()) or a serialized params string) so each
distinct (optimizer, scheduler name, scheduler params) combination gets its own
bucket; update the lookup/creation at groups[...] and keep storing the same
tuple (list, cfg_scheduler) so existing uses of groups and the stored
cfg_scheduler remain correct.

In `@tests/integration/test_finetuning.py`:
- Line 8: Replace the private import "from torch._prims_common import Tensor"
with the public API "from torch import Tensor" and remove any leftover marker
comments "#!CHECK" and "# CHECK" that remain in the test file (they trigger Ruff
EXE003/EXE005); search for the exact string "from torch._prims_common import
Tensor" to locate the import to change and search for the literal marker
comments "#!CHECK" and "# CHECK" to delete them.

---

Outside diff comments:
In `@luxonis_train/lightning/utils.py`:
- Around line 999-1017: The ReduceLROnPlateau branch builds a monitor key with
main_metric.node_name which can differ from the logged/formatted node name;
update the monitor construction to use the metric's formatted node name (e.g.,
main_metric.formatted_node_name) or call the existing formatting helper (e.g.,
format_node_name(main_metric.node_name)) so the monitor string becomes
f"val/metric/{formatted_node_name}/{main_metric.metric_name}" when
cfg_scheduler.name == "ReduceLROnPlateau" and mode == "max".

---

Duplicate comments:
In `@luxonis_train/lightning/luxonis_lightning.py`:
- Around line 485-501: The ReduceLROnPlateau logic currently inside
training_step (the block that checks self.trainer.is_last_batch and calls
scheduler.step(loss) or scheduler.step(value) using
nodes.main_metric_reference.compute()) must be removed from training_step and
moved to a post-validation hook where metrics have been updated (e.g.,
on_validation_epoch_end or a dedicated end-of-epoch method run after
metric.run_update/metric.reset). Specifically, stop calling
ReduceLROnPlateau.step from training_step; instead iterate the same schedulers
list in the chosen validation-end hook, compute the main metric via
nodes.main_metric_reference.compute() there (ensuring it’s not called before
validation completes), and call scheduler.step(value) for non-loss modes or
scheduler.step(loss) only when you have the correct training loss signal; keep
other schedulers' scheduler.step() behavior unchanged. Ensure code references:
training_step (remove block), nodes.main_metric_reference.compute(), and the
schedulers iteration (re-add in the validation-end hook).

---

Nitpick comments:
In `@tests/integration/test_finetuning.py`:
- Around line 552-553: Remove the leftover authoring markers by deleting the
stray "# CHECK" comments immediately above the test functions
test_inherits_omitted_optimizer_and_scheduler and
test_inherits_name_and_merges_params_when_name_is_missing; ensure no other
sentinel comments remain in that test file and run the test suite to confirm
nothing relied on those markers.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b3e28619-c0c4-4caa-9147-a38605033fc9

📥 Commits

Reviewing files that changed from the base of the PR and between fdf1ed4 and 83885f1.

📒 Files selected for processing (10)
  • configs/README.md
  • luxonis_train/config/config.py
  • luxonis_train/config/predefined_models/base_predefined_model.py
  • luxonis_train/lightning/luxonis_lightning.py
  • luxonis_train/lightning/utils.py
  • luxonis_train/nodes/heads/ocr_ctc_head.py
  • luxonis_train/strategies/base_strategy.py
  • luxonis_train/strategies/triple_lr_sgd.py
  • tests/integration/test_finetuning.py
  • tests/unittests/test_config.py
🚧 Files skipped from review as they are similar to previous changes (5)
  • tests/unittests/test_config.py
  • configs/README.md
  • luxonis_train/nodes/heads/ocr_ctc_head.py
  • luxonis_train/config/config.py
  • luxonis_train/config/predefined_models/base_predefined_model.py

Comment thread luxonis_train/lightning/utils.py Outdated
Comment thread tests/integration/test_finetuning.py Outdated
@luxonis luxonis deleted a comment from coderabbitai Bot Jun 8, 2026
@luxonis luxonis deleted a comment from coderabbitai Bot Jun 8, 2026
@luxonis luxonis deleted a comment from coderabbitai Bot Jun 8, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
luxonis_train/lightning/utils.py (2)

1061-1067: ⚠️ Potential issue | 🟡 Minor | ⚡ Quick win

Config mutation could cause side effects; also fix warning message formatting.

Line 1063 mutates cfg_scheduler.params in place. If the same SchedulerConfig instance is reused or inspected later, the mutation persists unexpectedly.

Additionally, line 1065-1066 has a missing space: the string should be "'CosineAnnealingLR'. Automatically".

Proposed fix
     if cfg_scheduler.name == "CosineAnnealingLR":
         if "T_max" not in cfg_scheduler.params:
-            cfg_scheduler.params["T_max"] = cfg.trainer.epochs
+            cfg_scheduler = SchedulerConfig(
+                name=cfg_scheduler.name,
+                params={**cfg_scheduler.params, "T_max": cfg.trainer.epochs},
+            )
             logger.warning(
-                "`T_max` was not set for 'CosineAnnealingLR'"
-                "Automatically setting `T_max` to number of epochs."
+                "`T_max` was not set for 'CosineAnnealingLR'. "
+                "Automatically setting `T_max` to number of epochs."
             )
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@luxonis_train/lightning/utils.py` around lines 1061 - 1067, The code mutates
cfg_scheduler.params in place which can cause unexpected side effects; instead
create a shallow copy of the params dict for the scheduler (e.g., new_params =
dict(cfg_scheduler.params)), set new_params["T_max"] = cfg.trainer.epochs when
missing, and assign the copy back to cfg_scheduler.params so the original object
isn’t mutated; also fix the logger.warning message in the block to include the
missing space/period so it reads "'CosineAnnealingLR'. Automatically setting
`T_max` to number of epochs." and reference the cfg_scheduler, params,
cfg.trainer.epochs, and logger.warning symbols when making the change.

561-637: ⚠️ Potential issue | 🟠 Major | ⚡ Quick win

Missing AIMETCallback integration in centralized callback builder.

The new Nodes.build_callbacks method does not include the AIMETCallback logic that exists in the module-level build_callbacks function (lines 738-739). Since LuxonisLightningModule.configure_callbacks calls self.nodes.build_callbacks(...), the AIMETCallback will never be added when cfg.exporter.aimet.active is True.

Proposed fix - add AIMETCallback before returning
+        if self.cfg.exporter.aimet.active:
+            callbacks.append(AIMETCallback())
+
         return callbacks
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@luxonis_train/lightning/utils.py` around lines 561 - 637, The
Nodes.build_callbacks method omits the AIMETCallback logic, so when
cfg.exporter.aimet.active is True the AIMETCallback never gets added; modify the
build_callbacks method to mirror the module-level build_callbacks by checking
self.cfg.exporter.aimet.active (or cfg.exporter.aimet.active) and appending an
AIMETCallback instance before returning callbacks (use the existing
AIMETCallback class name and same construction used in the module-level
build_callbacks), ensuring this happens regardless of other callback logic so
LuxonisLightningModule.configure_callbacks receives the AIMETCallback.
🧹 Nitpick comments (1)
luxonis_train/lightning/utils.py (1)

702-769: Consider deprecating/removing the unused module-level build_callbacks

LuxonisLightningModule.configure_callbacks returns self.nodes.build_callbacks(...), and there are no internal imports/usages of the module-level build_callbacks in luxonis_train/lightning/utils.py (only the definitions themselves appear). If it’s not a supported public API, remove it or turn it into a deprecated wrapper/alias to avoid future divergence.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@luxonis_train/lightning/utils.py` around lines 702 - 769, The module-level
function build_callbacks appears unused externally and duplicates
Nodes.build_callbacks (LuxonisLightningModule.configure_callbacks already calls
self.nodes.build_callbacks); either remove this module-level build_callbacks or
make it a tiny deprecated wrapper that forwards to Nodes.build_callbacks while
emitting a deprecation warning. Locate the function build_callbacks in
luxonis_train/lightning/utils.py and either delete it and update any external
references, or replace its body with a call to nodes.build_callbacks (preserving
the same signature) and add a clear DeprecationWarning/log message mentioning
that callers should use Nodes.build_callbacks (refer to
LuxonisLightningModule.configure_callbacks for the existing call pattern).
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@luxonis_train/lightning/utils.py`:
- Around line 156-165: The override of NodeWrapper.train is not calling
super().train(mode), so self.training won't be updated; modify the train method
(NodeWrapper.train) to call super().train(mode) before/after propagating mode to
self.module, each loss in self.losses.values(), each metric in
self.metrics.values(), and each visualizer in self.visualizers.values(),
ensuring self.training reflects the new state while still setting training on
the wrapped module and subcomponents.

---

Outside diff comments:
In `@luxonis_train/lightning/utils.py`:
- Around line 1061-1067: The code mutates cfg_scheduler.params in place which
can cause unexpected side effects; instead create a shallow copy of the params
dict for the scheduler (e.g., new_params = dict(cfg_scheduler.params)), set
new_params["T_max"] = cfg.trainer.epochs when missing, and assign the copy back
to cfg_scheduler.params so the original object isn’t mutated; also fix the
logger.warning message in the block to include the missing space/period so it
reads "'CosineAnnealingLR'. Automatically setting `T_max` to number of epochs."
and reference the cfg_scheduler, params, cfg.trainer.epochs, and logger.warning
symbols when making the change.
- Around line 561-637: The Nodes.build_callbacks method omits the AIMETCallback
logic, so when cfg.exporter.aimet.active is True the AIMETCallback never gets
added; modify the build_callbacks method to mirror the module-level
build_callbacks by checking self.cfg.exporter.aimet.active (or
cfg.exporter.aimet.active) and appending an AIMETCallback instance before
returning callbacks (use the existing AIMETCallback class name and same
construction used in the module-level build_callbacks), ensuring this happens
regardless of other callback logic so LuxonisLightningModule.configure_callbacks
receives the AIMETCallback.

---

Nitpick comments:
In `@luxonis_train/lightning/utils.py`:
- Around line 702-769: The module-level function build_callbacks appears unused
externally and duplicates Nodes.build_callbacks
(LuxonisLightningModule.configure_callbacks already calls
self.nodes.build_callbacks); either remove this module-level build_callbacks or
make it a tiny deprecated wrapper that forwards to Nodes.build_callbacks while
emitting a deprecation warning. Locate the function build_callbacks in
luxonis_train/lightning/utils.py and either delete it and update any external
references, or replace its body with a call to nodes.build_callbacks (preserving
the same signature) and add a clear DeprecationWarning/log message mentioning
that callers should use Nodes.build_callbacks (refer to
LuxonisLightningModule.configure_callbacks for the existing call pattern).
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 82bd1192-d9f0-46b6-a48b-925b38f0e0c0

📥 Commits

Reviewing files that changed from the base of the PR and between 466923f and 1a4e271.

📒 Files selected for processing (5)
  • configs/README.md
  • luxonis_train/config/config.py
  • luxonis_train/config/predefined_models/base_predefined_model.py
  • luxonis_train/lightning/luxonis_lightning.py
  • luxonis_train/lightning/utils.py
✅ Files skipped from review due to trivial changes (1)
  • configs/README.md
🚧 Files skipped from review as they are similar to previous changes (3)
  • luxonis_train/config/config.py
  • luxonis_train/config/predefined_models/base_predefined_model.py
  • luxonis_train/lightning/luxonis_lightning.py

coderabbitai[bot]

This comment was marked as resolved.

@codecov

codecov Bot commented Jun 8, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 92.48021% with 57 lines in your changes missing coverage. Please review.
✅ Project coverage is 65.24%. Comparing base (9b17d5b) to head (e84a412).
✅ All tests successful. No failed tests found.

Files with missing lines Patch % Lines
luxonis_train/lightning/luxonis_lightning.py 69.23% 28 Missing ⚠️
luxonis_train/lightning/utils.py 84.61% 10 Missing ⚠️
tests/integration/test_predefined_models.py 14.28% 6 Missing ⚠️
luxonis_train/core/utils/aimet_utils.py 73.33% 4 Missing ⚠️
tests/unittests/test_finetuning/_helpers.py 96.82% 4 Missing ⚠️
tests/unittests/test_aimet_utils.py 95.65% 2 Missing ⚠️
tests/unittests/test_finetuning/test_strategy.py 98.11% 2 Missing ⚠️
luxonis_train/strategies/triple_lr_sgd.py 97.50% 1 Missing ⚠️

❗ There is a different number of reports uploaded between BASE (9b17d5b) and HEAD (e84a412). Click for more details.

HEAD has 4 uploads less than BASE
Flag BASE (9b17d5b) HEAD (e84a412)
4 0
Additional details and impacted files
@@             Coverage Diff             @@
##             main     #358       +/-   ##
===========================================
- Coverage   93.71%   65.24%   -28.48%     
===========================================
  Files         269      275        +6     
  Lines       13175    13764      +589     
===========================================
- Hits        12347     8980     -3367     
- Misses        828     4784     +3956     
Flag Coverage Δ
unit 65.24% <92.48%> (?)

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation enhancement New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants