Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
|
@@ -34,7 +34,10 @@ class GlobalVars:
|
|
| 34 |
|
| 35 |
g = GlobalVars()
|
| 36 |
|
| 37 |
-
|
|
|
|
|
|
|
|
|
|
| 38 |
|
| 39 |
def initialize_models(device):
|
| 40 |
try:
|
|
@@ -85,10 +88,6 @@ def initialize_models(device):
|
|
| 85 |
print(f"Error during model initialization: {str(e)}")
|
| 86 |
raise
|
| 87 |
|
| 88 |
-
# CUDA ๋ฉ๋ชจ๋ฆฌ ๊ด๋ฆฌ ์ค์
|
| 89 |
-
torch.cuda.empty_cache()
|
| 90 |
-
torch.backends.cuda.matmul.allow_tf32 = True
|
| 91 |
-
torch.backends.cudnn.benchmark = True
|
| 92 |
|
| 93 |
# ํ๊ฒฝ ๋ณ์ ์ค์
|
| 94 |
# ํ๊ฒฝ ๋ณ์ ์ค์
|
|
@@ -104,6 +103,13 @@ os.environ['PYTORCH_NO_CUDA_MEMORY_CACHING'] = '1'
|
|
| 104 |
# CUDA ์ด๊ธฐํ ๋ฐฉ์ง
|
| 105 |
torch.set_grad_enabled(False)
|
| 106 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
|
| 108 |
# Hugging Face ํ ํฐ ์ค์
|
| 109 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
@@ -209,123 +215,110 @@ def unpack_state(state: dict) -> Tuple[Gaussian, edict, str]:
|
|
| 209 |
return gs, mesh, state['trial_id']
|
| 210 |
|
| 211 |
@spaces.GPU
|
| 212 |
-
def image_to_3d(trial_id: str, seed: int, randomize_seed: bool, ss_guidance_strength: float,
|
| 213 |
-
|
| 214 |
-
|
| 215 |
-
if not trial_id or trial_id.strip() == "":
|
| 216 |
-
print("Error: No trial_id provided")
|
| 217 |
-
return None, None
|
| 218 |
-
|
| 219 |
try:
|
| 220 |
-
#
|
| 221 |
-
|
| 222 |
-
torch.cuda.empty_cache()
|
| 223 |
-
torch.cuda.synchronize()
|
| 224 |
-
gc.collect()
|
| 225 |
|
| 226 |
-
if
|
| 227 |
-
|
| 228 |
|
| 229 |
image_path = f"{TMP_DIR}/{trial_id}.png"
|
| 230 |
-
print(f"Looking for image at: {image_path}")
|
| 231 |
-
|
| 232 |
if not os.path.exists(image_path):
|
| 233 |
-
print(f"Error: Image file not found at {image_path}")
|
| 234 |
return None, None
|
| 235 |
|
| 236 |
image = Image.open(image_path)
|
| 237 |
-
print(f"Successfully loaded image with size: {image.size}")
|
| 238 |
|
| 239 |
-
# ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ํ
|
| 240 |
-
max_size =
|
| 241 |
if max(image.size) > max_size:
|
| 242 |
ratio = max_size / max(image.size)
|
| 243 |
new_size = tuple(int(dim * ratio) for dim in image.size)
|
| 244 |
image = image.resize(new_size, Image.LANCZOS)
|
| 245 |
-
print(f"Resized image to: {image.size}")
|
| 246 |
|
| 247 |
-
# GPU ์์
์์
|
| 248 |
with torch.inference_mode():
|
| 249 |
try:
|
| 250 |
-
#
|
| 251 |
g.trellis_pipeline.to('cuda')
|
| 252 |
-
torch.cuda.synchronize()
|
| 253 |
|
| 254 |
-
#
|
| 255 |
outputs = g.trellis_pipeline.run(
|
| 256 |
image,
|
| 257 |
seed=seed,
|
| 258 |
formats=["gaussian", "mesh"],
|
| 259 |
preprocess_image=False,
|
| 260 |
sparse_structure_sampler_params={
|
| 261 |
-
"steps": min(ss_sampling_steps,
|
| 262 |
"cfg_strength": ss_guidance_strength,
|
|
|
|
| 263 |
},
|
| 264 |
slat_sampler_params={
|
| 265 |
-
"steps": min(slat_sampling_steps,
|
| 266 |
"cfg_strength": slat_guidance_strength,
|
|
|
|
| 267 |
},
|
| 268 |
)
|
| 269 |
-
torch.cuda.synchronize()
|
| 270 |
|
| 271 |
-
#
|
|
|
|
|
|
|
|
|
|
| 272 |
video = render_utils.render_video(
|
| 273 |
outputs['gaussian'][0],
|
| 274 |
-
num_frames=
|
| 275 |
-
resolution=
|
| 276 |
)['color']
|
| 277 |
-
torch.cuda.synchronize()
|
| 278 |
|
| 279 |
video_geo = render_utils.render_video(
|
| 280 |
outputs['mesh'][0],
|
| 281 |
-
num_frames=
|
| 282 |
-
resolution=
|
| 283 |
)['normal']
|
| 284 |
-
torch.cuda.synchronize()
|
| 285 |
|
| 286 |
-
# CPU๋ก ๋ฐ์ดํฐ ์ด๋
|
| 287 |
-
video = [v.cpu().numpy()
|
| 288 |
-
video_geo = [v.cpu().numpy()
|
|
|
|
| 289 |
|
|
|
|
| 290 |
video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
|
| 291 |
new_trial_id = str(uuid.uuid4())
|
| 292 |
video_path = f"{TMP_DIR}/{new_trial_id}.mp4"
|
| 293 |
-
os.makedirs(os.path.dirname(video_path), exist_ok=True)
|
| 294 |
imageio.mimsave(video_path, video, fps=15)
|
| 295 |
|
| 296 |
-
# ์ํ ์ ์ฅ
|
| 297 |
state = pack_state(outputs['gaussian'][0], outputs['mesh'][0], new_trial_id)
|
| 298 |
-
|
| 299 |
return state, video_path
|
| 300 |
|
| 301 |
finally:
|
| 302 |
# ์ ๋ฆฌ ์์
|
| 303 |
g.trellis_pipeline.to('cpu')
|
| 304 |
-
|
| 305 |
-
|
| 306 |
-
torch.cuda.synchronize()
|
| 307 |
-
gc.collect()
|
| 308 |
-
|
| 309 |
except Exception as e:
|
| 310 |
print(f"Error in image_to_3d: {str(e)}")
|
| 311 |
-
|
| 312 |
-
|
| 313 |
-
if torch.cuda.is_available():
|
| 314 |
-
torch.cuda.empty_cache()
|
| 315 |
-
torch.cuda.synchronize()
|
| 316 |
-
gc.collect()
|
| 317 |
return None, None
|
| 318 |
|
| 319 |
def clear_gpu_memory():
|
| 320 |
-
"""GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ ๋ฆฌํ๋
|
| 321 |
try:
|
| 322 |
if torch.cuda.is_available():
|
| 323 |
-
|
| 324 |
-
|
| 325 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 326 |
gc.collect()
|
| 327 |
except Exception as e:
|
| 328 |
-
print(f"Error
|
| 329 |
|
| 330 |
def move_to_device(model, device):
|
| 331 |
"""๋ชจ๋ธ์ ์์ ํ๊ฒ ๋๋ฐ์ด์ค๋ก ์ด๋ํ๋ ํจ์"""
|
|
|
|
| 34 |
|
| 35 |
g = GlobalVars()
|
| 36 |
|
| 37 |
+
# ํ์ผ ์๋จ์ ์ถ๊ฐ
|
| 38 |
+
torch.backends.cudnn.benchmark = False # ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ๊ฐ์
|
| 39 |
+
torch.backends.cudnn.deterministic = True
|
| 40 |
+
torch.cuda.set_per_process_memory_fraction(0.7) # GPU ๋ฉ๋ชจ๋ฆฌ ์ฌ์ฉ๋ ์ ํ
|
| 41 |
|
| 42 |
def initialize_models(device):
|
| 43 |
try:
|
|
|
|
| 88 |
print(f"Error during model initialization: {str(e)}")
|
| 89 |
raise
|
| 90 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 91 |
|
| 92 |
# ํ๊ฒฝ ๋ณ์ ์ค์
|
| 93 |
# ํ๊ฒฝ ๋ณ์ ์ค์
|
|
|
|
| 103 |
# CUDA ์ด๊ธฐํ ๋ฐฉ์ง
|
| 104 |
torch.set_grad_enabled(False)
|
| 105 |
|
| 106 |
+
def periodic_cleanup():
|
| 107 |
+
"""์ฃผ๊ธฐ์ ์ผ๋ก ์คํ๋ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ ํจ์"""
|
| 108 |
+
clear_gpu_memory()
|
| 109 |
+
return None
|
| 110 |
+
|
| 111 |
+
# Gradio ์ธํฐํ์ด์ค์ ์ฃผ๊ธฐ์ ์ ๋ฆฌ ์ถ๊ฐ
|
| 112 |
+
demo.load(periodic_cleanup, every=5) # 5์ด๋ง๋ค ์ ๋ฆฌ
|
| 113 |
|
| 114 |
# Hugging Face ํ ํฐ ์ค์
|
| 115 |
HF_TOKEN = os.getenv("HF_TOKEN")
|
|
|
|
| 215 |
return gs, mesh, state['trial_id']
|
| 216 |
|
| 217 |
@spaces.GPU
|
| 218 |
+
def image_to_3d(trial_id: str, seed: int, randomize_seed: bool, ss_guidance_strength: float,
|
| 219 |
+
ss_sampling_steps: int, slat_guidance_strength: float, slat_sampling_steps: int) -> Tuple[dict, str]:
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 220 |
try:
|
| 221 |
+
# ์ด๊ธฐ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ
|
| 222 |
+
clear_gpu_memory()
|
|
|
|
|
|
|
|
|
|
| 223 |
|
| 224 |
+
if not trial_id or trial_id.strip() == "":
|
| 225 |
+
return None, None
|
| 226 |
|
| 227 |
image_path = f"{TMP_DIR}/{trial_id}.png"
|
|
|
|
|
|
|
| 228 |
if not os.path.exists(image_path):
|
|
|
|
| 229 |
return None, None
|
| 230 |
|
| 231 |
image = Image.open(image_path)
|
|
|
|
| 232 |
|
| 233 |
+
# ์ด๋ฏธ์ง ํฌ๊ธฐ ์ ํ ๊ฐํ
|
| 234 |
+
max_size = 384 # ๋ ์์ ํฌ๊ธฐ๋ก ์ ํ
|
| 235 |
if max(image.size) > max_size:
|
| 236 |
ratio = max_size / max(image.size)
|
| 237 |
new_size = tuple(int(dim * ratio) for dim in image.size)
|
| 238 |
image = image.resize(new_size, Image.LANCZOS)
|
|
|
|
| 239 |
|
|
|
|
| 240 |
with torch.inference_mode():
|
| 241 |
try:
|
| 242 |
+
# ํ์ดํ๋ผ์ธ์ GPU๋ก ์ด๋
|
| 243 |
g.trellis_pipeline.to('cuda')
|
|
|
|
| 244 |
|
| 245 |
+
# ๋ฐฐ์น ํฌ๊ธฐ ์ ํ
|
| 246 |
outputs = g.trellis_pipeline.run(
|
| 247 |
image,
|
| 248 |
seed=seed,
|
| 249 |
formats=["gaussian", "mesh"],
|
| 250 |
preprocess_image=False,
|
| 251 |
sparse_structure_sampler_params={
|
| 252 |
+
"steps": min(ss_sampling_steps, 8), # ์คํ
์ ์ ํ
|
| 253 |
"cfg_strength": ss_guidance_strength,
|
| 254 |
+
"batch_size": 1 # ๋ฐฐ์น ํฌ๊ธฐ ๋ช
์์ ์ ํ
|
| 255 |
},
|
| 256 |
slat_sampler_params={
|
| 257 |
+
"steps": min(slat_sampling_steps, 8), # ์คํ
์ ์ ํ
|
| 258 |
"cfg_strength": slat_guidance_strength,
|
| 259 |
+
"batch_size": 1
|
| 260 |
},
|
| 261 |
)
|
|
|
|
| 262 |
|
| 263 |
+
# ์ค๊ฐ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ
|
| 264 |
+
clear_gpu_memory()
|
| 265 |
+
|
| 266 |
+
# ๋น๋์ค ๋ ๋๋ง ์ต์ ํ
|
| 267 |
video = render_utils.render_video(
|
| 268 |
outputs['gaussian'][0],
|
| 269 |
+
num_frames=30, # ํ๋ ์ ์ ๊ฐ์
|
| 270 |
+
resolution=384 # ํด์๋ ์ ํ
|
| 271 |
)['color']
|
|
|
|
| 272 |
|
| 273 |
video_geo = render_utils.render_video(
|
| 274 |
outputs['mesh'][0],
|
| 275 |
+
num_frames=30,
|
| 276 |
+
resolution=384
|
| 277 |
)['normal']
|
|
|
|
| 278 |
|
| 279 |
+
# CPU๋ก ๋ฐ์ดํฐ ์ด๋ ๋ฐ ๋ฉ๋ชจ๋ฆฌ ์ ๋ฆฌ
|
| 280 |
+
video = [v.cpu().numpy() for v in video]
|
| 281 |
+
video_geo = [v.cpu().numpy() for v in video_geo]
|
| 282 |
+
clear_gpu_memory()
|
| 283 |
|
| 284 |
+
# ๋๋จธ์ง ์ฒ๋ฆฌ
|
| 285 |
video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
|
| 286 |
new_trial_id = str(uuid.uuid4())
|
| 287 |
video_path = f"{TMP_DIR}/{new_trial_id}.mp4"
|
|
|
|
| 288 |
imageio.mimsave(video_path, video, fps=15)
|
| 289 |
|
|
|
|
| 290 |
state = pack_state(outputs['gaussian'][0], outputs['mesh'][0], new_trial_id)
|
|
|
|
| 291 |
return state, video_path
|
| 292 |
|
| 293 |
finally:
|
| 294 |
# ์ ๋ฆฌ ์์
|
| 295 |
g.trellis_pipeline.to('cpu')
|
| 296 |
+
clear_gpu_memory()
|
| 297 |
+
|
|
|
|
|
|
|
|
|
|
| 298 |
except Exception as e:
|
| 299 |
print(f"Error in image_to_3d: {str(e)}")
|
| 300 |
+
g.trellis_pipeline.to('cpu')
|
| 301 |
+
clear_gpu_memory()
|
|
|
|
|
|
|
|
|
|
|
|
|
| 302 |
return None, None
|
| 303 |
|
| 304 |
def clear_gpu_memory():
|
| 305 |
+
"""GPU ๋ฉ๋ชจ๋ฆฌ๋ฅผ ๋ ์ฒ ์ ํ๊ฒ ์ ๋ฆฌํ๋ ํจ์"""
|
| 306 |
try:
|
| 307 |
if torch.cuda.is_available():
|
| 308 |
+
# ๋ชจ๋ GPU ์บ์ ์ ๋ฆฌ
|
| 309 |
+
torch.cuda.empty_cache()
|
| 310 |
+
torch.cuda.synchronize()
|
| 311 |
+
|
| 312 |
+
# ์ฌ์ฉํ์ง ์๋ ์บ์๋ ๋ฉ๋ชจ๋ฆฌ ํด์
|
| 313 |
+
for i in range(torch.cuda.device_count()):
|
| 314 |
+
with torch.cuda.device(i):
|
| 315 |
+
torch.cuda.empty_cache()
|
| 316 |
+
torch.cuda.ipc_collect()
|
| 317 |
+
|
| 318 |
+
# Python ๊ฐ๋น์ง ์ปฌ๋ ํฐ ์คํ
|
| 319 |
gc.collect()
|
| 320 |
except Exception as e:
|
| 321 |
+
print(f"Error in clear_gpu_memory: {e}")
|
| 322 |
|
| 323 |
def move_to_device(model, device):
|
| 324 |
"""๋ชจ๋ธ์ ์์ ํ๊ฒ ๋๋ฐ์ด์ค๋ก ์ด๋ํ๋ ํจ์"""
|