Skip to content

optuna_config

orchard.core.config.optuna_config

Optuna Optimization Configuration Schema.

Pydantic v2 schema defining Optuna study parameters, search strategies, pruning policies, storage backend configuration, and configurable search space bounds.

Search Space Overrides:

  • FloatRange / IntRange: Typed bounds for continuous/discrete parameters.
  • SearchSpaceOverrides: Aggregates all search ranges with domain defaults. Overrides are applied by SearchSpaceRegistry at trial sampling time.

FloatRange

Bases: BaseModel

Typed bounds for a continuous hyperparameter search range.

Attributes:

Name Type Description
low float

Lower bound (inclusive).

high float

Upper bound (inclusive).

log bool

If True, sample in log-uniform distribution.

check_bounds()

Validate low < high.

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def check_bounds(self) -> "FloatRange":
    """
    Validate low < high.
    """
    if self.low >= self.high:
        raise OrchardConfigError(
            f"FloatRange low ({self.low}) must be strictly less than high ({self.high})"
        )
    return self

IntRange

Bases: BaseModel

Typed bounds for a discrete hyperparameter search range.

Attributes:

Name Type Description
low int

Lower bound (inclusive).

high int

Upper bound (inclusive).

check_bounds()

Validate low < high.

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def check_bounds(self) -> "IntRange":
    """
    Validate low < high.
    """
    if self.low >= self.high:
        raise OrchardConfigError(
            f"IntRange low ({self.low}) must be strictly less than high ({self.high})"
        )
    return self

SearchSpaceOverrides

Bases: BaseModel

Configurable bounds for Optuna hyperparameter search ranges.

Provides sensible defaults for image classification while allowing full customization via YAML. Each field maps 1:1 to a parameter sampled by SearchSpaceRegistry.

Example YAML::

optuna:
  search_space_overrides:
    learning_rate:
      low: 1e-4
      high: 1e-1
      log: true
    batch_size_low_res: [32, 64, 128]

OptunaConfig

Bases: BaseModel

Optuna hyperparameter optimization study configuration.

Defines search strategy, pruning policy, budget, and storage backend for automated hyperparameter tuning.

Attributes:

Name Type Description
study_name str

Identifier for the Optuna study.

n_trials PositiveInt

Total number of optimization trials to run.

epochs PositiveInt

Training epochs per trial (typically shorter than final training).

timeout NonNegativeInt | None

Maximum optimization time in seconds (None=unlimited).

direction Literal['maximize', 'minimize']

Whether to 'maximize' or 'minimize' the metric.

sampler_type Literal['tpe', 'cmaes', 'random']

Sampling algorithm ('tpe', 'cmaes', 'random').

search_space_preset Literal['quick', 'full']

Predefined search space ('quick', 'full', etc.).

enable_model_search bool

Include architecture in search space.

model_pool list[str] | None

Restrict model search to these architectures (None=all).

enable_early_stopping bool

Stop study when target performance reached.

early_stopping_threshold float | None

Metric threshold for early stopping.

early_stopping_patience PositiveInt

Consecutive trials meeting threshold before stop.

enable_pruning bool

Enable early termination of unpromising trials.

pruner_type Literal['median', 'percentile', 'hyperband', 'none']

Pruning algorithm ('median', 'percentile', 'hyperband').

pruning_warmup_epochs NonNegativeInt

Minimum epochs before pruning can trigger.

storage_type Literal['sqlite', 'memory', 'postgresql']

Backend for study persistence ('sqlite', 'memory', 'postgresql').

storage_path ValidatedPath | None

Path to SQLite database file (auto-generated if None).

postgresql_url str | None

PostgreSQL connection string (required when storage_type='postgresql').

n_jobs int

Parallel trial execution (1=sequential, -1=all cores).

load_if_exists bool

Resume existing study or create new.

show_progress_bar bool

Display tqdm progress during optimization.

save_plots bool

Generate optimization visualization plots.

save_best_config bool

Export best trial hyperparameters as YAML.

search_space_overrides SearchSpaceOverrides

Configurable bounds for search ranges.

check_model_pool()

Validate model_pool constraints.

Raises:

Type Description
OrchardConfigError

If model_pool set without enable_model_search, or contains fewer than 2 entries.

Returns:

Type Description
'OptunaConfig'

