Migration to structured and validated configs - #3198
Merged
Conversation
21 tasks
deruyter92
force-pushed
the
feat/structured_configs
branch
5 times, most recently
from
February 4, 2026 11:04
b5f2fdc to
fdfec16
Compare
deruyter92
force-pushed
the
feat/structured_configs
branch
2 times, most recently
from
February 18, 2026 07:31
786653b to
46a0e56
Compare
…onverter_config.py Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
- reading breaks for corrupted yaml - added tests for prefered behavior that is currently not implemented (yaml safeloading and validating config keys)
This mixin provides methods for:
- Loading configurations from dictionaries or YAML files
- Validating configuration data against pydantic models
- Converting configurations to dictionaries
- Pretty printing configuration data
add imports from utils
- Introduced new configuration classes for inference, logging, model, pose, project, runner, and training settings. - Refactored data loading mechanisms to utilize new configuration structures. - Moved the multithreading and compilation options in inference configuration to the config module. - Typed configuration for logging. - Updated dataset loaders to accept model configurations directly or via file paths.
(The fields are kept identical to old multianimal project configs for now) move ProjectConfig to deeplabcut/core/config
…correct TypeAdapter usage)
The return value should be the dictionary, not the instantiated transforms
2 tasks
This was referenced May 29, 2026
deruyter92
marked this pull request as ready for review
June 18, 2026 09:32
deruyter92
marked this pull request as draft
June 18, 2026 09:33
…, field validation This commit introduces several refactors and simplifactions: 1. Settle with Pydantic BaseModel (no OmegaConf or Pydantic dataclasses, or Mixins) 2. Introduce a separate PoseMetadataConfig, rather than using a ProjectConfig as metadata field on the PoseConfig 3. Add a validation suite for field validators e.g. BodypartPair, UniqueStrList, etc 4. Clean up / update the schemas where necessary (e.g. default values.) 5. Better normalization / serializion for tuples, lists, ndArrays (WeightInitialization) 6. Simplify change tracking on the DLCBaseConfig 7. Simplify versioning migration: only `from_dict`, not on the full class 8. remove duplicate fields and add linting rule 9. add BaseConfig `set_nested` method 10. ProjectConfig: add convenience repair project path
Apply a set of small fixes and cleanup changes across multiple modules: - fix Path/string handling in weight_init - remove many redundant `pass` stubs in abstract classes and placeholders - adjust loop/range usages (camera calibration, tracklets, DataFrame index) - improve legacy-argument handling in Loader (DeprecationWarning with stacklevel, error messages) and infer model config path - reorder and add/remove imports where appropriate - avoid silently swallowing exceptions after printing (materialize, make_labeled_video) - use tuple form for startswith check in auxiliary functions - tweak test random.sample range; and other minor formatting/consistency tweaks. These changes are intended to improve correctness, clarity, and maintainability without altering core behavior. - Prevent notes on missing fields. - Fix yaml comments for nested config fields. - fix validation for None-type read_config_as_dict. - VersionedConfigs use default factories for PrivateAttrs. - add missing snapshot_prefix to runner (SA inference requires it). - fix some faulty default values for modelzoo config templates
1. Refactor PoseConfig: separate modules and add canonical build method. - Split enums into separate file - Split PoseMetadata into separate file - Split PafParamters into separate file - Add canonical build methods for structured configs: e.g. build from project config 2. Refactor make_pose_config: - build entire default dict for net_type from the yaml file, before validation. - deprecate `make_pytorch_test_config`, `make_pytorch_pose_config` and `make_basic_project_config`. 3. Refactor modelzoo - superanimal configs construction via build method
1. Add tests for centralized config edge cases Introduce tests/core/config/test_config_breakage.py covering pathological cases for the centralized config model. Tests exercise in-place nested mutation validation (xfail), dirty-state isolation between instances, change-note handling and alias-to-canonical mapping, nested YAML comments (xfail), and normalization/serialization of nested models containing Path and Enum values. Uses ProjectConfig, DLCBaseConfig and DLCVersionedConfig to assert expected dirty-tracking, logging, validation, and YAML output behaviors. add test for cross-field validation with bulk updates 2. fix invalid test imaug (faulty fixture) see DeepLabCut/UnitTestData#4 3. Update testscript_pytorch_multi_animal: ctd_conditions required for ctd shuffle. The documented primary workflow is: set conditions at shuffle / dataset creation, not defer until inference. This was not reflected in the test, and surfaced with the new structured configs. This commit makes the test in line with recommended workflow in API docstring; Config docs; BUCTD COLAB notebook; and GUI. -> ctd_conditions are passed at dataset creation time. making the shuffle a fully complete artefact, rather than somthing that requires patching in later API calls. 4. fix testscript multianimal transfer learning pass net_type when creating training dataset 5. add tests: resume training from existing snapshot add tests for pose config creation refactor test_pose_config_creation (test cases for migration to typed) update xfail for cross fields overrides remove comment tests fix test_apis_training make migrations fixtures to fix registry pollution use tmp instead of tempfile tests/core/config: catch expected DeprecationWarnings for aliases move TEST_DATA_DIR to fixture use centralized yaml loader instead of pyyaml update test_modify_train_test_cfg_sets_expected_values update documentation and tests for write_project_config update test_pose_config_creation copy dict instead of mutate update test_pose_config_creation, use centralized yaml loader add test for ProjectConfig bodypartslist update test_pose_config_creation separate testing of saving
expose get_yaml_loader get_yaml_dumper in core.config
…old API - export.py - deprecate update_config_by_dotpath and update_config - simplified schema DetectorDataConfig instead of DataConfig use centralized read_config in trainingsetmanipulation hook up trainsetmanipulation.py to typed ProjectConfig update callers of edit_config to use typed updates instead
Notable: revert default `box_score_thresh` in `DetectorModelConfig` currently a different box_score_thresh is used in inference (0.01) and evaluation (0.6), putting a default value in the config would change behavior. move deprecation.py from utils to core
deruyter92
marked this pull request as ready for review
June 24, 2026 14:58
C-Achard
self-requested a review
June 24, 2026 15:50
C-Achard
approved these changes
Jun 24, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This PR implements the features proposed in #3193, and will be the final PR for merging all changes from the feature branch, implemented in the smaller PRs #3190, #3191, #3194, etc..
Summary
Large refactor (~117 files, +7k/−1.5k lines) that introduces typed Pydantic configs for DLC, starting with project
config.yamland PyTorchpytorch_config.yaml. Config I/O is centralized indeeplabcut.core.config, and the PyTorch pipeline is wired to use the new typed configurations.Motivation
Config handling had grown organically: YAML I/O was spread across several modules, configs were plain dicts without a shared schema, and there was no single place to validate shape or types at load time. That made it easy for typos, type mismatches, and inconsistent defaults to slip through undetected until much later in the pipeline. It was also often unclear what each field was supposed to be, and configs were frequently patched in multiple places rather than built once up front — so it was hard to tell which component owned which settings, or when a config was truly complete versus still missing downstream additions.
This PR consolidates that into a clearer model: centralized I/O, validation at load time, typed configs with IDE support, and a versioning framework for future schema changes. Pose configs are built through canonical entry points (e.g. PoseConfig.build), after which the result is treated as fully initialized.
Scope
The current typed schema version 0 deliberately captures the existing config shape as closely as possible. This enables for round-trip compatibility. A future v1 migration could introduce a refined structure and naming (e.g. replacing different aliases to a single canonical name); but this is conisidered a separate topic and is out of scope for this PR. The migration infrastructure (
config_version, registered migrations, aliases) is included so v1 can be added later with a smooth-transition refactor. Note that currently deeper nested dicts, such as the model configuration passed to the registry builder, are kept as dictionaries because the large variety of models do not fit in a singe schema. In the future we may want to add separate hierarchical schemas for the models with clear discriminating fields if better validation per model is required.What's new
Typed config models
DLCBaseConfig— base for nested configs (data, inference, runner, etc.)DLCVersionedConfig— top-level configs with versioning and change trackingProjectConfig— typed projectconfig.yamlPoseConfig(+ nested configs) — typedpytorch_config.yamlTestConfig,WeightInitialization, and related helpersCore capabilities
extra="forbid")from_yaml,from_dict,from_any,to_yaml,to_dict(with optional normalization for serialization)cfg["key"],.get(),.update())select()/set_nested()Not everything is fully typed: some nested sections (e.g. model-specific parameters inside
ModelConfig) remain plain dicts so different architectures can keep their own flexible parameter sets.API changes
read_config()returnsProjectConfig(still re-exported fromauxiliaryfunctions)make_pytorch_pose_configand related factories are deprecated wrappers aroundPoseConfig.build/TestConfig.buildLoaderacceptsmodel_config(path, dict, orPoseConfig);model_config_pathstill works with a deprecation warningfrom_anyImportant behavioral changes
config.yamlraise validation errorsengine— defaults topytorch(was tensorflow)project_pathauto-repair — still corrected on load;read_configwrites back when needed!!python/tupletags are no longer auto-repairedNonerather than{}; call sites updated accordinglytorch.saveScope
deeplabcut/core/config/, PyTorch config package, and call sites across training, inference, export, modelzoo, metadata, and utilitiesTest changes
New tests (~3,400 lines)
tests/core/config/— base config, project config, YAML I/O, versioning, change tracking, edge casestest_pose_config_creation.py— parametrizedPoseConfig.buildwith v0-style YAML fixturestest_apis_training.py—train()respectsresume_training_fromtest_generalized_data_converter_config.py— modelzooProjectConfigtemplatesModified existing tests (11 files) — mostly to match typed configs:
ProjectConfig/PoseConfigfixtures and assertionstest_dataset.py: removed config mock onLoader— tests now use real config loadingtest_pose_multianimal_imgaug.py: fixture patched to satisfy new multi-animal validationruamelcallstest_make_pose_config.pyandtest_config_utils.pyare unchanged; new behavior is covered by the added tests.Test plan
tests/core/config/tests/pose_estimation_pytorch/config/test_pose_config_creation.py(runs on main as well)