C4G-HKUST commited on
Commit
7b63b72
·
1 Parent(s): f0617b0

Simplify GPU handling following LivePortrait pattern: CPU in main process, GPU in worker via @spaces.GPU

Browse files
Files changed (1) hide show
  1. app.py +12 -48
app.py CHANGED
@@ -384,14 +384,9 @@ def run_graio_demo(args):
384
 
385
  os.makedirs(args.audio_save_dir, exist_ok=True)
386
 
387
- # 在 Stateless GPU 环境中,主进程不能初始化 CUDA
388
- # GPU 检测和初始化将在 worker 进程中进行(通过 @spaces.GPU 装饰器)
389
- # 在主进程中,我们使用 CPU 加载模型,然后在 worker 进程中移动到 GPU
390
- gpu_device_id = None
391
- gpu_name = None
392
- gpu_uuid = None
393
-
394
- # 检查是否在 Stateless GPU 环境中(通过检查 SPACE_ID 和 spaces 模块)
395
  is_stateless_gpu = os.environ.get("SPACE_ID") is not None
396
 
397
  if is_stateless_gpu:
@@ -405,16 +400,10 @@ def run_graio_demo(args):
405
  try:
406
  num_gpus = torch.cuda.device_count()
407
  if num_gpus > 0:
408
- gpu_device_id = local_rank if world_size > 1 else 0
409
- torch.cuda.set_device(gpu_device_id)
410
- gpu_name = torch.cuda.get_device_name(gpu_device_id)
411
- # 尝试获取 GPU UUID(如果可用)
412
- try:
413
- gpu_uuid = torch.cuda.get_device_properties(gpu_device_id).uuid
414
- except:
415
- pass
416
- logging.info(f"GPU AVAILABLE: {num_gpus} GPU(s), Device ID: {gpu_device_id}, Name: {gpu_name}, UUID: {gpu_uuid}")
417
- device = gpu_device_id
418
  else:
419
  logging.warning("CUDA is available but no GPU devices found. Using CPU.")
420
  device = -1 # 使用 CPU
@@ -448,17 +437,16 @@ def run_graio_demo(args):
448
 
449
  def generate_video(img2vid_image, img2vid_prompt, n_prompt, img2vid_audio_1, img2vid_audio_2, img2vid_audio_3,
450
  sd_steps, seed, guide_scale, person_num_selector, audio_mode_selector):
451
- # 在 worker 进程中设置 GPU 设备(Stateless GPU 环境)
 
 
452
  if torch.cuda.is_available():
453
  try:
454
- # 如果记录了 GPU 设备 ID,使用它;否则使用默认设备 0
455
- target_device = gpu_device_id if gpu_device_id is not None else 0
456
- torch.cuda.set_device(target_device)
457
  current_device = torch.cuda.current_device()
458
  current_gpu_name = torch.cuda.get_device_name(current_device)
459
  logging.info(f"Using GPU device {current_device} ({current_gpu_name}) for inference")
460
  except Exception as e:
461
- logging.warning(f"Failed to set GPU device: {e}")
462
 
463
  input_data = {}
464
  input_data["prompt"] = img2vid_prompt
@@ -609,33 +597,9 @@ def run_graio_demo(args):
609
 
610
  # 使用 @spaces.GPU 装饰器包装 generate_video 函数(参考 LivePortrait)
611
  # 参考: https://huggingface.co/spaces/KlingTeam/LivePortrait/blob/main/app.py
 
612
  @spaces.GPU(duration=360)
613
  def gpu_wrapped_generate_video(*args, **kwargs):
614
- # 在 worker 进程中初始化 GPU(Stateless GPU 环境)
615
- worker_gpu_device_id = None
616
- try:
617
- if torch.cuda.is_available():
618
- # 在 worker 进程中检测 GPU
619
- num_gpus = torch.cuda.device_count()
620
- if num_gpus > 0:
621
- worker_gpu_device_id = 0 # 使用第一个 GPU
622
- torch.cuda.set_device(worker_gpu_device_id)
623
- current_device = torch.cuda.current_device()
624
- current_gpu_name = torch.cuda.get_device_name(current_device)
625
- logging.info(f"Worker process initialized GPU: device {current_device} ({current_gpu_name})")
626
-
627
- # 如果模型是在 CPU 上加载的,需要移动到 GPU
628
- if device == -1:
629
- logging.info("Moving models from CPU to GPU in worker process...")
630
- # 注意:这里需要确保模型已经加载,并且可以移动到 GPU
631
- # 由于模型是在主进程加载的,可能需要重新加载或移动
632
- else:
633
- logging.warning("No GPU devices found in worker process")
634
- else:
635
- logging.warning("CUDA not available in worker process")
636
- except RuntimeError as e:
637
- logging.warning(f"GPU initialization error in worker process: {e}")
638
-
639
  return generate_video(*args, **kwargs)
640
 
641
  def toggle_audio_inputs(person_num):
 
384
 
385
  os.makedirs(args.audio_save_dir, exist_ok=True)
386
 
387
+ # 参考 LivePortrait: 在 Stateless GPU 环境中,主进程不能初始化 CUDA
388
+ # 参考: https://huggingface.co/spaces/KlingTeam/LivePortrait/blob/main/app.py
389
+ # 在主进程中,我们使用 CPU 加载模型,GPU 将在 worker 进程中通过 @spaces.GPU 装饰器初始化
 
 
 
 
 
390
  is_stateless_gpu = os.environ.get("SPACE_ID") is not None
391
 
392
  if is_stateless_gpu:
 
400
  try:
401
  num_gpus = torch.cuda.device_count()
402
  if num_gpus > 0:
403
+ device = local_rank if world_size > 1 else 0
404
+ torch.cuda.set_device(device)
405
+ gpu_name = torch.cuda.get_device_name(device)
406
+ logging.info(f"GPU AVAILABLE: {num_gpus} GPU(s), Device ID: {device}, Name: {gpu_name}")
 
 
 
 
 
 
407
  else:
408
  logging.warning("CUDA is available but no GPU devices found. Using CPU.")
409
  device = -1 # 使用 CPU
 
437
 
438
  def generate_video(img2vid_image, img2vid_prompt, n_prompt, img2vid_audio_1, img2vid_audio_2, img2vid_audio_3,
439
  sd_steps, seed, guide_scale, person_num_selector, audio_mode_selector):
440
+ # 参考 LivePortrait: 在 worker 进程中直接使用 cuda 设备
441
+ # 参考: https://huggingface.co/spaces/KlingTeam/LivePortrait/blob/main/src/gradio_pipeline.py
442
+ # @spaces.GPU 装饰器已经初始化了 GPU,这里直接使用即可
443
  if torch.cuda.is_available():
444
  try:
 
 
 
445
  current_device = torch.cuda.current_device()
446
  current_gpu_name = torch.cuda.get_device_name(current_device)
447
  logging.info(f"Using GPU device {current_device} ({current_gpu_name}) for inference")
448
  except Exception as e:
449
+ logging.warning(f"GPU check error: {e}")
450
 
451
  input_data = {}
452
  input_data["prompt"] = img2vid_prompt
 
597
 
598
  # 使用 @spaces.GPU 装饰器包装 generate_video 函数(参考 LivePortrait)
599
  # 参考: https://huggingface.co/spaces/KlingTeam/LivePortrait/blob/main/app.py
600
+ # @spaces.GPU 装饰器会自动处理 GPU 初始化,不需要手动初始化
601
  @spaces.GPU(duration=360)
602
  def gpu_wrapped_generate_video(*args, **kwargs):
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
603
  return generate_video(*args, **kwargs)
604
 
605
  def toggle_audio_inputs(person_num):