You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
[GENERAL SUPPORT]: Expose Acquisition Function and Kernel Hyper parameter #5099
I’m currently using Client from ax.api.client for my research experiments. While the high-level abstraction is great for running trials, I need deeper insights into the model's behavior over time for my analysis.
Specifically, I am looking for a way to expose and track:
Hyperparameter Evolution: How the kernel hyperparameters (e.g., lengthscales) evolve trial-by-trial.
Acquisition Function Values: The values of the acquisition function at each step.
Model Metadata: A way to programmatically identify the exact kernel and acquisition function being used when relying on the default GenerationStrategy and not the one I built.
Currently, the Client API seems to abstract away the underlying ModelBridge and BoTorchModel.
Could you please provide a snippet if applicable?
Please provide any relevant code snippet if applicable.
I took a look through and I believe you can get everything you need by accessing the descendent properties of the experiment objects. I summarized the call stack and the paths to the objects you'll need. From here just add the checks and log your tracked information trial by trial
For your purposes to move through Client abstraction, you'll access things as follows:
client.generation_strategy # GenerationStrategy
.adapter # Adapter (the "model bridge")
.generator # BoTorchGenerator
.surrogate.model # fitted BoTorch GP model
._botorch_acqf_class # resolved AcquisitionFunction class
Log these after each get_next_trial() call to track evolution.
2. Acquisition Function Values
These are stored in gen_metadata on each GeneratorRun:
trial = client.experiment.trials[trial_index]
gr = trial.generator_run
gr.gen_metadata # dict with generation-time metadata
3. Model Metadata (kernel + acqf identity)Copy
gs = client.generation_strategy
Which generation node you're on:
gs.current_node_name
The resolved acqf class:
generator = gs.adapter.generator
generator._botorch_acqf_class # e.g. qLogExpectedImprovement
generator.surrogate_spec # SurrogateSpec with botorch_model_class
The actual fitted model class:
type(generator.surrogate.model) # e.g. SingleTaskGP
All of this is accessible after at least one BO trial has been generated (i.e., after the Sobol phase ends and the adapter is instantiated). Before that, gs.adapter will be None.
Let me know if you get blocked on anything else, thank you again for using Ax!
Activity
mgrange1998 commentedon Mar 30, 2026
Hi Pietro,
I took a look through and I believe you can get everything you need by accessing the descendent properties of the experiment objects. I summarized the call stack and the paths to the objects you'll need. From here just add the checks and log your tracked information trial by trial
For your purposes to move through Client abstraction, you'll access things as follows:
Code Pointers to Relevant Attributes
ax/service/ax_client.py—generation_strategypropertyax/generation_strategy/generation_strategy.py—.adapterpropertyax/adapter/base.py—.generatorattributeax/generators/torch/botorch_modular/generator.py—BoTorchGenerator(holds.surrogate_spec,._botorch_acqf_class)ax/generators/torch/botorch_modular/surrogate.py—Surrogate.modelproperty → returns the fittedbotorch.models.Modelax/core/generator_run.py—gen_metadataproperty onGeneratorRunSuggestions
1. Hyperparameter Evolution
After calling get_next_trial() (which triggers a model fit), extract kernel hyperparameters:
With these, use standard BoTorch/GPyTorch inspection as needed:
Log these after each get_next_trial() call to track evolution.
2. Acquisition Function Values
These are stored in gen_metadata on each GeneratorRun:
3. Model Metadata (kernel + acqf identity)Copy
Which generation node you're on:
The resolved acqf class:
The actual fitted model class:
All of this is accessible after at least one BO trial has been generated (i.e., after the Sobol phase ends and the adapter is instantiated). Before that, gs.adapter will be None.
Let me know if you get blocked on anything else, thank you again for using Ax!