fix(hyperopt): enforce minimum 5 trials, skip hyperopt when trials=0

The hyperopt binary was crashing with "trials (5) must be greater than
n_initial (5)" when --trials 0 was passed. Root cause: the bump logic
set trials = n_initial instead of max(5, n_initial + 1).

Fix: both hyperopt_baseline_rl and hyperopt_baseline_supervised now clamp
trials to max(5, n_initial + 1). Also add `when` condition to the
compile-and-train DAG so hyperopt step is skipped when trials=0, and
train-best gracefully handles missing hyperopt results.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
jgrusewski
2026-03-12 21:58:11 +01:00
parent 2086405352
commit 85b3f02af4
3 changed files with 28 additions and 22 deletions

View File

@@ -509,15 +509,16 @@ fn main() -> Result<()> {
);
}
// Enforce trials > n_initial (ArgminOptimizer needs at least n_initial
// LHS exploration rounds + 1 TPE-guided trial to be meaningful)
let min_trials = args.n_initial + 1;
if args.trials < min_trials {
// Enforce minimum 5 trials AND trials > n_initial
// (ArgminOptimizer needs at least n_initial LHS rounds + 1 TPE-guided trial)
const MIN_TRIALS: usize = 5;
let effective_min = MIN_TRIALS.max(args.n_initial + 1);
if args.trials < effective_min {
info!(
"Trials {} below minimum (n_initial {} + 1) — bumping to {}",
args.trials, args.n_initial, min_trials
"Trials {} below minimum {} (floor={}, n_initial {}+1={}) — clamping",
args.trials, effective_min, MIN_TRIALS, args.n_initial, args.n_initial + 1
);
args.trials = min_trials;
args.trials = effective_min;
}
// Create output directory

View File

@@ -654,14 +654,16 @@ fn main() -> Result<()> {
info!("Models to optimize: {:?}", models);
// Enforce trials > n_initial (ArgminOptimizer needs LHS exploration + ≥1 TPE trial)
let min_trials = args.n_initial + 1;
if args.trials < min_trials {
// Enforce minimum 5 trials AND trials > n_initial
// (ArgminOptimizer needs at least n_initial LHS rounds + 1 TPE-guided trial)
const MIN_TRIALS: usize = 5;
let effective_min = MIN_TRIALS.max(args.n_initial + 1);
if args.trials < effective_min {
info!(
"Trials {} below minimum (n_initial {} + 1) — bumping to {}",
args.trials, args.n_initial, min_trials
"Trials {} below minimum {} (floor={}, n_initial {}+1={}) — clamping",
args.trials, effective_min, MIN_TRIALS, args.n_initial, args.n_initial + 1
);
args.trials = min_trials;
args.trials = effective_min;
}
if let Some(parent) = args.output.parent() {

View File

@@ -111,9 +111,10 @@ spec:
- name: hyperopt
template: hyperopt
dependencies: [fetch-binary, gpu-warmup]
when: "{{workflow.parameters.hyperopt-trials}} != 0"
- name: train-best
template: train-best
dependencies: [hyperopt]
dependencies: [fetch-binary, gpu-warmup, hyperopt]
- name: evaluate
template: evaluate
dependencies: [train-best]
@@ -431,16 +432,18 @@ spec:
# Determine binary and hyperopt flag
case "$MODEL" in
dqn|ppo)
BINARY=train_baseline_rl
HYPEROPT_FLAG="--hyperopt-results /workspace/output/${MODEL}_hyperopt_results.json"
;;
*)
BINARY=train_baseline_supervised
HYPEROPT_FLAG="--hyperopt-results /workspace/output/${MODEL}_hyperopt_results.json"
;;
dqn|ppo) BINARY=train_baseline_rl ;;
*) BINARY=train_baseline_supervised ;;
esac
HYPEROPT_FLAG=""
if [ -f "/workspace/output/${MODEL}_hyperopt_results.json" ]; then
HYPEROPT_FLAG="--hyperopt-results /workspace/output/${MODEL}_hyperopt_results.json"
echo " Using hyperopt results: ${MODEL}_hyperopt_results.json"
else
echo " No hyperopt results — training with default hyperparams"
fi
echo "=== Training best: $MODEL ({{workflow.parameters.train-epochs}} epochs) ==="
/workspace/bin/${BINARY} \