Skip to content

[Bug]: Default samplers are dependent for qHVKG #3303

@TobyBoyne

Description

@TobyBoyne

What happened?

Issue #2658 showed that the sampler from get_sampler is not independent for multiple samplers. When using qHVKG, the default sampler has the same issue.

Please provide a minimal, reproducible example of the unexpected behavior.

Correlated sampler

Using similar code to the linked issue, the output is similarly correlated:

from botorch.models import SingleTaskGP, ModelList
from botorch.acquisition.multi_objective import qHypervolumeKnowledgeGradient
import torch
import matplotlib.pyplot as plt

train_X = torch.rand((10, 2))
train_Y = train_X ** 2 + train_X.flip(dims=(1,))

model = ModelList(
    SingleTaskGP(train_X=train_X, train_Y=train_Y[:, :1]),
    SingleTaskGP(train_X=train_X, train_Y=train_Y[:, 1:2]),
)

acqf = qHypervolumeKnowledgeGradient(model=model, ref_point=torch.zeros((2,)), num_fantasies=512)

with torch.no_grad():
    posterior = model.posterior(torch.zeros((1, 2)))
    samples = acqf.sampler(posterior).squeeze()
plt.scatter(samples[:, 0], samples[:, 1])
plt.show()
Image

Using get_sampler breaks qHVKG

There is a related issue when we use get_sampler manually, using a ModelListGP:

train_X = torch.rand((10, 2))
train_Y = train_X ** 2 + train_X.flip(dims=(1,))

model = ModelListGP(
    SingleTaskGP(train_X=train_X, train_Y=train_Y[:, :1]),
    SingleTaskGP(train_X=train_X, train_Y=train_Y[:, 1:2]),
)

posterior = model.posterior(torch.zeros((1, 2)))
sampler = get_sampler(posterior, sample_shape=torch.Size([512]))
acqf = qHypervolumeKnowledgeGradient(
    model=model, ref_point=torch.zeros((2,)), sampler=sampler, num_fantasies=512
)

This raises an AttributeError, since qHVKG expects sampler to be a ListSampler, where it is instead a SobolQMCNormalSampler. This error is avoided if model is a ModelList instead of a ModelListGP.

Please paste any relevant traceback/logs produced by the example provided.

Traceback (most recent call last):
    acqf = qHypervolumeKnowledgeGradient(
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "botorch/acquisition/multi_objective/hypervolume_knowledge_gradient.py", line 150, in __init__
    sample_shape = sampler.samplers[0].sample_shape
                   ^^^^^^^^^^^^^^^^
  File "torch/nn/modules/module.py", line 1965, in __getattr__
    raise AttributeError(
AttributeError: 'SobolQMCNormalSampler' object has no attribute 'samplers'

BoTorch Version

0.17.2

Python Version

3.12.11

Operating System

WSL

(Optional) Describe any potential fixes you've considered to the issue outlined above.

In qHypervolumeKnowledgeGradient.__init__:

  • replace the sampler constructor with get_sampler
  • allow sampler to not be a ListSampler.

Pull Request

Yes

Code of Conduct

  • I agree to follow BoTorch's Code of Conduct

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions