-
Notifications
You must be signed in to change notification settings - Fork 455
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for grid search algorithm in Optuna Suggestion Service #2060
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
Signed-off-by: Yuki Iwai <yuki.iwai.tz@gmail.com>
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -15,10 +15,10 @@ | |||||||||||||||||||||||||||||
import threading | ||||||||||||||||||||||||||||||
import grpc | ||||||||||||||||||||||||||||||
import logging | ||||||||||||||||||||||||||||||
import itertools | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
from pkg.apis.manager.v1beta1.python import api_pb2 | ||||||||||||||||||||||||||||||
from pkg.apis.manager.v1beta1.python import api_pb2_grpc | ||||||||||||||||||||||||||||||
from pkg.suggestion.v1beta1.internal.constant import INTEGER, DOUBLE | ||||||||||||||||||||||||||||||
from pkg.suggestion.v1beta1.internal.search_space import HyperParameterSearchSpace | ||||||||||||||||||||||||||||||
from pkg.suggestion.v1beta1.internal.trial import Trial, Assignment | ||||||||||||||||||||||||||||||
from pkg.suggestion.v1beta1.optuna.base_service import BaseOptunaService | ||||||||||||||||||||||||||||||
|
@@ -55,7 +55,7 @@ def GetSuggestions(self, request, context): | |||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
def ValidateAlgorithmSettings(self, request, context): | ||||||||||||||||||||||||||||||
is_valid, message = OptimizerConfiguration.validate_algorithm_spec( | ||||||||||||||||||||||||||||||
request.experiment.spec.algorithm) | ||||||||||||||||||||||||||||||
request.experiment) | ||||||||||||||||||||||||||||||
if not is_valid: | ||||||||||||||||||||||||||||||
context.set_code(grpc.StatusCode.INVALID_ARGUMENT) | ||||||||||||||||||||||||||||||
context.set_details(message) | ||||||||||||||||||||||||||||||
|
@@ -86,6 +86,9 @@ class OptimizerConfiguration(object): | |||||||||||||||||||||||||||||
"random": { | ||||||||||||||||||||||||||||||
"seed": lambda x: int(x), | ||||||||||||||||||||||||||||||
}, | ||||||||||||||||||||||||||||||
"grid": { | ||||||||||||||||||||||||||||||
"seed": lambda x: int(x), | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
} | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||
|
@@ -110,7 +113,8 @@ def convert_algorithm_spec(cls, algorithm_spec): | |||||||||||||||||||||||||||||
return algorithm_spec.algorithm_name, config | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||
def validate_algorithm_spec(cls, algorithm_spec): | ||||||||||||||||||||||||||||||
def validate_algorithm_spec(cls, experiment): | ||||||||||||||||||||||||||||||
algorithm_spec = experiment.spec.algorithm | ||||||||||||||||||||||||||||||
algorithm_name = algorithm_spec.algorithm_name | ||||||||||||||||||||||||||||||
algorithm_settings = algorithm_spec.algorithm_settings | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
|
@@ -120,6 +124,10 @@ def validate_algorithm_spec(cls, algorithm_spec): | |||||||||||||||||||||||||||||
return cls._validate_cmaes_setting(algorithm_settings) | ||||||||||||||||||||||||||||||
elif algorithm_name == "random": | ||||||||||||||||||||||||||||||
return cls._validate_random_setting(algorithm_settings) | ||||||||||||||||||||||||||||||
elif algorithm_name == "grid": | ||||||||||||||||||||||||||||||
return cls._validate_grid_setting(experiment) | ||||||||||||||||||||||||||||||
tenzen-y marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||
return False, "unknown algorithm name {}".format(algorithm_name) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||
def _validate_tpe_setting(cls, algorithm_spec): | ||||||||||||||||||||||||||||||
|
@@ -178,3 +186,34 @@ def _validate_random_setting(cls, algorithm_settings): | |||||||||||||||||||||||||||||
exception=e) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return True, "" | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
@classmethod | ||||||||||||||||||||||||||||||
def _validate_grid_setting(cls, experiment): | ||||||||||||||||||||||||||||||
algorithm_settings = experiment.spec.algorithm.algorithm_settings | ||||||||||||||||||||||||||||||
search_space = HyperParameterSearchSpace.convert(experiment) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
for s in algorithm_settings: | ||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||
if s.name == "random_state": | ||||||||||||||||||||||||||||||
if not int(s.value) >= 0: | ||||||||||||||||||||||||||||||
return False, "" | ||||||||||||||||||||||||||||||
else: | ||||||||||||||||||||||||||||||
return False, "unknown setting {} for algorithm grid".format(s.name) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||
return False, "failed to validate {name}({value}): {exception}".format(name=s.name, value=s.value, | ||||||||||||||||||||||||||||||
exception=e) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
try: | ||||||||||||||||||||||||||||||
combinations = HyperParameterSearchSpace.convert_to_combinations(search_space) | ||||||||||||||||||||||||||||||
num_combinations = len(list(itertools.product(*combinations.values()))) | ||||||||||||||||||||||||||||||
max_trial_count = experiment.spec.max_trial_count | ||||||||||||||||||||||||||||||
if max_trial_count > num_combinations: | ||||||||||||||||||||||||||||||
return False, "Max Trial Count: {max_trial} > all possible search combinations: {combinations}".\ | ||||||||||||||||||||||||||||||
format(max_trial=max_trial_count, combinations=num_combinations) | ||||||||||||||||||||||||||||||
Comment on lines
+211
to
+213
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not familiar with optuna, Is it ok to set There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes, that's right about optuna behavior. Although optuna suggestion-service creates trials using already used parameters after all combinations used. katib/pkg/suggestion/v1beta1/optuna/base_service.py Lines 58 to 65 in db72ce1
This does not mean the optuna suggestion service can remove duplicated suggestions in the above section since the suggestionclient faces the error in the following: katib/pkg/controller.v1beta1/suggestion/suggestionclient/suggestionclient.go Lines 123 to 128 in db72ce1
Also, if users want to run experiments using all combinations, users can skip setting For these reasons, it would be good to provide that validation. @anencore94 Does that make sense? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeap I see now. Thanks for your kind reply :) |
||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
except Exception as e: | ||||||||||||||||||||||||||||||
return False, "failed to validate parameters({parameters}): {exception}".\ | ||||||||||||||||||||||||||||||
format(parameters=search_space.params, exception=e) | ||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||
return True, "" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@andreyvelich I updated this error message.