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

feat: update the samples of hyperparameter tuning in the public doc #1600

Merged
merged 8 commits into from
Sep 6, 2022
34 changes: 34 additions & 0 deletions samples/model-builder/cancel_hyperparameter_tuning_job_sample.py
Original file line number Diff line number Diff line change
@@ -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]
Original file line number Diff line number Diff line change
@@ -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()
55 changes: 55 additions & 0 deletions samples/model-builder/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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


"""
----------------------------------------------------------------------------
Expand Down
74 changes: 74 additions & 0 deletions samples/model-builder/create_hyperparameter_tuning_job_sample.py
Original file line number Diff line number Diff line change
@@ -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,
Copy link
Contributor

Choose a reason for hiding this comment

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

Seems weird to pass in container_uri when it's not used in the tuning job.

@dizcology thoughts?

Copy link
Contributor

Choose a reason for hiding this comment

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

Hptuning job creates sub jobs(trials) using the container image uri, it's actually used by the vertex hptuning jobs.

"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={
Copy link
Contributor

@ivanmkc ivanmkc Aug 22, 2022

Choose a reason for hiding this comment

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

We usually pass in some of these as parameters to the function but I'm not sure how to include things like parameter specs without cluttering the parameter space with all possible parameters to CustomJob and HyperparameterTuningJob.

Copy link
Contributor

Choose a reason for hiding this comment

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

@dizcology do you have guidance or is this okay?

'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]
Original file line number Diff line number Diff line change
@@ -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()
34 changes: 34 additions & 0 deletions samples/model-builder/delete_hyperparameter_tuning_job_sample.py
Original file line number Diff line number Diff line change
@@ -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]
Original file line number Diff line number Diff line change
@@ -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()
34 changes: 34 additions & 0 deletions samples/model-builder/get_hyperparameter_tuning_job_sample.py
Original file line number Diff line number Diff line change
@@ -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]
Loading