-
Notifications
You must be signed in to change notification settings - Fork 792
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[Perf] Evaluate API: Support parallelized evaluator batch run through…
… pf.run (#3380) # Description The change in this PR addresses the performance issues we were seeing with the Evaluate API. This is the first step in optimizing performance. The improvements include: - Parallelizing the pf.run for evaluators. Previously, it ran sequentially, contributing to most of the latency. - Addressing the slowness of the import Evaluate API, which was due to the import of MLClient. - Using threads to infer signatures for eval batch runs instead of processes. (This change has been moved to a seperated PR: #3412) **Improvements from this change:** Windows OS, remote tracking disabled - 4 evaluators, 100 rows: - Previous (pf.run without threadpool): 320 secs - Current (pf.run with threadpool): 78 secs (~75% improvement) - 1 evaluator, 1 row: - Previous: 53 secs - Current: 17 secs (~68% improvement) Investigation details can be found [here](https://microsoft-my.sharepoint.com/:w:/p/ninhu/ETB_zdMkFrdAuf3Lcg9ssrUB6RVmyuFs5Un1G74O1HlwSA?e=23ngPm) # All Promptflow Contribution checklist: - [ ] **The pull request does not introduce [breaking changes].** - [ ] **CHANGELOG is updated for new features, bug fixes or other significant changes.** - [ ] **I have read the [contribution guidelines](../CONTRIBUTING.md).** - [ ] **Create an issue and link to the pull request to get dedicated review from promptflow team. Learn more: [suggested workflow](../CONTRIBUTING.md#suggested-workflow).** ## General Guidelines and Best Practices - [ ] Title of the pull request is clear and informative. - [ ] There are a small number of commits, each of which have an informative message. This means that previously merged commits do not appear in the history of the PR. For more information on cleaning up the commits in your PR, [see this page](https://github.com/Azure/azure-powershell/blob/master/documentation/development-docs/cleaning-up-commits.md). ### Testing Guidelines - [ ] Pull request includes test coverage for the included changes. --------- Co-authored-by: Clement Wang <47586720+wangchao1230@users.noreply.github.com>
- Loading branch information
1 parent
01267fd
commit 32115d3
Showing
15 changed files
with
255 additions
and
806 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
8 changes: 8 additions & 0 deletions
8
src/promptflow-evals/promptflow/evals/evaluate/_batch_run_client/__init__.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
# --------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# --------------------------------------------------------- | ||
from .batch_run_context import BatchRunContext | ||
from .code_client import CodeClient | ||
from .proxy_client import ProxyClient | ||
|
||
__all__ = ["CodeClient", "ProxyClient", "BatchRunContext"] |
32 changes: 32 additions & 0 deletions
32
src/promptflow-evals/promptflow/evals/evaluate/_batch_run_client/batch_run_context.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# --------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# --------------------------------------------------------- | ||
import os | ||
|
||
from promptflow._sdk._constants import PF_FLOW_ENTRY_IN_TMP | ||
from promptflow._utils.user_agent_utils import ClientUserAgentUtil | ||
from promptflow.tracing._integrations._openai_injector import inject_openai_api, recover_openai_api | ||
|
||
from ..._user_agent import USER_AGENT | ||
from .code_client import CodeClient | ||
from .proxy_client import ProxyClient | ||
|
||
|
||
class BatchRunContext: | ||
def __init__(self, client): | ||
self.client = client | ||
|
||
def __enter__(self): | ||
if isinstance(self.client, CodeClient): | ||
ClientUserAgentUtil.append_user_agent(USER_AGENT) | ||
inject_openai_api() | ||
|
||
if isinstance(self.client, ProxyClient): | ||
os.environ[PF_FLOW_ENTRY_IN_TMP] = "true" | ||
|
||
def __exit__(self, exc_type, exc_val, exc_tb): | ||
if isinstance(self.client, CodeClient): | ||
recover_openai_api() | ||
|
||
if isinstance(self.client, ProxyClient): | ||
os.environ.pop(PF_FLOW_ENTRY_IN_TMP, None) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
40 changes: 40 additions & 0 deletions
40
src/promptflow-evals/promptflow/evals/evaluate/_batch_run_client/proxy_client.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
# --------------------------------------------------------- | ||
# Copyright (c) Microsoft Corporation. All rights reserved. | ||
# --------------------------------------------------------- | ||
import logging | ||
|
||
import numpy as np | ||
|
||
from promptflow.client import PFClient | ||
from promptflow.tracing import ThreadPoolExecutorWithContext as ThreadPoolExecutor | ||
|
||
from ..._constants import BATCH_RUN_TIMEOUT | ||
|
||
LOGGER = logging.getLogger(__name__) | ||
|
||
|
||
class ProxyRun: | ||
def __init__(self, run, **kwargs): | ||
self.run = run | ||
|
||
|
||
class ProxyClient: | ||
def __init__(self, pf_client: PFClient): | ||
self._pf_client = pf_client | ||
self._thread_pool = ThreadPoolExecutor(thread_name_prefix="evaluators_thread") | ||
|
||
def run(self, flow, data, column_mapping=None, **kwargs): | ||
eval_future = self._thread_pool.submit( | ||
self._pf_client.run, flow, data=data, column_mapping=column_mapping, **kwargs | ||
) | ||
return ProxyRun(run=eval_future) | ||
|
||
def get_details(self, proxy_run, all_results=False): | ||
run = proxy_run.run.result(timeout=BATCH_RUN_TIMEOUT) | ||
result_df = self._pf_client.get_details(run, all_results=all_results) | ||
result_df.replace("(Failed)", np.nan, inplace=True) | ||
return result_df | ||
|
||
def get_metrics(self, proxy_run): | ||
run = proxy_run.run.result(timeout=BATCH_RUN_TIMEOUT) | ||
return self._pf_client.get_metrics(run) |
3 changes: 0 additions & 3 deletions
3
src/promptflow-evals/promptflow/evals/evaluate/_code_client/__init__.py
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.