tommytracx commited on
Commit
4dda59b
·
verified ·
1 Parent(s): c8944a3

Bound interactive inference backpressure

Browse files

Exact source: ttracx/thoxroute@4f71bbe0dea6d8f029c06a66f010928f0f363550

Files changed (3) hide show
  1. Dockerfile +2 -1
  2. README.md +7 -3
  3. app.py +22 -2
Dockerfile CHANGED
@@ -23,7 +23,8 @@ ENV HF_HOME=/home/mambauser/.cache/huggingface \
23
  THOX_FAST_MODEL_REPO=Qwen/Qwen2.5-0.5B-Instruct-GGUF \
24
  THOX_FAST_MODEL_REVISION=9217f5db79a29953eb74d5343926648285ec7e67 \
25
  THOX_FAST_MODEL_FILE=qwen2.5-0.5b-instruct-q4_k_m.gguf \
26
- THOX_FAST_POOL_SIZE=2 \
 
27
  THOX_MAX_OUTPUT_TOKENS=128
28
 
29
  # Bake the immutable public interactive model into the image. A RUNNING Space
 
23
  THOX_FAST_MODEL_REPO=Qwen/Qwen2.5-0.5B-Instruct-GGUF \
24
  THOX_FAST_MODEL_REVISION=9217f5db79a29953eb74d5343926648285ec7e67 \
25
  THOX_FAST_MODEL_FILE=qwen2.5-0.5b-instruct-q4_k_m.gguf \
26
+ THOX_FAST_POOL_SIZE=1 \
27
+ THOX_FAST_QUEUE_TIMEOUT_S=6 \
28
  THOX_MAX_OUTPUT_TOKENS=128
29
 
30
  # Bake the immutable public interactive model into the image. A RUNNING Space
README.md CHANGED
@@ -12,10 +12,14 @@ license: apache-2.0
12
 
13
  This Space exposes one OpenAI-compatible endpoint:
14
 
15
- - `thox-fast-chat`: eagerly loaded, bounded, interactive Qwen2.5 0.5B target;
 
16
  - `thox-rust-coder`: lazily loaded 25B/3B-active Rust-specialist target.
17
 
18
- `GET /healthz` is ready only after the two-instance interactive pool is loaded
19
- and each llama context has completed a one-token startup warmup.
 
 
 
20
  The interactive model is pinned to immutable model revision
21
  `9217f5db79a29953eb74d5343926648285ec7e67` and baked into the image.
 
12
 
13
  This Space exposes one OpenAI-compatible endpoint:
14
 
15
+ - `thox-fast-chat`: eagerly loaded, bounded, full-CPU Qwen2.5 0.5B target with
16
+ a six-second queue ceiling;
17
  - `thox-rust-coder`: lazily loaded 25B/3B-active Rust-specialist target.
18
 
19
+ `GET /healthz` is ready only after the interactive context is loaded and has
20
+ completed a one-token startup warmup. Streaming sends a role chunk before model
21
+ evaluation so upstream time-to-first-byte watchdogs do not abandon healthy CPU
22
+ work. First-party 15-second requests are capped at 16 output tokens by
23
+ ThoxRoute.
24
  The interactive model is pinned to immutable model revision
25
  `9217f5db79a29953eb74d5343926648285ec7e67` and baked into the image.
app.py CHANGED
@@ -43,7 +43,10 @@ CODER_MODEL_FILE = os.environ.get(
43
  "THOX_CODER_MODEL_FILE", "Qwen3-Coder-REAP-25B-A3B-Rust-Q4_K_M.gguf"
44
  )
45
  N_CTX = int(os.environ.get("THOX_N_CTX", "4096"))
46
- FAST_POOL_SIZE = max(1, min(int(os.environ.get("THOX_FAST_POOL_SIZE", "2")), 4))
 
 
 
47
  MAX_OUTPUT_TOKENS = max(
48
  1, min(int(os.environ.get("THOX_MAX_OUTPUT_TOKENS", "128")), 512)
49
  )
@@ -142,7 +145,7 @@ class Runtime:
142
  def acquire(self, model_id: str) -> Lease:
143
  if model_id == FAST_MODEL_ID:
144
  try:
145
- model = self._fast.get_nowait()
146
  except queue.Empty as exc:
147
  raise HTTPException(status_code=429, detail="interactive capacity busy") from exc
148
  return Lease(model=model, release=lambda: self._fast.put(model))
@@ -251,6 +254,23 @@ def _stream_completion(req: ChatRequest, lease: Lease) -> Iterator[bytes]:
251
  completion_id = _completion_id()
252
  created = int(time.time())
253
  try:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
254
  chunks = lease.model.create_chat_completion(
255
  messages=_messages(req),
256
  max_tokens=_max_tokens(req),
 
43
  "THOX_CODER_MODEL_FILE", "Qwen3-Coder-REAP-25B-A3B-Rust-Q4_K_M.gguf"
44
  )
45
  N_CTX = int(os.environ.get("THOX_N_CTX", "4096"))
46
+ FAST_POOL_SIZE = max(1, min(int(os.environ.get("THOX_FAST_POOL_SIZE", "1")), 2))
47
+ FAST_QUEUE_TIMEOUT_S = max(
48
+ 0.1, min(float(os.environ.get("THOX_FAST_QUEUE_TIMEOUT_S", "6")), 10.0)
49
+ )
50
  MAX_OUTPUT_TOKENS = max(
51
  1, min(int(os.environ.get("THOX_MAX_OUTPUT_TOKENS", "128")), 512)
52
  )
 
145
  def acquire(self, model_id: str) -> Lease:
146
  if model_id == FAST_MODEL_ID:
147
  try:
148
+ model = self._fast.get(timeout=FAST_QUEUE_TIMEOUT_S)
149
  except queue.Empty as exc:
150
  raise HTTPException(status_code=429, detail="interactive capacity busy") from exc
151
  return Lease(model=model, release=lambda: self._fast.put(model))
 
254
  completion_id = _completion_id()
255
  created = int(time.time())
256
  try:
257
+ # Send a valid role chunk before llama prompt evaluation. This proves
258
+ # the stream is alive inside ThoxRoute's short time-to-first-byte budget
259
+ # and prevents a healthy CPU inference from being abandoned at 12 s.
260
+ initial = {
261
+ "id": completion_id,
262
+ "object": "chat.completion.chunk",
263
+ "created": created,
264
+ "model": req.model,
265
+ "choices": [
266
+ {
267
+ "index": 0,
268
+ "delta": {"role": "assistant", "content": ""},
269
+ "finish_reason": None,
270
+ }
271
+ ],
272
+ }
273
+ yield f"data: {json.dumps(initial, separators=(',', ':'))}\n\n".encode()
274
  chunks = lease.model.create_chat_completion(
275
  messages=_messages(req),
276
  max_tokens=_max_tokens(req),