Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
58 commits
Select commit Hold shift + click to select a range
ee25235
Add predict_stream with fallback
Jul 4, 2023
c799f54
Add predict_stream to handlers
Jul 4, 2023
4fa9c7a
Add sse-starlette to deps
Jul 11, 2023
fadff06
Send inference stream back as SSE
Jul 11, 2023
8c24122
Add tests for ServerSentEvent encoding
Jul 11, 2023
266420e
Update responses to use \n\n as separator
Jul 12, 2023
f23c60f
Add tests for infer-stream endpoint
Jul 12, 2023
1451a14
WIP: disable batch when streaming and adding tests for batch
Jul 13, 2023
f5a5de3
WIP
Jul 20, 2023
69b3423
Included generate and generate_stream endpoints and dataplane impleme…
RobertSamoilescu Apr 22, 2024
5024f1e
Included generate and generate_stream to MLModel.
RobertSamoilescu Apr 22, 2024
9abd39d
Included adaptive batching hooks for generate and generate_stream.
RobertSamoilescu Apr 22, 2024
1a7a2b3
Included test for batch hooks.
RobertSamoilescu Apr 22, 2024
43c983b
Corrected type in batch hooks comment.
RobertSamoilescu Apr 22, 2024
ab324bf
Included inputs to the text-model.
RobertSamoilescu Apr 22, 2024
3de2216
Included dataplane generate and generate_stream tests.
RobertSamoilescu Apr 22, 2024
55cf350
Included endpoint tests for generate and generate_stream.
RobertSamoilescu Apr 23, 2024
7f2140e
Split text model in TextModel and TextStreamModel.
RobertSamoilescu Apr 23, 2024
482a499
Included model tests (generate_stream fallback and generate_stream).
RobertSamoilescu Apr 23, 2024
124e6be
Refactored benchmarking text-model.
RobertSamoilescu Apr 23, 2024
1eefd22
Included gRPC support for generate and generate stream.
RobertSamoilescu Apr 25, 2024
d9119ae
Included grpc servicers tests.
RobertSamoilescu Apr 25, 2024
245b477
Included infer_stream as stream stream method.
RobertSamoilescu Apr 26, 2024
91b23c2
Back to the initially proposed batching hook.
RobertSamoilescu Apr 26, 2024
795dd26
Fixed rest tests.
RobertSamoilescu Apr 26, 2024
3cf01cd
Fixed grpc tests.
RobertSamoilescu Apr 26, 2024
c19fa47
Fixed adaptive batching hooks.
RobertSamoilescu Apr 26, 2024
6a01fa5
Included grpc stream proto.
RobertSamoilescu May 9, 2024
14a6b25
Included enable streaming flag for rest.
RobertSamoilescu May 9, 2024
322fc3e
Fixed rest stream tests.
RobertSamoilescu May 9, 2024
dd56030
Included logging warning for disabling gzip when streaming.
RobertSamoilescu May 9, 2024
107266c
Disabled grpc interceptor while streaming.
RobertSamoilescu May 9, 2024
1ce1ab4
Fixed predict_stream fallback.
RobertSamoilescu May 9, 2024
1f7da51
Settings streaming validator.
RobertSamoilescu May 9, 2024
37614c2
Checkout sum-model model-settings.json
RobertSamoilescu May 9, 2024
c143a50
Fixed inclusion of infer_stream endpoint.
RobertSamoilescu May 9, 2024
6a9d134
Checkout runtimes poetry lock.
RobertSamoilescu May 9, 2024
37ef1e3
Updated dependencies.
RobertSamoilescu May 9, 2024
c291d7d
Removed commented outdate batching test hook.
RobertSamoilescu May 9, 2024
26a0812
Removed sse_starlette dependency.
RobertSamoilescu May 9, 2024
5435d48
Fixed benchmarking text-model settings.
RobertSamoilescu May 9, 2024
d7d3c74
Fixed linting issues.
RobertSamoilescu May 9, 2024
447e658
Renamed benchmarking text model.
RobertSamoilescu May 10, 2024
12cbccd
Included lazy fixtures as depenedency.
RobertSamoilescu May 10, 2024
d52aca0
Removed streaming_enabled flag and introduced gzip_enabled flag.
RobertSamoilescu May 10, 2024
2302d99
Fixed linting issues.
RobertSamoilescu May 10, 2024
ccbf945
Fixed handlers tests.
RobertSamoilescu May 10, 2024
2cf3cb6
Checkout runtimes poetry.lock
RobertSamoilescu May 10, 2024
04a2aa8
Updated poetry.lock
RobertSamoilescu May 10, 2024
b632250
Regenerated lock after rebasing.
RobertSamoilescu May 15, 2024
37af739
Fixed merge conflicts.
RobertSamoilescu May 20, 2024
0841790
Removed proto dummy hello.
RobertSamoilescu May 20, 2024
852cfc1
Fixed grpc comments.
RobertSamoilescu May 20, 2024
bf49a3a
Adressed review comments.
RobertSamoilescu May 20, 2024
499bc9a
Fixed dataplane test.
RobertSamoilescu May 20, 2024
d900100
Included grpc stream error handling.
RobertSamoilescu May 21, 2024
93e3503
Minor fix stream infer error.
RobertSamoilescu May 21, 2024
0ec59c7
Included new line at the end of json file.
RobertSamoilescu May 22, 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
22 changes: 22 additions & 0 deletions benchmarking/testserver/models/text-model/model-settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"name": "text-model",

