diff --git a/samples/model-builder/cancel_hyperparameter_tuning_job_sample.py b/samples/model-builder/cancel_hyperparameter_tuning_job_sample.py new file mode 100644 index 0000000000..57379f8ddf --- /dev/null +++ b/samples/model-builder/cancel_hyperparameter_tuning_job_sample.py @@ -0,0 +1,34 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START aiplatform_sdk_cancel_hyperparameter_tuning_job_sample] +from google.cloud import aiplatform + + +def cancel_hyperparameter_tuning_job_sample( + project: str, + hyperparameter_tuning_job_id: str, + location: str = "us-central1", +): + + aiplatform.init(project=project, location=location) + + hpt_job = aiplatform.HyperparameterTuningJob.get( + resource_name=hyperparameter_tuning_job_id, + ) + + hpt_job.cancel() + + +# [END aiplatform_sdk_cancel_hyperparameter_tuning_job_sample] diff --git a/samples/model-builder/cancel_hyperparameter_tuning_job_sample_test.py b/samples/model-builder/cancel_hyperparameter_tuning_job_sample_test.py new file mode 100644 index 0000000000..2b24d20053 --- /dev/null +++ b/samples/model-builder/cancel_hyperparameter_tuning_job_sample_test.py @@ -0,0 +1,40 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import cancel_hyperparameter_tuning_job_sample +import test_constants as constants + + +def test_cancel_hyperparameter_tuning_job_sample( + mock_sdk_init, + mock_hyperparameter_tuning_job_get, + mock_hyperparameter_tuning_job_cancel, +): + + cancel_hyperparameter_tuning_job_sample.cancel_hyperparameter_tuning_job_sample( + project=constants.PROJECT, + location=constants.LOCATION, + hyperparameter_tuning_job_id=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) + + mock_sdk_init.assert_called_once_with( + project=constants.PROJECT, + location=constants.LOCATION, + ) + + mock_hyperparameter_tuning_job_get.assert_called_once_with( + resource_name=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) + + mock_hyperparameter_tuning_job_cancel.assert_called_once_with() diff --git a/samples/model-builder/conftest.py b/samples/model-builder/conftest.py index 3c009ae13d..0f984aa7ee 100644 --- a/samples/model-builder/conftest.py +++ b/samples/model-builder/conftest.py @@ -327,6 +327,19 @@ def mock_run_custom_package_training_job(mock_custom_package_training_job): yield mock +@pytest.fixture +def mock_custom_job(): + mock = MagicMock(aiplatform.CustomJob) + yield mock + + +@pytest.fixture +def mock_get_custom_job(mock_custom_job): + with patch.object(aiplatform, "CustomJob") as mock: + mock.return_value = mock_custom_job + yield mock + + """ ---------------------------------------------------------------------------- Model Fixtures @@ -419,6 +432,48 @@ def mock_endpoint_explain(mock_endpoint): mock_get_endpoint.return_value = mock_endpoint yield mock_endpoint_explain +# ---------------------------------------------------------------------------- +# Hyperparameter Tuning Job Fixtures +# ---------------------------------------------------------------------------- + + +@pytest.fixture +def mock_hyperparameter_tuning_job(): + mock = MagicMock(aiplatform.HyperparameterTuningJob) + yield mock + + +@pytest.fixture +def mock_get_hyperparameter_tuning_job(mock_hyperparameter_tuning_job): + with patch.object(aiplatform, "HyperparameterTuningJob") as mock: + mock.return_value = mock_hyperparameter_tuning_job + yield mock + + +@pytest.fixture +def mock_run_hyperparameter_tuning_job(mock_hyperparameter_tuning_job): + with patch.object(mock_hyperparameter_tuning_job, "run") as mock: + yield mock + + +@pytest.fixture +def mock_hyperparameter_tuning_job_get(mock_hyperparameter_tuning_job): + with patch.object(aiplatform.HyperparameterTuningJob, "get") as mock_hyperparameter_tuning_job_get: + mock_hyperparameter_tuning_job_get.return_value = mock_hyperparameter_tuning_job + yield mock_hyperparameter_tuning_job_get + + +@pytest.fixture +def mock_hyperparameter_tuning_job_cancel(mock_hyperparameter_tuning_job): + with patch.object(mock_hyperparameter_tuning_job, "cancel") as mock: + yield mock + + +@pytest.fixture +def mock_hyperparameter_tuning_job_delete(mock_hyperparameter_tuning_job): + with patch.object(mock_hyperparameter_tuning_job, "delete") as mock: + yield mock + """ ---------------------------------------------------------------------------- diff --git a/samples/model-builder/create_hyperparameter_tuning_job_sample.py b/samples/model-builder/create_hyperparameter_tuning_job_sample.py new file mode 100644 index 0000000000..8c8c732357 --- /dev/null +++ b/samples/model-builder/create_hyperparameter_tuning_job_sample.py @@ -0,0 +1,74 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START aiplatform_sdk_create_hyperparameter_tuning_job_sample] +from google.cloud import aiplatform + +from google.cloud.aiplatform import hyperparameter_tuning as hpt + + +def create_hyperparameter_tuning_job_sample( + project: str, + location: str, + staging_bucket: str, + display_name: str, + container_uri: str, +): + aiplatform.init(project=project, location=location, staging_bucket=staging_bucket) + + worker_pool_specs = [ + { + "machine_spec": { + "machine_type": "n1-standard-4", + "accelerator_type": "NVIDIA_TESLA_K80", + "accelerator_count": 1, + }, + "replica_count": 1, + "container_spec": { + "image_uri": container_uri, + "command": [], + "args": [], + }, + } + ] + + custom_job = aiplatform.CustomJob( + display_name='custom_job', + worker_pool_specs=worker_pool_specs, + ) + + hpt_job = aiplatform.HyperparameterTuningJob( + display_name=display_name, + custom_job=custom_job, + metric_spec={ + 'loss': 'minimize', + }, + parameter_spec={ + 'lr': hpt.DoubleParameterSpec(min=0.001, max=0.1, scale='log'), + 'units': hpt.IntegerParameterSpec(min=4, max=128, scale='linear'), + 'activation': hpt.CategoricalParameterSpec(values=['relu', 'selu']), + 'batch_size': hpt.DiscreteParameterSpec(values=[128, 256], scale='linear') + }, + max_trial_count=128, + parallel_trial_count=8, + labels={'my_key': 'my_value'}, + ) + + hpt_job.run() + + print(hpt_job.resource_name) + return hpt_job + + +# [END aiplatform_sdk_create_hyperparameter_tuning_job_sample] diff --git a/samples/model-builder/create_hyperparameter_tuning_job_sample_test.py b/samples/model-builder/create_hyperparameter_tuning_job_sample_test.py new file mode 100644 index 0000000000..a21f9041e0 --- /dev/null +++ b/samples/model-builder/create_hyperparameter_tuning_job_sample_test.py @@ -0,0 +1,59 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +from unittest.mock import ANY + +import create_hyperparameter_tuning_job_sample + +import test_constants as constants + + +def test_create_hyperparameter_tuning_job_sample( + mock_sdk_init, + mock_custom_job, + mock_get_custom_job, + mock_get_hyperparameter_tuning_job, + mock_run_hyperparameter_tuning_job, +): + + create_hyperparameter_tuning_job_sample.create_hyperparameter_tuning_job_sample( + project=constants.PROJECT, + location=constants.LOCATION, + staging_bucket=constants.STAGING_BUCKET, + display_name=constants.HYPERPARAMETER_TUNING_JOB_DISPLAY_NAME, + container_uri=constants.CONTAINER_URI, + ) + + mock_sdk_init.assert_called_once_with( + project=constants.PROJECT, + location=constants.LOCATION, + staging_bucket=constants.STAGING_BUCKET, + ) + + mock_get_custom_job.assert_called_once_with( + display_name=constants.CUSTOM_JOB_DISPLAY_NAME, + worker_pool_specs=constants.CUSTOM_JOB_WORKER_POOL_SPECS, + ) + + mock_get_hyperparameter_tuning_job.assert_called_once_with( + display_name=constants.HYPERPARAMETER_TUNING_JOB_DISPLAY_NAME, + custom_job=mock_custom_job, + metric_spec=constants.HYPERPARAMETER_TUNING_JOB_METRIC_SPEC, + parameter_spec=ANY, + max_trial_count=constants.HYPERPARAMETER_TUNING_JOB_MAX_TRIAL_COUNT, + parallel_trial_count=constants.HYPERPARAMETER_TUNING_JOB_PARALLEL_TRIAL_COUNT, + labels=constants.HYPERPARAMETER_TUNING_JOB_LABELS, + ) + + mock_run_hyperparameter_tuning_job.assert_called_once() diff --git a/samples/model-builder/delete_hyperparameter_tuning_job_sample.py b/samples/model-builder/delete_hyperparameter_tuning_job_sample.py new file mode 100644 index 0000000000..c34462fd31 --- /dev/null +++ b/samples/model-builder/delete_hyperparameter_tuning_job_sample.py @@ -0,0 +1,34 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START aiplatform_sdk_delete_hyperparameter_tuning_job_sample] +from google.cloud import aiplatform + + +def delete_hyperparameter_tuning_job_sample( + project: str, + hyperparameter_tuning_job_id: str, + location: str = "us-central1", +): + + aiplatform.init(project=project, location=location) + + hpt_job = aiplatform.HyperparameterTuningJob.get( + resource_name=hyperparameter_tuning_job_id, + ) + + hpt_job.delete() + + +# [END aiplatform_sdk_delete_hyperparameter_tuning_job_sample] diff --git a/samples/model-builder/delete_hyperparameter_tuning_job_sample_test.py b/samples/model-builder/delete_hyperparameter_tuning_job_sample_test.py new file mode 100644 index 0000000000..28374c6b32 --- /dev/null +++ b/samples/model-builder/delete_hyperparameter_tuning_job_sample_test.py @@ -0,0 +1,40 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import delete_hyperparameter_tuning_job_sample +import test_constants as constants + + +def test_delete_hyperparameter_tuning_job_sample( + mock_sdk_init, + mock_hyperparameter_tuning_job_get, + mock_hyperparameter_tuning_job_delete, +): + + delete_hyperparameter_tuning_job_sample.delete_hyperparameter_tuning_job_sample( + project=constants.PROJECT, + location=constants.LOCATION, + hyperparameter_tuning_job_id=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) + + mock_sdk_init.assert_called_once_with( + project=constants.PROJECT, + location=constants.LOCATION, + ) + + mock_hyperparameter_tuning_job_get.assert_called_once_with( + resource_name=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) + + mock_hyperparameter_tuning_job_delete.assert_called_once_with() diff --git a/samples/model-builder/get_hyperparameter_tuning_job_sample.py b/samples/model-builder/get_hyperparameter_tuning_job_sample.py new file mode 100644 index 0000000000..e2b028993a --- /dev/null +++ b/samples/model-builder/get_hyperparameter_tuning_job_sample.py @@ -0,0 +1,34 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# [START aiplatform_sdk_get_hyperparameter_tuning_job_sample] +from google.cloud import aiplatform + + +def get_hyperparameter_tuning_job_sample( + project: str, + hyperparameter_tuning_job_id: str, + location: str = "us-central1", +): + + aiplatform.init(project=project, location=location) + + hpt_job = aiplatform.HyperparameterTuningJob.get( + resource_name=hyperparameter_tuning_job_id, + ) + + return hpt_job + + +# [END aiplatform_sdk_get_hyperparameter_tuning_job_sample] diff --git a/samples/model-builder/get_hyperparameter_tuning_job_sample_test.py b/samples/model-builder/get_hyperparameter_tuning_job_sample_test.py new file mode 100644 index 0000000000..d228d7fb95 --- /dev/null +++ b/samples/model-builder/get_hyperparameter_tuning_job_sample_test.py @@ -0,0 +1,37 @@ +# Copyright 2022 Google LLC +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import get_hyperparameter_tuning_job_sample +import test_constants as constants + + +def test_get_hyperparameter_tuning_job_sample( + mock_sdk_init, + mock_hyperparameter_tuning_job_get, +): + + get_hyperparameter_tuning_job_sample.get_hyperparameter_tuning_job_sample( + project=constants.PROJECT, + location=constants.LOCATION, + hyperparameter_tuning_job_id=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) + + mock_sdk_init.assert_called_once_with( + project=constants.PROJECT, + location=constants.LOCATION, + ) + + mock_hyperparameter_tuning_job_get.assert_called_once_with( + resource_name=constants.HYPERPARAMETER_TUNING_JOB_ID, + ) diff --git a/samples/model-builder/test_constants.py b/samples/model-builder/test_constants.py index 9e8cbae6eb..1ff2b1d96e 100644 --- a/samples/model-builder/test_constants.py +++ b/samples/model-builder/test_constants.py @@ -278,6 +278,32 @@ STEP = 1 TIMESTAMP = timestamp_pb2.Timestamp() +# Hyperparameter tuning job +HYPERPARAMETER_TUNING_JOB_DISPLAY_NAME = "hpt_job" +HYPERPARAMETER_TUNING_JOB_ID = "4447046521673744384" +HYPERPARAMETER_TUNING_JOB_METRIC_SPEC = {'loss': 'minimize'} +HYPERPARAMETER_TUNING_JOB_MAX_TRIAL_COUNT = 128 +HYPERPARAMETER_TUNING_JOB_PARALLEL_TRIAL_COUNT = 8 +HYPERPARAMETER_TUNING_JOB_LABELS = {'my_key': 'my_value'} + +# Custom job +CUSTOM_JOB_DISPLAY_NAME = "custom_job" +CUSTOM_JOB_WORKER_POOL_SPECS = [ + { + "machine_spec": { + "machine_type": "n1-standard-4", + "accelerator_type": "NVIDIA_TESLA_K80", + "accelerator_count": 1, + }, + "replica_count": 1, + "container_spec": { + "image_uri": CONTAINER_URI, + "command": [], + "args": [], + }, + } +] + VERSION_ID = "test-version" IS_DEFAULT_VERSION = False VERSION_ALIASES = ["test-version-alias"]