Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Port over the latest batch score changes from the ADO repository #2170

Merged
merged 98 commits into from
Jan 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
98 commits
Select commit Hold shift + click to select a range
04b1148
Latest copy
Iyer-Narayan Jan 22, 2024
cba6790
Update
Iyer-Narayan Jan 22, 2024
6ff9065
Updtae
Iyer-Narayan Jan 22, 2024
1dc83b9
Fix flake8 errors in e2e tests
yetamsft Jan 22, 2024
92a30a0
Update
Iyer-Narayan Jan 22, 2024
ee1febb
Fix flake8 error in test fixtures
yetamsft Jan 22, 2024
9a335cc
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
yetamsft Jan 22, 2024
a809eb6
Update
Iyer-Narayan Jan 22, 2024
a3d71c4
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 22, 2024
ddd2344
remove all whitespaces
Iyer-Narayan Jan 22, 2024
8b82ca3
Fix flake8 errors in unit tests
yetamsft Jan 22, 2024
c5f1e1b
update
Iyer-Narayan Jan 22, 2024
4eecfce
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 22, 2024
4c05e7d
update
Iyer-Narayan Jan 22, 2024
9f06b73
Fix flake8 unit tests
yetamsft Jan 22, 2024
2e1dcbe
Fix flake8 error in tests
yetamsft Jan 22, 2024
90246a6
update
Iyer-Narayan Jan 22, 2024
2d8bfa5
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 22, 2024
c490e1d
update
Iyer-Narayan Jan 22, 2024
37bedc0
update
Iyer-Narayan Jan 23, 2024
822ebc9
update
Iyer-Narayan Jan 23, 2024
8d787e9
Fix pydocstyle error in tests
yetamsft Jan 23, 2024
b97f47e
update
Iyer-Narayan Jan 23, 2024
570263f
update
Iyer-Narayan Jan 23, 2024
a06e605
update
Iyer-Narayan Jan 23, 2024
e7a5341
update
Iyer-Narayan Jan 23, 2024
6b96a23
update
Iyer-Narayan Jan 23, 2024
79ce289
update
Iyer-Narayan Jan 23, 2024
b8a5644
update
Iyer-Narayan Jan 23, 2024
1a3a9f6
update
Iyer-Narayan Jan 23, 2024
8f58dfe
update
Iyer-Narayan Jan 23, 2024
ca75233
update
Iyer-Narayan Jan 23, 2024
2782068
update
Iyer-Narayan Jan 23, 2024
2fb388b
update
Iyer-Narayan Jan 23, 2024
69b53db
update
Iyer-Narayan Jan 23, 2024
da9f8ee
update
Iyer-Narayan Jan 23, 2024
29c08f2
update
Iyer-Narayan Jan 23, 2024
0a798b6
Fix flake8
yetamsft Jan 23, 2024
80514bb
pydocstyle
yetamsft Jan 23, 2024
2bf12a9
update
Iyer-Narayan Jan 23, 2024
9d70ae7
update
Iyer-Narayan Jan 23, 2024
91b1ca9
fix pydocstyle
yetamsft Jan 23, 2024
525065d
Add file headers
Iyer-Narayan Jan 23, 2024
12c31ff
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
ac2e249
fix pydocstring
yetamsft Jan 23, 2024
e398634
update
yetamsft Jan 23, 2024
082f70e
update
yetamsft Jan 23, 2024
270976e
update
yetamsft Jan 23, 2024
43b3af2
Update init
Iyer-Narayan Jan 23, 2024
9d321f4
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
39db5e7
Update
Iyer-Narayan Jan 23, 2024
3693bdb
update
Iyer-Narayan Jan 23, 2024
3444b71
fix comments
Iyer-Narayan Jan 23, 2024
9f02911
fix comments
Iyer-Narayan Jan 23, 2024
78f04d4
update
yetamsft Jan 23, 2024
ca77da3
update
yetamsft Jan 23, 2024
3e2f3b6
Add flake8 ignore to init files
Iyer-Narayan Jan 23, 2024
680e8c8
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
1dddc8a
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
yetamsft Jan 23, 2024
299dcd8
updte
Iyer-Narayan Jan 23, 2024
38e8de6
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
927b086
update
yetamsft Jan 23, 2024
50878ad
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
yetamsft Jan 23, 2024
95a8f85
Add missing init files
Iyer-Narayan Jan 23, 2024
5a9caa2
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
a51d76a
update
yetamsft Jan 23, 2024
c79090d
update
yetamsft Jan 23, 2024
46b5517
formatting
Iyer-Narayan Jan 23, 2024
7ea65b9
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
Iyer-Narayan Jan 23, 2024
5a4c532
fix dev
yetamsft Jan 23, 2024
4415cf7
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
yetamsft Jan 23, 2024
abae8b6
Update
yetamsft Jan 23, 2024
c98f656
update
yetamsft Jan 23, 2024
3fa8c93
Add docstring to files under common.telemetry.events
chupadhy Jan 23, 2024
0c8220a
Merge branch 'niyer/batch_score/20240122' of https://github.com/Azure…
chupadhy Jan 23, 2024
5f47bbd
Merge remote-tracking branch 'origin/main' into niyer/batch_score/202…
yetamsft Jan 23, 2024
c016086
revert unintented
yetamsft Jan 23, 2024
34a6acb
Fix
yetamsft Jan 23, 2024
a9bb034
update
yetamsft Jan 23, 2024
7bd2cf4
fix
yetamsft Jan 23, 2024
d2fafc4
remove dev training folder
yetamsft Jan 23, 2024
e319cfb
Fix
yetamsft Jan 23, 2024
fbc8221
update
yetamsft Jan 23, 2024
348b000
fix
yetamsft Jan 23, 2024
dc2836d
Fix
yetamsft Jan 24, 2024
7182eaa
Add missing file
yetamsft Jan 24, 2024
54aa510
Merge remote-tracking branch 'origin/main' into niyer/batch_score/202…
yetamsft Jan 24, 2024
48f42c4
timeout
yetamsft Jan 24, 2024
42d1f89
Fix e2e tests
yetamsft Jan 24, 2024
733d7af
fix e2e tests
yetamsft Jan 24, 2024
375d482
fix tiktoken
yetamsft Jan 24, 2024
cf11638
fix
yetamsft Jan 24, 2024
656f37a
fix
yetamsft Jan 24, 2024
749c251
update
yetamsft Jan 24, 2024
b2499a0
update
yetamsft Jan 24, 2024
63acf33
update
yetamsft Jan 24, 2024
1a7a40c
update
yetamsft Jan 24, 2024
019a572
update
yetamsft Jan 24, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion assets/batch_score/components/driver/dev/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ This folder does not verify any yaml configurations.
},
"args": [
"--debug_mode", "true",
"--online_endpoint_url", "https://real-dv3-stable.centralus.inference.ml.azure.com/v1/engines/davinci/completions"
"--online_endpoint_url", "https://real-dv3-stable.centralus.inference.ml.azure.com/v1/engines/davinci/completions",
]
}
]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,9 @@ class Simulator:
"""PRS Simulator."""

