adarshcod30 commited on
Commit
f2aeec5
·
verified ·
1 Parent(s): 87e0c95

Force CPU device explicitly (ZeroGPU makes cuda.is_available() report True outside a real grant, breaking auto-detection)

Browse files
Files changed (2) hide show
  1. app.py +12 -1
  2. src/drdetect/serve/demo.py +13 -5
app.py CHANGED
@@ -27,6 +27,15 @@ Space's own runtime error, not guessed:
27
  on CPU exactly as the rest of this project does. It exists solely to
28
  satisfy that platform check without changing this project's actual
29
  CPU-only inference path.
 
 
 
 
 
 
 
 
 
30
 
31
  Both are wrapped so this file still runs unmodified outside a Space
32
  (`spaces` is not, and should not be, a dependency of the main `drdetect`
@@ -63,5 +72,7 @@ if __name__ == "__main__":
63
 
64
  # regression loss, not ce: it won the locked external evaluation decisively
65
  # (docs/22_PHASE8_VALIDATION_RESULTS.md, referable AUC 0.924 vs 0.888, DeLong p=6.1e-10)
66
- demo = build_interface(checkpoint, backbone="efficientnet_b0", loss_name="regression", size=512)
 
 
67
  demo.launch(ssr_mode=False)
 
27
  on CPU exactly as the rest of this project does. It exists solely to
28
  satisfy that platform check without changing this project's actual
29
  CPU-only inference path.
30
+ 3. **`device="cpu"` passed explicitly to `build_interface` below**: its
31
+ default auto-detection (`drdetect.serve.demo`) checks
32
+ `torch.cuda.is_available()`, which ZeroGPU makes report `True` even
33
+ outside an actual `@spaces.GPU` grant -- auto-detection then picked
34
+ "cuda" and crashed the first real request with `RuntimeError: Low-level
35
+ CUDA init... reached` the moment a tensor was moved to it, since nothing
36
+ in the demo path is wrapped in `@spaces.GPU`. Forcing "cpu" here matches
37
+ this project's actual design (CPU-only inference throughout) rather than
38
+ trusting a detection heuristic that ZeroGPU's emulation invalidates.
39
 
40
  Both are wrapped so this file still runs unmodified outside a Space
41
  (`spaces` is not, and should not be, a dependency of the main `drdetect`
 
72
 
73
  # regression loss, not ce: it won the locked external evaluation decisively
74
  # (docs/22_PHASE8_VALIDATION_RESULTS.md, referable AUC 0.924 vs 0.888, DeLong p=6.1e-10)
75
+ demo = build_interface(
76
+ checkpoint, backbone="efficientnet_b0", loss_name="regression", size=512, device="cpu"
77
+ )
78
  demo.launch(ssr_mode=False)
src/drdetect/serve/demo.py CHANGED
@@ -52,15 +52,23 @@ def build_interface(
52
  backbone: str = "efficientnet_b0",
53
  loss_name: str = "ce",
54
  size: int = 512,
 
55
  ):
 
 
 
 
 
 
56
  import gradio as gr
57
  import torch
58
 
59
- device = (
60
- "mps"
61
- if torch.backends.mps.is_available()
62
- else ("cuda" if torch.cuda.is_available() else "cpu")
63
- )
 
64
  model = load_grader(checkpoint, backbone=backbone, loss_name=loss_name, device=device)
65
  temperature = load_temperature(checkpoint)
66
 
 
52
  backbone: str = "efficientnet_b0",
53
  loss_name: str = "ce",
54
  size: int = 512,
55
+ device: str | None = None,
56
  ):
57
+ """`device=None` (default) auto-detects mps/cuda/cpu, the right choice for
58
+ local development. Pass an explicit `device` to override that -- needed
59
+ on HF Spaces' free ZeroGPU tier, where `torch.cuda.is_available()`
60
+ reports True outside an actual `@spaces.GPU` grant, so auto-detection
61
+ would pick "cuda" and crash the moment a tensor touches it (see app.py).
62
+ """
63
  import gradio as gr
64
  import torch
65
 
66
+ if device is None:
67
+ device = (
68
+ "mps"
69
+ if torch.backends.mps.is_available()
70
+ else ("cuda" if torch.cuda.is_available() else "cpu")
71
+ )
72
  model = load_grader(checkpoint, backbone=backbone, loss_name=loss_name, device=device)
73
  temperature = load_temperature(checkpoint)
74