Spaces:
Runtime error
Runtime error
soutrik
commited on
Commit
•
035df3d
1
Parent(s):
a31745a
check and confirm docker compose on gpu
Browse files- Dockerfile +29 -13
- docker-compose.yaml +29 -0
- ec2_runner_setup.md +20 -1
- main.py +4 -2
- poetry.lock +125 -80
- pyproject.toml +1 -1
- src/litserve_benchmark.py +32 -37
Dockerfile
CHANGED
@@ -1,16 +1,31 @@
|
|
1 |
-
# Stage 1: Base image with
|
2 |
-
FROM
|
3 |
|
4 |
LABEL maintainer="Soutrik soutrik1991@gmail.com" \
|
5 |
description="Base Docker image for running a Python app with Poetry and GPU support."
|
6 |
|
7 |
-
# Install
|
8 |
-
RUN apt-get update && apt-get install -y --no-install-recommends
|
9 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
10 |
apt-get clean && rm -rf /var/lib/apt/lists/*
|
11 |
|
12 |
-
#
|
13 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
14 |
|
15 |
# Configure Poetry environment
|
16 |
ENV POETRY_NO_INTERACTION=1 \
|
@@ -23,7 +38,7 @@ WORKDIR /app
|
|
23 |
# Copy pyproject.toml and poetry.lock to install dependencies
|
24 |
COPY pyproject.toml poetry.lock /app/
|
25 |
|
26 |
-
# Install dependencies without
|
27 |
RUN --mount=type=cache,target=/tmp/poetry_cache poetry install --only main --no-root
|
28 |
|
29 |
# Stage 2: Build stage for the application
|
@@ -38,13 +53,11 @@ COPY main.py /app/main.py
|
|
38 |
# Stage 3: Final runtime stage
|
39 |
FROM base as runner
|
40 |
|
41 |
-
# Copy application source code and
|
42 |
COPY --from=builder /app/src /app/src
|
43 |
COPY --from=builder /app/configs /app/configs
|
44 |
COPY --from=builder /app/.project-root /app/.project-root
|
45 |
COPY --from=builder /app/main.py /app/main.py
|
46 |
-
|
47 |
-
# Copy virtual environment from the builder stage
|
48 |
COPY --from=builder /app/.venv /app/.venv
|
49 |
|
50 |
# Copy client files
|
@@ -53,8 +66,11 @@ COPY run_client.sh /app/run_client.sh
|
|
53 |
# Set the working directory to /app
|
54 |
WORKDIR /app
|
55 |
|
56 |
-
#
|
57 |
ENV PATH="/app/.venv/bin:$PATH"
|
58 |
|
59 |
-
#
|
|
|
|
|
|
|
60 |
CMD ["python", "-m", "main"]
|
|
|
1 |
+
# Stage 1: Base image with CUDA 12.2, cuDNN 9, and minimal runtime for PyTorch
|
2 |
+
FROM nvidia/cuda:12.2.0-runtime-ubuntu20.04 as base
|
3 |
|
4 |
LABEL maintainer="Soutrik soutrik1991@gmail.com" \
|
5 |
description="Base Docker image for running a Python app with Poetry and GPU support."
|
6 |
|
7 |
+
# Install necessary system dependencies, including Python 3.10
|
8 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
9 |
+
software-properties-common && \
|
10 |
+
add-apt-repository ppa:deadsnakes/ppa && \
|
11 |
+
apt-get update && apt-get install -y --no-install-recommends \
|
12 |
+
python3.10 \
|
13 |
+
python3.10-venv \
|
14 |
+
python3.10-dev \
|
15 |
+
python3-pip \
|
16 |
+
curl \
|
17 |
+
git \
|
18 |
+
build-essential && \
|
19 |
apt-get clean && rm -rf /var/lib/apt/lists/*
|
20 |
|
21 |
+
# Set Python 3.10 as the default
|
22 |
+
RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
|
23 |
+
update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1 && \
|
24 |
+
python --version
|
25 |
+
|
26 |
+
# Install Poetry
|
27 |
+
RUN curl -sSL https://install.python-poetry.org | python3 - && \
|
28 |
+
ln -s /root/.local/bin/poetry /usr/local/bin/poetry
|
29 |
|
30 |
# Configure Poetry environment
|
31 |
ENV POETRY_NO_INTERACTION=1 \
|
|
|
38 |
# Copy pyproject.toml and poetry.lock to install dependencies
|
39 |
COPY pyproject.toml poetry.lock /app/
|
40 |
|
41 |
+
# Install Python dependencies without building the app itself
|
42 |
RUN --mount=type=cache,target=/tmp/poetry_cache poetry install --only main --no-root
|
43 |
|
44 |
# Stage 2: Build stage for the application
|
|
|
53 |
# Stage 3: Final runtime stage
|
54 |
FROM base as runner
|
55 |
|
56 |
+
# Copy application source code and dependencies from the builder stage
|
57 |
COPY --from=builder /app/src /app/src
|
58 |
COPY --from=builder /app/configs /app/configs
|
59 |
COPY --from=builder /app/.project-root /app/.project-root
|
60 |
COPY --from=builder /app/main.py /app/main.py
|
|
|
|
|
61 |
COPY --from=builder /app/.venv /app/.venv
|
62 |
|
63 |
# Copy client files
|
|
|
66 |
# Set the working directory to /app
|
67 |
WORKDIR /app
|
68 |
|
69 |
+
# Add virtual environment to PATH
|
70 |
ENV PATH="/app/.venv/bin:$PATH"
|
71 |
|
72 |
+
# Install PyTorch with CUDA 12.2 support (adjusted for compatibility)
|
73 |
+
RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu122
|
74 |
+
|
75 |
+
# Default command to run the application
|
76 |
CMD ["python", "-m", "main"]
|
docker-compose.yaml
CHANGED
@@ -19,6 +19,13 @@ services:
|
|
19 |
- default
|
20 |
env_file:
|
21 |
- .env
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
22 |
|
23 |
eval:
|
24 |
build:
|
@@ -38,6 +45,13 @@ services:
|
|
38 |
- default
|
39 |
env_file:
|
40 |
- .env
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
41 |
|
42 |
|
43 |
server:
|
@@ -61,6 +75,13 @@ services:
|
|
61 |
- .env
|
62 |
ports:
|
63 |
- "8080:8080"
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
64 |
|
65 |
client:
|
66 |
build:
|
@@ -82,6 +103,14 @@ services:
|
|
82 |
env_file:
|
83 |
- .env
|
84 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
85 |
|
86 |
volumes:
|
87 |
data:
|
|
|
19 |
- default
|
20 |
env_file:
|
21 |
- .env
|
22 |
+
deploy:
|
23 |
+
resources:
|
24 |
+
reservations:
|
25 |
+
devices:
|
26 |
+
- driver: nvidia
|
27 |
+
count: 1
|
28 |
+
capabilities: [gpu]
|
29 |
|
30 |
eval:
|
31 |
build:
|
|
|
45 |
- default
|
46 |
env_file:
|
47 |
- .env
|
48 |
+
deploy:
|
49 |
+
resources:
|
50 |
+
reservations:
|
51 |
+
devices:
|
52 |
+
- driver: nvidia
|
53 |
+
count: 1
|
54 |
+
capabilities: [gpu]
|
55 |
|
56 |
|
57 |
server:
|
|
|
75 |
- .env
|
76 |
ports:
|
77 |
- "8080:8080"
|
78 |
+
deploy:
|
79 |
+
resources:
|
80 |
+
reservations:
|
81 |
+
devices:
|
82 |
+
- driver: nvidia
|
83 |
+
count: 1
|
84 |
+
capabilities: [gpu]
|
85 |
|
86 |
client:
|
87 |
build:
|
|
|
103 |
env_file:
|
104 |
- .env
|
105 |
|
106 |
+
deploy:
|
107 |
+
resources:
|
108 |
+
reservations:
|
109 |
+
devices:
|
110 |
+
- driver: nvidia
|
111 |
+
count: 1
|
112 |
+
capabilities: [gpu]
|
113 |
+
|
114 |
|
115 |
volumes:
|
116 |
data:
|
ec2_runner_setup.md
CHANGED
@@ -335,4 +335,23 @@ If successful, it should show details of the T4 GPU.
|
|
335 |
- **PyTorch**: Installed with CUDA 12.2 support
|
336 |
|
337 |
This setup ensures your system is ready for deep learning workloads with the T4 GPU.
|
338 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
335 |
- **PyTorch**: Installed with CUDA 12.2 support
|
336 |
|
337 |
This setup ensures your system is ready for deep learning workloads with the T4 GPU.
|
338 |
+
|
339 |
+
Install conda and create a new environment for the project
|
340 |
+
Install pytorch and torchvision in the new environment
|
341 |
+
Install other dependencies like numpy, pandas, matplotlib, etc.
|
342 |
+
Run the project code in the new environment
|
343 |
+
>>> import torch
|
344 |
+
>>> print(torch.cuda.is_available())
|
345 |
+
>>> print(torch.cuda.get_device_name(0))
|
346 |
+
>>> print(torch.version.cuda)
|
347 |
+
```
|
348 |
+
__CUDA Docker Setup__:
|
349 |
+
```bash
|
350 |
+
# If you are using docker and want to run a container with CUDA support
|
351 |
+
sudo apt install -y nvidia-container-toolkit
|
352 |
+
nvidia-ctk --version
|
353 |
+
sudo systemctl restart docker
|
354 |
+
sudo systemctl status docker
|
355 |
+
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu20.04 nvidia-smi
|
356 |
+
docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu20.04 nvcc --version
|
357 |
+
```
|
main.py
CHANGED
@@ -1,3 +1,5 @@
|
|
1 |
-
|
2 |
|
3 |
-
|
|
|
|
|
|
1 |
+
import torch
|
2 |
|
3 |
+
print(torch.cuda.is_available()) # Should return True if our GPU is enabled
|
4 |
+
print(torch.cuda.get_device_name(0)) # Should return "Tesla T4" if our GPU is enabled
|
5 |
+
print(torch.version.cuda) # Should return "12.4" if our GPU is enabled
|
poetry.lock
CHANGED
@@ -246,92 +246,93 @@ files = [
|
|
246 |
|
247 |
[[package]]
|
248 |
name = "aiohttp"
|
249 |
-
version = "3.11.
|
250 |
description = "Async http client/server framework (asyncio)"
|
251 |
optional = false
|
252 |
python-versions = ">=3.9"
|
253 |
files = [
|
254 |
-
{file = "aiohttp-3.11.
|
255 |
-
{file = "aiohttp-3.11.
|
256 |
-
{file = "aiohttp-3.11.
|
257 |
-
{file = "aiohttp-3.11.
|
258 |
-
{file = "aiohttp-3.11.
|
259 |
-
{file = "aiohttp-3.11.
|
260 |
-
{file = "aiohttp-3.11.
|
261 |
-
{file = "aiohttp-3.11.
|
262 |
-
{file = "aiohttp-3.11.
|
263 |
-
{file = "aiohttp-3.11.
|
264 |
-
{file = "aiohttp-3.11.
|
265 |
-
{file = "aiohttp-3.11.
|
266 |
-
{file = "aiohttp-3.11.
|
267 |
-
{file = "aiohttp-3.11.
|
268 |
-
{file = "aiohttp-3.11.
|
269 |
-
{file = "aiohttp-3.11.
|
270 |
-
{file = "aiohttp-3.11.
|
271 |
-
{file = "aiohttp-3.11.
|
272 |
-
{file = "aiohttp-3.11.
|
273 |
-
{file = "aiohttp-3.11.
|
274 |
-
{file = "aiohttp-3.11.
|
275 |
-
{file = "aiohttp-3.11.
|
276 |
-
{file = "aiohttp-3.11.
|
277 |
-
{file = "aiohttp-3.11.
|
278 |
-
{file = "aiohttp-3.11.
|
279 |
-
{file = "aiohttp-3.11.
|
280 |
-
{file = "aiohttp-3.11.
|
281 |
-
{file = "aiohttp-3.11.
|
282 |
-
{file = "aiohttp-3.11.
|
283 |
-
{file = "aiohttp-3.11.
|
284 |
-
{file = "aiohttp-3.11.
|
285 |
-
{file = "aiohttp-3.11.
|
286 |
-
{file = "aiohttp-3.11.
|
287 |
-
{file = "aiohttp-3.11.
|
288 |
-
{file = "aiohttp-3.11.
|
289 |
-
{file = "aiohttp-3.11.
|
290 |
-
{file = "aiohttp-3.11.
|
291 |
-
{file = "aiohttp-3.11.
|
292 |
-
{file = "aiohttp-3.11.
|
293 |
-
{file = "aiohttp-3.11.
|
294 |
-
{file = "aiohttp-3.11.
|
295 |
-
{file = "aiohttp-3.11.
|
296 |
-
{file = "aiohttp-3.11.
|
297 |
-
{file = "aiohttp-3.11.
|
298 |
-
{file = "aiohttp-3.11.
|
299 |
-
{file = "aiohttp-3.11.
|
300 |
-
{file = "aiohttp-3.11.
|
301 |
-
{file = "aiohttp-3.11.
|
302 |
-
{file = "aiohttp-3.11.
|
303 |
-
{file = "aiohttp-3.11.
|
304 |
-
{file = "aiohttp-3.11.
|
305 |
-
{file = "aiohttp-3.11.
|
306 |
-
{file = "aiohttp-3.11.
|
307 |
-
{file = "aiohttp-3.11.
|
308 |
-
{file = "aiohttp-3.11.
|
309 |
-
{file = "aiohttp-3.11.
|
310 |
-
{file = "aiohttp-3.11.
|
311 |
-
{file = "aiohttp-3.11.
|
312 |
-
{file = "aiohttp-3.11.
|
313 |
-
{file = "aiohttp-3.11.
|
314 |
-
{file = "aiohttp-3.11.
|
315 |
-
{file = "aiohttp-3.11.
|
316 |
-
{file = "aiohttp-3.11.
|
317 |
-
{file = "aiohttp-3.11.
|
318 |
-
{file = "aiohttp-3.11.
|
319 |
-
{file = "aiohttp-3.11.
|
320 |
-
{file = "aiohttp-3.11.
|
321 |
-
{file = "aiohttp-3.11.
|
322 |
-
{file = "aiohttp-3.11.
|
323 |
-
{file = "aiohttp-3.11.
|
324 |
-
{file = "aiohttp-3.11.
|
325 |
-
{file = "aiohttp-3.11.
|
326 |
-
{file = "aiohttp-3.11.
|
327 |
-
{file = "aiohttp-3.11.
|
328 |
-
{file = "aiohttp-3.11.
|
329 |
-
{file = "aiohttp-3.11.
|
330 |
]
|
331 |
|
332 |
[package.dependencies]
|
333 |
aiohappyeyeballs = ">=2.3.0"
|
334 |
aiosignal = ">=1.1.2"
|
|
|
335 |
attrs = ">=17.3.0"
|
336 |
frozenlist = ">=1.1.1"
|
337 |
multidict = ">=4.5,<7.0"
|
@@ -544,8 +545,10 @@ files = [
|
|
544 |
]
|
545 |
|
546 |
[package.dependencies]
|
|
|
547 |
idna = ">=2.8"
|
548 |
sniffio = ">=1.1"
|
|
|
549 |
|
550 |
[package.extras]
|
551 |
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
@@ -646,6 +649,9 @@ files = [
|
|
646 |
{file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"},
|
647 |
]
|
648 |
|
|
|
|
|
|
|
649 |
[package.extras]
|
650 |
docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"]
|
651 |
gssauth = ["gssapi", "sspilib"]
|
@@ -883,6 +889,8 @@ mypy-extensions = ">=0.4.3"
|
|
883 |
packaging = ">=22.0"
|
884 |
pathspec = ">=0.9.0"
|
885 |
platformdirs = ">=2"
|
|
|
|
|
886 |
|
887 |
[package.extras]
|
888 |
colorama = ["colorama (>=0.4.3)"]
|
@@ -1614,6 +1622,9 @@ files = [
|
|
1614 |
{file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"},
|
1615 |
]
|
1616 |
|
|
|
|
|
|
|
1617 |
[package.extras]
|
1618 |
toml = ["tomli"]
|
1619 |
|
@@ -2133,6 +2144,20 @@ files = [
|
|
2133 |
{file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
|
2134 |
]
|
2135 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
2136 |
[[package]]
|
2137 |
name = "fastapi"
|
2138 |
version = "0.115.5"
|
@@ -4248,6 +4273,9 @@ files = [
|
|
4248 |
{file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"},
|
4249 |
]
|
4250 |
|
|
|
|
|
|
|
4251 |
[[package]]
|
4252 |
name = "mypy-extensions"
|
4253 |
version = "1.0.0"
|
@@ -4768,7 +4796,7 @@ files = [
|
|
4768 |
]
|
4769 |
|
4770 |
[package.dependencies]
|
4771 |
-
numpy = {version = ">=1.
|
4772 |
python-dateutil = ">=2.8.2"
|
4773 |
pytz = ">=2020.1"
|
4774 |
tzdata = ">=2022.7"
|
@@ -5791,9 +5819,11 @@ files = [
|
|
5791 |
|
5792 |
[package.dependencies]
|
5793 |
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
|
|
5794 |
iniconfig = "*"
|
5795 |
packaging = "*"
|
5796 |
pluggy = ">=1.5,<2"
|
|
|
5797 |
|
5798 |
[package.extras]
|
5799 |
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
@@ -6048,6 +6078,9 @@ files = [
|
|
6048 |
{file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
|
6049 |
]
|
6050 |
|
|
|
|
|
|
|
6051 |
[package.extras]
|
6052 |
hiredis = ["hiredis (>1.0.0)"]
|
6053 |
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
|
@@ -7245,6 +7278,17 @@ dev = ["tokenizers[testing]"]
|
|
7245 |
docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
|
7246 |
testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"]
|
7247 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
7248 |
[[package]]
|
7249 |
name = "tomlkit"
|
7250 |
version = "0.13.2"
|
@@ -7620,6 +7664,7 @@ h11 = ">=0.8"
|
|
7620 |
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
7621 |
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
7622 |
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
|
|
7623 |
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
7624 |
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
7625 |
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
@@ -8177,5 +8222,5 @@ type = ["pytest-mypy"]
|
|
8177 |
|
8178 |
[metadata]
|
8179 |
lock-version = "2.0"
|
8180 |
-
python-versions = "3.
|
8181 |
-
content-hash = "
|
|
|
246 |
|
247 |
[[package]]
|
248 |
name = "aiohttp"
|
249 |
+
version = "3.11.6"
|
250 |
description = "Async http client/server framework (asyncio)"
|
251 |
optional = false
|
252 |
python-versions = ">=3.9"
|
253 |
files = [
|
254 |
+
{file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7510b3ca2275691875ddf072a5b6cd129278d11fe09301add7d292fc8d3432de"},
|
255 |
+
{file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfab0d2c3380c588fc925168533edb21d3448ad76c3eadc360ff963019161724"},
|
256 |
+
{file = "aiohttp-3.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf02dba0f342f3a8228f43fae256aafc21c4bc85bffcf537ce4582e2b1565188"},
|
257 |
+
{file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92daedf7221392e7a7984915ca1b0481a94c71457c2f82548414a41d65555e70"},
|
258 |
+
{file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2274a7876e03429e3218589a6d3611a194bdce08c3f1e19962e23370b47c0313"},
|
259 |
+
{file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a2e1eae2d2f62f3660a1591e16e543b2498358593a73b193006fb89ee37abc6"},
|
260 |
+
{file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978ec3fb0a42efcd98aae608f58c6cfcececaf0a50b4e86ee3ea0d0a574ab73b"},
|
261 |
+
{file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51f87b27d9219ed4e202ed8d6f1bb96f829e5eeff18db0d52f592af6de6bdbf"},
|
262 |
+
{file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:04d1a02a669d26e833c8099992c17f557e3b2fdb7960a0c455d7b1cbcb05121d"},
|
263 |
+
{file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3679d5fcbc7f1ab518ab4993f12f80afb63933f6afb21b9b272793d398303b98"},
|
264 |
+
{file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a4b24e03d04893b5c8ec9cd5f2f11dc9c8695c4e2416d2ac2ce6c782e4e5ffa5"},
|
265 |
+
{file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d9abdfd35ecff1c95f270b7606819a0e2de9e06fa86b15d9080de26594cf4c23"},
|
266 |
+
{file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b5c3e7928a0ad80887a5eba1c1da1830512ddfe7394d805badda45c03db3109"},
|
267 |
+
{file = "aiohttp-3.11.6-cp310-cp310-win32.whl", hash = "sha256:913dd9e9378f3c38aeb5c4fb2b8383d6490bc43f3b427ae79f2870651ae08f22"},
|
268 |
+
{file = "aiohttp-3.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:4ac26d482c2000c3a59bf757a77adc972828c9d4177b4bd432a46ba682ca7271"},
|
269 |
+
{file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26ac4c960ea8debf557357a172b3ef201f2236a462aefa1bc17683a75483e518"},
|
270 |
+
{file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8b1f13ebc99fb98c7c13057b748f05224ccc36d17dee18136c695ef23faaf4ff"},
|
271 |
+
{file = "aiohttp-3.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4679f1a47516189fab1774f7e45a6c7cac916224c91f5f94676f18d0b64ab134"},
|
272 |
+
{file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74491fdb3d140ff561ea2128cb7af9ba0a360067ee91074af899c9614f88a18f"},
|
273 |
+
{file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f51e1a90412d387e62aa2d243998c5eddb71373b199d811e6ed862a9f34f9758"},
|
274 |
+
{file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72ab89510511c3bb703d0bb5504787b11e0ed8be928ed2a7cf1cda9280628430"},
|
275 |
+
{file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6681c9e046d99646e8059266688374a063da85b2e4c0ebfa078cda414905d080"},
|
276 |
+
{file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a17f8a6d3ab72cbbd137e494d1a23fbd3ea973db39587941f32901bb3c5c350"},
|
277 |
+
{file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:867affc7612a314b95f74d93aac550ce0909bc6f0b6c658cc856890f4d326542"},
|
278 |
+
{file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:00d894ebd609d5a423acef885bd61e7f6a972153f99c5b3ea45fc01fe909196c"},
|
279 |
+
{file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:614c87be9d0d64477d1e4b663bdc5d1534fc0a7ebd23fb08347ab9fd5fe20fd7"},
|
280 |
+
{file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:533ed46cf772f28f3bffae81c0573d916a64dee590b5dfaa3f3d11491da05b95"},
|
281 |
+
{file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:589884cfbc09813afb1454816b45677e983442e146183143f988f7f5a040791a"},
|
282 |
+
{file = "aiohttp-3.11.6-cp311-cp311-win32.whl", hash = "sha256:1da63633ba921669eec3d7e080459d4ceb663752b3dafb2f31f18edd248d2170"},
|
283 |
+
{file = "aiohttp-3.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:d778ddda09622e7d83095cc8051698a0084c155a1474bfee9bac27d8613dbc31"},
|
284 |
+
{file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:943a952df105a5305257984e7a1f5c2d0fd8564ff33647693c4d07eb2315446d"},
|
285 |
+
{file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d24ec28b7658970a1f1d98608d67f88376c7e503d9d45ff2ba1949c09f2b358c"},
|
286 |
+
{file = "aiohttp-3.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6720e809a660fdb9bec7c168c582e11cfedce339af0a5ca847a5d5b588dce826"},
|
287 |
+
{file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4252d30da0ada6e6841b325869c7ef5104b488e8dd57ec439892abbb8d7b3615"},
|
288 |
+
{file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f65f43ff01b238aa0b5c47962c83830a49577efe31bd37c1400c3d11d8a32835"},
|
289 |
+
{file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc5933f6c9b26404444d36babb650664f984b8e5fa0694540e7b7315d11a4ff"},
|
290 |
+
{file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bf546ba0c029dfffc718c4b67748687fd4f341b07b7c8f1719d6a3a46164798"},
|
291 |
+
{file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c351d05bbeae30c088009c0bb3b17dda04fd854f91cc6196c448349cc98f71c3"},
|
292 |
+
{file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:10499079b063576fad1597898de3f9c0a2ce617c19cc7cd6b62fdcff6b408bf7"},
|
293 |
+
{file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:442ee82eda47dd59798d6866ce020fb8d02ea31ac9ac82b3d719ed349e6a9d52"},
|
294 |
+
{file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:86fce9127bc317119b34786d9e9ae8af4508a103158828a535f56d201da6ab19"},
|
295 |
+
{file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:973d26a5537ce5d050302eb3cd876457451745b1da0624cbb483217970e12567"},
|
296 |
+
{file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:532b8f038a4e001137d3600cea5d3439d1881df41bdf44d0f9651264d562fdf0"},
|
297 |
+
{file = "aiohttp-3.11.6-cp312-cp312-win32.whl", hash = "sha256:4863c59f748dbe147da82b389931f2a676aebc9d3419813ed5ca32d057c9cb32"},
|
298 |
+
{file = "aiohttp-3.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:5d7f481f82c18ac1f7986e31ba6eea9be8b2e2c86f1ef035b6866179b6c5dd68"},
|
299 |
+
{file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:40f502350496ba4c6820816d3164f8a0297b9aa4e95d910da31beb189866a9df"},
|
300 |
+
{file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9072669b0bffb40f1f6977d0b5e8a296edc964f9cefca3a18e68649c214d0ce3"},
|
301 |
+
{file = "aiohttp-3.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:518160ecf4e6ffd61715bc9173da0925fcce44ae6c7ca3d3f098fe42585370fb"},
|
302 |
+
{file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f69cc1b45115ac44795b63529aa5caa9674be057f11271f65474127b24fc1ce6"},
|
303 |
+
{file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6be90a6beced41653bda34afc891617c6d9e8276eef9c183f029f851f0a3c3d"},
|
304 |
+
{file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00c22fe2486308770d22ef86242101d7b0f1e1093ce178f2358f860e5149a551"},
|
305 |
+
{file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2607ebb783e3aeefa017ec8f34b506a727e6b6ab2c4b037d65f0bc7151f4430a"},
|
306 |
+
{file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f761d6819870c2a8537f75f3e2fc610b163150cefa01f9f623945840f601b2c"},
|
307 |
+
{file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e44d1bc6c88f5234115011842219ba27698a5f2deee245c963b180080572aaa2"},
|
308 |
+
{file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7e0cb6a1b1f499cb2aa0bab1c9f2169ad6913c735b7447e058e0c29c9e51c0b5"},
|
309 |
+
{file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a76b4d4ca34254dca066acff2120811e2a8183997c135fcafa558280f2cc53f3"},
|
310 |
+
{file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69051c1e45fb18c0ae4d39a075532ff0b015982e7997f19eb5932eb4a3e05c17"},
|
311 |
+
{file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:aff2ed18274c0bfe0c1d772781c87d5ca97ae50f439729007cec9644ee9b15fe"},
|
312 |
+
{file = "aiohttp-3.11.6-cp313-cp313-win32.whl", hash = "sha256:2fbea25f2d44df809a46414a8baafa5f179d9dda7e60717f07bded56300589b3"},
|
313 |
+
{file = "aiohttp-3.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:f77bc29a465c0f9f6573d1abe656d385fa673e34efe615bd4acc50899280ee47"},
|
314 |
+
{file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:de6123b298d17bca9e53581f50a275b36e10d98e8137eb743ce69ee766dbdfe9"},
|
315 |
+
{file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a10200f705f4fff00e148b7f41e5d1d929c7cd4ac523c659171a0ea8284cd6fb"},
|
316 |
+
{file = "aiohttp-3.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7776ef6901b54dd557128d96c71e412eec0c39ebc07567e405ac98737995aad"},
|
317 |
+
{file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e5c2a55583cd91936baf73d223807bb93ace6eb1fe54424782690f2707162ab"},
|
318 |
+
{file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b032bd6cf7422583bf44f233f4a1489fee53c6d35920123a208adc54e2aba41e"},
|
319 |
+
{file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fe2d99acbc5cf606f75d7347bf3a027c24c27bc052d470fb156f4cfcea5739"},
|
320 |
+
{file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a79c366375c2250934d1238abe5d5ea7754c823a1c7df0c52bf0a2bfded6a9"},
|
321 |
+
{file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33cbbe97dc94a34d1295a7bb68f82727bcbff2b284f73ae7e58ecc05903da97"},
|
322 |
+
{file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:19e4fb9ac727834b003338dcdd27dcfe0de4fb44082b01b34ed0ab67c3469fc9"},
|
323 |
+
{file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a97f6b2afbe1d27220c0c14ea978e09fb4868f462ef3d56d810d206bd2e057a2"},
|
324 |
+
{file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c3f7afeea03a9bc49be6053dfd30809cd442cc12627d6ca08babd1c1f9e04ccf"},
|
325 |
+
{file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0d10967600ce5bb69ddcb3e18d84b278efb5199d8b24c3c71a4959c2f08acfd0"},
|
326 |
+
{file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:60f2f631b9fe7aa321fa0f0ff3f5d8b9f7f9b72afd4eecef61c33cf1cfea5d58"},
|
327 |
+
{file = "aiohttp-3.11.6-cp39-cp39-win32.whl", hash = "sha256:4d2b75333deb5c5f61bac5a48bba3dbc142eebbd3947d98788b6ef9cc48628ae"},
|
328 |
+
{file = "aiohttp-3.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:8908c235421972a2e02abcef87d16084aabfe825d14cc9a1debd609b3cfffbea"},
|
329 |
+
{file = "aiohttp-3.11.6.tar.gz", hash = "sha256:fd9f55c1b51ae1c20a1afe7216a64a88d38afee063baa23c7fce03757023c999"},
|
330 |
]
|
331 |
|
332 |
[package.dependencies]
|
333 |
aiohappyeyeballs = ">=2.3.0"
|
334 |
aiosignal = ">=1.1.2"
|
335 |
+
async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""}
|
336 |
attrs = ">=17.3.0"
|
337 |
frozenlist = ">=1.1.1"
|
338 |
multidict = ">=4.5,<7.0"
|
|
|
545 |
]
|
546 |
|
547 |
[package.dependencies]
|
548 |
+
exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
|
549 |
idna = ">=2.8"
|
550 |
sniffio = ">=1.1"
|
551 |
+
typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
|
552 |
|
553 |
[package.extras]
|
554 |
doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
|
|
|
649 |
{file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"},
|
650 |
]
|
651 |
|
652 |
+
[package.dependencies]
|
653 |
+
async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.11.0\""}
|
654 |
+
|
655 |
[package.extras]
|
656 |
docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"]
|
657 |
gssauth = ["gssapi", "sspilib"]
|
|
|
889 |
packaging = ">=22.0"
|
890 |
pathspec = ">=0.9.0"
|
891 |
platformdirs = ">=2"
|
892 |
+
tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
|
893 |
+
typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
|
894 |
|
895 |
[package.extras]
|
896 |
colorama = ["colorama (>=0.4.3)"]
|
|
|
1622 |
{file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"},
|
1623 |
]
|
1624 |
|
1625 |
+
[package.dependencies]
|
1626 |
+
tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
|
1627 |
+
|
1628 |
[package.extras]
|
1629 |
toml = ["tomli"]
|
1630 |
|
|
|
2144 |
{file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
|
2145 |
]
|
2146 |
|
2147 |
+
[[package]]
|
2148 |
+
name = "exceptiongroup"
|
2149 |
+
version = "1.2.2"
|
2150 |
+
description = "Backport of PEP 654 (exception groups)"
|
2151 |
+
optional = false
|
2152 |
+
python-versions = ">=3.7"
|
2153 |
+
files = [
|
2154 |
+
{file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
|
2155 |
+
{file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
|
2156 |
+
]
|
2157 |
+
|
2158 |
+
[package.extras]
|
2159 |
+
test = ["pytest (>=6)"]
|
2160 |
+
|
2161 |
[[package]]
|
2162 |
name = "fastapi"
|
2163 |
version = "0.115.5"
|
|
|
4273 |
{file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"},
|
4274 |
]
|
4275 |
|
4276 |
+
[package.dependencies]
|
4277 |
+
typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""}
|
4278 |
+
|
4279 |
[[package]]
|
4280 |
name = "mypy-extensions"
|
4281 |
version = "1.0.0"
|
|
|
4796 |
]
|
4797 |
|
4798 |
[package.dependencies]
|
4799 |
+
numpy = {version = ">=1.22.4", markers = "python_version < \"3.11\""}
|
4800 |
python-dateutil = ">=2.8.2"
|
4801 |
pytz = ">=2020.1"
|
4802 |
tzdata = ">=2022.7"
|
|
|
5819 |
|
5820 |
[package.dependencies]
|
5821 |
colorama = {version = "*", markers = "sys_platform == \"win32\""}
|
5822 |
+
exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
|
5823 |
iniconfig = "*"
|
5824 |
packaging = "*"
|
5825 |
pluggy = ">=1.5,<2"
|
5826 |
+
tomli = {version = ">=1", markers = "python_version < \"3.11\""}
|
5827 |
|
5828 |
[package.extras]
|
5829 |
dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
|
|
|
6078 |
{file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
|
6079 |
]
|
6080 |
|
6081 |
+
[package.dependencies]
|
6082 |
+
async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""}
|
6083 |
+
|
6084 |
[package.extras]
|
6085 |
hiredis = ["hiredis (>1.0.0)"]
|
6086 |
ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
|
|
|
7278 |
docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
|
7279 |
testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"]
|
7280 |
|
7281 |
+
[[package]]
|
7282 |
+
name = "tomli"
|
7283 |
+
version = "2.1.0"
|
7284 |
+
description = "A lil' TOML parser"
|
7285 |
+
optional = false
|
7286 |
+
python-versions = ">=3.8"
|
7287 |
+
files = [
|
7288 |
+
{file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"},
|
7289 |
+
{file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"},
|
7290 |
+
]
|
7291 |
+
|
7292 |
[[package]]
|
7293 |
name = "tomlkit"
|
7294 |
version = "0.13.2"
|
|
|
7664 |
httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
|
7665 |
python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
7666 |
pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
|
7667 |
+
typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
|
7668 |
uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
|
7669 |
watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
|
7670 |
websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
|
|
|
8222 |
|
8223 |
[metadata]
|
8224 |
lock-version = "2.0"
|
8225 |
+
python-versions = "3.10.15"
|
8226 |
+
content-hash = "f716178afcbcd2f78554e71f39d279ce266c633a668a8246716f601c76801647"
|
pyproject.toml
CHANGED
@@ -7,7 +7,7 @@ license = "Apache-2.0"
|
|
7 |
readme = "README.md"
|
8 |
|
9 |
[tool.poetry.dependencies]
|
10 |
-
python = "3.
|
11 |
black = "24.8.0"
|
12 |
coverage = ">=7.6.1"
|
13 |
hydra-colorlog = "1.2.0"
|
|
|
7 |
readme = "README.md"
|
8 |
|
9 |
[tool.poetry.dependencies]
|
10 |
+
python = "3.10.15"
|
11 |
black = "24.8.0"
|
12 |
coverage = ">=7.6.1"
|
13 |
hydra-colorlog = "1.2.0"
|
src/litserve_benchmark.py
CHANGED
@@ -6,6 +6,11 @@ import requests
|
|
6 |
import psutil
|
7 |
from urllib.request import urlopen
|
8 |
import matplotlib.pyplot as plt
|
|
|
|
|
|
|
|
|
|
|
9 |
|
10 |
# Try importing `gpustat` for GPU monitoring
|
11 |
try:
|
@@ -16,7 +21,7 @@ except ImportError:
|
|
16 |
GPU_AVAILABLE = False
|
17 |
|
18 |
# Constants
|
19 |
-
SERVER_URL = "http://localhost:8080"
|
20 |
TEST_IMAGE_URL = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/beignets-task-guide.png"
|
21 |
|
22 |
|
@@ -28,7 +33,7 @@ def fetch_and_prepare_payload():
|
|
28 |
img_data = urlopen(TEST_IMAGE_URL).read()
|
29 |
return base64.b64encode(img_data).decode("utf-8")
|
30 |
except Exception as e:
|
31 |
-
|
32 |
return None
|
33 |
|
34 |
|
@@ -47,7 +52,7 @@ def send_request(payload, batch=False):
|
|
47 |
predictions = response.json() if response.status_code == 200 else None
|
48 |
return response_time, response.status_code, predictions
|
49 |
except Exception as e:
|
50 |
-
|
51 |
return None, None, None
|
52 |
|
53 |
|
@@ -73,7 +78,7 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
|
|
73 |
"""
|
74 |
payload = fetch_and_prepare_payload()
|
75 |
if not payload:
|
76 |
-
|
77 |
return
|
78 |
|
79 |
payloads = [payload] * num_requests if batch else [payload]
|
@@ -114,11 +119,11 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
|
|
114 |
avg_response_time = np.mean(response_times) * 1000 if response_times else 0 # ms
|
115 |
requests_per_second = num_requests / total_benchmark_time
|
116 |
|
117 |
-
|
118 |
for i, prediction in enumerate(
|
119 |
predictions[:5]
|
120 |
): # Show predictions for the first 5 requests
|
121 |
-
|
122 |
|
123 |
return {
|
124 |
"total_requests": num_requests,
|
@@ -134,66 +139,56 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
|
|
134 |
|
135 |
def run_benchmarks():
|
136 |
"""
|
137 |
-
Run comprehensive benchmarks and create plots.
|
138 |
"""
|
139 |
concurrency_levels = [1, 8, 16, 32]
|
140 |
metrics = []
|
141 |
|
142 |
-
|
143 |
for concurrency in concurrency_levels:
|
144 |
-
|
145 |
result = benchmark_api(
|
146 |
num_requests=50, concurrency_level=concurrency, batch=False
|
147 |
)
|
148 |
if result:
|
149 |
metrics.append(result)
|
150 |
-
|
151 |
f"Concurrency {concurrency}: "
|
152 |
f"{result['requests_per_second']:.2f} reqs/sec, "
|
153 |
f"CPU: {result['avg_cpu_usage']:.1f}%, "
|
154 |
f"GPU: {result['avg_gpu_usage']:.1f}%"
|
155 |
)
|
156 |
|
157 |
-
# Generate
|
158 |
-
plt.figure(figsize=(
|
159 |
-
|
160 |
-
# Throughput
|
161 |
-
plt.subplot(1, 2, 1)
|
162 |
-
plt.plot(
|
163 |
-
concurrency_levels,
|
164 |
-
[m["requests_per_second"] for m in metrics],
|
165 |
-
"r-o",
|
166 |
-
label="Throughput",
|
167 |
-
)
|
168 |
-
plt.xlabel("Concurrency Level")
|
169 |
-
plt.ylabel("Requests per Second")
|
170 |
-
plt.title("API Throughput")
|
171 |
-
plt.grid(True)
|
172 |
-
|
173 |
-
# Resource Usage
|
174 |
-
plt.subplot(1, 2, 2)
|
175 |
plt.plot(
|
176 |
concurrency_levels,
|
177 |
[m["avg_cpu_usage"] for m in metrics],
|
178 |
"b-o",
|
179 |
label="CPU Usage",
|
180 |
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
181 |
if GPU_AVAILABLE:
|
|
|
182 |
plt.plot(
|
183 |
concurrency_levels,
|
184 |
[m["avg_gpu_usage"] for m in metrics],
|
185 |
"g-o",
|
186 |
label="GPU Usage",
|
187 |
)
|
188 |
-
|
189 |
-
|
190 |
-
|
191 |
-
|
192 |
-
|
193 |
-
|
194 |
-
plt.tight_layout()
|
195 |
-
plt.savefig("benchmark_results.png")
|
196 |
-
print("Benchmark results saved as 'benchmark_results.png'.")
|
197 |
|
198 |
|
199 |
if __name__ == "__main__":
|
|
|
6 |
import psutil
|
7 |
from urllib.request import urlopen
|
8 |
import matplotlib.pyplot as plt
|
9 |
+
from loguru import logger
|
10 |
+
import os
|
11 |
+
from dotenv import load_dotenv, find_dotenv
|
12 |
+
|
13 |
+
load_dotenv(find_dotenv())
|
14 |
|
15 |
# Try importing `gpustat` for GPU monitoring
|
16 |
try:
|
|
|
21 |
GPU_AVAILABLE = False
|
22 |
|
23 |
# Constants
|
24 |
+
SERVER_URL = os.getenv("SERVER_URL", "http://localhost:8080")
|
25 |
TEST_IMAGE_URL = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/beignets-task-guide.png"
|
26 |
|
27 |
|
|
|
33 |
img_data = urlopen(TEST_IMAGE_URL).read()
|
34 |
return base64.b64encode(img_data).decode("utf-8")
|
35 |
except Exception as e:
|
36 |
+
logger.info(f"Error fetching the image: {e}")
|
37 |
return None
|
38 |
|
39 |
|
|
|
52 |
predictions = response.json() if response.status_code == 200 else None
|
53 |
return response_time, response.status_code, predictions
|
54 |
except Exception as e:
|
55 |
+
logger.info(f"Error sending request: {e}")
|
56 |
return None, None, None
|
57 |
|
58 |
|
|
|
78 |
"""
|
79 |
payload = fetch_and_prepare_payload()
|
80 |
if not payload:
|
81 |
+
logger.info("Error preparing payload. Benchmark aborted.")
|
82 |
return
|
83 |
|
84 |
payloads = [payload] * num_requests if batch else [payload]
|
|
|
119 |
avg_response_time = np.mean(response_times) * 1000 if response_times else 0 # ms
|
120 |
requests_per_second = num_requests / total_benchmark_time
|
121 |
|
122 |
+
logger.info("\n--- Sample Predictions ---")
|
123 |
for i, prediction in enumerate(
|
124 |
predictions[:5]
|
125 |
): # Show predictions for the first 5 requests
|
126 |
+
logger.info(f"Request {i + 1}: {prediction}")
|
127 |
|
128 |
return {
|
129 |
"total_requests": num_requests,
|
|
|
139 |
|
140 |
def run_benchmarks():
|
141 |
"""
|
142 |
+
Run comprehensive benchmarks and create separate plots for CPU and GPU usage.
|
143 |
"""
|
144 |
concurrency_levels = [1, 8, 16, 32]
|
145 |
metrics = []
|
146 |
|
147 |
+
logger.info("Running API benchmarks...")
|
148 |
for concurrency in concurrency_levels:
|
149 |
+
logger.info(f"\nTesting concurrency level: {concurrency}")
|
150 |
result = benchmark_api(
|
151 |
num_requests=50, concurrency_level=concurrency, batch=False
|
152 |
)
|
153 |
if result:
|
154 |
metrics.append(result)
|
155 |
+
logger.info(
|
156 |
f"Concurrency {concurrency}: "
|
157 |
f"{result['requests_per_second']:.2f} reqs/sec, "
|
158 |
f"CPU: {result['avg_cpu_usage']:.1f}%, "
|
159 |
f"GPU: {result['avg_gpu_usage']:.1f}%"
|
160 |
)
|
161 |
|
162 |
+
# Generate CPU Usage Plot
|
163 |
+
plt.figure(figsize=(10, 5))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
164 |
plt.plot(
|
165 |
concurrency_levels,
|
166 |
[m["avg_cpu_usage"] for m in metrics],
|
167 |
"b-o",
|
168 |
label="CPU Usage",
|
169 |
)
|
170 |
+
plt.xlabel("Concurrency Level")
|
171 |
+
plt.ylabel("CPU Usage (%)")
|
172 |
+
plt.title("CPU Usage vs. Concurrency Level")
|
173 |
+
plt.grid(True)
|
174 |
+
plt.savefig("artifacts/cpu_usage.png")
|
175 |
+
logger.info("CPU usage plot saved as 'cpu_usage.png'.")
|
176 |
+
|
177 |
+
# Generate GPU Usage Plot
|
178 |
if GPU_AVAILABLE:
|
179 |
+
plt.figure(figsize=(10, 5))
|
180 |
plt.plot(
|
181 |
concurrency_levels,
|
182 |
[m["avg_gpu_usage"] for m in metrics],
|
183 |
"g-o",
|
184 |
label="GPU Usage",
|
185 |
)
|
186 |
+
plt.xlabel("Concurrency Level")
|
187 |
+
plt.ylabel("GPU Usage (%)")
|
188 |
+
plt.title("GPU Usage vs. Concurrency Level")
|
189 |
+
plt.grid(True)
|
190 |
+
plt.savefig("artifacts/gpu_usage.png")
|
191 |
+
logger.info("GPU usage plot saved as 'gpu_usage.png'.")
|
|
|
|
|
|
|
192 |
|
193 |
|
194 |
if __name__ == "__main__":
|