def __init__(self, data_input_folder_path):
"""Init function."""
"""Initialize PRS Simulator."""
os.getcwd()

self.__mltable_data: mltable = mltable.load(data_input_folder_path)
self.__df_data = self.__mltable_data.to_pandas_dataframe()
self.__minibatch_size = 500 # lines
Expand Down
4 changes: 2 additions & 2 deletions assets/batch_score/components/driver/dev/quota_simulator.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class QuotaSimulator(ServiceSimulator):
"""Quota simulator."""

def __init__(self):
"""Init function."""
"""Initialize QuotaSimulator."""
super().__init__(handler=partial(self.RequestHandler, simulator=self))

self._leases = {}
Expand All @@ -48,7 +48,7 @@ class RequestHandler(ServiceSimulator.RequestHandler):
"""Simulator request handler."""

def __init__(self, *args, simulator: 'QuotaSimulator', **kwargs):
"""Init function."""
"""Initialize RequestHandler."""
self.__simulator = simulator
super().__init__(*args, **kwargs)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ class RoutingSimulator(ServiceSimulator):
"""Routing simulator."""

def __init__(self):
"""Init function."""
"""Initialize RoutingSimulator."""
super().__init__(handler=self.RequestHandler)

@classmethod
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ class ServiceSimulator:
"""Service simulator."""

def __init__(self, handler):
"""Init function."""
"""Initialize ServiceSimulator."""
self.__server = ThreadingHTTPServer(("localhost", 0), handler)
self.__thread = Thread(target=self.__server.serve_forever, daemon=True)

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ def print_stats(model: LinearRegression, test_x, test_y, *, name=''):
print(f'Model {name}')
print('=====')
print()
print('Coefficients: ', model.coef_, sep='\n')
print('Coefficients:', model.coef_, sep='\n')
print('---')
print(f'Min: {test_y.min()}')
print(f'Avg: {int(test_y.mean())}')
Expand Down
3 changes: 3 additions & 0 deletions assets/batch_score/components/driver/src/__init__.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# flake8: noqa: F401

"""__init__."""
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# flake8: noqa: F401

"""__init__."""

import subprocess
import sys

# TODO: remove this hack after dedicated environment is published.
subprocess.check_call([sys.executable, "-m", "pip", "install", 'tiktoken==0.5.2'])
subprocess.check_call([sys.executable,"-m", "pip", "install",
'PyDispatcher==2.0.7',
'StrEnum==0.4.15',
'tiktoken==0.5.2'])
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# flake8: noqa: F401

"""__init__."""
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

# flake8: noqa: F401

"""__init__."""
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

"""This file contains the definition for AOAI header provider."""

import json
import uuid

from ...common.auth.auth_provider import AuthProvider
from ...common.scoring.generic_scoring_client import HeaderProvider


class AoaiHeaderProvider(HeaderProvider):
"""Defines the AOAI header provider."""

def __init__(
self,
auth_provider: AuthProvider,
additional_headers: str = None,
):
"""Initialize AoaiHeaderProvider."""
self._auth_provider = auth_provider

