Skip to main content

Minerva-OPT

Auto Release Deploy Docs

Hyperparameter optimization and ablation study extensions for Minerva, powered by Ray Tune.

Description

Minerva-OPT provides two Minerva-compatible pipelines built on top of Ray Tune and PyTorch Lightning:

  • RayHyperParameterSearch — runs distributed hyperparameter sweeps with support for random search, grid search, and Bayesian optimization (via HyperOpt), with early stopping through the ASHA scheduler.
  • AblationStudyPipeline — trains a full-model baseline alongside a set of named ablation conditions over multiple seeds, then aggregates the results so you can measure each component's contribution with statistical confidence.

Features

  • Drop-in Minerva pipeline: both pipelines inherit from minerva.pipelines.base.Pipeline, integrating with Minerva's logging, reproducibility, and run-status tracking out of the box.
  • Flexible search algorithms: use Ray Tune's default random/grid search or pass any ray.tune.search.Searcher (e.g. HyperOptSearch for Bayesian optimization).
  • ASHA early stopping: trials are stopped early based on intermediate results; grace_period and max_t are derived automatically from max_epochs.
  • Ablation studies: measure the contribution of individual model components by comparing named conditions against a shared baseline across multiple seeds.
  • Distributed training: uses RayDDPStrategy and RayLightningEnvironment for multi-worker trials.
  • Configurable checkpointing: interval-based or keep-only-last strategies, scored on the target metric.

Installation

Requires Python 3.10+.

With uv (recommended)

uv pip install minerva-opt

With pip

pip install minerva-opt

To use Bayesian optimization via HyperOpt, install the optional extra:

pip install "minerva-opt[hyperopt]"

Usage

Hyperparameter search

Random / grid search

from ray import tune
from minerva_opt import RayHyperParameterSearch

search_space = {
    "learning_rate": tune.loguniform(1e-4, 1e-1),
    "hidden_size": tune.choice([64, 128, 256]),
}

pipeline = RayHyperParameterSearch(
    model=MyLightningModel,  # class, not instance — instantiated per trial as MyLightningModel(**config)
    search_space=search_space,
    log_dir="logs/",
)

results = pipeline.run(data=my_data_module, num_samples=20, max_epochs=50)
best = results.get_best_result()
print(best.config)

Bayesian optimization with HyperOpt

from ray.tune.search.hyperopt import HyperOptSearch

pipeline = RayHyperParameterSearch(
    model=MyLightningModel,
    search_space=search_space,
)

results = pipeline.run(
    data=my_data_module,
    search_alg=HyperOptSearch(),
    num_samples=30,
    max_epochs=100,
    tuner_metric="val_loss",
    tuner_mode="min",
)

Testing the best model after search

# Run search first, then test using the best checkpoint automatically
results = pipeline.run(data=my_data_module, num_samples=20, max_epochs=50)
pipeline.run(data=my_data_module, task="test")

# Or test from an explicit checkpoint path
pipeline.run(data=my_data_module, task="test", ckpt_path="path/to/model.ckpt")

Resuming an interrupted search

pipeline.run(
    data=my_data_module,
    restore_path="logs/TorchTrainer_2024-01-01_00-00-00",
)

Key run() parameters

Parameter Default Description
data LightningDataModule for training and testing
task "search" "search" to run the sweep, "test" to evaluate best checkpoint
ckpt_path None Warm-start all trials from a checkpoint (search) or eval path (test)
data_factory None Callable that returns a fresh LightningDataModule per trial
num_samples 10 Number of trials to run
max_epochs 100 Max epochs per trial
tuner_metric "val_loss" Metric to optimize
tuner_mode "min" "min" or "max"
search_alg None Any ray.tune.search.Searcher; None = random search
max_concurrent 4 Max concurrent trials (when using a search_alg)
scheduler ASHA Override the trial scheduler
scaling_config Auto-detected (GPU or CPU) Override Ray ScalingConfig
resources_per_worker {"GPU": 1} when GPU detected Custom resource dict, e.g. {"GPU": 0.5} for fractional GPU
checkpoint_interval 1 Save a checkpoint every N epochs
num_checkpoints_to_keep 1 Number of top checkpoints to retain per trial
restore_path None Path to a Ray experiment dir to resume an interrupted search
debug_mode False Disable checkpointing for fast iteration

GPU detection: when scaling_config is not provided, the pipeline auto-detects GPU availability. A UserWarning is emitted if falling back to CPU. Pass an explicit scaling_config to suppress it.


Ablation studies

AblationStudyPipeline trains a baseline condition and a set of named ablation conditions — each being the baseline with one or more components removed or altered — across multiple seeds, then aggregates the results for statistical comparison.

Defining conditions

You supply a baseline_config (the complete config for your full model) and an ablations dict mapping condition names to override dicts. The pipeline merges them automatically:

baseline_config = {"lr": 1e-3, "dropout": 0.2, "use_attention": True, "hidden_size": 128}
ablations       = {"no_attention": {"use_attention": False}}

# Internally becomes:
# baseline     → {"lr": 1e-3, "dropout": 0.2, "use_attention": True,  "hidden_size": 128}
# no_attention → {"lr": 1e-3, "dropout": 0.2, "use_attention": False, "hidden_size": 128}

The key "baseline" is reserved and added automatically — passing it inside ablations raises a ValueError.

Sweeping multiple values for one parameter

To test several values of a single parameter without writing a separate condition for each, pass a list as the override value. The pipeline expands it into one named condition per value using the pattern "{name}_{value}":

