Skip to content

factory

orchard.architectures.factory

Models Factory Module.

Implements the Factory Pattern using a registry-based approach to decouple model instantiation from execution logic. Architectures are dynamically adapted to geometric constraints (channels, classes) resolved at runtime.

Architecture:

  • Registry Pattern: Internal _MODEL_REGISTRY maps names to builders
  • Dynamic Adaptation: Structural parameters derived from DatasetConfig
  • Device Management: Automatic model transfer to target accelerator

Key Components:

  • get_model: Factory function for architecture resolution and instantiation
  • _MODEL_REGISTRY: Internal mapping of architecture names to builders
Example

from orchard.architectures.factory import get_model model = get_model(device, dataset_cfg=cfg.dataset, arch_cfg=cfg.architecture) print(f"Parameters: {sum(p.numel() for p in model.parameters()):,}")

get_model(device, dataset_cfg, arch_cfg, verbose=True)

Factory function to resolve, instantiate, and prepare architectures.

It maps configuration identifiers to specific builder functions via an internal registry. Structural parameters like input channels and class cardinality are derived from the 'effective' geometry resolved by the DatasetConfig.

Parameters:

Name Type Description Default
device device

Hardware accelerator target.

required
dataset_cfg DatasetConfig

Dataset sub-config with resolved metadata.

required
arch_cfg ArchitectureConfig

Architecture sub-config with model selection.

required
verbose bool

If True, emit builder-internal INFO logging.

True

Returns:

Type Description
Module

nn.Module: The instantiated model synchronized with the target device.

Example

model = get_model(device, dataset_cfg=cfg.dataset, arch_cfg=cfg.architecture)

Raises:

Type Description
ValueError

If the requested architecture is not found in the registry.

Source code in orchard/architectures/factory.py
def get_model(
    device: torch.device,
    dataset_cfg: DatasetConfig,
    arch_cfg: ArchitectureConfig,
    verbose: bool = True,
) -> nn.Module:
    """
    Factory function to resolve, instantiate, and prepare architectures.

    It maps configuration identifiers to specific builder functions via an
    internal registry. Structural parameters like input channels and class
    cardinality are derived from the 'effective' geometry resolved by
    the DatasetConfig.

    Args:
        device: Hardware accelerator target.
        dataset_cfg: Dataset sub-config with resolved metadata.
        arch_cfg: Architecture sub-config with model selection.
        verbose: If True, emit builder-internal INFO logging.

    Returns:
        nn.Module: The instantiated model synchronized with the target device.

    Example:
        >>> model = get_model(device, dataset_cfg=cfg.dataset, arch_cfg=cfg.architecture)

    Raises:
        ValueError: If the requested architecture is not found in the registry.
    """
    # Resolve structural dimensions from sub-configs
    in_channels = dataset_cfg.effective_in_channels
    num_classes = dataset_cfg.num_classes
    model_name_lower = arch_cfg.name.lower()

    if verbose:
        logger.info(
            "%s%s %-18s: %s | Input: %dx%dx%d | Output: %d classes",
            LogStyle.INDENT,
            LogStyle.ARROW,
            "Architecture",
            arch_cfg.name,
            dataset_cfg.img_size,
            dataset_cfg.img_size,
            in_channels,
            num_classes,
        )

    # Instance construction and adaptation.
    # When verbose=False (e.g. export phase), suppress builder-internal INFO logs
    # to avoid duplicating messages already shown during training.
    _prev_level = logger.level
    if not verbose:
        logger.setLevel(logging.WARNING)
    try:
        with _suppress_download_noise():
            model = _dispatch_builder(
                model_name_lower, num_classes, in_channels, arch_cfg, dataset_cfg.resolution
            )
    finally:
        logger.setLevel(_prev_level)

    # Centralised device placement (builders stay device-agnostic)
    model = model.to(device)

    # Parameter telemetry
    if verbose:
        total_params = sum(p.numel() for p in model.parameters())
        logger.info(
            "%s%s %-18s: %s | Parameters: %s",
            LogStyle.INDENT,
            LogStyle.ARROW,
            "Deployed",
            str(device).upper(),
            f"{total_params:,}",
        )

    return model