Use GPSampler as the Default Optuna Sampler When torch Is Available
Summary
MotherML currently hard-codes TPESampler as the default Optuna sampler in MotherTuner. The official Optuna documentation and benchmarks show that GPSampler is the better choice for budgets up to ~500 trials, which covers virtually all practical MotherML tuning runs (the default n_trials_optuna is 100). We should switch the default to GPSampler whenever torch (and scipy) is available, with a graceful fallback to TPESampler when it is not.
Evidence from the Optuna Documentation
Sampler Comparison Table
The official Optuna sampler reference contains an explicit recommended budget row:
| Sampler |
Recommended Budget (# trials) |
Time Complexity (per trial) |
TPESampler |
100 – 1 000 |
$O(d \cdot n \log n)$ |
GPSampler |
up to ~500 |
$O(n^3)$ |
CmaEsSampler |
1 000 – 10 000 |
$O(d^3)$ |
Where $d$ = search-space dimension, $n$ = number of completed trials.
Key observation: GPSampler is explicitly recommended for budgets ≤ 500 trials — the exact regime MotherML operates in by default. The $O(n^3)$ cost is negligible when $n < 200$ and the evaluation cost of a CatBoost/RF model dominates by orders of magnitude.
Algorithm Selection Guide
The Efficient Optimization Algorithms tutorial from the Optuna developers summarises:
For limited parallel compute resources and no (or few) categorical hyperparameters:
TPE. GP-EI if search space is low-dimensional and continuous.
MotherML's CatBoost/RandomForest search spaces are exactly this: low-to-medium dimensional, mostly continuous/integer parameters (learning rate, depth, L2 reg, etc.), with only a handful of categorical choices (boosting type, grow policy). This is the ideal GPSampler regime.
Evidence from AutoSampler (OptunaHub)
The Optuna team's own AutoSampler — their recommended "just works" sampler — applies exactly this logic:
"Using GPSampler during the early stages of a search, as it has excellent sample efficiency but is only applicable to a small number of evaluations."
Benchmark results from the AutoSampler announcement blog post show:
- AutoSampler (GP-first) with < 100 trials finds a better solution than TPESampler with 1 000 trials on multiple benchmark functions.
- AutoSampler converges significantly faster and is more stable (narrower variance bands) than default TPESampler on Hartmann6 and McCourt11 benchmarks.
This is the core argument: GPSampler uses the trial budget dramatically more efficiently at small $n$, because it builds a principled probabilistic surrogate (Matérn-5/2 GP with ARD) that models parameter correlations globally, whereas TPE's kernel density estimates only become reliable after ~50–100 observations.
Why GPSampler Is Better in the Low-Budget Regime
| Property |
TPESampler |
GPSampler |
| Surrogate model |
Kernel Density Estimates (l/g split) |
Gaussian Process (Matérn-5/2, ARD) |
| Models parameter correlations |
Partially (multivariate mode) |
Yes, natively |
| Sample efficiency at $n < 100$
|
Moderate |
High |
| Sample efficiency at $n > 500$
|
Good |
Degrades ($O(n^3)$) |
| Acquisition function |
EI via ratio of densities |
log-EI (numerically superior) |
| Handles integers + floats well |
Yes |
Yes (better than CMA-ES) |
Requires torch
|
No |
Yes (scipy + torch) |
The GP's ability to reason about the global landscape from very few points is the fundamental advantage. TPE requires enough trials in each density bucket to estimate l(x) and g(x) reliably — this threshold is usually around 25–50 trials just for n_startup_trials, meaning effective Bayesian search only starts after that point.
Fit for MotherML's Search Spaces
MotherML's CatBoost hyperparameter spaces (e.g., learning_rate, depth, l2_leaf_reg, bagging_temperature) are:
- Primarily continuous and integer — GPSampler's strength.
- Low-to-medium dimensional (typically 5–12 parameters) — well within the GP's reliable range.
- Not heavily conditional/tree-structured — GPSampler handles this adequately (vs. TPE's strength in deep conditional spaces).
The few categorical dimensions (boosting_type, grow_policy) are handled by GPSampler's independent fallback sampler (random by default), identical to how TPE handles them.
Proposed Implementation
In src/mother/optimization/core.py, replace the hard-coded TPESampler default with a conditional:
def _default_sampler(
seed: int, n_startup_trials: int, multivariate: bool
) -> optuna.samplers.BaseSampler:
"""Return GPSampler when torch is available, else fall back to TPESampler."""
try:
import torch # noqa: F401
import scipy # noqa: F401
module_logger.debug("torch available — using GPSampler as default")
return optuna.samplers.GPSampler(
seed=seed,
n_startup_trials=n_startup_trials,
deterministic_objective=False,
)
except ImportError:
module_logger.debug("torch not available — falling back to TPESampler")
return optuna.samplers.TPESampler(
multivariate=multivariate,
group=True,
constant_liar=True,
seed=seed,
n_startup_trials=n_startup_trials,
)
Then in MotherTuner.__init__:
if sampler is None:
self.sampler = _default_sampler(
seed=seed,
n_startup_trials=n_startup_trials,
multivariate=kwargs.get("multivariate", True),
)
else:
self.sampler = sampler
Users who need the old behaviour can still pass sampler=optuna.samplers.TPESampler(...) explicitly.
Considerations / Open Questions
-
torch is already a CatBoost dependency in many environments; the incremental cost of this switch is zero for most MotherML users.
-
GPSampler does not support pruning (
NopPruner is effectively required). MotherML does not currently use Optuna pruners, so this is a non-issue.
-
GPSampler does not support batch/distributed optimization well. MotherML runs
n_threads_optuna=1 by default; multi-threaded runs may want TPE with constant_liar=True. Could expose sampler selection as a config option tied to n_threads_optuna.
-
n_startup_trials: GPSampler defaults to 10 random warm-up trials; MotherML's current default is 12 — compatible.
-
Categorical parameters (boosting type, grow policy): GPSampler falls back to its
independent_sampler (random) for categoricals. This is acceptable; TPE's handling of categoricals at small $n$ is not much better.
References
Use
GPSampleras the Default Optuna Sampler WhentorchIs AvailableSummary
MotherML currently hard-codes
TPESampleras the default Optuna sampler inMotherTuner. The official Optuna documentation and benchmarks show thatGPSampleris the better choice for budgets up to ~500 trials, which covers virtually all practical MotherML tuning runs (the defaultn_trials_optunais 100). We should switch the default toGPSamplerwhenevertorch(andscipy) is available, with a graceful fallback toTPESamplerwhen it is not.Evidence from the Optuna Documentation
Sampler Comparison Table
The official Optuna sampler reference contains an explicit recommended budget row:
TPESamplerGPSamplerCmaEsSamplerWhere$d$ = search-space dimension, $n$ = number of completed trials.
Key observation:$O(n^3)$ cost is negligible when $n < 200$ and the evaluation cost of a CatBoost/RF model dominates by orders of magnitude.
GPSampleris explicitly recommended for budgets ≤ 500 trials — the exact regime MotherML operates in by default. TheAlgorithm Selection Guide
The Efficient Optimization Algorithms tutorial from the Optuna developers summarises:
MotherML's CatBoost/RandomForest search spaces are exactly this: low-to-medium dimensional, mostly continuous/integer parameters (learning rate, depth, L2 reg, etc.), with only a handful of categorical choices (boosting type, grow policy). This is the ideal GPSampler regime.
Evidence from AutoSampler (OptunaHub)
The Optuna team's own AutoSampler — their recommended "just works" sampler — applies exactly this logic:
Benchmark results from the AutoSampler announcement blog post show:
This is the core argument: GPSampler uses the trial budget dramatically more efficiently at small$n$ , because it builds a principled probabilistic surrogate (Matérn-5/2 GP with ARD) that models parameter correlations globally, whereas TPE's kernel density estimates only become reliable after ~50–100 observations.
Why GPSampler Is Better in the Low-Budget Regime
torchscipy+torch)The GP's ability to reason about the global landscape from very few points is the fundamental advantage. TPE requires enough trials in each density bucket to estimate l(x) and g(x) reliably — this threshold is usually around 25–50 trials just for
n_startup_trials, meaning effective Bayesian search only starts after that point.Fit for MotherML's Search Spaces
MotherML's CatBoost hyperparameter spaces (e.g.,
learning_rate,depth,l2_leaf_reg,bagging_temperature) are:The few categorical dimensions (
boosting_type,grow_policy) are handled by GPSampler's independent fallback sampler (random by default), identical to how TPE handles them.Proposed Implementation
In
src/mother/optimization/core.py, replace the hard-codedTPESamplerdefault with a conditional:Then in
MotherTuner.__init__:Users who need the old behaviour can still pass
sampler=optuna.samplers.TPESampler(...)explicitly.Considerations / Open Questions
torchis already a CatBoost dependency in many environments; the incremental cost of this switch is zero for most MotherML users.NopPruneris effectively required). MotherML does not currently use Optuna pruners, so this is a non-issue.n_threads_optuna=1by default; multi-threaded runs may want TPE withconstant_liar=True. Could exposesamplerselection as a config option tied ton_threads_optuna.n_startup_trials: GPSampler defaults to 10 random warm-up trials; MotherML's current default is 12 — compatible.independent_sampler(random) for categoricals. This is acceptable; TPE's handling of categoricals at smallReferences
GPSamplerAPI Reference