akhaliq HF Staff commited on
Commit
3b7c628
·
1 Parent(s): 9f7d349

feat: add thread-safe model initialization, nest_asyncio support, and pre-loading on startup

Browse files
Files changed (1) hide show
  1. app.py +50 -36
app.py CHANGED
@@ -14,11 +14,15 @@ from datetime import datetime
14
  from typing import *
15
  from PIL import Image
16
 
17
- # Re-install utils3d as in original app.py
18
- subprocess.run([
19
- "pip", "install", "--force-reinstall", "--no-deps",
20
- "https://github.com/LDYang694/Storages/releases/download/20260430/utils3d-0.0.2-py3-none-any.whl"
21
- ], check=True)
 
 
 
 
22
 
23
  os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '1'
24
  os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
@@ -119,36 +123,37 @@ envmap = None
119
 
120
  def init_models():
121
  global pipeline, moge_model, envmap
122
- if pipeline is not None:
123
- return
124
-
125
- model_path = "TencentARC/Pixal3D-T"
126
- print(f"[Pipeline] Loading from {model_path}...")
127
- pipeline = Pixal3DImageTo3DPipeline.from_pretrained(model_path)
128
-
129
- print("[ImageCond] Building DinoV3ProjFeatureExtractor models...")
130
- pipeline.image_cond_model_ss = build_image_cond_model(IMAGE_COND_CONFIGS["ss"])
131
- pipeline.image_cond_model_shape_512 = build_image_cond_model(IMAGE_COND_CONFIGS["shape_512"])
132
- pipeline.image_cond_model_shape_1024 = build_image_cond_model(IMAGE_COND_CONFIGS["shape_1024"])
133
- pipeline.image_cond_model_tex_1024 = build_image_cond_model(IMAGE_COND_CONFIGS["tex_1024"])
134
-
135
- pipeline.cuda()
136
-
137
- print("[NAF] Pre-loading NAF upsampler model...")
138
- for attr in ['image_cond_model_ss', 'image_cond_model_shape_512', 'image_cond_model_shape_1024', 'image_cond_model_tex_1024']:
139
- model = getattr(pipeline, attr, None)
140
- if model is not None and getattr(model, 'use_naf_upsample', False):
141
- model._load_naf()
142
-
143
- print("[MoGe-2] Loading model for camera estimation...")
144
- moge_model = load_moge_model(device="cuda")
145
-
146
- print("[EnvMap] Loading environment maps...")
147
- envmap = {
148
- 'forest': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/forest.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
149
- 'sunset': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/sunset.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
150
- 'courtyard': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/courtyard.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
151
- }
 
152
 
153
  # ============================================================================
154
  # Utilities
@@ -341,4 +346,13 @@ def extract_glb_api(state_path: str, decimation_target: int, texture_size: int)
341
  app.mount("/assets", StaticFiles(directory="assets"), name="assets")
342
 
343
  if __name__ == "__main__":
344
- app.launch(show_error=True)
 
 
 
 
 
 
 
 
 
 
14
  from typing import *
15
  from PIL import Image
16
 
17
+ import threading
18
+ try:
19
+ import nest_asyncio
20
+ nest_asyncio.apply()
21
+ except ImportError:
22
+ pass
23
+
24
+ # Lock for model initialization
25
+ init_lock = threading.Lock()
26
 
27
  os.environ['OPENCV_IO_ENABLE_OPENEXR'] = '1'
28
  os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "expandable_segments:True"
 
123
 
124
  def init_models():
125
  global pipeline, moge_model, envmap
126
+ with init_lock:
127
+ if pipeline is not None:
128
+ return
129
+
130
+ model_path = "TencentARC/Pixal3D-T"
131
+ print(f"[Pipeline] Loading from {model_path}...")
132
+ pipeline = Pixal3DImageTo3DPipeline.from_pretrained(model_path)
133
+
134
+ print("[ImageCond] Building DinoV3ProjFeatureExtractor models...")
135
+ pipeline.image_cond_model_ss = build_image_cond_model(IMAGE_COND_CONFIGS["ss"])
136
+ pipeline.image_cond_model_shape_512 = build_image_cond_model(IMAGE_COND_CONFIGS["shape_512"])
137
+ pipeline.image_cond_model_shape_1024 = build_image_cond_model(IMAGE_COND_CONFIGS["shape_1024"])
138
+ pipeline.image_cond_model_tex_1024 = build_image_cond_model(IMAGE_COND_CONFIGS["tex_1024"])
139
+
140
+ pipeline.cuda()
141
+
142
+ print("[NAF] Pre-loading NAF upsampler model...")
143
+ for attr in ['image_cond_model_ss', 'image_cond_model_shape_512', 'image_cond_model_shape_1024', 'image_cond_model_tex_1024']:
144
+ model = getattr(pipeline, attr, None)
145
+ if model is not None and getattr(model, 'use_naf_upsample', False):
146
+ model._load_naf()
147
+
148
+ print("[MoGe-2] Loading model for camera estimation...")
149
+ moge_model = load_moge_model(device="cuda")
150
+
151
+ print("[EnvMap] Loading environment maps...")
152
+ envmap = {
153
+ 'forest': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/forest.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
154
+ 'sunset': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/sunset.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
155
+ 'courtyard': EnvMap(torch.tensor(cv2.cvtColor(cv2.imread('assets/hdri/courtyard.exr', cv2.IMREAD_UNCHANGED), cv2.COLOR_BGR2RGB), dtype=torch.float32, device='cuda')),
156
+ }
157
 
158
  # ============================================================================
159
  # Utilities
 
346
  app.mount("/assets", StaticFiles(directory="assets"), name="assets")
347
 
348
  if __name__ == "__main__":
349
+ # Re-install utils3d as in original app.py
350
+ subprocess.run([
351
+ "pip", "install", "--force-reinstall", "--no-deps",
352
+ "https://github.com/LDYang694/Storages/releases/download/20260430/utils3d-0.0.2-py3-none-any.whl"
353
+ ], check=True)
354
+
355
+ # Pre-initialize models before launching the server
356
+ init_models()
357
+
358
+ app.launch(show_error=True, share=True)