litserve 0.2.6.dev1__tar.gz → 0.2.6.dev2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {litserve-0.2.6.dev1/src/litserve.egg-info → litserve-0.2.6.dev2}/PKG-INFO +5 -5
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/__about__.py +1 -1
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/api.py +2 -2
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/loops.py +72 -28
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/specs/base.py +4 -1
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/specs/openai.py +5 -5
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2/src/litserve.egg-info}/PKG-INFO +5 -5
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/LICENSE +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/MANIFEST.in +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/README.md +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/requirements.txt +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/setup.cfg +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/setup.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/__main__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/callbacks/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/callbacks/base.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/callbacks/defaults/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/callbacks/defaults/metric_callback.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/connector.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/docker_builder.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/loggers.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/middlewares.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/python_client.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/schema/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/schema/image.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/server.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/specs/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/specs/openai_embedding.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/test_examples/__init__.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/test_examples/openai_embedding_spec_example.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/test_examples/openai_spec_example.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/test_examples/simple_example.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/utils.py +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/SOURCES.txt +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/dependency_links.txt +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/entry_points.txt +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/not-zip-safe +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/requires.txt +0 -0
- {litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: litserve
|
|
3
|
-
Version: 0.2.6.
|
|
3
|
+
Version: 0.2.6.dev2
|
|
4
4
|
Summary: Lightweight AI server.
|
|
5
5
|
Home-page: https://github.com/Lightning-AI/litserve
|
|
6
6
|
Download-URL: https://github.com/Lightning-AI/litserve
|
|
@@ -29,6 +29,10 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: fastapi>=0.100
|
|
31
31
|
Requires-Dist: uvicorn[standard]>=0.29.0
|
|
32
|
+
Provides-Extra: perf
|
|
33
|
+
Requires-Dist: jsonargparse; extra == "perf"
|
|
34
|
+
Requires-Dist: tenacity; extra == "perf"
|
|
35
|
+
Requires-Dist: uvloop; extra == "perf"
|
|
32
36
|
Provides-Extra: test
|
|
33
37
|
Requires-Dist: asgi-lifespan; extra == "test"
|
|
34
38
|
Requires-Dist: coverage[toml]>=7.5.3; extra == "test"
|
|
@@ -47,10 +51,6 @@ Requires-Dist: python-multipart; extra == "test"
|
|
|
47
51
|
Requires-Dist: requests; extra == "test"
|
|
48
52
|
Requires-Dist: torch>2.0.0; extra == "test"
|
|
49
53
|
Requires-Dist: transformers; extra == "test"
|
|
50
|
-
Provides-Extra: perf
|
|
51
|
-
Requires-Dist: jsonargparse; extra == "perf"
|
|
52
|
-
Requires-Dist: tenacity; extra == "perf"
|
|
53
|
-
Requires-Dist: uvloop; extra == "perf"
|
|
54
54
|
|
|
55
55
|
<div align='center'>
|
|
56
56
|
|
|
@@ -11,7 +11,7 @@
|
|
|
11
11
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
12
12
|
# See the License for the specific language governing permissions and
|
|
13
13
|
# limitations under the License.
|
|
14
|
-
__version__ = "0.2.6.
|
|
14
|
+
__version__ = "0.2.6.dev2"
|
|
15
15
|
__author__ = "Lightning-AI et al."
|
|
16
16
|
__author_email__ = "community@lightning.ai"
|
|
17
17
|
__license__ = "Apache-2.0"
|
|
@@ -56,10 +56,9 @@ class LitAPI(ABC):
|
|
|
56
56
|
|
|
57
57
|
return inputs
|
|
58
58
|
|
|
59
|
-
@abstractmethod
|
|
60
59
|
def predict(self, x, **kwargs):
|
|
61
60
|
"""Run the model on the input and return or yield the output."""
|
|
62
|
-
|
|
61
|
+
raise NotImplementedError("predict is not implemented")
|
|
63
62
|
|
|
64
63
|
def _unbatch_no_stream(self, output):
|
|
65
64
|
if isinstance(output, str):
|
|
@@ -121,6 +120,7 @@ class LitAPI(ABC):
|
|
|
121
120
|
|
|
122
121
|
if spec:
|
|
123
122
|
self._spec = spec
|
|
123
|
+
spec.pre_setup(self)
|
|
124
124
|
|
|
125
125
|
def set_logger_queue(self, queue: Queue):
|
|
126
126
|
"""Set the queue for logging events."""
|
|
@@ -495,9 +495,6 @@ class LitLoop(_BaseLoop):
|
|
|
495
495
|
self._context = {}
|
|
496
496
|
|
|
497
497
|
def get_batch_requests(self, lit_api: LitAPI, request_queue: Queue, max_batch_size: int, batch_timeout: float):
|
|
498
|
-
if max_batch_size <= 1:
|
|
499
|
-
raise ValueError("max_batch_size must be greater than 1")
|
|
500
|
-
|
|
501
498
|
batches, timed_out_uids = collate_requests(
|
|
502
499
|
lit_api,
|
|
503
500
|
request_queue,
|
|
@@ -507,8 +504,10 @@ class LitLoop(_BaseLoop):
|
|
|
507
504
|
return batches, timed_out_uids
|
|
508
505
|
|
|
509
506
|
def get_request(self, request_queue: Queue, timeout: float = 1.0):
|
|
510
|
-
|
|
511
|
-
|
|
507
|
+
try:
|
|
508
|
+
return request_queue.get(timeout=timeout)
|
|
509
|
+
except Empty:
|
|
510
|
+
return None
|
|
512
511
|
|
|
513
512
|
def populate_context(self, lit_spec: LitSpec, request: Any):
|
|
514
513
|
if lit_spec and hasattr(lit_spec, "populate_context"):
|
|
@@ -700,19 +699,65 @@ class Output:
|
|
|
700
699
|
|
|
701
700
|
class ContinuousBatchingLoop(LitLoop):
|
|
702
701
|
def __init__(self, max_sequence_length: int = 2048):
|
|
702
|
+
"""Runs continuous batching loop. This loop handles adding new requests, processing them in batches, and
|
|
703
|
+
managing the state of active sequences.
|
|
704
|
+
|
|
705
|
+
The loop requires the following methods to be implemented in the LitAPI:
|
|
706
|
+
- setup: sets up the model on the device
|
|
707
|
+
- decode_request: decodes the client request into a format that can be processed by the model
|
|
708
|
+
- step: generates a new token for each sequence
|
|
709
|
+
- encode_response: encodes the response into a format that can be sent to the client
|
|
710
|
+
- has_finished: checks if the sequence has finished generating
|
|
711
|
+
|
|
712
|
+
Args:
|
|
713
|
+
max_sequence_length (int): The maximum sequence length allowed for any active sequence.
|
|
714
|
+
|
|
715
|
+
"""
|
|
703
716
|
super().__init__()
|
|
704
|
-
self.active_sequences: Dict[str, Dict] = {} # uid -> {input, current_length,
|
|
717
|
+
self.active_sequences: Dict[str, Dict] = {} # uid -> {input, current_length, generated_sequence}
|
|
705
718
|
self.max_sequence_length = max_sequence_length
|
|
706
719
|
self.response_queue_ids: Dict[str, int] = {} # uid -> response_queue_id
|
|
707
720
|
|
|
721
|
+
def pre_setup(self, lit_api: LitAPI, spec: Optional[LitSpec]):
|
|
722
|
+
if not lit_api.stream:
|
|
723
|
+
raise ValueError(
|
|
724
|
+
"Continuous batching loop requires streaming to be enabled. Please set LitServe(..., stream=True)"
|
|
725
|
+
)
|
|
726
|
+
|
|
727
|
+
if not hasattr(lit_api, "step") and not hasattr(lit_api, "predict"):
|
|
728
|
+
raise ValueError("""Using the default step method with Continuous batching loop requires the lit_api to
|
|
729
|
+
have a `predict` method which accepts decoded request inputs and a list of generated_sequence.
|
|
730
|
+
Please implement the has_finished method in the lit_api.
|
|
731
|
+
|
|
732
|
+
class ExampleAPI(LitAPI):
|
|
733
|
+
...
|
|
734
|
+
def predict(self, inputs, generated_sequence):
|
|
735
|
+
# implement predict logic
|
|
736
|
+
# return list of new tokens
|
|
737
|
+
...
|
|
738
|
+
""")
|
|
739
|
+
|
|
740
|
+
if not hasattr(lit_api, "step") and not hasattr(lit_api, "has_finished"):
|
|
741
|
+
raise ValueError("""Using the default step method with Continuous batching loop
|
|
742
|
+
requires the lit_api to have a has_finished method. Please implement the has_finished method in the lit_api.
|
|
743
|
+
|
|
744
|
+
class ExampleAPI(LitAPI):
|
|
745
|
+
...
|
|
746
|
+
def has_finished(self, uid: str, token: str, max_sequence_length: int) -> bool:
|
|
747
|
+
# implement has_finished logic
|
|
748
|
+
return False
|
|
749
|
+
""")
|
|
750
|
+
|
|
708
751
|
def add_request(self, uid: str, request: Any, lit_api: LitAPI, lit_spec: Optional[LitSpec]) -> None:
|
|
709
|
-
"""Add a new sequence to active sequences."""
|
|
752
|
+
"""Add a new sequence to active sequences and perform any action before prediction such as filling the cache."""
|
|
753
|
+
if hasattr(lit_api, "add_request"):
|
|
754
|
+
lit_api.add_request(uid, request)
|
|
710
755
|
decoded_request = lit_api.decode_request(request)
|
|
711
|
-
self.active_sequences[uid] = {"input": decoded_request, "current_length": 0, "
|
|
756
|
+
self.active_sequences[uid] = {"input": decoded_request, "current_length": 0, "generated_sequence": []}
|
|
712
757
|
|
|
713
758
|
def mark_completed(self, uid: str) -> None:
|
|
714
|
-
"""Mark a
|
|
715
|
-
logger.
|
|
759
|
+
"""Mark a request as completed and remove it from the tracked state."""
|
|
760
|
+
logger.debug(f"Marking sequence {uid} as completed")
|
|
716
761
|
del self.active_sequences[uid]
|
|
717
762
|
del self.response_queue_ids[uid]
|
|
718
763
|
|
|
@@ -725,36 +770,39 @@ class ContinuousBatchingLoop(LitLoop):
|
|
|
725
770
|
)
|
|
726
771
|
return capacity
|
|
727
772
|
|
|
728
|
-
def step(
|
|
729
|
-
self, prev_outputs: Optional[List[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]
|
|
730
|
-
) -> List[Tuple[str, Tuple[Any, LitAPIStatus]]]:
|
|
773
|
+
def step(self, prev_outputs: Optional[List[Output]], lit_api: LitAPI, lit_spec: Optional[LitSpec]) -> List[Output]:
|
|
731
774
|
"""Process one token generation step for all active sequences."""
|
|
775
|
+
if hasattr(lit_api, "step"):
|
|
776
|
+
return lit_api.step(prev_outputs)
|
|
777
|
+
|
|
732
778
|
if not self.active_sequences:
|
|
733
779
|
return []
|
|
734
780
|
|
|
735
781
|
# Batch forward pass for all active sequences
|
|
736
782
|
inputs = [seq["input"] for seq in self.active_sequences.values()]
|
|
737
|
-
generated = [seq["
|
|
783
|
+
generated = [seq["generated_sequence"] for seq in self.active_sequences.values()]
|
|
738
784
|
|
|
739
785
|
try:
|
|
740
786
|
# Assume lit_api.predict handles batched token generation
|
|
741
|
-
new_tokens = lit_api.predict(inputs, generated)
|
|
787
|
+
new_tokens: List[Any] = lit_api.predict(inputs, generated)
|
|
742
788
|
|
|
743
|
-
responses = []
|
|
789
|
+
responses: List[Output] = []
|
|
744
790
|
|
|
745
791
|
# Process each sequence's new token
|
|
746
792
|
for uid, token in zip(self.active_sequences.keys(), new_tokens):
|
|
747
793
|
seq = self.active_sequences[uid]
|
|
748
|
-
seq["
|
|
794
|
+
seq["generated_sequence"].append(token)
|
|
749
795
|
seq["current_length"] += 1
|
|
750
796
|
|
|
797
|
+
step_output = Output(uid, token, LitAPIStatus.OK)
|
|
798
|
+
responses.append(step_output)
|
|
799
|
+
|
|
751
800
|
# Check completion conditions
|
|
752
|
-
is_finished = lit_api.
|
|
801
|
+
is_finished = lit_api.has_finished(uid, token, self.max_sequence_length)
|
|
753
802
|
|
|
754
803
|
if is_finished:
|
|
755
804
|
# Encode final response for completed sequence
|
|
756
|
-
|
|
757
|
-
step_output = Output(uid, response, LitAPIStatus.FINISH_STREAMING)
|
|
805
|
+
step_output = Output(uid, "", LitAPIStatus.FINISH_STREAMING)
|
|
758
806
|
responses.append(step_output)
|
|
759
807
|
|
|
760
808
|
return responses
|
|
@@ -792,7 +840,7 @@ class ContinuousBatchingLoop(LitLoop):
|
|
|
792
840
|
if new_batches:
|
|
793
841
|
# Add new requests to pending_requests and try to process them
|
|
794
842
|
for response_queue_id, uid, input in new_batches:
|
|
795
|
-
logger.
|
|
843
|
+
logger.debug(f"New request: {uid}, {input}")
|
|
796
844
|
if self.has_capacity(lit_api):
|
|
797
845
|
self.add_request(uid, input, lit_api, lit_spec)
|
|
798
846
|
self.response_queue_ids[uid] = response_queue_id
|
|
@@ -815,11 +863,6 @@ class ContinuousBatchingLoop(LitLoop):
|
|
|
815
863
|
workers_setup_status: Dict[int, str],
|
|
816
864
|
callback_runner: CallbackRunner,
|
|
817
865
|
):
|
|
818
|
-
if not lit_api.stream:
|
|
819
|
-
raise ValueError(
|
|
820
|
-
"Continuous batching loop requires streaming to be enabled. Please set LitServe(..., stream=True)"
|
|
821
|
-
)
|
|
822
|
-
|
|
823
866
|
"""Main loop that processes batches of requests."""
|
|
824
867
|
pending_requests = self.prefill(
|
|
825
868
|
[],
|
|
@@ -846,10 +889,11 @@ class ContinuousBatchingLoop(LitLoop):
|
|
|
846
889
|
for step_output in responses:
|
|
847
890
|
logger.debug(f"Processing response: {step_output}")
|
|
848
891
|
status = step_output.status
|
|
849
|
-
response_data = step_output.output
|
|
892
|
+
response_data = lit_api.encode_response(step_output.output)
|
|
850
893
|
uid = step_output.uid
|
|
851
894
|
response_queue_id = self.response_queue_ids[uid]
|
|
852
895
|
|
|
896
|
+
response_data = lit_api.format_encoded_response(response_data)
|
|
853
897
|
if status == LitAPIStatus.ERROR:
|
|
854
898
|
self.put_error_response(response_queues, response_queue_id, uid, response_data)
|
|
855
899
|
self.mark_completed(uid)
|
|
@@ -870,7 +914,7 @@ class ContinuousBatchingLoop(LitLoop):
|
|
|
870
914
|
)
|
|
871
915
|
|
|
872
916
|
except Exception as e:
|
|
873
|
-
logger.exception("Error in continuous batching loop")
|
|
917
|
+
logger.exception(f"Error in continuous batching loop: {e}")
|
|
874
918
|
# Handle any errors by sending error responses for all tracked requests
|
|
875
919
|
for uid, response_queue_id in self.response_queue_ids.items():
|
|
876
920
|
self.put_error_response(response_queues, response_queue_id, uid, e)
|
|
@@ -15,7 +15,7 @@ from abc import abstractmethod
|
|
|
15
15
|
from typing import TYPE_CHECKING, Callable, List
|
|
16
16
|
|
|
17
17
|
if TYPE_CHECKING:
|
|
18
|
-
from litserve import LitServer
|
|
18
|
+
from litserve import LitAPI, LitServer
|
|
19
19
|
|
|
20
20
|
|
|
21
21
|
class LitSpec:
|
|
@@ -26,6 +26,9 @@ class LitSpec:
|
|
|
26
26
|
|
|
27
27
|
self._server: LitServer = None
|
|
28
28
|
|
|
29
|
+
def pre_setup(self, lit_api: "LitAPI"):
|
|
30
|
+
pass
|
|
31
|
+
|
|
29
32
|
def setup(self, server: "LitServer"):
|
|
30
33
|
self._server = server
|
|
31
34
|
|
|
@@ -30,7 +30,7 @@ from litserve.specs.base import LitSpec
|
|
|
30
30
|
from litserve.utils import LitAPIStatus, azip
|
|
31
31
|
|
|
32
32
|
if typing.TYPE_CHECKING:
|
|
33
|
-
from litserve import LitServer
|
|
33
|
+
from litserve import LitAPI, LitServer
|
|
34
34
|
|
|
35
35
|
logger = logging.getLogger(__name__)
|
|
36
36
|
|
|
@@ -262,18 +262,18 @@ class OpenAISpec(LitSpec):
|
|
|
262
262
|
self.add_endpoint("/v1/chat/completions", self.chat_completion, ["POST"])
|
|
263
263
|
self.add_endpoint("/v1/chat/completions", self.options_chat_completions, ["OPTIONS"])
|
|
264
264
|
|
|
265
|
-
def
|
|
265
|
+
def pre_setup(self, lit_api: "LitAPI"):
|
|
266
266
|
from litserve import LitAPI
|
|
267
267
|
|
|
268
|
-
super().setup(server)
|
|
269
|
-
|
|
270
|
-
lit_api = self._server.lit_api
|
|
271
268
|
if not inspect.isgeneratorfunction(lit_api.predict):
|
|
272
269
|
raise ValueError(LITAPI_VALIDATION_MSG.format("predict is not a generator"))
|
|
273
270
|
|
|
274
271
|
is_encode_response_original = lit_api.encode_response.__code__ is LitAPI.encode_response.__code__
|
|
275
272
|
if not is_encode_response_original and not inspect.isgeneratorfunction(lit_api.encode_response):
|
|
276
273
|
raise ValueError(LITAPI_VALIDATION_MSG.format("encode_response is not a generator"))
|
|
274
|
+
|
|
275
|
+
def setup(self, server: "LitServer"):
|
|
276
|
+
super().setup(server)
|
|
277
277
|
print("OpenAI spec setup complete")
|
|
278
278
|
|
|
279
279
|
def populate_context(self, context, request):
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: litserve
|
|
3
|
-
Version: 0.2.6.
|
|
3
|
+
Version: 0.2.6.dev2
|
|
4
4
|
Summary: Lightweight AI server.
|
|
5
5
|
Home-page: https://github.com/Lightning-AI/litserve
|
|
6
6
|
Download-URL: https://github.com/Lightning-AI/litserve
|
|
@@ -29,6 +29,10 @@ Description-Content-Type: text/markdown
|
|
|
29
29
|
License-File: LICENSE
|
|
30
30
|
Requires-Dist: fastapi>=0.100
|
|
31
31
|
Requires-Dist: uvicorn[standard]>=0.29.0
|
|
32
|
+
Provides-Extra: perf
|
|
33
|
+
Requires-Dist: jsonargparse; extra == "perf"
|
|
34
|
+
Requires-Dist: tenacity; extra == "perf"
|
|
35
|
+
Requires-Dist: uvloop; extra == "perf"
|
|
32
36
|
Provides-Extra: test
|
|
33
37
|
Requires-Dist: asgi-lifespan; extra == "test"
|
|
34
38
|
Requires-Dist: coverage[toml]>=7.5.3; extra == "test"
|
|
@@ -47,10 +51,6 @@ Requires-Dist: python-multipart; extra == "test"
|
|
|
47
51
|
Requires-Dist: requests; extra == "test"
|
|
48
52
|
Requires-Dist: torch>2.0.0; extra == "test"
|
|
49
53
|
Requires-Dist: transformers; extra == "test"
|
|
50
|
-
Provides-Extra: perf
|
|
51
|
-
Requires-Dist: jsonargparse; extra == "perf"
|
|
52
|
-
Requires-Dist: tenacity; extra == "perf"
|
|
53
|
-
Requires-Dist: uvloop; extra == "perf"
|
|
54
54
|
|
|
55
55
|
<div align='center'>
|
|
56
56
|
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/callbacks/defaults/metric_callback.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{litserve-0.2.6.dev1 → litserve-0.2.6.dev2}/src/litserve/test_examples/openai_spec_example.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|