From eaf5d816a7a752373243033ea98146d70987ce18 Mon Sep 17 00:00:00 2001 From: Alexey Volkov Date: Tue, 10 Oct 2023 22:15:53 -0700 Subject: [PATCH] feat: LLM - Enable tuning eval TensorBoard without evaluation data PiperOrigin-RevId: 572460871 --- tests/unit/aiplatform/test_language_models.py | 50 +++++++++++++++++++ vertexai/language_models/_language_models.py | 15 +++--- 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/tests/unit/aiplatform/test_language_models.py b/tests/unit/aiplatform/test_language_models.py index 7b253da5f8..3548133d7f 100644 --- a/tests/unit/aiplatform/test_language_models.py +++ b/tests/unit/aiplatform/test_language_models.py @@ -1638,6 +1638,56 @@ def test_tune_text_generation_model_ga( == test_constants.EndpointConstants._TEST_ENDPOINT_NAME ) + @pytest.mark.parametrize( + "job_spec", + [_TEST_PIPELINE_SPEC_JSON], + ) + @pytest.mark.parametrize( + "mock_request_urlopen", + ["https://us-central1-kfp.pkg.dev/proj/repo/pack/latest"], + indirect=True, + ) + def test_tune_text_generation_model_evaluation_with_only_tensorboard( + self, + mock_pipeline_service_create, + mock_pipeline_job_get, + mock_pipeline_bucket_exists, + job_spec, + mock_load_yaml_and_json, + mock_gcs_from_string, + mock_gcs_upload, + mock_request_urlopen, + mock_get_tuned_model, + ): + """Tests tuning the text generation model.""" + with mock.patch.object( + target=model_garden_service_client.ModelGardenServiceClient, + attribute="get_publisher_model", + return_value=gca_publisher_model.PublisherModel( + _TEXT_BISON_PUBLISHER_MODEL_DICT + ), + ): + model = language_models.TextGenerationModel.from_pretrained( + "text-bison@001" + ) + + tuning_job_location = "europe-west4" + tensorboard_name = f"projects/{_TEST_PROJECT}/locations/{tuning_job_location}/tensorboards/123" + + model.tune_model( + training_data=_TEST_TEXT_BISON_TRAINING_DF, + tuning_job_location=tuning_job_location, + tuned_model_location="us-central1", + tuning_evaluation_spec=preview_language_models.TuningEvaluationSpec( + tensorboard=tensorboard_name, + ), + ) + call_kwargs = mock_pipeline_service_create.call_args[1] + pipeline_arguments = call_kwargs[ + "pipeline_job" + ].runtime_config.parameter_values + assert pipeline_arguments["tensorboard_resource_id"] == tensorboard_name + @pytest.mark.parametrize( "job_spec", [_TEST_PIPELINE_SPEC_JSON], diff --git a/vertexai/language_models/_language_models.py b/vertexai/language_models/_language_models.py index 9a13ae5916..6981782e3b 100644 --- a/vertexai/language_models/_language_models.py +++ b/vertexai/language_models/_language_models.py @@ -214,13 +214,14 @@ def tune_model( tuning_parameters["learning_rate_multiplier"] = learning_rate_multiplier eval_spec = tuning_evaluation_spec if eval_spec is not None: - if isinstance(eval_spec.evaluation_data, str): - if eval_spec.evaluation_data.startswith("gs://"): - tuning_parameters["evaluation_data_uri"] = eval_spec.evaluation_data + if eval_spec.evaluation_data: + if isinstance(eval_spec.evaluation_data, str): + if eval_spec.evaluation_data.startswith("gs://"): + tuning_parameters["evaluation_data_uri"] = eval_spec.evaluation_data + else: + raise ValueError("evaluation_data should be a GCS URI") else: - raise ValueError("evaluation_data should be a GCS URI") - else: - raise TypeError("evaluation_data should be a URI string") + raise TypeError("evaluation_data should be a URI string") if eval_spec.evaluation_interval is not None: tuning_parameters["evaluation_interval"] = eval_spec.evaluation_interval if eval_spec.enable_early_stopping is not None: @@ -648,7 +649,7 @@ class TuningEvaluationSpec: __module__ = "vertexai.language_models" - evaluation_data: str + evaluation_data: Optional[str] = None evaluation_interval: Optional[int] = None enable_early_stopping: Optional[bool] = None tensorboard: Optional[Union[aiplatform.Tensorboard, str]] = None