Zhengrui commited on
Commit
605bf4f
·
verified ·
1 Parent(s): d437211

Restore full image app with GPU-lazy DVD imports

Browse files
Files changed (2) hide show
  1. README.md +2 -1
  2. app_dvd_image.py +89 -5
README.md CHANGED
@@ -5,11 +5,12 @@ colorFrom: blue
5
  colorTo: green
6
  sdk: gradio
7
  sdk_version: 5.34.2
8
- app_file: app_dvd_image_gpu_lazy.py
9
  pinned: false
10
  license: mit
11
  models:
12
  - Zhengrui/dvd
 
13
  ---
14
 
15
  # DVD: Discrete Voxel Diffusion for 3D Generation and Editing
 
5
  colorTo: green
6
  sdk: gradio
7
  sdk_version: 5.34.2
8
+ app_file: app_dvd_image.py
9
  pinned: false
10
  license: mit
11
  models:
12
  - Zhengrui/dvd
13
+ - microsoft/TRELLIS-image-large
14
  ---
15
 
16
  # DVD: Discrete Voxel Diffusion for 3D Generation and Editing
app_dvd_image.py CHANGED
@@ -90,6 +90,89 @@ def log_event(message: str):
90
  print(f"[DVD Space] {message}", flush=True)
91
 
92
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
93
  def ensure_dvd_imports():
94
  global DVDImageToVoxelPipeline
95
  global TrellisImageTo3DPipeline
@@ -203,7 +286,7 @@ EDIT_IMAGE_EXAMPLES = [
203
  (asset_label(path), str(path)) for path in list_asset_files("assets/example_image_edit", IMAGE_EXTENSIONS)
204
  ]
205
  EDIT_VOXEL_EXAMPLES = [
206
- (asset_label(path), str(path)) for path in list_asset_files("assets/example_voxel_edit", {".npy", ".pt", ".pth"})
207
  ]
208
 
209
 
@@ -290,7 +373,7 @@ def ensure_trellis_pipeline(device: str | None = None):
290
 
291
  def preload_zero_gpu_models(device: str | None = None, preload: str | None = None):
292
  device = device or os.environ.get("DVD_SPACE_DEVICE", "cuda")
293
- preload = preload or os.environ.get("DVD_STARTUP_PRELOAD", "gen")
294
  requested = {
295
  item.strip().lower()
296
  for item in preload.replace(";", ",").split(",")
@@ -530,7 +613,7 @@ def mask_inputs():
530
  ]
531
 
532
 
