jboth commited on
Commit
31ef6d3
·
verified ·
1 Parent(s): 8df3f9a

Upload app.py with huggingface_hub

Browse files
Files changed (1) hide show
  1. app.py +73 -32
app.py CHANGED
@@ -28,7 +28,9 @@ def _pip(*a):
28
  capture_output=True, text=True, timeout=1200)
29
  ok = r.returncode == 0
30
  if not ok:
31
- print(f" pip FAIL ({a[-1][:30]}): {r.stderr[-150:]}")
 
 
32
  return ok
33
 
34
  print("=== Runtime installs ===")
@@ -56,6 +58,7 @@ if not SAM3D_PATH.exists():
56
  subprocess.run([sys.executable, "-m", "pip", "install", "-e", str(SAM3D_PATH), "--no-deps"],
57
  capture_output=True, text=True)
58
 
 
59
  patch = SAM3D_PATH / "patching" / "hydra"
60
  if patch.exists():
61
  subprocess.run(["bash", str(patch)], capture_output=True, cwd=str(SAM3D_PATH))
@@ -73,57 +76,92 @@ if hf_ckpt.exists() and not local_ckpt.exists():
73
  local_ckpt.parent.mkdir(parents=True, exist_ok=True)
74
  local_ckpt.symlink_to(hf_ckpt)
75
  CONFIG_PATH = str(local_ckpt / "pipeline.yaml")
76
- print(f"Config: {Path(CONFIG_PATH).exists()}")
77
 
78
- # Verify key imports
79
- for mod in ["open3d", "utils3d", "sam2", "gsplat"]:
80
- try:
81
- __import__(mod)
82
- print(f" {mod}: OK")
83
- except Exception as e:
84
- print(f" {mod}: {e}")
85
-
86
- print("=== Setup done ===")
87
-
88
- # --- Model state ---
89
- SAM3D_MODEL = None
90
- SAM2_GEN = None
91
 
92
  # --- Endpoints ---
 
93
  @spaces.GPU(duration=60)
94
  def diagnose():
 
95
  import torch
96
  lines = [f"torch={torch.__version__}", f"cuda={torch.cuda.is_available()}"]
97
  if torch.cuda.is_available():
98
  lines.append(f"gpu={torch.cuda.get_device_name()}")
99
- for mod in ["kaolin", "gsplat", "open3d", "sam2", "utils3d"]:
 
 
100
  try:
101
- m = __import__(mod)
102
- lines.append(f"{mod}={getattr(m, '__version__', 'ok')}")
103
  except Exception as e:
104
- lines.append(f"{mod}: {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  return "\n".join(lines)
106
 
 
 
 
 
 
 
107
  @spaces.GPU(duration=300)
108
  def reconstruct_objects(image: np.ndarray):
109
- global SAM3D_MODEL, SAM2_GEN
110
  if image is None:
111
  return None, None, "No image"
112
  try:
113
  import torch, trimesh, time
114
  t0 = time.time()
115
- print(f"GPU: {torch.cuda.get_device_name() if torch.cuda.is_available() else 'no CUDA'}")
116
 
117
  # Load SAM2
118
- if SAM2_GEN is None:
119
- from sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator
120
- SAM2_GEN = SAM2AutomaticMaskGenerator.from_pretrained("facebook/sam2-hiera-large")
121
  print(f" SAM2 ready ({time.time()-t0:.0f}s)")
122
 
123
  image_np = np.array(image) if not isinstance(image, np.ndarray) else image
124
 
125
  # Detect objects
126
- masks = SAM2_GEN.generate(image_np)
127
  if not masks:
128
  return None, image_np, "No objects detected"
129
  masks = sorted(masks, key=lambda x: x["area"], reverse=True)
@@ -134,13 +172,12 @@ def reconstruct_objects(image: np.ndarray):
134
  print(f" {len(masks)} masks ({time.time()-t0:.0f}s)")
135
 
136
  # Load SAM3D
137
- if SAM3D_MODEL is None:
138
- from inference import Inference
139
- SAM3D_MODEL = Inference(CONFIG_PATH, compile=False)
140
  print(f" SAM3D ready ({time.time()-t0:.0f}s)")
141
 
142
  # Reconstruct
143
- result = SAM3D_MODEL(image=image_np, mask=best_mask, seed=42)
144
  print(f" Reconstructed ({time.time()-t0:.0f}s)")
145
 
146
  if result is None:
@@ -193,7 +230,7 @@ def reconstruct_objects(image: np.ndarray):
193
 
194
  # --- UI ---
195
  with gr.Blocks(title="SAM 3D Objects") as demo:
196
- gr.Markdown("# SAM 3D Objects\nImage -> 3D (GLB). SAM2 detection + SAM3D reconstruction.")
197
  with gr.Tab("Reconstruct"):
198
  with gr.Row():
199
  with gr.Column():
@@ -208,8 +245,12 @@ with gr.Blocks(title="SAM 3D Objects") as demo:
208
  btn.click(reconstruct_objects, inputs=[inp], outputs=[m3d, prev, stat])
209
  m3d.change(lambda x: x, inputs=[m3d], outputs=[dl])
210
  with gr.Tab("Diagnose"):
211
- dbtn = gr.Button("GPU Diagnose")
212
- dout = gr.Textbox(lines=12)
213
  dbtn.click(diagnose, outputs=[dout])
 
 
 
 
214
 
215
  demo.launch(mcp_server=True)
 
28
  capture_output=True, text=True, timeout=1200)
29
  ok = r.returncode == 0
30
  if not ok:
31
+ print(f" pip FAIL ({a[-1][:40]}): {r.stderr[-200:]}")
32
+ else:
33
+ print(f" pip OK: {a[-1][:40]}")
34
  return ok
35
 
36
  print("=== Runtime installs ===")
 
58
  subprocess.run([sys.executable, "-m", "pip", "install", "-e", str(SAM3D_PATH), "--no-deps"],
59
  capture_output=True, text=True)
60
 
61
+ # Hydra patch
62
  patch = SAM3D_PATH / "patching" / "hydra"
63
  if patch.exists():
64
  subprocess.run(["bash", str(patch)], capture_output=True, cwd=str(SAM3D_PATH))
 
76
  local_ckpt.parent.mkdir(parents=True, exist_ok=True)
77
  local_ckpt.symlink_to(hf_ckpt)
78
  CONFIG_PATH = str(local_ckpt / "pipeline.yaml")
79
+ print(f"Config exists: {Path(CONFIG_PATH).exists()}")
80
 
81
+ print("=== Startup complete ===")
 
 
 
 
 
 
 
 
 
 
 
 
82
 
83
  # --- Endpoints ---
84
+
85
  @spaces.GPU(duration=60)
86
  def diagnose():
87
+ """Safe diagnostic - test each module individually."""
88
  import torch
89
  lines = [f"torch={torch.__version__}", f"cuda={torch.cuda.is_available()}"]
90
  if torch.cuda.is_available():
91
  lines.append(f"gpu={torch.cuda.get_device_name()}")
92
+
93
+ # Test each module safely
94
+ for mod_name in ["kaolin", "open3d", "utils3d", "iopath"]:
95
  try:
96
+ __import__(mod_name)
97
+ lines.append(f"{mod_name}: OK")
98
  except Exception as e:
