|
18 | 18 |
|
19 | 19 | import functools
|
20 | 20 | import io
|
| 21 | +import json |
21 | 22 | import os
|
22 | 23 | import tempfile
|
23 | 24 | import threading
|
|
30 | 31 | from google.cloud.aiplatform import compat
|
31 | 32 | from google.cloud.aiplatform import initializer
|
32 | 33 | from google.cloud.aiplatform import utils
|
| 34 | +from google.cloud.aiplatform.utils import _ipython_utils |
| 35 | +from vertexai.evaluation import _base as eval_base |
33 | 36 | from google.cloud.aiplatform_v1beta1.services import (
|
34 | 37 | evaluation_service as gapic_evaluation_services,
|
35 | 38 | )
|
36 |
| - |
| 39 | +from vertexai.evaluation.metrics import ( |
| 40 | + _base as metrics_base, |
| 41 | + metric_prompt_template as metric_prompt_template_base, |
| 42 | +) |
37 | 43 |
|
38 | 44 | if TYPE_CHECKING:
|
39 | 45 | import pandas as pd
|
@@ -255,6 +261,16 @@ def _read_gcs_file_contents(filepath: str) -> str:
|
255 | 261 | return blob.download_as_string().decode("utf-8")
|
256 | 262 |
|
257 | 263 |
|
| 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 | + |
258 | 274 | def _upload_pandas_df_to_gcs(
|
259 | 275 | df: "pd.DataFrame", upload_gcs_path: str, file_type: str
|
260 | 276 | ) -> None:
|
@@ -288,28 +304,94 @@ def _upload_pandas_df_to_gcs(
|
288 | 304 | ).upload_from_filename(filename=local_dataset_path)
|
289 | 305 |
|
290 | 306 |
|
| 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 | + |
291 | 345 | 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, |
293 | 353 | ) -> None:
|
294 | 354 | """Uploads eval results to GCS destination.
|
295 | 355 |
|
296 | 356 | Args:
|
297 |
| - dataset: Pandas dataframe to upload. |
| 357 | + eval_result: Eval results to upload. |
298 | 358 | 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. |
300 | 364 | """
|
301 |
| - |
302 | 365 | if not destination_uri_prefix:
|
| 366 | + _ipython_utils.display_gen_ai_evaluation_results_button() |
| 367 | + return |
| 368 | + if eval_result.metrics_table is None: |
303 | 369 | return
|
304 | 370 | 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) |
306 | 374 | 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 | + ) |
309 | 391 | else:
|
310 | 392 | raise ValueError(
|
311 | 393 | 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" |
313 | 395 | f" {_GCS_PREFIX}."
|
314 | 396 | )
|
315 | 397 |
|
|
0 commit comments