hjerpe commited on
Commit
44ce4f7
·
verified ·
1 Parent(s): 18d5549

F006/F008: serve Qwen models + model switcher (vanilla-first)

Browse files
Files changed (2) hide show
  1. app.py +9 -0
  2. server/serving.py +9 -7
app.py CHANGED
@@ -12,6 +12,15 @@ Run locally: ``uv run python app.py``.
12
 
13
  from __future__ import annotations
14
 
 
 
 
 
 
 
 
 
 
15
  # Prefer the ABSOLUTE packaged module so that `import app` (flat, via the test
16
  # pythonpath) and `import sql_env.app` BOTH delegate to the exact same
17
  # `sql_env.server.app_ui` — a single `Step`/class identity (R1). The flat
 
12
 
13
  from __future__ import annotations
14
 
15
+ # ZeroGPU: the `spaces` package MUST be imported before ANYTHING initializes CUDA
16
+ # (i.e. before preload/torch below), or it raises "CUDA has been initialized before
17
+ # importing the `spaces` package". So import it FIRST. Absent off-Space (local/tests),
18
+ # where the `@spaces.GPU` decorator is a documented no-op anyway.
19
+ try:
20
+ import spaces # noqa: F401
21
+ except ImportError: # pragma: no cover - not on a ZeroGPU Space (local / tests)
22
+ pass
23
+
24
  # Prefer the ABSOLUTE packaged module so that `import app` (flat, via the test
25
  # pythonpath) and `import sql_env.app` BOTH delegate to the exact same
26
  # `sql_env.server.app_ui` — a single `Step`/class identity (R1). The flat
server/serving.py CHANGED
@@ -141,16 +141,18 @@ def _load_model_and_tokenizer(source: str, revision: str | None) -> tuple[Any, A
141
 
142
 
143
  def _maybe_to_cuda(model: Any) -> Any:
144
- """Move the model to CUDA when available (the only torch touch in the load path).
145
 
146
- Mirrors ``training/pipeline.py::run_eval`` and ``scripts/inference_smoke.py``. On a
147
- CPU box this is a no-op; ``ModelPolicy._generate`` sends inputs to ``model.device``.
 
 
 
148
  """
149
- import torch # noqa: PLC0415
150
-
151
- if torch.cuda.is_available():
152
  return model.to("cuda")
153
- return model
 
154
 
155
 
156
  def _ensure_loaded(key: str) -> tuple[Any, Any]:
 
141
 
142
 
143
  def _maybe_to_cuda(model: Any) -> Any:
144
+ """Place the model on CUDA the GPU-placement step of the load path.
145
 
146
+ On a ZeroGPU Space, ``import spaces`` (done first in ``app.py``) enables a CUDA
147
+ emulation, so moving to ``cuda`` at load time is the REQUIRED pattern; the model
148
+ is materialized on the real GPU inside ``@spaces.GPU``. ``cuda.is_available()`` is
149
+ False on the startup container, so we must NOT guard on it. On a CPU-only box
150
+ ``.to("cuda")`` raises, so we fall back to CPU.
151
  """
152
+ try:
 
 
153
  return model.to("cuda")
154
+ except Exception: # CPU fallback when no CUDA is available (e.g. local dev)
155
+ return model
156
 
157
 
158
  def _ensure_loaded(key: str) -> tuple[Any, Any]: