Skip to content
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

Adding support for concurrency formula as an option in Optuna search #885

Merged
merged 2 commits into from
May 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions model_analyzer/config/generate/optuna_run_config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -213,10 +213,10 @@ def _create_trial_objectives(self, trial: optuna.Trial) -> TrialObjectives:
trial, parameter_name, parameter
)

# TODO: TMA-1884: Need an option to choose btw. concurrency formula and optuna searching
trial_objectives["concurrency"] = self._get_objective_concurrency(
trial_objectives
)
if self._config.use_concurrency_formula:
trial_objectives["concurrency"] = self._get_objective_concurrency(
trial_objectives
)

return trial_objectives

Expand Down
15 changes: 4 additions & 11 deletions model_analyzer/config/generate/search_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,23 +90,14 @@ def _number_of_configurations_for_parameter(
return number_of_parameter_configs

def _populate_search_parameters(self) -> None:
if self._parameters:
self._populate_parameters()
else:
self._populate_default_parameters()
debermudez marked this conversation as resolved.
Show resolved Hide resolved

self._populate_parameters()
self._populate_model_config_parameters()

def _populate_parameters(self) -> None:
self._populate_batch_sizes()
self._populate_concurrency()
# TODO: Populate request rate - TMA-1903

def _populate_default_parameters(self) -> None:
# Always populate batch sizes if nothing is specified
# TODO: TMA-1884: Will need to add concurrency if the user wants this searched
self._populate_batch_sizes()

def _populate_model_config_parameters(self) -> None:
self._populate_instance_group()
self._populate_max_queue_delay_microseconds()
Expand All @@ -126,12 +117,14 @@ def _populate_batch_sizes(self) -> None:
)

def _populate_concurrency(self) -> None:
if self._parameters["concurrency"]:
if self._parameters and self._parameters["concurrency"]:
self._populate_list_parameter(
parameter_name="concurrency",
parameter_list=self._parameters["concurrency"],
parameter_category=ParameterCategory.INT_LIST,
)
elif self._config.use_concurrency_formula:
return
else:
self._populate_rcs_parameter(
parameter_name="concurrency",
Expand Down
11 changes: 11 additions & 0 deletions model_analyzer/config/input/config_command_profile.py
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@
DEFAULT_TRITON_LAUNCH_MODE,
DEFAULT_TRITON_METRICS_URL,
DEFAULT_TRITON_SERVER_PATH,
DEFAULT_USE_CONCURRENCY_FORMULA,
)
from .config_enum import ConfigEnum
from .config_field import ConfigField
Expand Down Expand Up @@ -956,6 +957,16 @@ def _add_run_search_configs(self):
description="Maximum number of trials to profile when using Optuna",
)
)
self._add_config(
ConfigField(
"use_concurrency_formula",
flags=["--use-concurrency-formula"],
field_type=ConfigPrimitive(bool),
parser_args={"action": "store_true"},
default_value=DEFAULT_USE_CONCURRENCY_FORMULA,
description="Use the concurrency formula instead of searching the concurrency space in Optuna search mode",
)
)
self._add_config(
ConfigField(
"run_config_search_mode",
Expand Down
1 change: 1 addition & 0 deletions model_analyzer/config/input/config_defaults.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@
DEFAULT_OPTUNA_MAX_PERCENTAGE_OF_SEARCH_SPACE = 10
DEFAULT_OPTUNA_MIN_TRIALS = 20
DEFAULT_OPTUNA_MAX_TRIALS = 200
DEFAULT_USE_CONCURRENCY_FORMULA = False
DEFAULT_REQUEST_RATE_SEARCH_ENABLE = False
DEFAULT_TRITON_LAUNCH_MODE = "local"
DEFAULT_TRITON_DOCKER_IMAGE = "nvcr.io/nvidia/tritonserver:24.04-py3"
Expand Down
2 changes: 2 additions & 0 deletions tests/test_cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@ def get_test_options():
OptionStruct("bool", "profile","--skip-summary-reports"),
OptionStruct("bool", "profile","--skip-detailed-reports"),
OptionStruct("bool", "profile","--always-report-gpu-metrics"),
OptionStruct("bool", "profile","--use-concurrency-formula"),

#Int/Float options
# Options format:
Expand Down Expand Up @@ -385,6 +386,7 @@ def _test_boolean_option(self, option_struct):
cli = option_struct.cli_subcommand()
_, config = cli.parse()
option_value = config.get_config().get(option_with_underscores).value()
# Boolean values must always default to False
debermudez marked this conversation as resolved.
Show resolved Hide resolved
self.assertEqual(option_value, False)

# Test boolean option
Expand Down
39 changes: 38 additions & 1 deletion tests/test_optuna_run_config_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def setUp(self):
)
]

config = self._create_config()
config = self._create_config(additional_args=["--use-concurrency-formula"])
model = config.profile_models[0]
search_parameters = SearchParameters(
config=config,
Expand Down Expand Up @@ -159,6 +159,43 @@ def test_create_objective_based_run_config(self):
self.assertEqual(perf_config["batch-size"], DEFAULT_BATCH_SIZES)
self.assertEqual(perf_config["concurrency-range"], 64)

def test_create_run_config_with_concurrency_formula(self):
config = self._create_config(["--use-concurrency-formula"])
model = config.profile_models[0]
search_parameters = SearchParameters(
config=config,
parameters={},
model_config_parameters=model.model_config_parameters(),
)

rcg = OptunaRunConfigGenerator(
config=config,
gpu_count=1,
models=self._mock_models,
model_variant_name_manager=ModelVariantNameManager(),
search_parameters={"add_sub": search_parameters},
seed=100,
)

trial = rcg._study.ask()
trial_objectives = rcg._create_trial_objectives(trial)
run_config = rcg._create_objective_based_run_config(trial_objectives)

model_config = run_config.model_run_configs()[0].model_config()
perf_config = run_config.model_run_configs()[0].perf_config()

self.assertEqual(model_config.to_dict()["name"], self._test_config_dict["name"])

# These values are the result of using a fixed seed of 100
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice note!

self.assertEqual(model_config.to_dict()["maxBatchSize"], 16)
self.assertEqual(model_config.to_dict()["instanceGroup"][0]["count"], 2)
self.assertEqual(
model_config.to_dict()["dynamicBatching"]["maxQueueDelayMicroseconds"],
"200",
)
self.assertEqual(perf_config["batch-size"], DEFAULT_BATCH_SIZES)
self.assertEqual(perf_config["concurrency-range"], 64)

def _create_config(self, additional_args=[]):
args = [
"model-analyzer",
Expand Down
32 changes: 32 additions & 0 deletions tests/test_search_parameters.py
Original file line number Diff line number Diff line change
Expand Up @@ -248,6 +248,38 @@ def test_search_parameter_creation_default(self):
default.DEFAULT_RUN_CONFIG_MAX_INSTANCE_COUNT, instance_group.max_range
)

def test_search_parameter_concurrency_formula(self):
"""
Test that when concurrency formula is specified it is
not added as a search parameter
"""

args = [
"model-analyzer",
"profile",
"--model-repository",
"cli-repository",
"-f",
"path-to-config-file",
"--run-config-search-mode",
"optuna",
"--use-concurrency-formula",
]

yaml_content = """
profile_models: add_sub
"""
config = TestConfig()._evaluate_config(args=args, yaml_content=yaml_content)

analyzer = Analyzer(config, MagicMock(), MagicMock(), MagicMock())
analyzer._populate_search_parameters()

concurrency = analyzer._search_parameters["add_sub"].get_parameter(
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wont error out?
get_parameter is designed to return None when a parameter isnt found?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it will return None when the key is not found.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well done!

"concurrency"
)

self.assertEqual(concurrency, None)

def test_search_parameter_creation_multi_model_non_default(self):
"""
Test that search parameters are correctly created in
Expand Down
Loading