Core Concepts¶
CAMPD is built around a flexible, modular architecture designed to separate the definition of physical components from their configuration and instantiation.
Registry System¶
The framework uses a registry pattern to enable configuration-driven component selection. This means you do not need to alter hardcoded imports when testing different models, experiments, or datasets; you simply update a string in a YAML file.
Each category of component has its own Registry instance.
Registry |
Module |
Purpose |
|---|---|---|
|
|
Experiment runners (Train vs Inference) |
|
|
Generic |
|
|
Denoising networks inside the Diffusion model |
|
|
Context encoder networks |
|
|
Torch loss functions ( |
|
|
Training callbacks for metrics and operations |
|
|
Generation and logging of periodic summaries |
|
|
Implementation of diffusion loss steps |
|
|
Inference validation logic |
Custom components can self-register using decorators:
from campd.training.registry import CALLBACKS
@CALLBACKS.register("MyCallback")
class MyCallback(Callback):
...
How it works under the hood: For a registry string (e.g., "MyCallback") to be resolved, the module containing that class MUST be imported before the registry lookup occurs. For built-in CAMPD components, this is automatically handled by campd/all_imports.py when an experiment starts. For your own custom classes, you must use the YAML dependencies key (see Configuration sections).
The Spec Pattern¶
A Spec (defined in utils/registry.py) is a Pydantic model that describes exactly how to build an object from a configuration.
Because we decouple instantiation from configuration, a Spec allows you to declare dynamic pipelines using either direct constructor arguments or factory methods.
Init Mode (Direct kwargs)¶
Pass arguments directly to an imported class’s __init__ constructor.
optimizer:
cls: "torch.optim.Adam" # Full import path
init:
lr: 1.0e-4
weight_decay: 0.0
Config Mode (Factory method)¶
Certain complex objects (like Objectives or Modules) benefit from deeply nested dictionaries validating their properties. Using config, the class must implement a @classmethod def from_config(cls, cfg): factory to handle initialization.
objective:
cls: "DiffusionObjective" # Registry key
config:
loss_fn:
cls: "torch.nn.MSELoss"
init:
reduction: "mean"
The system first checks if cls is a known registry key. If not, it attempts to resolve it as a standard Python import path (pkg.module.ClassName).
Configuration and Attribute Propagation¶
Configurations in CAMPD are validated using Pydantic V2. A major feature of our configuration structure is attribute propagation: parent-level configurations automatically push matching fields down to their nested children if the child declares that field, keeping your YAML cleanly structured without excessive repetition.
For example, if the top-level Experiment configuration dictates device: "cuda:0", any child config (such as the Dataset config or Trainer config) that explicitly requests a device property will automatically inherit "cuda:0" without you needing to duplicate it in the YAML.