Fix overflow and underflow in trust region lengthscale normalization - #451
Open
gian21391 wants to merge 2 commits into
Open
Fix overflow and underflow in trust region lengthscale normalization#451gian21391 wants to merge 2 commits into
gian21391 wants to merge 2 commits into
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. 📢 Thoughts on this report? Let us know! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
TurboController.get_trust_regionscales the trust region by the model's lengthscales:torch.prod(lengthscales)multiplies together one number per dimension. With enough dimensions that product runs out of floating-point range — and it can go wrong in both directions:inf, every weight becomes0, and the trust region shrinks to a single point.0, every weight becomesinf, and the trust region gets clamped out to the whole domain.Either way there is no warning, no NaN and no exception. The optimizer just quietly stops behaving like TuRBO.
Overflow needs unusually large lengthscales (degenerate GP fits). The product exceeds the dtype maximum once the geometric mean passes
max ** (1 / d):So in float32 a lengthscale of 12 at d=40 already does it.
Underflow needs nothing unusual — just a lot of dimensions.
0.3 ** 700is already zero in float64, and lengthscales below 1 are normal for normalized inputs.Fix
Take the root of each lengthscale before multiplying:
Mathematically the same value, but every factor is now close to 1, so the product stays in range. This is the form the BoTorch BAxUS tutorial uses.
Test
test_get_trust_region_extreme_lengthscalesnow covers both cases,1e200and1e-200. Both fail onmainand pass with the fix:It checks
0 < width <= length * bound_widthrather than an exact width, so it still passes when the incumbent sits near a bound and the region is legitimately clipped.The test is a module-level function rather than a
TestTurbomethod because pytest cannot parametrizeunittest.TestCasemethods. Existing turbo and contextual-BO tests are unchanged.