Spaces:
Running
on
Zero
Running
on
Zero
Update
Browse files- .gitignore +2 -1
- app.py +66 -21
- tmp/config.log +2 -1
- tmp/models.log +2 -0
.gitignore
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
.venv/
|
|
|
|
|
|
| 1 |
+
.venv/
|
| 2 |
+
sample_images/
|
app.py
CHANGED
|
@@ -2,6 +2,7 @@
|
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
|
|
|
| 5 |
import sys
|
| 6 |
from pathlib import Path
|
| 7 |
from typing import NamedTuple
|
|
@@ -12,7 +13,10 @@ if _REPO_ROOT not in sys.path:
|
|
| 12 |
sys.path.insert(0, str(_REPO_ROOT))
|
| 13 |
|
| 14 |
_GRADIO_DIR = Path(__file__).resolve().parent
|
| 15 |
-
|
|
|
|
|
|
|
|
|
|
| 16 |
import gradio as gr
|
| 17 |
import numpy as np
|
| 18 |
import torch
|
|
@@ -73,16 +77,28 @@ def _get_assets() -> HFAssets:
|
|
| 73 |
return _cached_assets
|
| 74 |
|
| 75 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 76 |
def _get_sample_image_paths() -> list[str]:
|
| 77 |
-
"""Return
|
|
|
|
| 78 |
assets = _get_assets()
|
| 79 |
-
|
|
|
|
| 80 |
return []
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 86 |
return paths
|
| 87 |
|
| 88 |
|
|
@@ -113,13 +129,12 @@ def _get_model(device: str):
|
|
| 113 |
|
| 114 |
def build_ui():
|
| 115 |
_get_assets()
|
| 116 |
-
|
| 117 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 118 |
# Start loading the model in the background so it is ready (or nearly ready) by first use.
|
| 119 |
print(f"Initializing model on {device}...")
|
| 120 |
_get_model(device)
|
| 121 |
|
| 122 |
-
@spaces.GPU
|
| 123 |
def run_inference(image: np.ndarray | None) -> np.ndarray | None:
|
| 124 |
"""Run reflection removal using the cached model. Returns RGB numpy [H,W,3] in 0–255 or None."""
|
| 125 |
if image is None:
|
|
@@ -134,9 +149,15 @@ def build_ui():
|
|
| 134 |
tensor = TF.resize(tensor, [target_side, target_side], antialias=True)
|
| 135 |
tensor = tensor.to(ura_model.device, dtype=torch.float32)
|
| 136 |
mask = tensor.mean(1, keepdim=True) > 0.9 # [1, 1, S, S]
|
|
|
|
|
|
|
| 137 |
with torch.no_grad():
|
|
|
|
| 138 |
diffuse = ura_model(images=tensor, inpaint_mask_override=mask)
|
|
|
|
| 139 |
diffuse = diffuse.cpu()
|
|
|
|
|
|
|
| 140 |
diffuse = TF.resize(diffuse, [h, w], antialias=True)
|
| 141 |
out = diffuse[0].numpy().transpose(1, 2, 0)
|
| 142 |
out = (np.clip(out, 0.0, 1.0) * 255).astype(np.uint8)
|
|
@@ -178,12 +199,12 @@ def build_ui():
|
|
| 178 |
with gr.Row():
|
| 179 |
inp = gr.Image(
|
| 180 |
type="numpy",
|
| 181 |
-
label="
|
| 182 |
height=600,
|
| 183 |
width=600,
|
| 184 |
)
|
| 185 |
out_slider = gr.ImageSlider(
|
| 186 |
-
label="
|
| 187 |
type="numpy",
|
| 188 |
height=600,
|
| 189 |
show_label=True,
|
|
@@ -208,7 +229,7 @@ def build_ui():
|
|
| 208 |
[GitHub](https://github.com/alberto-rota/UnReflectAnything) ⋅
|
| 209 |
[Model Card](https://huggingface.co/AlbeRota/UnReflectAnything) ⋅
|
| 210 |
[Paper](https://arxiv.org/abs/2512.09583) ⋅
|
| 211 |
-
[Contact](mailto:alberto1.rota@polimi.it)
|
| 212 |
""")
|
| 213 |
return demo
|
| 214 |
|
|
@@ -221,15 +242,39 @@ def _launch_allowed_paths():
|
|
| 221 |
paths = [str(_GRADIO_DIR)]
|
| 222 |
try:
|
| 223 |
assets = _get_assets()
|
| 224 |
-
|
| 225 |
-
|
| 226 |
-
|
| 227 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 228 |
return paths
|
| 229 |
|
| 230 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 231 |
if __name__ == "__main__":
|
| 232 |
-
demo.launch(
|
| 233 |
-
allowed_paths=_launch_allowed_paths(),
|
| 234 |
-
theme=gr.themes.Soft(primary_hue="orange", secondary_hue="blue"),
|
| 235 |
-
)
|
|
|
|
| 2 |
|
| 3 |
from __future__ import annotations
|
| 4 |
|
| 5 |
+
import shutil
|
| 6 |
import sys
|
| 7 |
from pathlib import Path
|
| 8 |
from typing import NamedTuple
|
|
|
|
| 13 |
sys.path.insert(0, str(_REPO_ROOT))
|
| 14 |
|
| 15 |
_GRADIO_DIR = Path(__file__).resolve().parent
|
| 16 |
+
try:
|
| 17 |
+
import spaces
|
| 18 |
+
except ModuleNotFoundError:
|
| 19 |
+
spaces = None
|
| 20 |
import gradio as gr
|
| 21 |
import numpy as np
|
| 22 |
import torch
|
|
|
|
| 77 |
return _cached_assets
|
| 78 |
|
| 79 |
|
| 80 |
+
# Local copy of sample images under cwd so Gradio never needs allowed_paths for examples
|
| 81 |
+
_SAMPLE_IMAGES_COPY_DIR: Path | None = None
|
| 82 |
+
|
| 83 |
+
|
| 84 |
def _get_sample_image_paths() -> list[str]:
|
| 85 |
+
"""Return paths of sample images under cwd (copied from HF cache) so Gradio can use them without allowed_paths."""
|
| 86 |
+
global _SAMPLE_IMAGES_COPY_DIR
|
| 87 |
assets = _get_assets()
|
| 88 |
+
src = assets.sample_images_dir
|
| 89 |
+
if not src.is_dir():
|
| 90 |
return []
|
| 91 |
+
dest = _GRADIO_DIR / "sample_images"
|
| 92 |
+
dest.mkdir(parents=True, exist_ok=True)
|
| 93 |
+
paths = []
|
| 94 |
+
for p in sorted(src.iterdir()):
|
| 95 |
+
if not p.is_file() or p.suffix.lower() not in IMAGE_EXTENSIONS:
|
| 96 |
+
continue
|
| 97 |
+
dst_file = dest / p.name
|
| 98 |
+
if not dst_file.exists() or dst_file.stat().st_mtime < p.stat().st_mtime:
|
| 99 |
+
shutil.copy2(p, dst_file)
|
| 100 |
+
paths.append(str(dst_file.resolve()))
|
| 101 |
+
_SAMPLE_IMAGES_COPY_DIR = dest
|
| 102 |
return paths
|
| 103 |
|
| 104 |
|
|
|
|
| 129 |
|
| 130 |
def build_ui():
|
| 131 |
_get_assets()
|
|
|
|
| 132 |
device = "cuda" if torch.cuda.is_available() else "cpu"
|
| 133 |
# Start loading the model in the background so it is ready (or nearly ready) by first use.
|
| 134 |
print(f"Initializing model on {device}...")
|
| 135 |
_get_model(device)
|
| 136 |
|
| 137 |
+
@spaces.GPU if spaces else lambda x: x
|
| 138 |
def run_inference(image: np.ndarray | None) -> np.ndarray | None:
|
| 139 |
"""Run reflection removal using the cached model. Returns RGB numpy [H,W,3] in 0–255 or None."""
|
| 140 |
if image is None:
|
|
|
|
| 149 |
tensor = TF.resize(tensor, [target_side, target_side], antialias=True)
|
| 150 |
tensor = tensor.to(ura_model.device, dtype=torch.float32)
|
| 151 |
mask = tensor.mean(1, keepdim=True) > 0.9 # [1, 1, S, S]
|
| 152 |
+
import time
|
| 153 |
+
|
| 154 |
with torch.no_grad():
|
| 155 |
+
start_time = time.time()
|
| 156 |
diffuse = ura_model(images=tensor, inpaint_mask_override=mask)
|
| 157 |
+
end_time = time.time()
|
| 158 |
diffuse = diffuse.cpu()
|
| 159 |
+
inference_time_ms = (end_time - start_time) * 1000
|
| 160 |
+
gr.Success(f"Inference time: {inference_time_ms:.1f} ms")
|
| 161 |
diffuse = TF.resize(diffuse, [h, w], antialias=True)
|
| 162 |
out = diffuse[0].numpy().transpose(1, 2, 0)
|
| 163 |
out = (np.clip(out, 0.0, 1.0) * 255).astype(np.uint8)
|
|
|
|
| 199 |
with gr.Row():
|
| 200 |
inp = gr.Image(
|
| 201 |
type="numpy",
|
| 202 |
+
label="Input",
|
| 203 |
height=600,
|
| 204 |
width=600,
|
| 205 |
)
|
| 206 |
out_slider = gr.ImageSlider(
|
| 207 |
+
label="Output",
|
| 208 |
type="numpy",
|
| 209 |
height=600,
|
| 210 |
show_label=True,
|
|
|
|
| 229 |
[GitHub](https://github.com/alberto-rota/UnReflectAnything) ⋅
|
| 230 |
[Model Card](https://huggingface.co/AlbeRota/UnReflectAnything) ⋅
|
| 231 |
[Paper](https://arxiv.org/abs/2512.09583) ⋅
|
| 232 |
+
[Contact](mailto:alberto1.rota@polimi.it)
|
| 233 |
""")
|
| 234 |
return demo
|
| 235 |
|
|
|
|
| 242 |
paths = [str(_GRADIO_DIR)]
|
| 243 |
try:
|
| 244 |
assets = _get_assets()
|
| 245 |
+
sample_dir = assets.sample_images_dir
|
| 246 |
+
if sample_dir.is_dir():
|
| 247 |
+
paths.append(str(sample_dir.resolve()))
|
| 248 |
+
# Also allow parent (snapshot root) in case Gradio resolves paths from repo root
|
| 249 |
+
parent = sample_dir.parent
|
| 250 |
+
if parent.is_dir():
|
| 251 |
+
paths.append(str(parent.resolve()))
|
| 252 |
+
except Exception as e:
|
| 253 |
+
print(f"Warning: could not add HF sample_images to allowed_paths: {e}")
|
| 254 |
return paths
|
| 255 |
|
| 256 |
|
| 257 |
+
def _launch_kwargs():
|
| 258 |
+
"""Default kwargs for launch() so allowed_paths are always set (e.g. when HF Spaces runs demo.launch())."""
|
| 259 |
+
return {
|
| 260 |
+
"allowed_paths": _launch_allowed_paths(),
|
| 261 |
+
"theme": gr.themes.Soft(primary_hue="orange", secondary_hue="blue"),
|
| 262 |
+
}
|
| 263 |
+
|
| 264 |
+
|
| 265 |
+
# Ensure launch() always receives allowed_paths (e.g. when HF Spaces runner calls demo.launch() without args)
|
| 266 |
+
_original_launch = demo.launch
|
| 267 |
+
|
| 268 |
+
|
| 269 |
+
def _launch_with_allowed_paths(*args, **kwargs):
|
| 270 |
+
for key, value in _launch_kwargs().items():
|
| 271 |
+
if key not in kwargs:
|
| 272 |
+
kwargs[key] = value
|
| 273 |
+
return _original_launch(*args, **kwargs)
|
| 274 |
+
|
| 275 |
+
|
| 276 |
+
demo.launch = _launch_with_allowed_paths
|
| 277 |
+
|
| 278 |
+
|
| 279 |
if __name__ == "__main__":
|
| 280 |
+
demo.launch()
|
|
|
|
|
|
|
|
|
tmp/config.log
CHANGED
|
@@ -1 +1,2 @@
|
|
| 1 |
-
2026-02-11
|
|
|
|
|
|
| 1 |
+
2026-02-11 21:26:27,642 - utilities.config - CONFIG - CONFIG DISTRIBUTE is 'singlegpu' even though multiple GPUs are available
|
| 2 |
+
2026-02-11 21:26:32,739 - utilities.config - CONFIG - CONFIG DISTRIBUTE is 'singlegpu' even though multiple GPUs are available
|
tmp/models.log
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
|
|
|
| 1 |
+
2026-02-11 21:26:30,960 - models - MODEL - MODEL Decoder 'diffuse' frozen due to DECODER_LR=0.0
|
| 2 |
+
2026-02-11 21:26:35,539 - models - MODEL - MODEL Decoder 'diffuse' frozen due to DECODER_LR=0.0
|