Deploy Lost & Found Desk
Browse filesCo-authored-by: Codex <codex@openai.com>
- README.md +1 -1
- src/lost_found_desk/config.py +5 -1
- src/lost_found_desk/runtime/device.py +1 -1
- src/lost_found_desk/runtime/gpu.py +10 -8
README.md
CHANGED
|
@@ -213,7 +213,7 @@ This repo was updated to match the current official docs as of 2026-06-14:
|
|
| 213 |
| --- | --- | --- |
|
| 214 |
| Gradio | `gradio==6.17.3` | Space metadata pins the same `sdk_version`. |
|
| 215 |
| Gradio Server mode | `gradio.Server` + `@app.api()` | Gives FastAPI routes plus Gradio API queue/concurrency/ZeroGPU behavior. |
|
| 216 |
-
| ZeroGPU | `spaces>=0.50.4`, `@spaces.GPU` via `maybe_zerogpu()` | GPU-dependent calls are
|
| 217 |
| MiniCPM-V | `openbmb/MiniCPM-V-4.6` through `AutoProcessor` + `AutoModelForImageTextToText` | Matches the model card's Transformers path. |
|
| 218 |
| MiniCPM5 | `openbmb/MiniCPM5-1B` through `AutoTokenizer` + `AutoModelForCausalLM` | Matches the model card's standard `LlamaForCausalLM` path. |
|
| 219 |
| Frontend | Svelte 5 + Vite 8 + `@gradio/client` | The compiled Svelte app is committed into `static/` so the Space needs no Node build step. |
|
|
|
|
| 213 |
| --- | --- | --- |
|
| 214 |
| Gradio | `gradio==6.17.3` | Space metadata pins the same `sdk_version`. |
|
| 215 |
| Gradio Server mode | `gradio.Server` + `@app.api()` | Gives FastAPI routes plus Gradio API queue/concurrency/ZeroGPU behavior. |
|
| 216 |
+
| ZeroGPU | `spaces>=0.50.4`, `@spaces.GPU` via `maybe_zerogpu()` | GPU-dependent calls are registered with the official decorator; `spaces` activates the wrapper when HF sets `SPACES_ZERO_GPU=true`, and the real MiniCPM adapters are eagerly loaded at app startup to match the ZeroGPU model-loading recommendation. |
|
| 217 |
| MiniCPM-V | `openbmb/MiniCPM-V-4.6` through `AutoProcessor` + `AutoModelForImageTextToText` | Matches the model card's Transformers path. |
|
| 218 |
| MiniCPM5 | `openbmb/MiniCPM5-1B` through `AutoTokenizer` + `AutoModelForCausalLM` | Matches the model card's standard `LlamaForCausalLM` path. |
|
| 219 |
| Frontend | Svelte 5 + Vite 8 + `@gradio/client` | The compiled Svelte app is committed into `static/` so the Space needs no Node build step. |
|
src/lost_found_desk/config.py
CHANGED
|
@@ -10,6 +10,10 @@ def _env_flag(name: str, default: str) -> bool:
|
|
| 10 |
return os.getenv(name, default).lower() not in {"0", "false", "no", ""}
|
| 11 |
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
@dataclass(frozen=True)
|
| 14 |
class Settings:
|
| 15 |
app_name: str
|
|
@@ -66,7 +70,7 @@ def _load_settings() -> Settings:
|
|
| 66 |
retrieval_enabled=_env_flag("LFD_RETRIEVAL", "1"),
|
| 67 |
embed_strong_threshold=float(os.getenv("LFD_EMBED_STRONG", "0.32")),
|
| 68 |
embed_weak_threshold=float(os.getenv("LFD_EMBED_WEAK", "0.18")),
|
| 69 |
-
zerogpu=
|
| 70 |
zerogpu_caption_duration=int(os.getenv("LFD_ZEROGPU_CAPTION_DURATION", "45")),
|
| 71 |
zerogpu_text_duration=int(os.getenv("LFD_ZEROGPU_TEXT_DURATION", "30")),
|
| 72 |
seed_event_id=os.getenv("LFD_SEED_EVENT_ID", "demo"),
|
|
|
|
| 10 |
return os.getenv(name, default).lower() not in {"0", "false", "no", ""}
|
| 11 |
|
| 12 |
|
| 13 |
+
def _hf_zero_gpu_enabled() -> bool:
|
| 14 |
+
return os.getenv("SPACES_ZERO_GPU", "").lower() in {"1", "t", "true"}
|
| 15 |
+
|
| 16 |
+
|
| 17 |
@dataclass(frozen=True)
|
| 18 |
class Settings:
|
| 19 |
app_name: str
|
|
|
|
| 70 |
retrieval_enabled=_env_flag("LFD_RETRIEVAL", "1"),
|
| 71 |
embed_strong_threshold=float(os.getenv("LFD_EMBED_STRONG", "0.32")),
|
| 72 |
embed_weak_threshold=float(os.getenv("LFD_EMBED_WEAK", "0.18")),
|
| 73 |
+
zerogpu=_hf_zero_gpu_enabled(),
|
| 74 |
zerogpu_caption_duration=int(os.getenv("LFD_ZEROGPU_CAPTION_DURATION", "45")),
|
| 75 |
zerogpu_text_duration=int(os.getenv("LFD_ZEROGPU_TEXT_DURATION", "30")),
|
| 76 |
seed_event_id=os.getenv("LFD_SEED_EVENT_ID", "demo"),
|
src/lost_found_desk/runtime/device.py
CHANGED
|
@@ -19,7 +19,7 @@ def detect_runtime(requested: str = "auto") -> RuntimeInfo:
|
|
| 19 |
"""
|
| 20 |
requested = (requested or "auto").lower()
|
| 21 |
|
| 22 |
-
if os.getenv("
|
| 23 |
return RuntimeInfo(runtime="zerogpu", device="cuda", dtype="auto")
|
| 24 |
|
| 25 |
try:
|
|
|
|
| 19 |
"""
|
| 20 |
requested = (requested or "auto").lower()
|
| 21 |
|
| 22 |
+
if os.getenv("SPACES_ZERO_GPU", "").lower() in {"1", "t", "true"}:
|
| 23 |
return RuntimeInfo(runtime="zerogpu", device="cuda", dtype="auto")
|
| 24 |
|
| 25 |
try:
|
src/lost_found_desk/runtime/gpu.py
CHANGED
|
@@ -1,24 +1,26 @@
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
| 3 |
-
import os
|
| 4 |
from typing import Callable, TypeVar
|
| 5 |
|
| 6 |
F = TypeVar("F", bound=Callable)
|
| 7 |
|
| 8 |
|
| 9 |
def maybe_zerogpu(duration: int = 60, size: str | None = None):
|
| 10 |
-
"""Return @spaces.GPU
|
| 11 |
|
| 12 |
-
|
| 13 |
-
|
|
|
|
|
|
|
| 14 |
"""
|
| 15 |
-
|
| 16 |
-
|
|
|
|
|
|
|
| 17 |
def identity(fn: F) -> F:
|
| 18 |
return fn
|
| 19 |
-
return identity
|
| 20 |
|
| 21 |
-
|
| 22 |
|
| 23 |
kwargs = {"duration": duration}
|
| 24 |
if size:
|
|
|
|
| 1 |
from __future__ import annotations
|
| 2 |
|
|
|
|
| 3 |
from typing import Callable, TypeVar
|
| 4 |
|
| 5 |
F = TypeVar("F", bound=Callable)
|
| 6 |
|
| 7 |
|
| 8 |
def maybe_zerogpu(duration: int = 60, size: str | None = None):
|
| 9 |
+
"""Return the official @spaces.GPU decorator when the package is present.
|
| 10 |
|
| 11 |
+
The `spaces` package decides whether the current runtime is ZeroGPU from
|
| 12 |
+
Hugging Face's `SPACES_ZERO_GPU` environment variable. Outside ZeroGPU it
|
| 13 |
+
returns the original function unchanged, so local CUDA/MPS/CPU runs keep the
|
| 14 |
+
same call path while HF startup can still discover GPU-decorated functions.
|
| 15 |
"""
|
| 16 |
+
|
| 17 |
+
try:
|
| 18 |
+
import spaces # type: ignore
|
| 19 |
+
except ImportError:
|
| 20 |
def identity(fn: F) -> F:
|
| 21 |
return fn
|
|
|
|
| 22 |
|
| 23 |
+
return identity
|
| 24 |
|
| 25 |
kwargs = {"duration": duration}
|
| 26 |
if size:
|