If a process running a trial is killed unexpectedly (e.g., by a cluster job scheduler), the trial remains in the RUNNING state. Optuna's experimental heartbeat mechanism can automatically transition these trials to FAIL.
Using study.optimize
When using study.optimize, configure heartbeat_interval and grace_period in RDBStorage. A trial will be marked as failed if no heartbeat is recorded within the grace_period after the heartbeat_interval.
import optuna
def objective(trial):
# (Very time-consuming computation)
# Recording heartbeats every 60 seconds.
# Trials with no heartbeat for > 120 seconds are automatically failed.
storage = optuna.storages.RDBStorage(url="sqlite:///:memory:", heartbeat_interval=60, grace_period=120)
study = optuna.create_study(storage=storage)
study.optimize(objective, n_trials=100)
Using ask and tell
If you use the manual ask/tell API, the heartbeat mechanism does not automatically update states. You must manually check for stale trials and update them:
from datetime import datetime
import optuna
study = optuna.create_study(storage=...)
# Example: fail trials running for more than 1 day
grace_period = 3600*24
for t in study.get_trials(states=[optuna.trial.TrialState.RUNNING]):
if (datetime.now() - t.datetime_start).total_seconds() > grace_period:
study.tell(t, state=optuna.trial.TrialState.FAIL)
Retrying stale trials
You can use RetryHeartbeatStaleTrialCallback to automatically retry trials that have failed due to a lost heartbeat. This callback is invoked at the start of each new trial.
import optuna
from optuna.storages import RetryHeartbeatStaleTrialCallback
storage = optuna.storages.RDBStorage(
url="sqlite:///:memory:",
heartbeat_interval=60,
grace_period=120,
heartbeat_stale_trial_callback=RetryHeartbeatStaleTrialCallback(max_retry=3),
)
study = optuna.create_study(storage=storage)