99
+ lines.append(f"{mod_name}: FAIL - {e}")
100
+
101
+ # Test sam2 (careful - no CUDA init at import)
102
+ try:
103
+ from sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator
104
+ lines.append("sam2: OK")
105
+ except Exception as e:
106
+ lines.append(f"sam2: FAIL - {e}")
107
+
108
+ # Test gsplat carefully
109
+ try:
110
+ import gsplat
111
+ lines.append(f"gsplat: OK ({gsplat.__version__})")
112
+ except Exception as e:
113
+ lines.append(f"gsplat: FAIL - {e}")
114
+
115
+ # Test pytorch3d carefully
116
+ try:
117
+ import pytorch3d
118
+ lines.append("pytorch3d: OK")
119
+ except Exception as e:
120
+ lines.append(f"pytorch3d: FAIL - {e}")
121
+
122
+ # Test MoGe
123
+ try:
124
+ import moge
125
+ lines.append("MoGe: OK")
126
+ except Exception as e:
127
+ lines.append(f"MoGe: FAIL - {e}")
128
+
129
+ # Test SAM3D inference
130
+ try:
131
+ from inference import Inference
132
+ lines.append("SAM3D inference: importable")
133
+ except Exception as e:
134
+ lines.append(f"SAM3D inference: FAIL - {e}")
135
+
136
+ # Config exists?
137
+ lines.append(f"config: {Path(CONFIG_PATH).exists()}")
138
+
139
  return "\n".join(lines)
140
 
141
+ @spaces.GPU(duration=60)
142
+ def diagnose_minimal():
143
+ """Absolutely minimal GPU test."""
144
+ import torch
145
+ return f"torch={torch.__version__}, cuda={torch.cuda.is_available()}, gpu={torch.cuda.get_device_name() if torch.cuda.is_available() else 'none'}"
146
+
147
  @spaces.GPU(duration=300)
148
  def reconstruct_objects(image: np.ndarray):
 
149
  if image is None:
150
  return None, None, "No image"
151
  try:
152
  import torch, trimesh, time
153
  t0 = time.time()
154
+ print(f"GPU: {torch.cuda.get_device_name()}")
155
 
156
  # Load SAM2
157
+ from sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator
158
+ sam2_gen = SAM2AutomaticMaskGenerator.from_pretrained("facebook/sam2-hiera-large")
 
159
  print(f" SAM2 ready ({time.time()-t0:.0f}s)")
160
 
161
  image_np = np.array(image) if not isinstance(image, np.ndarray) else image
162
 
163
  # Detect objects
164
+ masks = sam2_gen.generate(image_np)
165
  if not masks:
166
  return None, image_np, "No objects detected"
167
  masks = sorted(masks, key=lambda x: x["area"], reverse=True)
 
172
  print(f" {len(masks)} masks ({time.time()-t0:.0f}s)")
173
 
174
  # Load SAM3D
175
+ from inference import Inference
176
+ sam3d = Inference(CONFIG_PATH, compile=False)
 
177
  print(f" SAM3D ready ({time.time()-t0:.0f}s)")
178
 
179
  # Reconstruct
180
+ result = sam3d(image=image_np, mask=best_mask, seed=42)
181
  print(f" Reconstructed ({time.time()-t0:.0f}s)")
182
 
183
  if result is None:
 
230
 
231
  # --- UI ---
232
  with gr.Blocks(title="SAM 3D Objects") as demo:
233
+ gr.Markdown("# SAM 3D Objects\nImage 3D (GLB). SAM2 detection + SAM3D reconstruction.")
234
  with gr.Tab("Reconstruct"):
235
  with gr.Row():
236
  with gr.Column():
 
245
  btn.click(reconstruct_objects, inputs=[inp], outputs=[m3d, prev, stat])
246
  m3d.change(lambda x: x, inputs=[m3d], outputs=[dl])
247
  with gr.Tab("Diagnose"):
248
+ dbtn = gr.Button("Full Diagnose")
249
+ dout = gr.Textbox(lines=15)
250
  dbtn.click(diagnose, outputs=[dout])
251
+ gr.Markdown("---")
252
+ mbtn = gr.Button("Minimal GPU Test")
253
+ mout = gr.Textbox(lines=3)
254
+ mbtn.click(diagnose_minimal, outputs=[mout])
255
 
256
  demo.launch(mcp_server=True)