Spaces:
Paused
Paused
Update app.py
Browse files
app.py
CHANGED
@@ -23,6 +23,7 @@ from typing import Tuple, Dict, Any # Tuple import μΆκ°
|
|
23 |
import transformers
|
24 |
from transformers import pipeline as transformers_pipeline
|
25 |
from transformers import Pipeline
|
|
|
26 |
|
27 |
# μ μ λ³μ μ΄κΈ°ν
|
28 |
class GlobalVars:
|
@@ -81,7 +82,8 @@ torch.backends.cuda.matmul.allow_tf32 = True
|
|
81 |
torch.backends.cudnn.benchmark = True
|
82 |
|
83 |
# νκ²½ λ³μ μ€μ
|
84 |
-
|
|
|
85 |
os.environ['SPCONV_ALGO'] = 'native'
|
86 |
os.environ['SPARSE_BACKEND'] = 'native'
|
87 |
os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
|
@@ -89,7 +91,6 @@ os.environ['XFORMERS_FORCE_DISABLE_TRITON'] = '1'
|
|
89 |
os.environ['XFORMERS_ENABLE_FLASH_ATTENTION'] = '1'
|
90 |
os.environ['TORCH_CUDA_MEMORY_ALLOCATOR'] = 'native'
|
91 |
os.environ['PYTORCH_NO_CUDA_MEMORY_CACHING'] = '1'
|
92 |
-
os.environ['CUDA_VISIBLE_DEVICES'] = '0'
|
93 |
|
94 |
# CUDA μ΄κΈ°ν λ°©μ§
|
95 |
torch.set_grad_enabled(False)
|
@@ -207,9 +208,7 @@ def image_to_3d(trial_id: str, seed: int, randomize_seed: bool, ss_guidance_stre
|
|
207 |
return None, None
|
208 |
|
209 |
try:
|
210 |
-
|
211 |
-
torch.cuda.empty_cache()
|
212 |
-
torch.cuda.synchronize()
|
213 |
|
214 |
if randomize_seed:
|
215 |
seed = np.random.randint(0, MAX_SEED)
|
@@ -232,88 +231,69 @@ def image_to_3d(trial_id: str, seed: int, randomize_seed: bool, ss_guidance_stre
|
|
232 |
image = image.resize(new_size, Image.LANCZOS)
|
233 |
print(f"Resized image to: {image.size}")
|
234 |
|
235 |
-
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
240 |
-
|
241 |
-
|
242 |
-
|
243 |
-
|
244 |
-
|
245 |
-
|
246 |
-
|
247 |
-
|
248 |
-
|
249 |
-
|
250 |
-
|
251 |
-
|
252 |
-
|
253 |
-
|
254 |
-
|
255 |
-
|
256 |
-
|
257 |
-
|
258 |
-
|
259 |
-
|
260 |
-
|
261 |
-
|
262 |
-
|
263 |
-
|
264 |
-
|
265 |
-
|
266 |
-
|
267 |
-
|
268 |
-
|
269 |
-
|
270 |
-
|
271 |
-
|
272 |
-
|
273 |
-
|
274 |
-
|
275 |
-
|
276 |
-
|
277 |
-
|
278 |
-
|
279 |
-
|
280 |
-
torch.cuda.synchronize()
|
281 |
-
|
282 |
-
# CPUλ‘ λ°μ΄ν° μ΄λ λ° νμ²λ¦¬
|
283 |
-
video = [v.cpu().numpy() if torch.is_tensor(v) else v for v in video]
|
284 |
-
video_geo = [v.cpu().numpy() if torch.is_tensor(v) else v for v in video_geo]
|
285 |
-
|
286 |
-
video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
|
287 |
-
new_trial_id = str(uuid.uuid4())
|
288 |
-
video_path = f"{TMP_DIR}/{new_trial_id}.mp4"
|
289 |
-
os.makedirs(os.path.dirname(video_path), exist_ok=True)
|
290 |
-
imageio.mimsave(video_path, video, fps=15)
|
291 |
-
|
292 |
-
# μν μ μ₯
|
293 |
-
state = pack_state(outputs['gaussian'][0], outputs['mesh'][0], new_trial_id)
|
294 |
-
|
295 |
-
return state, video_path
|
296 |
-
|
297 |
-
finally:
|
298 |
-
# μ 리 μμ
|
299 |
-
move_to_device(g.trellis_pipeline, 'cpu')
|
300 |
-
torch.cuda.empty_cache()
|
301 |
-
torch.cuda.synchronize()
|
302 |
-
|
303 |
except Exception as e:
|
304 |
print(f"Error in image_to_3d: {str(e)}")
|
305 |
-
if hasattr(g.trellis_pipeline, 'to'):
|
306 |
-
move_to_device(g.trellis_pipeline, 'cpu')
|
307 |
-
torch.cuda.empty_cache()
|
308 |
-
torch.cuda.synchronize()
|
309 |
return None, None
|
|
|
|
|
|
|
|
|
310 |
|
311 |
def clear_gpu_memory():
|
312 |
"""GPU λ©λͺ¨λ¦¬λ₯Ό μ 리νλ μ νΈλ¦¬ν° ν¨μ"""
|
313 |
-
|
314 |
-
torch.cuda.
|
315 |
-
|
316 |
-
|
|
|
|
|
|
|
|
|
317 |
|
318 |
def move_to_device(model, device):
|
319 |
"""λͺ¨λΈμ μμ νκ² λλ°μ΄μ€λ‘ μ΄λνλ ν¨μ"""
|
@@ -346,26 +326,27 @@ def deactivate_button() -> gr.Button:
|
|
346 |
@spaces.GPU
|
347 |
def text_to_image(prompt: str, height: int, width: int, steps: int, scales: float, seed: int) -> Image.Image:
|
348 |
try:
|
349 |
-
|
350 |
-
|
351 |
-
torch.cuda.empty_cache()
|
352 |
-
|
353 |
# νκΈ κ°μ§ λ° λ²μ
|
354 |
def contains_korean(text):
|
355 |
return any(ord('κ°') <= ord(c) <= ord('ν£') for c in text)
|
356 |
|
357 |
-
# ν둬ννΈ μ μ²λ¦¬
|
358 |
if contains_korean(prompt):
|
359 |
translated = g.translator(prompt)[0]['translation_text']
|
360 |
prompt = translated
|
361 |
|
362 |
-
# ν둬ννΈ νμ κ°μ
|
363 |
formatted_prompt = f"wbgmsst, 3D, {prompt}, white background"
|
364 |
|
365 |
-
|
|
|
|
|
|
|
|
|
|
|
366 |
generated_image = g.flux_pipe(
|
367 |
prompt=[formatted_prompt],
|
368 |
-
generator=torch.Generator().manual_seed(int(seed)),
|
369 |
num_inference_steps=int(steps),
|
370 |
guidance_scale=float(scales),
|
371 |
height=int(height),
|
@@ -375,7 +356,9 @@ def text_to_image(prompt: str, height: int, width: int, steps: int, scales: floa
|
|
375 |
|
376 |
if generated_image is not None:
|
377 |
trial_id = str(uuid.uuid4())
|
378 |
-
|
|
|
|
|
379 |
return generated_image
|
380 |
else:
|
381 |
print("Error: Generated image is None")
|
@@ -384,6 +367,8 @@ def text_to_image(prompt: str, height: int, width: int, steps: int, scales: floa
|
|
384 |
except Exception as e:
|
385 |
print(f"Error in image generation: {str(e)}")
|
386 |
return None
|
|
|
|
|
387 |
|
388 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
389 |
gr.Markdown("""## Craft3D""")
|
@@ -480,9 +465,9 @@ with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
|
480 |
label="Click an image to use it",
|
481 |
show_label=True,
|
482 |
elem_id="gallery",
|
483 |
-
columns=
|
484 |
-
rows=
|
485 |
-
height=
|
486 |
allow_preview=True,
|
487 |
object_fit="contain" # μ΄λ―Έμ§ λΉμ¨ μ μ§
|
488 |
)
|
|
|
23 |
import transformers
|
24 |
from transformers import pipeline as transformers_pipeline
|
25 |
from transformers import Pipeline
|
26 |
+
import gc # νμΌ μλ¨μ μΆκ°
|
27 |
|
28 |
# μ μ λ³μ μ΄κΈ°ν
|
29 |
class GlobalVars:
|
|
|
82 |
torch.backends.cudnn.benchmark = True
|
83 |
|
84 |
# νκ²½ λ³μ μ€μ
|
85 |
+
# νκ²½ λ³μ μ€μ
|
86 |
+
os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:128"
|
87 |
os.environ['SPCONV_ALGO'] = 'native'
|
88 |
os.environ['SPARSE_BACKEND'] = 'native'
|
89 |
os.environ['CUDA_LAUNCH_BLOCKING'] = '1'
|
|
|
91 |
os.environ['XFORMERS_ENABLE_FLASH_ATTENTION'] = '1'
|
92 |
os.environ['TORCH_CUDA_MEMORY_ALLOCATOR'] = 'native'
|
93 |
os.environ['PYTORCH_NO_CUDA_MEMORY_CACHING'] = '1'
|
|
|
94 |
|
95 |
# CUDA μ΄κΈ°ν λ°©μ§
|
96 |
torch.set_grad_enabled(False)
|
|
|
208 |
return None, None
|
209 |
|
210 |
try:
|
211 |
+
clear_gpu_memory()
|
|
|
|
|
212 |
|
213 |
if randomize_seed:
|
214 |
seed = np.random.randint(0, MAX_SEED)
|
|
|
231 |
image = image.resize(new_size, Image.LANCZOS)
|
232 |
print(f"Resized image to: {image.size}")
|
233 |
|
234 |
+
with spaces.GPU(), torch.inference_mode():
|
235 |
+
# 3D μμ±
|
236 |
+
g.trellis_pipeline.to('cuda')
|
237 |
+
outputs = g.trellis_pipeline.run(
|
238 |
+
image,
|
239 |
+
seed=seed,
|
240 |
+
formats=["gaussian", "mesh"],
|
241 |
+
preprocess_image=False,
|
242 |
+
sparse_structure_sampler_params={
|
243 |
+
"steps": min(ss_sampling_steps, 12),
|
244 |
+
"cfg_strength": ss_guidance_strength,
|
245 |
+
},
|
246 |
+
slat_sampler_params={
|
247 |
+
"steps": min(slat_sampling_steps, 12),
|
248 |
+
"cfg_strength": slat_guidance_strength,
|
249 |
+
},
|
250 |
+
)
|
251 |
+
|
252 |
+
# λΉλμ€ λ λλ§
|
253 |
+
video = render_utils.render_video(
|
254 |
+
outputs['gaussian'][0],
|
255 |
+
num_frames=60,
|
256 |
+
resolution=512
|
257 |
+
)['color']
|
258 |
+
|
259 |
+
video_geo = render_utils.render_video(
|
260 |
+
outputs['mesh'][0],
|
261 |
+
num_frames=60,
|
262 |
+
resolution=512
|
263 |
+
)['normal']
|
264 |
+
|
265 |
+
# CPUλ‘ λ°μ΄ν° μ΄λ
|
266 |
+
video = [v.cpu().numpy() if torch.is_tensor(v) else v for v in video]
|
267 |
+
video_geo = [v.cpu().numpy() if torch.is_tensor(v) else v for v in video_geo]
|
268 |
+
|
269 |
+
video = [np.concatenate([video[i], video_geo[i]], axis=1) for i in range(len(video))]
|
270 |
+
new_trial_id = str(uuid.uuid4())
|
271 |
+
video_path = f"{TMP_DIR}/{new_trial_id}.mp4"
|
272 |
+
os.makedirs(os.path.dirname(video_path), exist_ok=True)
|
273 |
+
imageio.mimsave(video_path, video, fps=15)
|
274 |
+
|
275 |
+
state = pack_state(outputs['gaussian'][0], outputs['mesh'][0], new_trial_id)
|
276 |
+
|
277 |
+
return state, video_path
|
278 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
279 |
except Exception as e:
|
280 |
print(f"Error in image_to_3d: {str(e)}")
|
|
|
|
|
|
|
|
|
281 |
return None, None
|
282 |
+
finally:
|
283 |
+
if hasattr(g.trellis_pipeline, 'to'):
|
284 |
+
g.trellis_pipeline.to('cpu')
|
285 |
+
clear_gpu_memory()
|
286 |
|
287 |
def clear_gpu_memory():
|
288 |
"""GPU λ©λͺ¨λ¦¬λ₯Ό μ 리νλ μ νΈλ¦¬ν° ν¨μ"""
|
289 |
+
try:
|
290 |
+
if torch.cuda.is_available():
|
291 |
+
with torch.cuda.device('cuda'):
|
292 |
+
torch.cuda.empty_cache()
|
293 |
+
torch.cuda.synchronize()
|
294 |
+
gc.collect()
|
295 |
+
except Exception as e:
|
296 |
+
print(f"Error clearing GPU memory: {e}")
|
297 |
|
298 |
def move_to_device(model, device):
|
299 |
"""λͺ¨λΈμ μμ νκ² λλ°μ΄μ€λ‘ μ΄λνλ ν¨μ"""
|
|
|
326 |
@spaces.GPU
|
327 |
def text_to_image(prompt: str, height: int, width: int, steps: int, scales: float, seed: int) -> Image.Image:
|
328 |
try:
|
329 |
+
clear_gpu_memory()
|
330 |
+
|
|
|
|
|
331 |
# νκΈ κ°μ§ λ° λ²μ
|
332 |
def contains_korean(text):
|
333 |
return any(ord('κ°') <= ord(c) <= ord('ν£') for c in text)
|
334 |
|
|
|
335 |
if contains_korean(prompt):
|
336 |
translated = g.translator(prompt)[0]['translation_text']
|
337 |
prompt = translated
|
338 |
|
|
|
339 |
formatted_prompt = f"wbgmsst, 3D, {prompt}, white background"
|
340 |
|
341 |
+
# ν¬κΈ° μ ν
|
342 |
+
height = min(height, 512)
|
343 |
+
width = min(width, 512)
|
344 |
+
steps = min(steps, 12)
|
345 |
+
|
346 |
+
with spaces.GPU(), torch.inference_mode():
|
347 |
generated_image = g.flux_pipe(
|
348 |
prompt=[formatted_prompt],
|
349 |
+
generator=torch.Generator('cuda').manual_seed(int(seed)),
|
350 |
num_inference_steps=int(steps),
|
351 |
guidance_scale=float(scales),
|
352 |
height=int(height),
|
|
|
356 |
|
357 |
if generated_image is not None:
|
358 |
trial_id = str(uuid.uuid4())
|
359 |
+
save_path = f"{TMP_DIR}/{trial_id}.png"
|
360 |
+
generated_image.save(save_path)
|
361 |
+
print(f"Saved generated image to: {save_path}")
|
362 |
return generated_image
|
363 |
else:
|
364 |
print("Error: Generated image is None")
|
|
|
367 |
except Exception as e:
|
368 |
print(f"Error in image generation: {str(e)}")
|
369 |
return None
|
370 |
+
finally:
|
371 |
+
clear_gpu_memory()
|
372 |
|
373 |
with gr.Blocks(theme=gr.themes.Soft()) as demo:
|
374 |
gr.Markdown("""## Craft3D""")
|
|
|
465 |
label="Click an image to use it",
|
466 |
show_label=True,
|
467 |
elem_id="gallery",
|
468 |
+
columns=11, # ν μ€μ 12κ°
|
469 |
+
rows=3, # 2μ€
|
470 |
+
height=400, # λμ΄ μ‘°μ
|
471 |
allow_preview=True,
|
472 |
object_fit="contain" # μ΄λ―Έμ§ λΉμ¨ μ μ§
|
473 |
)
|