if additional_headers is not None:
self._additional_headers = json.loads(additional_headers)
else:
self._additional_headers = {}

def get_headers(self) -> dict:
"""Get the headers from the auth provider and additional headers."""
headers = {
'Content-Type': 'application/json',
'x-ms-client-request-id': str(uuid.uuid4()),
}
headers.update(self._auth_provider.get_auth_headers())
headers.update(self._additional_headers)

return headers
Original file line number Diff line number Diff line change
@@ -0,0 +1,167 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.

"""This file contains the definition for AOAI response handler."""

import asyncio

import aiohttp

from ...common.scoring.generic_scoring_client import (
HttpResponseHandler,
HttpScoringResponse,
)
from ...common.scoring.scoring_request import ScoringRequest
from ...common.scoring.scoring_result import (
RetriableException,
ScoringResult,
ScoringResultStatus,
)
from ...common.scoring.tally_failed_request_handler import TallyFailedRequestHandler
from ...common.telemetry.events import event_utils
from ...common.telemetry.events.batch_score_request_completed_event import BatchScoreRequestCompletedEvent


class AoaiHttpResponseHandler(HttpResponseHandler):
"""Defines the AOAI HTTP response handler."""

RETRIABLE_STATUS_CODES = [408, 429, 500, 502, 503, 504]

def __init__(self, tally_handler: TallyFailedRequestHandler):
"""Initialize AoaiHttpResponseHandler."""
self.__tally_handler = tally_handler

def handle_response(
self,
http_response: HttpScoringResponse,
scoring_request: ScoringRequest,
x_ms_client_request_id: str,
start: float,
end: float,
worker_id: str) -> ScoringResult:
"""Handle the response from the model for the provided scoring request."""
# Emit request completed event
self._emit_request_completed_event(
http_response=http_response,
scoring_request=scoring_request,
x_ms_client_request_id=x_ms_client_request_id,
start=start,
end=end,
worker_id=worker_id
)

if http_response.exception:
return self._handle_exception(
http_response=http_response,
scoring_request=scoring_request,
start=start,
end=end,
)

response_status = http_response.status
if response_status == 200:
return self._create_scoring_result(
status=ScoringResultStatus.SUCCESS,
scoring_request=scoring_request,
start=start,
end=end,
http_post_response=http_response,
)

if self.is_retriable(response_status):
raise RetriableException(
status_code=http_response.status,
response_payload=http_response.payload)

result = self._create_scoring_result(
status=ScoringResultStatus.FAILURE,
scoring_request=scoring_request,
start=start,
end=end,
http_post_response=http_response,
)

model_response_code = http_response.get_model_response_code()
if (
result.status == ScoringResultStatus.FAILURE
and self.__tally_handler.should_tally(
response_status=response_status,
model_response_status=model_response_code)
):
result.omit = True

return result

def is_retriable(self, http_status: int) -> bool:
"""Is the http status retriable."""
return http_status in self.RETRIABLE_STATUS_CODES

def _handle_exception(
self,
http_response: HttpScoringResponse,
scoring_request: ScoringRequest,
start: float,
end: float) -> ScoringResult:
"""Handle exception by raising retriable exception or creating scoring result for non-retriable exception."""
try:
raise http_response.exception
except (
aiohttp.ClientConnectorError,
aiohttp.ServerConnectionError,
asyncio.TimeoutError,
):
raise RetriableException(
status_code=http_response.status,
response_payload=http_response.payload,
)
except Exception:
return self._create_scoring_result(
status=ScoringResultStatus.FAILURE,
scoring_request=scoring_request,
start=start,
end=end,
http_post_response=http_response,
)

@event_utils.catch_and_log_all_exceptions
def _emit_request_completed_event(
self,
http_response: HttpScoringResponse,
scoring_request: ScoringRequest,
x_ms_client_request_id: str,
start: float,
end: float,
worker_id: str) -> None:

def get_prompt_tokens(response_body: any):
if not isinstance(response_body, dict):
return None

return response_body.get("usage", {}).get("prompt_tokens")

def get_completion_tokens(response_body: any):
if not isinstance(response_body, dict):
return None

return response_body.get("usage", {}).get("completion_tokens")

def get_mini_batch_id(mini_batch_context: any):
if mini_batch_context:
return mini_batch_context.mini_batch_id

request_completed_event = BatchScoreRequestCompletedEvent(
minibatch_id=get_mini_batch_id(scoring_request.mini_batch_context),
input_row_id=scoring_request.internal_id,
x_ms_client_request_id=x_ms_client_request_id,
worker_id=worker_id,
scoring_url=scoring_request.scoring_url,
is_successful=http_response.status == 200,
is_retriable=self.is_retriable(http_response.status),
response_code=http_response.status,
model_response_code=http_response.get_model_response_code(),
prompt_tokens=get_prompt_tokens(http_response.payload),
completion_tokens=get_completion_tokens(http_response.payload),
duration_ms=(end - start) * 1000,
segmented_request_id=scoring_request.segment_id
)
event_utils.emit_event(batch_score_event=request_completed_event)
Loading
Loading