feat(api): add Normal and LogNormal distributions to SearchSpace - #3908
feat(api): add Normal and LogNormal distributions to SearchSpace#3908sanskar-singh-2403 wants to merge 1 commit into
Conversation
SearchSpace supports uniform, logUniform and categorical distributions.
All three are uninformative within their bounds: they can express where a
hyperparameter lives, but not where it is likely to be. Practitioners who
already know a good region, from a previous run, a paper, or the shape of
the architecture, have no way to say so, and every trial is spent
re-discovering it.
Add Normal and LogNormal as two further members of the SearchSpace union
so a prior can be expressed directly as a center and a spread:
- NormalSpace is a Gaussian over Mean with standard deviation StdDev,
concentrating trials near Mean while still allowing the tails.
- LogNormalSpace is a distribution whose logarithm is normal, so Mean and
StdDev are in log space. Samples are therefore always positive and the
spread is multiplicative, which is how positive-only hyperparameters
such as learning rate or weight decay are actually reasoned about
("around 1e-3, within a factor of 3"). Mean may be negative there,
since it is an exponent.
Both mirror the existing UniformSpace and LogUniformSpace shape and reuse
the Double string type, which keeps numeric values out of the float
round-tripping problems that JSON and protobuf have, and validates them
with the existing decimal pattern.
Mean is deliberately unconstrained: a Gaussian may legitimately be
centered below zero, and for LogNormal a negative Mean is the common
case. StdDev is constrained to be strictly positive by a CEL rule,
matching the XValidation style already used by LogUniformSpace, because
a zero standard deviation collapses the distribution to a point and a
negative one is undefined. Rejecting it at admission keeps the failure
next to the offending field instead of surfacing later from inside a
suggestion container.
The ExactlyOneOf marker on SearchSpace is extended to cover the two new
members, so they are mutually exclusive with each other and with the
existing three.
Two structs, trainer_v1alpha1_normal_space.py and
trainer_v1alpha1_log_normal_space.py, were already generated into the
Python API by kubeflow#3552 but had no Go counterparts and were not referenced by
SearchSpace. They declare exactly mean and stdDev, which is the field set
generated here, so this change wires up models that were already present
rather than introducing a new shape. Following those files, neither struct
carries a ParameterType: both distributions are continuous.
The pre-existing CEL rule requiring categorical parameters under grid
search already covers the new distributions, since grid enumerates a
finite cartesian product that a continuous distribution cannot provide.
Only its message needed updating, as it enumerated uniform and logUniform
by name and would otherwise have gone stale.
This is an API change only. Propagating the distributions into the
suggestion backend is tracked separately in kubeflow#3797, which is blocked on
the gRPC contract in kubeflow#3796; no .proto exists in the repository yet.
Landing the types first gives that work a defined SearchSpace to map onto
Optuna's FloatDistribution.
Add envtest coverage for both distributions: the accepted cases including
a negative normal mean and a negative log-space logNormal mean, the
rejected zero, negative and non-numeric stdDev, union violations against
each other and against uniform, and grid search with a continuous
parameter.
Regenerate the CRDs, Helm chart CRD templates, deepcopy, openapi, apply
configurations, swagger spec and Python API models.
Signed-off-by: Sanskar Singh <sanskarsinghty1234@gmail.com>
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
|
Thanks for creating this @sanskar-singh-2403 I think we need to wait for #3828 and #3797 are finalised before we can move this forward. I think we should look to implement both the api changes and wiring up to optuna within the same pr. /hold |
Thanks @robert-bell, makes sense thus I kept this as draft and sure i will wire up optuna as well as soon as #3797 gets merged |
What this PR does / why we need it
SearchSpacecurrently supportsuniform,logUniformandcategorical. All three are uninformative within their bounds: they can express where a hyperparameter lives, but not where it is likely to be. A practitioner who already knows a good region, from a previous run, a paper, or the shape of the architecture, has no way to say so, and every trial is spent re-discovering it.This adds
normalandlogNormalas two further members of the union, so a prior can be expressed directly as a center and a spread:NormalSpaceis a Gaussian overmeanwith standard deviationstdDev, concentrating trials nearmeanwhile still allowing the tails.LogNormalSpaceis a distribution whose logarithm is normal, someanandstdDevare in log space. Samples are therefore always positive and the spread is multiplicative, which is how positive-only hyperparameters such as learning rate or weight decay are actually reasoned about ("around 1e-3, within a factor of 3").Both mirror the existing
UniformSpace/LogUniformSpaceshape and reuse theDoublestring type, which keeps numeric values out of the float round-tripping problems JSON and protobuf have, and validates them with the existing decimal pattern.Design notes
meanis deliberately unconstrained. A Gaussian may legitimately be centered below zero, and forlogNormala negativemeanis the common case since it is an exponent. There is a test asserting negative means are accepted, so a lower bound is not added later by mistake.stdDevmust be strictly positive, enforced by a CEL rule in the sameXValidationstyleLogUniformSpacealready uses. A zero standard deviation collapses the distribution to a point and a negative one is undefined. Rejecting it at admission keeps the failure next to the offending field rather than surfacing later from inside a suggestion container.The
ExactlyOneOfmarker is extended to cover the two new members, so they are mutually exclusive with each other and with the existing three.No
ParameterTypefield on either struct.trainer_v1alpha1_normal_space.pyandtrainer_v1alpha1_log_normal_space.pywere already generated into the Python API by #3552, but had no Go counterparts and were not referenced bySearchSpace. They declare exactlymeanandstdDev, which is the field set generated here, so this wires up models that were already present rather than introducing a new shape. Both distributions are continuous, so a discrete/continuous type discriminator would not carry information. Happy to add one if reviewers prefer.Grid search needed no new rule. The existing CEL rule requiring categorical parameters under grid already covers the new distributions, since grid enumerates a finite cartesian product that a continuous distribution cannot provide. Only its message needed updating, as it enumerated
UniformandLogUniformby name and would otherwise have gone stale. There is a test covering grid plusnormal.Scope
This is an API change only. Propagating the distributions into the suggestion backend is tracked separately in #3797, which is blocked on the gRPC contract in #3796; no
.protoexists in the repository yet. Landing the types first gives that work a definedSearchSpaceto map onto Optuna'sFloatDistribution.Testing
New envtest coverage in
test/integration/webhooks/optimizationjob_test.go, 10 assertions, all passing against a real API server:normalwith valid mean and stdDevnormalwith negative meanlogNormalwith negative log-space meannormalwithstdDev: "0"normalwith negativestdDevlogNormalwithstdDev: "0"logNormalwith negativestdDevnormalwith non-numericstdDevnormalandlogNormalboth setnormalanduniformboth setnormalparametergo build ./...,go vetandgo test ./pkg/webhooks/...are clean.Generated assets
CRDs, Helm chart CRD templates, deepcopy, openapi, apply configurations, swagger spec and Python API models are all regenerated via
make generate.Which issue(s) this PR fixes
Fixes #3795
Part of KEP-3562 (#3562).
Checklist
make generate)