533
- @spaces.GPU(duration=120)
534
  def generate_voxels(
535
  image: Image.Image,
536
  seed: int,
@@ -651,7 +734,7 @@ def visualize_edit_mask(
651
  return mesh_path
652
 
653
 
654
- @spaces.GPU(duration=120)
655
  def run_editing(
656
  target_image: Image.Image,
657
  voxels,
@@ -1025,7 +1108,8 @@ def parse_args():
1025
  if __name__ == "__main__":
1026
  args = parse_args()
1027
 
1028
- # ZeroGPU's CUDA emulation expects CUDA model placement at startup.
 
1029
  preload_zero_gpu_models(os.environ.get("DVD_SPACE_DEVICE", "cuda"))
1030
  demo.queue().launch(
1031
  share=args.share,
 
90
  print(f"[DVD Space] {message}", flush=True)
91
 
92
 
93
+ def _download_file(url: str, dest: Path):
94
+ import urllib.request
95
+
96
+ dest.parent.mkdir(parents=True, exist_ok=True)
97
+ if dest.exists() and dest.stat().st_size > 0:
98
+ log_event(f"using cached {dest.name}")
99
+ return
100
+ tmp = dest.with_name(dest.name + ".tmp")
101
+ if tmp.exists():
102
+ tmp.unlink()
103
+ log_event(f"downloading {url} -> {dest}")
104
+ urllib.request.urlretrieve(url, tmp)
105
+ tmp.replace(dest)
106
+
107
+
108
+ def prefetch_dvd_weights():
109
+ from huggingface_hub import hf_hub_download, snapshot_download
110
+
111
+ if DVD_MODEL_REPO:
112
+ filenames = (
113
+ "dvd_img.json",
114
+ "dvd_img.safetensors",
115
+ "dvd_img_BSP_ft.json",
116
+ "dvd_img_BSP_ft.safetensors",
117
+ )
118
+ for filename in filenames:
119
+ log_event(f"prefetching {DVD_MODEL_REPO}/{filename}")
120
+ hf_hub_download(
121
+ repo_id=DVD_MODEL_REPO,
122
+ filename=filename,
123
+ subfolder=DVD_MODEL_SUBFOLDER,
124
+ revision=DVD_MODEL_REVISION,
125
+ token=DVD_MODEL_TOKEN,
126
+ )
127
+
128
+ if os.environ.get("DVD_PREFETCH_TRELLIS", "0").lower() not in {"0", "false", "no", "off"}:
129
+ log_event(f"prefetching TRELLIS stage2 model {TRELLIS_IMAGE_MODEL}")
130
+ snapshot_download(repo_id=TRELLIS_IMAGE_MODEL)
131
+
132
+
133
+ def prefetch_dinov2():
134
+ import shutil
135
+ import zipfile
136
+
137
+ hub_dir = Path(torch.hub.get_dir())
138
+ hub_dir.mkdir(parents=True, exist_ok=True)
139
+ repo_dir = hub_dir / "facebookresearch_dinov2_main"
140
+ if repo_dir.exists():
141
+ log_event(f"using cached DINOv2 repo {repo_dir}")
142
+ else:
143
+ zip_path = hub_dir / "main.zip"
144
+ _download_file("https://github.com/facebookresearch/dinov2/zipball/main", zip_path)
145
+ extract_tmp = hub_dir / "_dvd_dinov2_extract"
146
+ if extract_tmp.exists():
147
+ shutil.rmtree(extract_tmp)
148
+ extract_tmp.mkdir(parents=True, exist_ok=True)
149
+ log_event(f"extracting DINOv2 repo to {repo_dir}")
150
+ with zipfile.ZipFile(zip_path) as zf:
151
+ zf.extractall(extract_tmp)
152
+ top_level = zf.namelist()[0].split("/", 1)[0]
153
+ shutil.move(str(extract_tmp / top_level), str(repo_dir))
154
+ shutil.rmtree(extract_tmp, ignore_errors=True)
155
+
156
+ ckpt_dir = hub_dir / "checkpoints"
157
+ _download_file(
158
+ "https://dl.fbaipublicfiles.com/dinov2/dinov2_vitl14/dinov2_vitl14_reg4_pretrain.pth",
159
+ ckpt_dir / "dinov2_vitl14_reg4_pretrain.pth",
160
+ )
161
+
162
+
163
+ def prefetch_assets():
164
+ if os.environ.get("DVD_PREFETCH_ASSETS", "1").lower() in {"0", "false", "no", "off"}:
165
+ log_event("asset prefetch disabled")
166
+ return
167
+ try:
168
+ log_event("asset prefetch start")
169
+ prefetch_dvd_weights()
170
+ prefetch_dinov2()
171
+ log_event("asset prefetch done")
172
+ except Exception as exc:
173
+ log_event(f"asset prefetch failed; continuing without prefetch: {exc}")
174
+
175
+
176
  def ensure_dvd_imports():
177
  global DVDImageToVoxelPipeline
178
  global TrellisImageTo3DPipeline
 
286
  (asset_label(path), str(path)) for path in list_asset_files("assets/example_image_edit", IMAGE_EXTENSIONS)
287
  ]
288
  EDIT_VOXEL_EXAMPLES = [
289
+ (asset_label(path), str(path)) for path in list_asset_files("assets/example_voxel_edit", {".npy", ".npz", ".pt", ".pth"})
290
  ]
291
 
292
 
 
373
 
374
  def preload_zero_gpu_models(device: str | None = None, preload: str | None = None):
375
  device = device or os.environ.get("DVD_SPACE_DEVICE", "cuda")
376
+ preload = preload or os.environ.get("DVD_STARTUP_PRELOAD", "none")
377
  requested = {
378
  item.strip().lower()
379
  for item in preload.replace(";", ",").split(",")
 
613
  ]
614
 
615
 
616
+ @spaces.GPU(duration=600)
617
  def generate_voxels(
618
  image: Image.Image,
619
  seed: int,
 
734
  return mesh_path
735
 
736
 
737
+ @spaces.GPU(duration=600)
738
  def run_editing(
739
  target_image: Image.Image,
740
  voxels,
 
1108
  if __name__ == "__main__":
1109
  args = parse_args()
1110
 
1111
+ # Keep startup free of DVD/TRELLIS imports; only prefetch raw assets.
1112
+ prefetch_assets()
1113
  preload_zero_gpu_models(os.environ.get("DVD_SPACE_DEVICE", "cuda"))
1114
  demo.queue().launch(
1115
  share=args.share,