Validated OptunaConfig instance.

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def check_model_pool(self) -> "OptunaConfig":
    """
    Validate model_pool constraints.

    Raises:
        OrchardConfigError: If model_pool set without enable_model_search,
                    or contains fewer than 2 entries.

    Returns:
        Validated OptunaConfig instance.
    """
    if self.model_pool is not None:
        if not self.enable_model_search:
            raise OrchardConfigError("model_pool requires enable_model_search=True")
        if len(self.model_pool) < 2:
            raise OrchardConfigError(
                "model_pool must contain at least 2 architectures for meaningful search"
            )
    return self

validate_storage()

Validate storage backend configuration.

Raises:

Type Description
OrchardConfigError

If PostgreSQL selected without postgresql_url, or if postgresql_url set with non-postgresql storage_type, or if postgresql_url has an invalid scheme.

Returns:

Type Description
'OptunaConfig'

Validated OptunaConfig instance.

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def validate_storage(self) -> "OptunaConfig":
    """
    Validate storage backend configuration.

    Raises:
        OrchardConfigError: If PostgreSQL selected without postgresql_url,
            or if postgresql_url set with non-postgresql storage_type,
            or if postgresql_url has an invalid scheme.

    Returns:
        Validated OptunaConfig instance.
    """
    if self.storage_type == "postgresql":
        if self.postgresql_url is None:
            raise OrchardConfigError(
                "PostgreSQL storage requires postgresql_url "
                "(e.g. postgresql://user:pass@host/db)"
            )
        if not self.postgresql_url.startswith(("postgresql://", "postgresql+")):
            raise OrchardConfigError(
                f"postgresql_url must start with 'postgresql://' or 'postgresql+', "
                f"got: '{self.postgresql_url[:30]}...'"
            )
    elif self.postgresql_url is not None:
        raise OrchardConfigError(
            f"postgresql_url is set but storage_type is '{self.storage_type}', "
            f"not 'postgresql'"
        )
    return self

check_pruning()

Validate pruning warmup is less than total epochs.

Raises:

Type Description
OrchardConfigError

If pruning_warmup_epochs >= epochs.

Returns:

Type Description
'OptunaConfig'

Validated OptunaConfig instance.

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def check_pruning(self) -> "OptunaConfig":
    """
    Validate pruning warmup is less than total epochs.

    Raises:
        OrchardConfigError: If pruning_warmup_epochs >= epochs.

    Returns:
        Validated OptunaConfig instance.
    """
    if self.enable_pruning and self.pruning_warmup_epochs >= self.epochs:
        raise OrchardConfigError(
            f"pruning_warmup_epochs ({self.pruning_warmup_epochs}) "
            f"must be < epochs ({self.epochs})"
        )
    return self

check_tqdm_flag()

Warn about potential tqdm corruption with parallel execution.

Returns:

Type Description
'OptunaConfig'

Validated OptunaConfig instance (with warning if applicable).

Source code in orchard/core/config/optuna_config.py
@model_validator(mode="after")
def check_tqdm_flag(self) -> "OptunaConfig":
    """
    Warn about potential tqdm corruption with parallel execution.

    Returns:
        Validated OptunaConfig instance (with warning if applicable).
    """
    if self.show_progress_bar and self.n_jobs != 1:
        warnings.warn("show_progress_bar=True with n_jobs!=1 may corrupt tqdm output.")
    return self

get_storage_url(paths)

Constructs storage URL for Optuna study.

Parameters:

Name Type Description Default
paths RunPaths

RunPaths instance providing database directory

required

Returns:

Type Description
str | None

Storage URL string (sqlite:// or postgresql://)

Source code in orchard/core/config/optuna_config.py
def get_storage_url(self, paths: RunPaths) -> str | None:
    """
    Constructs storage URL for Optuna study.

    Args:
        paths (RunPaths): RunPaths instance providing database directory

    Returns:
        Storage URL string (sqlite:// or postgresql://)
    """
    if self.storage_type == "memory":
        return None

    if self.storage_type == "sqlite":
        if self.storage_path:
            db_path = self.storage_path
        else:
            # Use RunPaths database path
            db_path = paths.get_db_path()
        return f"sqlite:///{db_path}"

    if self.storage_type == "postgresql":
        return self.postgresql_url

    raise OrchardConfigError(f"Unknown storage type: {self.storage_type}")