Skip to content

Commit d6f99cb

Browse files
jsondaicopybara-github
authored andcommitted
feat: Copy output uploading features from GA Eval SDK to preview.
PiperOrigin-RevId: 740001047
1 parent 43ebe97 commit d6f99cb

File tree

1 file changed

+91
-9
lines changed

1 file changed

+91
-9
lines changed

vertexai/preview/evaluation/utils.py

+91-9
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919
import functools
2020
import io
21+
import json
2122
import os
2223
import tempfile
2324
import threading
@@ -30,10 +31,15 @@
3031
from google.cloud.aiplatform import compat
3132
from google.cloud.aiplatform import initializer
3233
from google.cloud.aiplatform import utils
34+
from google.cloud.aiplatform.utils import _ipython_utils
35+
from vertexai.evaluation import _base as eval_base
3336
from google.cloud.aiplatform_v1beta1.services import (
3437
evaluation_service as gapic_evaluation_services,
3538
)
36-
39+
from vertexai.evaluation.metrics import (
40+
_base as metrics_base,
41+
metric_prompt_template as metric_prompt_template_base,
42+
)
3743

3844
if TYPE_CHECKING:
3945
import pandas as pd
@@ -255,6 +261,16 @@ def _read_gcs_file_contents(filepath: str) -> str:
255261
return blob.download_as_string().decode("utf-8")
256262

257263

264+
def _upload_file_to_gcs(upload_gcs_path: str, filename: str) -> None:
265+
storage_client = storage.Client(
266+
project=initializer.global_config.project,
267+
credentials=initializer.global_config.credentials,
268+
)
269+
storage.Blob.from_string(
270+
uri=upload_gcs_path, client=storage_client
271+
).upload_from_filename(filename)
272+
273+
258274
def _upload_pandas_df_to_gcs(
259275
df: "pd.DataFrame", upload_gcs_path: str, file_type: str
260276
) -> None:
@@ -288,28 +304,94 @@ def _upload_pandas_df_to_gcs(
288304
).upload_from_filename(filename=local_dataset_path)
289305

290306

307+
def _upload_evaluation_summary_to_gcs(
308+
summary_metrics: Dict[str, float],
309+
upload_gcs_path: str,
310+
candidate_model_name: Optional[str] = None,
311+
baseline_model_name: Optional[str] = None,
312+
dataset_uri: Optional[str] = None,
313+
metrics: Optional[List[Union[str, metrics_base._Metric]]] = None,
314+
) -> None:
315+
"""Uploads the evaluation summary to a GCS bucket."""
316+
summary = {
317+
"summary_metrics": summary_metrics,
318+
}
319+
if candidate_model_name:
320+
summary["candidate_model_name"] = candidate_model_name
321+
if baseline_model_name:
322+
summary["baseline_model_name"] = baseline_model_name
323+
if dataset_uri:
324+
summary["dataset_uri"] = dataset_uri
325+
326+
if metrics:
327+
metric_descriptions = {}
328+
for metric in metrics:
329+
if isinstance(metric, metrics_base._ModelBasedMetric) and isinstance(
330+
metric._raw_metric_prompt_template,
331+
metric_prompt_template_base._MetricPromptTemplate,
332+
):
333+
metric_descriptions[metric.metric_name] = {
334+
"criteria": metric._raw_metric_prompt_template._criteria,
335+
"rating_rubric": metric._raw_metric_prompt_template._rating_rubric,
336+
}
337+
summary["metric_descriptions"] = metric_descriptions
338+
339+
with tempfile.TemporaryDirectory() as temp_dir:
340+
local_summary_path = os.path.join(temp_dir, "summary_metrics.json")
341+
json.dump(summary, open(local_summary_path, "w"))
342+
_upload_file_to_gcs(upload_gcs_path, local_summary_path)
343+
344+
291345
def upload_evaluation_results(
292-
dataset: "pd.DataFrame", destination_uri_prefix: str, file_name: str
346+
eval_result: eval_base.EvalResult,
347+
destination_uri_prefix: str,
348+
file_name: Optional[str] = None,
349+
candidate_model_name: Optional[str] = None,
350+
baseline_model_name: Optional[str] = None,
351+
dataset_uri: Optional[str] = None,
352+
metrics: Optional[List[Union[str, metrics_base._Metric]]] = None,
293353
) -> None:
294354
"""Uploads eval results to GCS destination.
295355
296356
Args:
297-
dataset: Pandas dataframe to upload.
357+
eval_result: Eval results to upload.
298358
destination_uri_prefix: GCS folder to store the data.
299-
file_name: File name to store the data.
359+
file_name: Optional. File name to store the metrics table.
360+
candidate_model_name: Optional. Candidate model name.
361+
baseline_model_name: Optional. Baseline model name.
362+
dataset_uri: Optional. URI pointing to the dataset.
363+
metrics: Optional. List of metrics used for evaluation.
300364
"""
301-
302365
if not destination_uri_prefix:
366+
_ipython_utils.display_gen_ai_evaluation_results_button()
367+
return
368+
if eval_result.metrics_table is None:
303369
return
304370
if destination_uri_prefix.startswith(_GCS_PREFIX):
305-
_, extension = os.path.splitext(file_name)
371+
if not file_name:
372+
file_name = f"eval_results_{utils.timestamped_unique_name()}.csv"
373+
base_name, extension = os.path.splitext(file_name)
306374
file_type = extension.lower()[1:]
307-
output_path = destination_uri_prefix + "/" + file_name
308-
_upload_pandas_df_to_gcs(dataset, output_path, file_type)
375+
output_folder = destination_uri_prefix + "/" + base_name
376+
metrics_table_path = output_folder + "/" + file_name
377+
_upload_pandas_df_to_gcs(
378+
eval_result.metrics_table, metrics_table_path, file_type
379+
)
380+
_upload_evaluation_summary_to_gcs(
381+
eval_result.summary_metrics,
382+
output_folder + "/summary_metrics.json",
383+
candidate_model_name,
384+
baseline_model_name,
385+
dataset_uri,
386+
metrics,
387+
)
388+
_ipython_utils.display_gen_ai_evaluation_results_button(
389+
metrics_table_path.split(_GCS_PREFIX)[1]
390+
)
309391
else:
310392
raise ValueError(
311393
f"Unsupported destination URI: {destination_uri_prefix}."
312-
" Please provide a valid GCS bucket URI prefix starting with"
394+
f" Please provide a valid GCS bucket URI prefix starting with"
313395
f" {_GCS_PREFIX}."
314396
)
315397

0 commit comments

Comments
 (0)