Files
wehub-resource-sync 16031aae96
CPU tests Workflow / Testing (ubuntu-latest, 3.12) (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.13) (push) Failing after 0s
Mypy Type Check / Type Check (push) Failing after 0s
Docs/Test WorkFlow / Test docs build (push) Failing after 1s
PR Conflict Labeler / labeling (push) Failing after 1s
Dependency resolution / Resolve [tflite] extra — Python 3.12 (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.10) (push) Failing after 0s
Smoke Tests / try-all-models (ubuntu-latest, 3.13) (push) Failing after 1s
CPU tests Workflow / build-pkg (push) Failing after 1s
CPU tests Workflow / Testing (ubuntu-latest, 3.10) (push) Failing after 0s
CPU tests Workflow / Testing (ubuntu-latest, 3.11) (push) Failing after 0s
Smoke Tests / try-all-models (macos-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (macos-latest, 3.13) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.10) (push) Has been cancelled
Smoke Tests / try-all-models (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (macos-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.10) (push) Has been cancelled
CPU tests Workflow / Testing (windows-latest, 3.13) (push) Has been cancelled
CPU tests Workflow / testing-guardian (push) Has been cancelled
GPU tests Workflow / Testing (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:26:24 +08:00

113 lines
4.7 KiB
Python

# ------------------------------------------------------------------------
# RF-DETR
# Copyright (c) 2025 Roboflow. All Rights Reserved.
# Licensed under the Apache License, Version 2.0 [see LICENSE for details]
# ------------------------------------------------------------------------
"""Regression tests for keypoint config defaults and namespace forwarding."""
import pytest
from rfdetr._namespace import _namespace_from_configs
from rfdetr.config import (
KeypointTrainConfig,
RFDETRBaseConfig,
RFDETRKeypointPreviewConfig,
SegmentationTrainConfig,
)
def test_keypoint_config_defaults() -> None:
"""Default model/train keypoint configuration values should match the preview contract."""
model = RFDETRKeypointPreviewConfig()
train = KeypointTrainConfig(dataset_dir="/tmp")
assert model.use_grouppose_keypoints is True
assert model.dual_projector is True
assert model.dual_projector_kp_only is True
assert model.num_keypoints_per_class == [17]
assert model.positional_encoding_size == 576 // 12
assert train.keypoint_l1_loss_coef == pytest.approx(1.0)
assert train.keypoint_findable_loss_coef == pytest.approx(1.0)
assert train.keypoint_visible_loss_coef == pytest.approx(1.0)
assert train.keypoint_nll_loss_coef == pytest.approx(1.0)
assert train.cls_loss_coef == pytest.approx(2.0)
def test_keypoint_preview_config_person_schema() -> None:
"""Person-keypoint preview config must expose a person-only schema."""
model = RFDETRKeypointPreviewConfig()
assert model.num_keypoints_per_class == [17]
assert sum(model.num_keypoints_per_class) == 17
assert model.out_feature_indexes == [3, 6, 9, 12]
assert model.num_windows == 2
assert model.dec_layers == 4
assert model.patch_size == 12
assert model.resolution == 576
assert model.pretrain_weights == "rf-detr-keypoint-preview-xlarge.pth"
def test_keypoint_fields_propagate_to_namespace(tmp_path) -> None:
"""All keypoint config fields are forwarded through _namespace_from_configs."""
model = RFDETRKeypointPreviewConfig()
train = KeypointTrainConfig(
dataset_dir=str(tmp_path),
keypoint_flip_pairs=[0, 1, 2, 3],
keypoint_l1_loss_coef=1.5,
keypoint_findable_loss_coef=2.5,
keypoint_visible_loss_coef=3.5,
keypoint_nll_loss_coef=4.5,
)
namespace = _namespace_from_configs(model, train)
assert namespace.use_grouppose_keypoints is True
assert namespace.keypoint_cross_attn is True
assert namespace.inter_instance_kp_attn is False
assert namespace.grouppose_keypoint_dim_downscale == 1
assert namespace.dual_projector is True
assert namespace.dual_projector_kp_only is True
assert namespace.num_keypoints_per_class == [17]
assert namespace.keypoint_flip_pairs == [0, 1, 2, 3]
assert namespace.keypoint_l1_loss_coef == pytest.approx(1.5)
assert namespace.keypoint_findable_loss_coef == pytest.approx(2.5)
assert namespace.keypoint_visible_loss_coef == pytest.approx(3.5)
assert namespace.keypoint_nll_loss_coef == pytest.approx(4.5)
def test_keypoint_nll_loss_coef_default_restored_to_1_0() -> None:
"""keypoint_nll_loss_coef must default to 1.0 after the 0.5 revert.
The 0.5 default was introduced to dampen OKS@75 oscillation. It was later reverted to 1.0 to align with all other
keypoint loss terms (l1, findable, visible). This test guards against silent regressions.
"""
train = KeypointTrainConfig(dataset_dir="/tmp")
assert train.keypoint_nll_loss_coef == pytest.approx(1.0)
def test_segmentation_train_config_cls_loss_coef_default() -> None:
"""SegmentationTrainConfig.cls_loss_coef must default to 1.0, not the erroneous 5.0.
The 5.0 value was always present in SegmentationTrainConfig but was dead code pre-v1.7 (namespace builder read from
ModelConfig=1.0). The v1.7 TrainConfig ownership migration silently activated it. This test guards against re-
introducing that regression.
"""
tc = SegmentationTrainConfig(dataset_dir="/tmp")
assert tc.cls_loss_coef == pytest.approx(1.0)
def test_unknown_keypoint_fields_are_not_public_config_fields() -> None:
"""Private keypoint implementation fields are not accepted as public model config."""
with pytest.raises(ValueError, match="Unknown parameter"):
RFDETRBaseConfig(num_classes=1, keypoint_private_hidden_dim=256)
# KeypointTrainConfig (a TrainConfig subclass) uses extra="forbid", so unknown
# kwargs raise with a helpful message rather than being silently dropped.
with pytest.raises(ValueError, match="Unknown parameter"):
KeypointTrainConfig(
dataset_dir="/tmp",
keypoint_private_hidden_dim=256,
keypoint_private_loss_coef=1.0,
)