ablations = {
    "dropout": {"dropout": [0.2, 0.5, 0.8]},  # expands to dropout_0.2, dropout_0.5, dropout_0.8
    "no_attention": {"use_attention": False},
}
# Produces 5 conditions total: baseline, dropout_0.2, dropout_0.5, dropout_0.8, no_attention

Constraint: only one key per condition entry may be a list. Passing two list-valued keys in the same entry raises ValueError — use separate entries or RayHyperParameterSearch for multi-parameter grid search.

Running the study

from minerva_opt import AblationStudyPipeline

pipeline = AblationStudyPipeline(
    model=MyLightningModel,
    baseline_config={
        "lr": 1e-3,
        "dropout": 0.2,
        "use_attention": True,
        "hidden_size": 128,
    },
    ablations={
        "no_attention": {"use_attention": False},
        "high_dropout":  {"dropout": 0.5},
        "small_model":   {"hidden_size": 64},
    },
    log_dir="logs/ablation",
    seed=0,
)

# 4 conditions × 5 seeds = 20 trials; no early stopping
results = pipeline.run(
    data=my_data_module,
    num_seeds=5,
    max_epochs=30,
    tuner_metric="val_loss",
    tuner_mode="min",
)

Analysing results

pipeline.run() returns an AblationResults object:

# Mean ± std of every logged metric per condition
print(results.summary())
#                val_loss_mean  val_loss_std
# baseline                0.21          0.01
# no_attention            0.27          0.02
# high_dropout            0.23          0.01
# small_model             0.25          0.02

# Signed improvement vs baseline — positive means better than baseline
print(results.delta_from_baseline())
# baseline         0.00
# no_attention    -0.06   ← most important component
# high_dropout    -0.02
# small_model     -0.04

# Rank components by impact
delta = results.delta_from_baseline()
print(delta.sort_values())   # most negative = most important

# Access the underlying Ray ResultGrid for custom analysis
for r in results.raw:
    cfg = r.config["train_loop_config"]
    print(cfg["condition_name"], cfg["ablation_seed"], r.metrics["val_loss"])

Loading a condition's best checkpoint

import os

ckpt = results.best_checkpoint("no_attention")
with ckpt.as_directory() as ckpt_dir:
    model = MyLightningModel.load_from_checkpoint(
        os.path.join(ckpt_dir, "checkpoint.ckpt")
    )

Testing a condition on the test set

# Evaluate the baseline (default)
pipeline.run(data=my_data_module, task="test")

# Evaluate a specific ablation condition
pipeline.run(data=my_data_module, task="test", condition="no_attention")

Key run() parameters

Parameter Default Description
data LightningDataModule for training and testing
task "ablate" "ablate" to run the study, "test" to evaluate
num_seeds 5 Independent seeds per condition
max_epochs 100 Training epochs per trial (no early stopping)
tuner_metric "val_loss" Metric logged by the model and used to rank seeds
tuner_mode "min" "min" or "max"
ckpt_path None Optional warm-start checkpoint forwarded to trainer.fit
condition "baseline" Which condition to evaluate when task="test"
data_factory None Callable returning a fresh LightningDataModule per trial
scaling_config Auto-detected Ray ScalingConfig
resources_per_worker {"GPU": 1} GPU resource dict used when auto-creating ScalingConfig
checkpoint_interval 1 Save a checkpoint every N epochs
num_checkpoints_to_keep 1 Checkpoints retained per trial
debug_mode False Disables checkpointing for fast iteration

Requirements

  • minerva >= 0.3.10b0
  • ray[tune] >= 2.55
  • hyperopt >= 0.2.7 (optional — only needed for HyperOptSearch)

Documentation

Full documentation including a detailed tutorial, API reference, and troubleshooting guide is available at gabrielbg0.github.io/Minerva-OPT.

License

MIT License. See LICENSE for details.

Contact

For questions or bug reports, open an issue on the GitHub issue tracker.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

minerva_opt-1.3.0.tar.gz (25.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

minerva_opt-1.3.0-py3-none-any.whl (22.0 kB view details)

Uploaded Python 3

File details

Details for the file minerva_opt-1.3.0.tar.gz.

File metadata

  • Download URL: minerva_opt-1.3.0.tar.gz
  • Upload date:
  • Size: 25.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for minerva_opt-1.3.0.tar.gz
Algorithm Hash digest
SHA256 bb146b078e4b495c082c2d3fd93c6548f19cfd699c3db926f89b3459fd2cc1ea
MD5 37ba9974815af7d47f0c55a6a67d6580
BLAKE2b-256 5e77cdfa5f3fb7372ad682aa2ccef5fe7dd9a4fab23856f2fced015a0dcdd309

See more details on using hashes here.

Provenance

The following attestation bundles were made for minerva_opt-1.3.0.tar.gz:

Publisher: auto-release.yml on GabrielBG0/Minerva-OPT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file minerva_opt-1.3.0-py3-none-any.whl.

File metadata

  • Download URL: minerva_opt-1.3.0-py3-none-any.whl
  • Upload date:
  • Size: 22.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for minerva_opt-1.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0b1336c7299ba3cac393f51eecdfd4316d45af2b879a07d9f11794227505b9f1
MD5 c465f2cd4f2bfd2929c253a25f8de86a
BLAKE2b-256 57409fb42ae640f595072c40b0f03c24fa6e249207850ca8d60c5555e38a26d4

See more details on using hashes here.

Provenance

The following attestation bundles were made for minerva_opt-1.3.0-py3-none-any.whl:

Publisher: auto-release.yml on GabrielBG0/Minerva-OPT

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page