Source code for orion.core.cli.hunt

#!/usr/bin/env python
"""
Module running the optimization command
=======================================

Gets an experiment and iterates over it until one of the exit conditions is met

"""

import logging

import orion.core
from orion.client.experiment import ExperimentClient
from orion.core.cli import base as cli
from orion.core.cli import evc as evc_cli
from orion.core.io import experiment_builder
from orion.core.utils import sigterm_as_interrupt
from orion.core.utils.exceptions import (
    BrokenExperiment,
    InexecutableUserScript,
    MissingResultFile,
)
from orion.core.utils.format_terminal import format_stats
from orion.core.worker.consumer import Consumer

log = logging.getLogger(__name__)
SHORT_DESCRIPTION = "Conducts hyperparameter optimization"
DESCRIPTION = """
This command starts hyperparameter optimization process for the user-provided model using the
configured optimization algorithm and search space.
"""


[docs]def add_subparser(parser): """Add the subparser that needs to be used for this command""" hunt_parser = parser.add_parser( "hunt", help=SHORT_DESCRIPTION, description=DESCRIPTION ) orion_group = cli.get_basic_args_group( hunt_parser, group_name="Hunt arguments", group_help="" ) orion.core.config.experiment.add_arguments( orion_group, rename=dict(max_broken="--exp-max-broken", max_trials="--exp-max-trials"), ) orion_group.add_argument( "--max-trials", type=int, metavar="#", help="(DEPRECATED) This argument will be removed in v0.3. Use --exp-max-trials instead", ) orion_group.add_argument( "--init-only", default=False, action="store_true", help="Only create the experiment and register in database, but do not execute any trial.", ) worker_args_group = hunt_parser.add_argument_group( "Worker arguments (optional)", description="Arguments to automatically resolved branching events.", ) orion.core.config.worker.add_arguments( worker_args_group, rename=dict(max_broken="--worker-max-broken", max_trials="--worker-max-trials"), ) evc_cli.get_branching_args_group(hunt_parser) cli.get_user_args_group(hunt_parser) hunt_parser.set_defaults(func=main) hunt_parser.set_defaults(help_empty=True) # Print help if command is empty return hunt_parser
COMPLETION_MESSAGE = """\ Hints ===== Info ---- To get more information on the experiment, run the command orion info --name {experiment.name} --version {experiment.version} """ NONCOMPLETED_MESSAGE = """\ Status ------ To get the status of the trials, run the command orion status --name {experiment.name} --version {experiment.version} For a detailed view with status of each trial listed, use the argument `--all` orion status --name {experiment.name} --version {experiment.version} --all """ # pylint:disable=unused-argument
[docs]def on_error(client, trial, error, worker_broken_trials): """If the script is not executable, don't waste time and raise right away""" if isinstance(error, (InexecutableUserScript, MissingResultFile)): raise error return True
# pylint:disable=too-many-arguments
[docs]def workon( experiment, n_workers=None, pool_size=None, max_trials=None, max_broken=None, max_idle_time=None, reservation_timeout=None, heartbeat=None, user_script_config=None, interrupt_signal_code=None, ignore_code_changes=None, executor=None, executor_configuration=None, idle_timeout=None, ): """Try to find solution to the search problem defined in `experiment`.""" # NOTE: Remove in v0.3.0 if max_idle_time is not None and reservation_timeout is None: reservation_timeout = max_idle_time consumer = Consumer( experiment, user_script_config, interrupt_signal_code, ignore_code_changes, ) client = ExperimentClient(experiment, heartbeat=heartbeat) if executor is None: executor = orion.core.config.worker.executor if executor_configuration is None: executor_configuration = orion.core.config.worker.executor_configuration log.debug("Starting workers") with client.tmp_executor(executor, n_workers=n_workers, **executor_configuration): try: client.workon( consumer, n_workers=n_workers, pool_size=pool_size, reservation_timeout=reservation_timeout, max_trials_per_worker=max_trials, max_broken=max_broken, trial_arg="trial", on_error=on_error, idle_timeout=idle_timeout, ) except BrokenExperiment as e: print(e) if client.is_done: print("Search finished successfully") print("\n" + format_stats(client)) print("\n" + COMPLETION_MESSAGE.format(experiment=client)) if not experiment.is_done: print(NONCOMPLETED_MESSAGE.format(experiment=client))
[docs]def main(args): """Build experiment and execute hunt command""" args["root"] = None args["leafs"] = [] # TODO: simplify when parameter parsing is refactored experiment = experiment_builder.build_from_args(args) if args["init_only"]: return config = experiment_builder.get_cmd_config(args) worker_config = orion.core.config.worker.to_dict() if config.get("worker"): worker_config.update(config.get("worker")) # If EVC is not enabled, we force Consumer to ignore code changes. if not config["branching"].get("enable", orion.core.config.evc.enable): ignore_code_changes = True else: ignore_code_changes = config["branching"].get("ignore_code_changes") with sigterm_as_interrupt(): workon(experiment, ignore_code_changes=ignore_code_changes, **worker_config)