Expand description
Pruner trait and implementations for trial pruning.
Pruners decide whether to stop (prune) a trial early based on its intermediate values compared to other trials. This is useful for discarding unpromising trials before they complete, saving compute.
§How pruning works
During optimization, each trial reports intermediate values at discrete steps (e.g., validation loss after each training epoch). A pruner inspects these values and compares them against completed trials to decide whether the current trial should be stopped early.
The typical flow is:
- Call
Trial::reportto record an intermediate value. - Call
Trial::should_pruneto check the pruner’s decision. - If the pruner says prune, return
TrialPrunedfrom the objective.
§Available pruners
| Pruner | Algorithm | Best for |
|---|---|---|
MedianPruner | Prune below median at each step | General-purpose default |
PercentilePruner | Prune below configurable percentile | Tunable aggressiveness |
ThresholdPruner | Prune outside fixed bounds | Known divergence limits |
PatientPruner | Require N consecutive prune signals | Noisy intermediate values |
SuccessiveHalvingPruner | Keep top 1/η fraction at each rung | Budget-aware pruning |
HyperbandPruner | Multiple SHA brackets with different budgets | Robust to budget choice |
WilcoxonPruner | Statistical signed-rank test vs. best trial | Rigorous noisy pruning |
NopPruner | Never prune | Disabling pruning explicitly |
§When to use pruning
Pruning is most beneficial when:
- The objective function has a natural notion of “steps” (e.g., training epochs)
- Early steps are informative about final performance
- Trials are expensive enough that stopping bad ones early saves significant time
Start with MedianPruner for most use cases. Switch to WilcoxonPruner
if your intermediate values are noisy, or to HyperbandPruner if you want
automatic budget scheduling.
§Stateful vs stateless pruners
Stateless pruners make their decision purely from the arguments passed
to Pruner::should_prune — they hold no mutable per-trial state.
MedianPruner, PercentilePruner, ThresholdPruner,
WilcoxonPruner, and NopPruner are all stateless.
Stateful pruners track information across calls. PatientPruner
uses Mutex<HashMap<u64, u64>> to count consecutive prune signals per
trial. HyperbandPruner uses Mutex and AtomicU64 for bracket
assignment state. When writing a stateful pruner, wrap mutable state in a
Mutex and key it by trial_id to keep trials independent.
§Cold start and warmup
Two builder parameters control when pruning begins:
n_warmup_steps— skip pruning before step N within a trial, giving the objective time to stabilize.n_min_trials— require N completed trials before pruning any trial, ensuring a meaningful comparison baseline.
See MedianPruner for the canonical implementation of both parameters.
Custom pruners should expose similar knobs when applicable.
§Composing pruners
PatientPruner demonstrates the decorator pattern: it wraps any
Box<dyn Pruner> and adds patience logic on top. Custom pruners can use
the same pattern to layer multiple pruning conditions — for example,
combining a statistical test with a hard threshold.
§Thread safety
The Pruner trait requires Send + Sync.
Study stores the pruner as Arc<dyn Pruner>, so
multiple threads may call Pruner::should_prune concurrently.
- Stateless pruners satisfy
Send + Syncautomatically. - Stateful pruners should use
std::sync::Mutexorparking_lot::Mutexto protect mutable state, keyed bytrial_id.
§Testing custom pruners
Recommended test categories:
- Never-prune baseline — empty history and early steps should not prune.
- Known-prune scenario — a clearly worse trial should be pruned.
- Known-keep scenario — a well-performing trial should survive.
- Warmup respected — pruning must be suppressed during warmup steps and while the minimum trial count has not been reached.
- Per-trial independence — stateful pruners must not leak state
between different
trial_idvalues.
Structs§
- Hyperband
Pruner HyperBandpruner that manages multiple Successive Halving brackets.- Median
Pruner - Prune trials that are performing worse than the median of completed trials at the same step.
- NopPruner
- A pruner that never prunes. This is the default when no pruner is configured.
- Patient
Pruner - Wraps another pruner and adds a patience window.
- Percentile
Pruner - Prune trials that are not in the top
percentile% of completed trials at the same training step. - Successive
Halving Pruner - Successive Halving pruner based on the SHA algorithm.
- Threshold
Pruner - Prune trials whose intermediate values exceed fixed thresholds.
- Wilcoxon
Pruner - Prune trials using a Wilcoxon signed-rank test comparing intermediate values against the best completed trial.
Traits§
- Pruner
- Trait for pluggable trial pruning strategies.