9
9
from typing import Any , Callable , Dict , List , Optional , Set , Tuple , TypedDict , Union , cast
10
10
11
11
from azure .ai .evaluation ._legacy ._adapters ._constants import LINE_NUMBER
12
+ from azure .ai .evaluation ._legacy ._adapters ._errors import MissingRequiredPackage
12
13
from azure .ai .evaluation ._legacy ._adapters .entities import Run
13
14
import pandas as pd
14
15
40
41
_write_output ,
41
42
DataLoaderFactory ,
42
43
)
43
- from ._batch_run .batch_clients import BatchClient
44
+ from ._batch_run .batch_clients import BatchClient , BatchClientRun
44
45
45
46
LOGGER = logging .getLogger (__name__ )
46
47
@@ -486,12 +487,12 @@ def _validate_and_load_data(target, data, evaluators, output_path, azure_ai_proj
486
487
487
488
def _apply_target_to_data (
488
489
target : Callable ,
489
- data : Union [str , os .PathLike ],
490
+ data : Union [str , os .PathLike , pd . DataFrame ],
490
491
batch_client : BatchClient ,
491
492
initial_data : pd .DataFrame ,
492
493
evaluation_name : Optional [str ] = None ,
493
494
** kwargs ,
494
- ) -> Tuple [pd .DataFrame , Set [str ], Run ]:
495
+ ) -> Tuple [pd .DataFrame , Set [str ], BatchClientRun ]:
495
496
"""
496
497
Apply the target function to the data set and return updated data and generated columns.
497
498
@@ -509,24 +510,18 @@ def _apply_target_to_data(
509
510
:rtype: Tuple[pandas.DataFrame, List[str]]
510
511
"""
511
512
512
- if not isinstance (batch_client , ProxyClient ):
513
- raise ValueError ("Only ProxyClient supports target runs for now." )
514
-
515
513
_run_name = kwargs .get ("_run_name" )
516
- with TargetRunContext ():
517
- run = cast (
518
- ProxyRun ,
519
- batch_client .run (
520
- flow = target ,
521
- display_name = evaluation_name ,
522
- data = data ,
523
- stream = True ,
524
- name = _run_name ,
525
- ),
514
+ with TargetRunContext (batch_client ):
515
+ run : BatchClientRun = batch_client .run (
516
+ flow = target ,
517
+ display_name = evaluation_name ,
518
+ data = data ,
519
+ stream = True ,
520
+ name = _run_name ,
521
+ evaluator_name = getattr (target , "__qualname__" , "TARGET" ),
526
522
)
527
-
528
- target_output : pd .DataFrame = batch_client .get_details (run , all_results = True )
529
- run_summary = batch_client .get_run_summary (run )
523
+ target_output : pd .DataFrame = batch_client .get_details (run , all_results = True )
524
+ run_summary = batch_client .get_run_summary (run )
530
525
531
526
if run_summary ["completed_lines" ] == 0 :
532
527
msg = (
@@ -557,7 +552,7 @@ def _apply_target_to_data(
557
552
# Concatenate output to input
558
553
target_output = pd .concat ([target_output , initial_data ], axis = 1 )
559
554
560
- return target_output , generated_columns , run . run . result ()
555
+ return target_output , generated_columns , run
561
556
562
557
563
558
def _process_column_mappings (
@@ -777,19 +772,27 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
777
772
column_mapping = column_mapping or {}
778
773
column_mapping .setdefault ("default" , {})
779
774
780
- target_run : Optional [Run ] = None
775
+ target_run : Optional [BatchClientRun ] = None
781
776
target_generated_columns : Set [str ] = set ()
782
777
batch_run_client : BatchClient
783
778
batch_run_data : Union [str , os .PathLike , pd .DataFrame ] = data
784
779
785
- # If target is set, apply 1-1 column mapping from target outputs to evaluator inputs
786
- if data is not None and target is not None :
787
- # Right now, only the ProxyClient that uses Promptflow supports a target function
780
+ if kwargs .pop ("_use_run_submitter_client" , False ):
781
+ batch_run_client = RunSubmitterClient ()
782
+ batch_run_data = input_data_df
783
+ elif kwargs .pop ("_use_pf_client" , True ):
788
784
batch_run_client = ProxyClient (user_agent = USER_AGENT )
785
+ # Ensure the absolute path is passed to pf.run, as relative path doesn't work with
786
+ # multiple evaluators. If the path is already absolute, abspath will return the original path.
789
787
batch_run_data = os .path .abspath (data )
788
+ else :
789
+ batch_run_client = CodeClient ()
790
+ batch_run_data = input_data_df
790
791
792
+ # If target is set, apply 1-1 column mapping from target outputs to evaluator inputs
793
+ if data is not None and target is not None :
791
794
input_data_df , target_generated_columns , target_run = _apply_target_to_data (
792
- target , data , batch_run_client , input_data_df , evaluation_name , ** kwargs
795
+ target , batch_run_data , batch_run_client , input_data_df , evaluation_name , ** kwargs
793
796
)
794
797
795
798
for evaluator_name , mapping in column_mapping .items ():
@@ -803,17 +806,6 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
803
806
# customer did not mapped target output.
804
807
if col not in mapping and run_output not in mapped_to_values :
805
808
column_mapping [evaluator_name ][col ] = run_output # pylint: disable=unnecessary-dict-index-lookup
806
- elif kwargs .pop ("_use_run_submitter_client" , False ):
807
- batch_run_client = RunSubmitterClient ()
808
- batch_run_data = input_data_df
809
- elif kwargs .pop ("_use_pf_client" , True ):
810
- batch_run_client = ProxyClient (user_agent = USER_AGENT )
811
- # Ensure the absolute path is passed to pf.run, as relative path doesn't work with
812
- # multiple evaluators. If the path is already absolute, abspath will return the original path.
813
- batch_run_data = os .path .abspath (data )
814
- else :
815
- batch_run_client = CodeClient ()
816
- batch_run_data = input_data_df
817
809
818
810
# After we have generated all columns, we can check if we have everything we need for evaluators.
819
811
_validate_columns_for_evaluators (input_data_df , evaluators , target , target_generated_columns , column_mapping )
@@ -896,12 +888,11 @@ def _evaluate( # pylint: disable=too-many-locals,too-many-statements
896
888
metrics .update (evaluators_metric )
897
889
898
890
# Since tracing is disabled, pass None for target_run so a dummy evaluation run will be created each time.
899
- target_run : Optional [Run ] = None
900
891
trace_destination = _trace_destination_from_project_scope (azure_ai_project ) if azure_ai_project else None
901
892
studio_url = None
902
893
if trace_destination :
903
894
studio_url = _log_metrics_and_instance_results (
904
- metrics , result_df , trace_destination , target_run , evaluation_name , ** kwargs
895
+ metrics , result_df , trace_destination , None , evaluation_name , ** kwargs
905
896
)
906
897
907
898
result_df_dict = result_df .to_dict ("records" )
0 commit comments