ritianyu commited on
Commit
c210cf5
·
1 Parent(s): 3c2ae9a
InfiniDepth/model/block/pe.py CHANGED
@@ -7,11 +7,11 @@ import torch.nn as nn
7
  import torch.nn.functional as F
8
  from typing import Any, Optional, Tuple, Dict
9
 
10
- acc_dtype = (
11
- torch.bfloat16
12
- if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8
13
- else torch.float16
14
- )
15
 
16
  POS_EMB_REGISTRY = {}
17
 
 
7
  import torch.nn.functional as F
8
  from typing import Any, Optional, Tuple, Dict
9
 
10
+ def _get_acc_dtype() -> torch.dtype:
11
+ """Determine autocast dtype lazily so ZeroGPU can set up CUDA first."""
12
+ if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8:
13
+ return torch.bfloat16
14
+ return torch.float16
15
 
16
  POS_EMB_REGISTRY = {}
17
 
InfiniDepth/model/block/prompt_models/rope.py CHANGED
@@ -3,11 +3,11 @@ import torch
3
  import torch.nn as nn
4
  import torch.nn.functional as F
5
 
6
- acc_dtype = (
7
- torch.bfloat16
8
- if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8
9
- else torch.float16
10
- )
11
 
12
 
13
  class PositionGetter:
@@ -186,7 +186,7 @@ class RotaryPositionEmbedding2D(nn.Module):
186
  """Positionally encode points that are normalized to [0,1]."""
187
  # assuming coords are in [0, 1]^2 square and have d_1 x ... x d_n x 2 shape
188
  max_position = int(coords.max()) + 1
189
- cos_comp, sin_comp = self._compute_frequency_components(self.feat_dim, max_position, coords.device, acc_dtype)
190
  vertical_cos = F.embedding(coords[..., 0], cos_comp)
191
  vertical_sin = F.embedding(coords[..., 0], sin_comp)
192
  horizontal_cos = F.embedding(coords[..., 1], cos_comp)
@@ -201,7 +201,7 @@ class RotaryPositionEmbedding2D(nn.Module):
201
  x_coords = torch.arange(width, device=device) * (self.patch_size * 2) + self.patch_size - 1
202
  positions = torch.cartesian_prod(y_coords, x_coords) # h, w
203
  max_position = int(positions.max()) + 1
204
- cos_comp, sin_comp = self._compute_frequency_components(self.feat_dim, max_position, device, acc_dtype)
205
  vertical_cos = F.embedding(positions[..., 0], cos_comp)
206
  vertical_sin = F.embedding(positions[..., 0], sin_comp)
207
  horizontal_cos = F.embedding(positions[..., 1], cos_comp)
 
3
  import torch.nn as nn
4
  import torch.nn.functional as F
5
 
6
+ def _get_acc_dtype() -> torch.dtype:
7
+ """Determine autocast dtype lazily so ZeroGPU can set up CUDA first."""
8
+ if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8:
9
+ return torch.bfloat16
10
+ return torch.float16
11
 
12
 
13
  class PositionGetter:
 
186
  """Positionally encode points that are normalized to [0,1]."""
187
  # assuming coords are in [0, 1]^2 square and have d_1 x ... x d_n x 2 shape
188
  max_position = int(coords.max()) + 1
189
+ cos_comp, sin_comp = self._compute_frequency_components(self.feat_dim, max_position, coords.device, _get_acc_dtype())
190
  vertical_cos = F.embedding(coords[..., 0], cos_comp)
191
  vertical_sin = F.embedding(coords[..., 0], sin_comp)
192
  horizontal_cos = F.embedding(coords[..., 1], cos_comp)
 
201
  x_coords = torch.arange(width, device=device) * (self.patch_size * 2) + self.patch_size - 1
202
  positions = torch.cartesian_prod(y_coords, x_coords) # h, w
203
  max_position = int(positions.max()) + 1
204
+ cos_comp, sin_comp = self._compute_frequency_components(self.feat_dim, max_position, device, _get_acc_dtype())
205
  vertical_cos = F.embedding(positions[..., 0], cos_comp)
206
  vertical_sin = F.embedding(positions[..., 0], sin_comp)
207
  horizontal_cos = F.embedding(positions[..., 1], cos_comp)
InfiniDepth/model/block/prompt_models/selfattn.py CHANGED
@@ -6,11 +6,11 @@ from .rope import RotaryPositionEmbedding2D
6
  from .utils.pe_utils import PositionEmbeddingRandom
7
  from torch import Tensor
8
 
9
- acc_dtype = (
10
- torch.bfloat16
11
- if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8
12
- else torch.float16
13
- )
14
 
15
 
16
  class SelfAttnPromptModel(nn.Module):
