Skip to content

refactor: BuilderArgs Protocol + ModelConfig/TrainConfig field deduplication#841

Open
Borda wants to merge 3 commits intodevelopfrom
refactor/builder-protocol-config-dedup
Open

refactor: BuilderArgs Protocol + ModelConfig/TrainConfig field deduplication#841
Borda wants to merge 3 commits intodevelopfrom
refactor/builder-protocol-config-dedup

Conversation

@Borda
Copy link
Member

@Borda Borda commented Mar 20, 2026

What does this PR do?

Item #7 — BuilderArgs Protocol:

  • Add src/rfdetr/models/_types.py with @runtime_checkable BuilderArgs Protocol
    documenting the minimum attribute set for build_model() and
    build_criterion_and_postprocessors().
  • Annotate both builder functions with args: "BuilderArgs".
  • Export BuilderArgs from rfdetr.models.__all__.

Item #3 Phase A — field ownership deprecation warnings:

  • TrainConfig.group_detr, .ia_bce_loss, .segmentation_head, .num_select
    emit DeprecationWarning when explicitly set (ownership moves to ModelConfig
    in v1.9).
  • ModelConfig.cls_loss_coef emits DeprecationWarning when explicitly set
    (ownership moves to TrainConfig in v1.9).
  • Fix _namespace.py: num_select always reads from ModelConfig (fixes the
    silent regression where TrainConfig.num_select=300 overrode model-specific
    values of 100–200).
  • Fix _namespace.py: cls_loss_coef reads from TrainConfig by default, with
    backward-compat fallback to ModelConfig when explicitly set there and not on
    TrainConfig (Phase A transitional logic; Codex-supplied fix).

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • Refactoring (no functional changes)

Testing

  • I have tested this change locally
  • I have added/updated tests for this change

Additional Context

Borda and others added 2 commits March 20, 2026 23:26
…ication (PR 4)

Item #7 — BuilderArgs Protocol:
- Add `src/rfdetr/models/_types.py` with `@runtime_checkable BuilderArgs Protocol`
  documenting the minimum attribute set for `build_model()` and
  `build_criterion_and_postprocessors()`.
- Annotate both builder functions with `args: "BuilderArgs"`.
- Export `BuilderArgs` from `rfdetr.models.__all__`.

Item #3 Phase A — field ownership deprecation warnings:
- `TrainConfig.group_detr`, `.ia_bce_loss`, `.segmentation_head`, `.num_select`
  emit `DeprecationWarning` when explicitly set (ownership moves to `ModelConfig`
  in v1.9).
- `ModelConfig.cls_loss_coef` emits `DeprecationWarning` when explicitly set
  (ownership moves to `TrainConfig` in v1.9).
- Fix `_namespace.py`: `num_select` always reads from `ModelConfig` (fixes the
  silent regression where `TrainConfig.num_select=300` overrode model-specific
  values of 100–200).
- Fix `_namespace.py`: `cls_loss_coef` reads from `TrainConfig` by default, with
  backward-compat fallback to `ModelConfig` when explicitly set there and not on
  `TrainConfig` (Phase A transitional logic; Codex-supplied fix).

Tests: 20 new tests — Protocol structural checks, all 4 cls_loss_coef precedence
combinations, num_select regression guard, per-field deprecation warnings.

Co-Authored-By: Codex <noreply@openai.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…cope comment

- CHANGELOG: add [Unreleased] section with BuilderArgs addition, 5 deprecated
  TrainConfig/ModelConfig fields (v1.9 removal), and num_select regression fix.
- _types.py: add comment explaining why decoder_norm / dropout /
  num_feature_levels are intentionally absent from BuilderArgs (they are
  computed constants, not caller-supplied values).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings March 20, 2026 22:30
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR introduces a typed BuilderArgs protocol for model builder functions and implements/validates a Phase A transition of config field ownership between ModelConfig and TrainConfig (with deprecation warnings), including fixing num_select precedence in the builder namespace.

Changes:

  • Added BuilderArgs (typing.Protocol) and annotated build_model() / build_criterion_and_postprocessors() to accept it; exported via rfdetr.models.
  • Added DeprecationWarning emission when deprecated fields are explicitly set on the “wrong” config object.
  • Updated _namespace.build_namespace() to source num_select from ModelConfig unconditionally and to apply transitional precedence for cls_loss_coef; expanded tests and changelog accordingly.

Reviewed changes

Copilot reviewed 9 out of 9 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/rfdetr/models/_types.py Adds BuilderArgs Protocol describing builder inputs.
src/rfdetr/models/lwdetr.py Annotates builder functions to accept BuilderArgs.
src/rfdetr/models/__init__.py Re-exports BuilderArgs from rfdetr.models.
src/rfdetr/config.py Adds model/train config validators that emit deprecation warnings for field ownership transitions.
src/rfdetr/_namespace.py Fixes namespace forwarding for num_select and implements transitional cls_loss_coef precedence logic.
tests/test_namespace.py Adds tests for BuilderArgs satisfaction and for field ownership/precedence rules.
tests/training/test_args.py Updates tests to expect deprecation warnings for explicit deprecated field usage.
tests/models/test_config.py Adds coverage for deprecation warnings and non-warning defaults behavior.
CHANGELOG.md Documents the new Protocol, deprecations, and the num_select regression fix under Unreleased.
Comments suppressed due to low confidence (1)

src/rfdetr/models/lwdetr.py:356

  • build_model() is now typed as taking BuilderArgs, but later in this function it mutates args (e.g. setting args.num_feature_levels). If the stated goal is to eventually pass ModelConfig/TrainConfig directly, Pydantic configs forbid setting undeclared attributes, so this will break at runtime. Prefer computing derived values locally (or building a separate mutable namespace) instead of mutating the incoming args.
def build_model(args: "BuilderArgs"):
    # the `num_classes` naming here is somewhat misleading.
    # it indeed corresponds to `max_obj_id + 1`, where max_obj_id
    # is the maximum id for a class in your dataset. For example,
    # COCO has a max_obj_id of 90, so we pass `num_classes` to be 91.

@codecov
Copy link

codecov bot commented Mar 20, 2026

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 76%. Comparing base (3cd6898) to head (d50fa7e).

❌ Your project check has failed because the head coverage (76%) is below the target coverage (95%). You can increase the head coverage or adjust the target coverage.

Additional details and impacted files
@@          Coverage Diff           @@
##           develop   #841   +/-   ##
======================================
  Coverage       75%    76%           
======================================
  Files           92     93    +1     
  Lines         7148   7222   +74     
======================================
+ Hits          5383   5457   +74     
  Misses        1765   1765           
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants