aiqtech commited on
Commit
d88c997
ยท
verified ยท
1 Parent(s): 1f3fd7c

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +78 -93
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
- os.environ["PYTORCH_CUDA_ALLOC_CONF"] = "max_split_size_mb:256,garbage_collection_threshold:0.8"
 
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
- # CUDA ๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ธฐํ™”
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
- # GPU ์ž‘์—… ์‹œ์ž‘
236
- with torch.cuda.device(0):
237
- try:
238
- # ๋ชจ๋ธ์„ GPU๋กœ ์ด๋™
239
- move_to_device(g.trellis_pipeline, 'cuda')
240
- torch.cuda.synchronize()
241
-
242
- with torch.inference_mode(), torch.cuda.amp.autocast():
243
- # ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ตœ์ ํ™”๋ฅผ ์œ„ํ•œ ๋ฐฐ์น˜ ํฌ๊ธฐ ์„ค์ •
244
- torch.cuda.set_per_process_memory_fraction(0.8) # GPU ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ์ œํ•œ
245
-
246
- # 3D ์ƒ์„ฑ
247
- outputs = g.trellis_pipeline.run(
248
- image,
249
- seed=seed,
250
- formats=["gaussian", "mesh"],
251
- preprocess_image=False,
252
- sparse_structure_sampler_params={
253
- "steps": min(ss_sampling_steps, 20), # ์Šคํ… ์ˆ˜ ์ œํ•œ
254
- "cfg_strength": ss_guidance_strength,
255
- },
256
- slat_sampler_params={
257
- "steps": min(slat_sampling_steps, 20), # ์Šคํ… ์ˆ˜ ์ œํ•œ
258
- "cfg_strength": slat_guidance_strength,
259
- },
260
- )
261
- torch.cuda.synchronize()
262
-
263
- # ๋น„๋””์˜ค ๋ Œ๋”๋ง์„ ์œ„ํ•œ ๋ฉ”๋ชจ๋ฆฌ ํ™•๋ณด
264
- torch.cuda.empty_cache()
265
-
266
- # ๋น„๋””์˜ค ๋ Œ๋”๋ง
267
- with torch.cuda.amp.autocast():
268
- video = render_utils.render_video(
269
- outputs['gaussian'][0],
270
- num_frames=60, # ํ”„๋ ˆ์ž„ ์ˆ˜ ๊ฐ์†Œ
271
- resolution=512 # ํ•ด์ƒ๋„ ์ œํ•œ
272
- )['color']
273
- torch.cuda.synchronize()
274
-
275
- video_geo = render_utils.render_video(
276
- outputs['mesh'][0],
277
- num_frames=60, # ํ”„๋ ˆ์ž„ ์ˆ˜ ๊ฐ์†Œ
278
- resolution=512 # ํ•ด์ƒ๋„ ์ œํ•œ
279
- )['normal']
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
- if torch.cuda.is_available():
314
- torch.cuda.empty_cache()
315
- torch.cuda.synchronize()
316
- gc.collect() # ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์‹คํ–‰
 
 
 
 
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
- # CUDA ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ
350
- if torch.cuda.is_available():
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
- with torch.inference_mode(), torch.autocast("cuda", dtype=torch.bfloat16):
 
 
 
 
 
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
- generated_image.save(f"{TMP_DIR}/{trial_id}.png")
 
 
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=12, # ํ•œ ์ค„์— 12๊ฐœ
484
- rows=2, # 2์ค„
485
- height=300, # ๋†’์ด ์กฐ์ •
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
  )