@@ -97,7 +97,7 @@ class SelfAttnPromptModel(nn.Module):
97
  query_pe = image_pe.reshape(1, -1, image_pe.shape[-1])
98
  prompt = prompt_embeddings # + prompt_pe
99
  query = image_embeddings[b : (b + 1)] # + query_pe
100
- with torch.autocast("cuda", enabled=True, dtype=acc_dtype):
101
  for block in self.prompt_blocks:
102
  query, prompt = block(query, query_pe, prompt, prompt_pe)
103
  image_embeddings_list.append(query[..., : image_embeddings.shape[-1]])
@@ -197,7 +197,7 @@ class SelfAttnRopePromptModel(nn.Module):
197
  query_pe = image_pe.reshape(1, -1, image_pe.shape[-1])
198
  prompt = prompt_embeddings # + prompt_pe
199
  query = image_embeddings[b : (b + 1)] # + query_pe
200
- with torch.autocast("cuda", enabled=True, dtype=acc_dtype):
201
  for block in self.prompt_blocks:
202
  query, prompt = block(query, query_pe, prompt, prompt_pe)
203
  image_embeddings_list.append(query[..., : image_embeddings.shape[-1]])
 
6
  from .utils.pe_utils import PositionEmbeddingRandom
7
  from torch import Tensor
8
 
9
+ def _get_acc_dtype() -> torch.dtype:
10
+ """Determine autocast dtype lazily so ZeroGPU can set up CUDA first."""
11
+ if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8:
12
+ return torch.bfloat16
13
+ return torch.float16
14
 
15
 
16
  class SelfAttnPromptModel(nn.Module):
 
97
  query_pe = image_pe.reshape(1, -1, image_pe.shape[-1])
98
  prompt = prompt_embeddings # + prompt_pe
99
  query = image_embeddings[b : (b + 1)] # + query_pe
100
+ with torch.autocast("cuda", enabled=True, dtype=_get_acc_dtype()):
101
  for block in self.prompt_blocks:
102
  query, prompt = block(query, query_pe, prompt, prompt_pe)
103
  image_embeddings_list.append(query[..., : image_embeddings.shape[-1]])
 
197
  query_pe = image_pe.reshape(1, -1, image_pe.shape[-1])
198
  prompt = prompt_embeddings # + prompt_pe
199
  query = image_embeddings[b : (b + 1)] # + query_pe
200
+ with torch.autocast("cuda", enabled=True, dtype=_get_acc_dtype()):
201
  for block in self.prompt_blocks:
202
  query, prompt = block(query, query_pe, prompt, prompt_pe)
203
  image_embeddings_list.append(query[..., : image_embeddings.shape[-1]])
InfiniDepth/model/model.py CHANGED
@@ -17,11 +17,11 @@ from .block.prompt_models import GeneralPromptModel, SelfAttnPromptModel
17
  from .block.implicit_decoder import ImplicitHead
18
  from .block.convolution import BasicEncoder
19
 
20
- acc_dtype = (
21
- torch.bfloat16
22
- if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8
23
- else torch.float16
24
- )
25
 
26
 
27
  def _resolve_local_dinov3_repo() -> str:
@@ -96,7 +96,8 @@ class _BaseInfiniDepthModel(nn.Module):
96
  raise FileNotFoundError(f"Model file {model_path} not found")
97
 
98
  # only for inference
99
- self.cuda()
 
100
  self.eval()
101
 
102
  def _init_variant_modules(self):
@@ -131,7 +132,7 @@ class _BaseInfiniDepthModel(nn.Module):
131
  ):
132
  h, w = x.shape[-2:]
133
  x_dino = (x - self._mean) / self._std
134
- with torch.autocast("cuda", enabled=True, dtype=acc_dtype):
135
  features = self.pretrained.get_intermediate_layers(
136
  x_dino,
137
  n=self.model_config["layer_idxs"],
 
17
  from .block.implicit_decoder import ImplicitHead
18
  from .block.convolution import BasicEncoder
19
 
20
+ def _get_acc_dtype() -> torch.dtype:
21
+ """Determine autocast dtype lazily so ZeroGPU can set up CUDA first."""
22
+ if torch.cuda.is_available() and torch.cuda.get_device_capability()[0] >= 8:
23
+ return torch.bfloat16
24
+ return torch.float16
25
 
26
 
27
  def _resolve_local_dinov3_repo() -> str:
 
96
  raise FileNotFoundError(f"Model file {model_path} not found")
97
 
98
  # only for inference
99
+ if torch.cuda.is_available():
100
+ self.cuda()
101
  self.eval()
102
 
103
  def _init_variant_modules(self):
 
132
  ):
133
  h, w = x.shape[-2:]
134
  x_dino = (x - self._mean) / self._std
135
+ with torch.autocast("cuda", enabled=True, dtype=_get_acc_dtype()):
136
  features = self.pretrained.get_intermediate_layers(
137
  x_dino,
138
  n=self.model_config["layer_idxs"],
app.py CHANGED
@@ -1,6 +1,7 @@
1
  import os
2
  import shutil
3
  import tempfile
 
4
  import traceback
5
  import uuid
6
  from pathlib import Path
@@ -246,7 +247,22 @@ def run_demo_gpu(
246
  trace_path: str,
247
  ):
248
  """GPU-only inference. Returns a GPUInferenceResult with all data on CPU."""
 
249
  _append_trace(trace_path, "worker:entered run_demo_gpu")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
250
  if image is None:
251
  raise ValueError("Input RGB image is required")
252
 
@@ -298,19 +314,35 @@ def run_demo(
298
  )
299
  try:
300
  # --- GPU-only inference (consumes ZeroGPU quota) ---
301
- gpu_result = run_demo_gpu(
302
- image=image,
303
- depth_file=depth_file,
304
- model_type=model_type,
305
- input_size=input_size,
306
- output_resolution_mode=output_resolution_mode,
307
- upsample_ratio=upsample_ratio,
308
- fx_org=fx_org,
309
- fy_org=fy_org,
310
- cx_org=cx_org,
311
- cy_org=cy_org,
312
- trace_path=trace_path,
313
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
314
  _append_trace(trace_path, "ui:gpu_done, starting cpu postprocess")
315
 
316
  # --- CPU post-processing (no GPU quota consumed) ---
 
1
  import os
2
  import shutil
3
  import tempfile
4
+ import time
5
  import traceback
6
  import uuid
7
  from pathlib import Path
 
247
  trace_path: str,
248
  ):
249
  """GPU-only inference. Returns a GPUInferenceResult with all data on CPU."""
250
+ import torch
251
  _append_trace(trace_path, "worker:entered run_demo_gpu")
252
+
253
+ # Log GPU info for diagnostics (visible in HF Space Logs tab)
254
+ if torch.cuda.is_available():
255
+ dev = torch.cuda.current_device()
256
+ gpu_name = torch.cuda.get_device_name(dev)
257
+ gpu_mem_total = torch.cuda.get_device_properties(dev).total_mem / 1e9
258
+ gpu_mem_alloc = torch.cuda.memory_allocated(dev) / 1e9
259
+ Log.info(f"[GPU-INFO] device={gpu_name}, total={gpu_mem_total:.1f}GB, allocated={gpu_mem_alloc:.1f}GB")
260
+ _append_trace(trace_path, f"worker:cuda_ready {gpu_name} {gpu_mem_total:.1f}GB")
261
+ torch.cuda.empty_cache()
262
+ else:
263
+ Log.warning("[GPU-INFO] CUDA not available inside @spaces.GPU!")
264
+ _append_trace(trace_path, "worker:cuda_NOT_available")
265
+
266
  if image is None:
267
  raise ValueError("Input RGB image is required")
268
 
 
314
  )
315
  try:
316
  # --- GPU-only inference (consumes ZeroGPU quota) ---
317
+ # Retry on transient "GPU task aborted" errors (common on ZeroGPU)
318
+ max_gpu_retries = 2
319
+ gpu_result = None
320
+ for attempt in range(max_gpu_retries + 1):
321
+ try:
322
+ gpu_result = run_demo_gpu(
323
+ image=image,
324
+ depth_file=depth_file,
325
+ model_type=model_type,
326
+ input_size=input_size,
327
+ output_resolution_mode=output_resolution_mode,
328
+ upsample_ratio=upsample_ratio,
329
+ fx_org=fx_org,
330
+ fy_org=fy_org,
331
+ cx_org=cx_org,
332
+ cy_org=cy_org,
333
+ trace_path=trace_path,
334
+ )
335
+ break # success
336
+ except Exception as gpu_exc:
337
+ is_aborted = "GPU task aborted" in str(gpu_exc)
338
+ if is_aborted and attempt < max_gpu_retries:
339
+ Log.warning(
340
+ f"[{request_id}] GPU task aborted (attempt {attempt + 1}/{max_gpu_retries + 1}), retrying..."
341
+ )
342
+ _append_trace(trace_path, f"ui:retry_{attempt + 1}_after_gpu_abort")
343
+ time.sleep(2)
344
+ continue
345
+ raise # not retryable or out of retries
346
  _append_trace(trace_path, "ui:gpu_done, starting cpu postprocess")
347
 
348
  # --- CPU post-processing (no GPU quota consumed) ---