cortexgrid-infer 0.2.3__tar.gz → 0.2.4__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.
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/PKG-INFO +13 -7
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/README.md +12 -6
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_complete_serve.py +40 -5
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/pyproject.toml +1 -1
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/.gitignore +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/LICENSE +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/__init__.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/compiling.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/completion.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/core.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/device.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/importing.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/__init__.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/anthropic.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/anthropic_serve.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_complete.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_image.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_image_serve.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/py.typed +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/requirements.py +0 -0
- {cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/utils.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: cortexgrid-infer
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.4
|
|
4
4
|
Summary: Deploy and interact with models across providers (Anthropic, HuggingFace LLM + diffusion)
|
|
5
5
|
Project-URL: Homepage, https://github.com/robodatalab/cortexgrid-infer
|
|
6
6
|
Project-URL: Repository, https://github.com/robodatalab/cortexgrid-infer
|
|
@@ -178,12 +178,18 @@ Both serve apps are tuned rather than defaulted:
|
|
|
178
178
|
whole loop. The VAE is left alone: smallest win of the three, and the one whose
|
|
179
179
|
shapes move most, especially with tiling on.
|
|
180
180
|
- **`HuggingFaceCompletingDeployment`** does *not* compile the module. Decode has
|
|
181
|
-
no stable shape
|
|
182
|
-
`cache_implementation="static"`
|
|
183
|
-
transformers compiles `generate`
|
|
184
|
-
separately, which it is better placed to
|
|
185
|
-
|
|
186
|
-
|
|
181
|
+
no stable shape of its own — the sequence grows a token per forward — so it
|
|
182
|
+
pins one: `cache_implementation="static"` with a fixed `max_cache_len`, plus a
|
|
183
|
+
`CompileConfig(mode=Mode.GRAPHED)`. transformers then compiles `generate`
|
|
184
|
+
itself, capturing prefill and decode separately, which it is better placed to
|
|
185
|
+
do; compiling the module here as well would compile the same forward twice.
|
|
186
|
+
|
|
187
|
+
The fixed length is the point, and it comes from the model: the cache is
|
|
188
|
+
pinned to `config.max_position_embeddings`. A prompt longer than that is
|
|
189
|
+
truncated to it — keeping the end, since a chat template puts the turn to
|
|
190
|
+
answer last — with a warning naming both lengths. Serving it instead would
|
|
191
|
+
resize the cache and recompile the decode loop, which costs more than the
|
|
192
|
+
generation itself.
|
|
187
193
|
|
|
188
194
|
Neither asks to be configured, for the same reason the serve apps do not ask which
|
|
189
195
|
dtype to load in. Both happen on CUDA and nowhere else — inductor is weakest off
|
|
@@ -152,12 +152,18 @@ Both serve apps are tuned rather than defaulted:
|
|
|
152
152
|
whole loop. The VAE is left alone: smallest win of the three, and the one whose
|
|
153
153
|
shapes move most, especially with tiling on.
|
|
154
154
|
- **`HuggingFaceCompletingDeployment`** does *not* compile the module. Decode has
|
|
155
|
-
no stable shape
|
|
156
|
-
`cache_implementation="static"`
|
|
157
|
-
transformers compiles `generate`
|
|
158
|
-
separately, which it is better placed to
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
no stable shape of its own — the sequence grows a token per forward — so it
|
|
156
|
+
pins one: `cache_implementation="static"` with a fixed `max_cache_len`, plus a
|
|
157
|
+
`CompileConfig(mode=Mode.GRAPHED)`. transformers then compiles `generate`
|
|
158
|
+
itself, capturing prefill and decode separately, which it is better placed to
|
|
159
|
+
do; compiling the module here as well would compile the same forward twice.
|
|
160
|
+
|
|
161
|
+
The fixed length is the point, and it comes from the model: the cache is
|
|
162
|
+
pinned to `config.max_position_embeddings`. A prompt longer than that is
|
|
163
|
+
truncated to it — keeping the end, since a chat template puts the turn to
|
|
164
|
+
answer last — with a warning naming both lengths. Serving it instead would
|
|
165
|
+
resize the cache and recompile the decode loop, which costs more than the
|
|
166
|
+
generation itself.
|
|
161
167
|
|
|
162
168
|
Neither asks to be configured, for the same reason the serve apps do not ask which
|
|
163
169
|
dtype to load in. Both happen on CUDA and nowhere else — inductor is weakest off
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
5
|
import asyncio
|
|
6
|
+
import logging
|
|
6
7
|
from collections.abc import AsyncIterator
|
|
7
8
|
from threading import Thread
|
|
8
9
|
from typing import Any
|
|
@@ -11,16 +12,26 @@ import cortexgrid
|
|
|
11
12
|
from cortexgrid import serve
|
|
12
13
|
from fastapi import FastAPI
|
|
13
14
|
from fastapi.responses import StreamingResponse
|
|
14
|
-
from transformers import
|
|
15
|
+
from transformers import (
|
|
16
|
+
AutoModelForCausalLM,
|
|
17
|
+
AutoTokenizer,
|
|
18
|
+
CompileConfig,
|
|
19
|
+
TextIteratorStreamer,
|
|
20
|
+
)
|
|
15
21
|
import torch
|
|
16
22
|
|
|
17
23
|
from cortexgrid_infer import compiling
|
|
18
24
|
from cortexgrid_infer.device import detect_device
|
|
19
25
|
|
|
20
26
|
|
|
27
|
+
log = logging.getLogger(__name__)
|
|
28
|
+
|
|
21
29
|
_app = FastAPI()
|
|
22
30
|
|
|
23
31
|
|
|
32
|
+
# Used only by a model whose config states no context length of its own.
|
|
33
|
+
FALLBACK_MAX_INPUT_TOKENS = 4096
|
|
34
|
+
|
|
24
35
|
_RESERVED_BODY_KEYS = {
|
|
25
36
|
"messages",
|
|
26
37
|
"tools",
|
|
@@ -44,10 +55,32 @@ class HuggingFaceCompletingDeployment:
|
|
|
44
55
|
str(path), torch_dtype=torch.float16
|
|
45
56
|
)
|
|
46
57
|
self._model.to(self._device) # type: ignore
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
self._model, self._device, compiling.Mode.FUSED, label="model"
|
|
58
|
+
self._max_input_tokens = getattr(
|
|
59
|
+
self._model.config, "max_position_embeddings", FALLBACK_MAX_INPUT_TOKENS
|
|
50
60
|
)
|
|
61
|
+
# A static cache of fixed length is what makes decode compilable: it
|
|
62
|
+
# pins the shape every forward sees, so the loop is captured once
|
|
63
|
+
# instead of recompiled per token. transformers then compiles `generate`
|
|
64
|
+
# itself, which is why the module is not compiled here as well.
|
|
65
|
+
self._compiled = compiling.supported(self._device)
|
|
66
|
+
if self._compiled:
|
|
67
|
+
config = self._model.generation_config
|
|
68
|
+
config.cache_implementation = "static"
|
|
69
|
+
config.max_cache_len = self._max_input_tokens
|
|
70
|
+
config.compile_config = CompileConfig(mode=compiling.Mode.GRAPHED)
|
|
71
|
+
|
|
72
|
+
def _truncate(self, inputs: Any) -> Any:
|
|
73
|
+
"""Cut an over-long prompt to what the model handles, keeping its end."""
|
|
74
|
+
length = inputs["input_ids"].shape[-1]
|
|
75
|
+
if length <= self._max_input_tokens:
|
|
76
|
+
return inputs
|
|
77
|
+
log.warning(
|
|
78
|
+
"truncating prompt from %d to %d tokens, the model's context",
|
|
79
|
+
length, self._max_input_tokens,
|
|
80
|
+
)
|
|
81
|
+
for key, value in inputs.items():
|
|
82
|
+
inputs[key] = value[..., -self._max_input_tokens :]
|
|
83
|
+
return inputs
|
|
51
84
|
|
|
52
85
|
@_app.post("/complete")
|
|
53
86
|
async def complete(self, body: dict[str, Any]) -> StreamingResponse:
|
|
@@ -66,7 +99,9 @@ class HuggingFaceCompletingDeployment:
|
|
|
66
99
|
tokenize=False,
|
|
67
100
|
add_generation_prompt=True,
|
|
68
101
|
)
|
|
69
|
-
inputs = self._tokenizer(prompt, return_tensors="pt").to(
|
|
102
|
+
inputs = self._truncate(self._tokenizer(prompt, return_tensors="pt")).to(
|
|
103
|
+
self._model.device
|
|
104
|
+
)
|
|
70
105
|
|
|
71
106
|
queue: asyncio.Queue[str | None] = asyncio.Queue()
|
|
72
107
|
error: list[BaseException] = []
|
|
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
|
{cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/anthropic_serve.py
RENAMED
|
File without changes
|
{cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_complete.py
RENAMED
|
File without changes
|
{cortexgrid_infer-0.2.3 → cortexgrid_infer-0.2.4}/cortexgrid_infer/providers/huggingface_image.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|