Optimizer Protocol#828
Conversation
Removed deprecated surrogate_model property and its warning.
|
@StefanPSchmid could it be the case that your pre-commit hook is not activated/configured incorrectly? I'm asking since both the |
AVHopp
left a comment
There was a problem hiding this comment.
Some intermediate comments
There was a problem hiding this comment.
Pull request overview
This PR introduces an optimizer abstraction for Bayesian continuous optimization while standardizing user-facing naming around BayesianRecommender and deprecating BotorchRecommender. It updates examples/docs/streamlit integration accordingly and refactors the continuous recommendation path to call a pluggable optimizer.
Changes:
- Add a BoTorch-backed optimizer interface (
OptimizerProtocol) with a first implementation (GradientOptimizer). - Refactor continuous Bayesian recommendation to delegate acquisition optimization to
recommender.optimizer. - Switch examples/docs/streamlit usage from
BotorchRecommendertoBayesianRecommenderand turnBotorchRecommenderinto a deprecation wrapper.
Reviewed changes
Copilot reviewed 27 out of 27 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| streamlit/surrogate_models.py | Update Streamlit app to use BayesianRecommender. |
| README.md | Update README examples to BayesianRecommender. |
| examples/Serialization/validate_config.py | Update serialized type strings to BayesianRecommender. |
| examples/Serialization/create_from_config.py | Update serialized type strings to BayesianRecommender. |
| examples/Serialization/basic_serialization.py | Update example imports/usages to BayesianRecommender. |
| examples/Searchspaces/hybrid_space.py | Update explanatory comment to BayesianRecommender. |
| examples/Multi_Armed_Bandit/bernoulli_multi_armed_bandit.py | Update example to construct BayesianRecommender. |
| examples/Custom_Surrogates/surrogate_params.py | Update example to construct BayesianRecommender. |
| examples/Custom_Surrogates/custom_pretrained.py | Update example to construct BayesianRecommender. |
| examples/Custom_Hooks/probability_of_improvement.py | Update hook typing/docs and usage to BayesianRecommender. |
| examples/Custom_Hooks/campaign_stopping.py | Update hook typing/docs and usage to BayesianRecommender. |
| examples/Constraints_Continuous/interpoint.py | Update continuous-constraints example to BayesianRecommender. |
| examples/Basics/recommenders.py | Update basics example to BayesianRecommender. |
| baybe/recommenders/pure/bayesian/hybrid.py | Rename typing/docs references to BayesianRecommender. |
| baybe/recommenders/pure/bayesian/discrete.py | Rename typing/docs references to BayesianRecommender. |
| baybe/recommenders/pure/bayesian/continuous.py | Delegate continuous acquisition optimization to recommender.optimizer. |
| baybe/recommenders/pure/bayesian/botorch/optimizers/basic.py | Add GradientOptimizer implementation using botorch.optim.optimize_acqf. |
| baybe/recommenders/pure/bayesian/botorch/optimizers/base.py | Add OptimizerProtocol for optimizer pluggability. |
| baybe/recommenders/pure/bayesian/botorch/optimizers/init.py | Export optimizer(s) from package. |
| baybe/recommenders/pure/bayesian/botorch/core.py | Replace class BotorchRecommender with deprecated factory wrapper. |
| baybe/recommenders/pure/bayesian/base.py | Add optimizer field and move recommendation routines into BayesianRecommender. |
| baybe/recommenders/pure/bayesian/init.py | Export BayesianRecommender from pure.bayesian. |
| baybe/recommenders/pure/init.py | Export BayesianRecommender from pure. |
| baybe/recommenders/naive.py | Default hybrid sub-recommenders to BayesianRecommender. |
| baybe/recommenders/meta/sequential.py | Default meta recommender to BayesianRecommender. |
| baybe/recommenders/init.py | Export BayesianRecommender at top-level recommenders package. |
| AGENTS.md | Update naming convention example to BayesianRecommender. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
AVHopp
left a comment
There was a problem hiding this comment.
Few comments that you can look at - hopefully easy fixes :)
AdrianSosic
left a comment
There was a problem hiding this comment.
Here some first comments
…ocol + AutoBool in GradientOptimizer
…ocol + AutoBool in GradientOptimizer
The Botorch doc itself points out that their name (num_restarts) is poorly chosen: "Even though the name suggests this happens sequentually, it is done in parallel ..."
6190dcb to
ad16da8
Compare
ad16da8 to
268c187
Compare
|
@StefanPSchmid @AdrianSosic @AVHopp please can you update the PR descrption witha s ummary of what the intended change in this pR is and what has been changed/deleted etc? Last I recall Stefan was supposed to work on refactoring recommenders such that multi-step optimization algorithms (naive hybrid, mfbo, currybo) can be naturally included. just form a quick look at the code it not totally clear whether this PR is still about that (also the PR title does not seem to be related to that??) |
Let me write a summary 👍🏼 |
@Scienfitz: now there |
AVHopp
left a comment
There was a problem hiding this comment.
The two tests are failing, so I am wondering if this has been tested properly. I would also recommend rebasing the dev branch onto the latest version of main (in particular after the PRs fixing our issues there have been merged) such that we actually see this in the CI.
Goal
Decompose the monolithic
BotorchRecommenderinto atomic, reusable optimization procedures that users can compose and pass toBayesianRecommendervia a newOptimizerProtocol. This decoupling makes it straightforward to express e.g. subset-based optimization over fragmented spaces, coordinate-wise hybrid strategies, or other multi-phase approaches without new top-level classes — users/callers assemble the strategy externally and hand it to the recommender as a single object.This PR is the first step: it establishes the
ContinuousOptimizerprimitive and theBayesianRecommenderconsumer, and deprecatesBotorchRecommenderwith full backward compatibility at both constructor and serialization level.Background
1. Opaque and invalid-by-design interface. Its fields (
n_restarts,n_raw_samples,sequential_continuous) were BoTorch optimizer parameters exposed directly on the recommender class, with no clear model of how they mapped to the underlying optimization strategy. Worse, the flat field structure made it impossible to enforce valid combinations by construction: certain arguments were only meaningful for specific search space types (continuous-only fields had no effect in discrete or hybrid settings), yet nothing in the type system prevented users from providing them. Invalid combinations were accepted silently, with irrelevant fields quietly dropped — a recurring source of user confusion.2. Monolithic, hard-coded optimization logic. The recommender owned both the high-level recommendation strategy and the low-level mechanics for optimizing over continuous and discrete spaces — all embedded in its class methods. This made it impossible to compose optimization primitives independently. Any new hybrid strategy (e.g. coordinate-wise ascent) required a new top-level recommender class (hence
NaiveHybridRecommender), duplicating logic and proliferating classes instead of assembling reusable parts.Changes
New
optimizerssubpackageIntroduces
OptimizerProtocol[TSpace]as a generic protocol over search space type, andContinuousOptimizeras the first concrete primitive. Fields are renamed to be self-describing:n_starts(wasn_restarts),n_initial_samples(wasn_raw_samples),sequential(wassequential_continuous).New
BayesianRecommenderReplaces
BotorchRecommenderas the primary public class. Accepts anoptimizer: OptimizerProtocolfield, making the optimization strategy explicit and swappable. Moves cardinality constraint handling out of the recommender (removingrecommend_continuous_without_cardinality_constraints) and into the optimizer, where it belongs. Structured to accommodate future primitives (e.g. discrete + continuous) for hybrid and fragmented-space strategies.BotorchRecommenderdeprecation shimReduces
BotorchRecommenderto a shim function that maps legacy constructor arguments toBayesianRecommender+ContinuousOptimizerwith aDeprecationWarning. Registers acattrsstructure hook onPureRecommenderto intercept"type": "BotorchRecommender"in serialized dicts and remap legacy optimizer fields before forwarding, ensuring full serialization backward compatibility.Deprecation tests
Adds
test_botorch_recommender(constructor shim) andtest_botorch_recommender_deserialization(parametrized:no_args,all_args) covering legacy dict round-trip throughconverter.structure.