"implementation": "text_model.TextModel",

"versions": ["text-model/v1.2.3"],
"platform": "mlserver",
"inputs": [
{
"datatype": "BYTES",
"name": "prompt",
"shape": [1]
}
],
"outputs": [
{
"datatype": "BYTES",
"name": "output",
"shape": [1]
}
]
}
6 changes: 6 additions & 0 deletions benchmarking/testserver/models/text-model/settings.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"debug": false,
"parallel_workers": 0,
"gzip_enabled": false,
"metrics_endpoint": null
Comment thread
RobertSamoilescu marked this conversation as resolved.
}
45 changes: 45 additions & 0 deletions benchmarking/testserver/models/text-model/text_model.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import asyncio

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

should we add an example infer.py that uses this model? it is part of the PR description but probably better to have it here as well. Happy for it to be part of a follow up docs and examples PR.

from typing import AsyncIterator
from mlserver import MLModel
from mlserver.types import InferenceRequest, InferenceResponse
from mlserver.codecs import StringCodec


class TextModel(MLModel):

async def predict(self, payload: InferenceRequest) -> InferenceResponse:
text = StringCodec.decode_input(payload.inputs[0])[0]
return InferenceResponse(
model_name=self._settings.name,
outputs=[
StringCodec.encode_output(
name="output",
payload=[text],
use_bytes=True,
),
],
)

async def predict_stream(
self, payloads: AsyncIterator[InferenceRequest]
) -> AsyncIterator[InferenceResponse]:
payload = [_ async for _ in payloads][0]
text = StringCodec.decode_input(payload.inputs[0])[0]
words = text.split(" ")

split_text = []
for i, word in enumerate(words):
split_text.append(word if i == 0 else " " + word)

for word in split_text:
await asyncio.sleep(0.5)
yield InferenceResponse(
model_name=self._settings.name,
outputs=[
StringCodec.encode_output(
name="output",
payload=[word],
use_bytes=True,
),
],
)
64 changes: 48 additions & 16 deletions mlserver/batching/hooks.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
from functools import wraps
from typing import Awaitable, Callable, Optional
from typing import Awaitable, Callable, Optional, AsyncIterator

from ..errors import MLServerError
from ..model import MLModel
Expand All @@ -20,6 +20,26 @@ def __init__(self, method_name: str, reason: Optional[str] = None):
super().__init__(msg)


def _get_batcher(f: Callable) -> AdaptiveBatcher:
wrapped_f = get_wrapped_method(f)
model = _get_model(f)

if not hasattr(model, _AdaptiveBatchingAttr):
raise InvalidBatchingMethod(
wrapped_f.__name__, reason="adaptive batching has not been loaded"
)

return getattr(model, _AdaptiveBatchingAttr)


def _get_model(f: Callable) -> MLModel:
wrapped_f = get_wrapped_method(f)
if not hasattr(wrapped_f, "__self__"):
raise InvalidBatchingMethod(wrapped_f.__name__, reason="method is not bound")

return getattr(wrapped_f, "__self__")


def adaptive_batching(f: Callable[[InferenceRequest], Awaitable[InferenceResponse]]):
"""
Decorator for the `predict()` method which will ensure it uses the
Expand All @@ -28,24 +48,36 @@ def adaptive_batching(f: Callable[[InferenceRequest], Awaitable[InferenceRespons

@wraps(f)
async def _inner(payload: InferenceRequest) -> InferenceResponse:
wrapped_f = get_wrapped_method(f)
if not hasattr(wrapped_f, "__self__"):
raise InvalidBatchingMethod(
wrapped_f.__name__, reason="method is not bound"
)

model = getattr(wrapped_f, "__self__")
if not hasattr(model, _AdaptiveBatchingAttr):
raise InvalidBatchingMethod(
wrapped_f.__name__, reason="adaptive batching has not been loaded"
)

batcher = getattr(model, _AdaptiveBatchingAttr)
batcher = _get_batcher(f)
return await batcher.predict(payload)

return _inner


def not_implemented_warning(
f: Callable[[AsyncIterator[InferenceRequest]], AsyncIterator[InferenceResponse]],
):
"""
Decorator to lets users know that adaptive batching is not required on
method `f`.
"""
model = _get_model(f)
logger.warning(
f"Adaptive Batching is enabled for model '{model.name}'"
" but not supported for inference streaming."
" Falling back to non-batched inference streaming."
)

@wraps(f)
async def _inner_stream(
payload: AsyncIterator[InferenceRequest],
) -> AsyncIterator[InferenceResponse]:
async for response in f(payload):
yield response

return _inner_stream


async def load_batching(model: MLModel) -> MLModel:
if model.settings.max_batch_size <= 1:
return model
Expand All @@ -64,7 +96,7 @@ async def load_batching(model: MLModel) -> MLModel:
batcher = AdaptiveBatcher(model)
setattr(model, _AdaptiveBatchingAttr, batcher)

# Decorate predict method
# Decorate predict methods
setattr(model, "predict", adaptive_batching(model.predict))

setattr(model, "predict_stream", not_implemented_warning(model.predict_stream))
return model
5 changes: 3 additions & 2 deletions mlserver/grpc/dataplane_pb2.py

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading