EuuIia commited on
Commit
a614adb
·
verified ·
1 Parent(s): 64e7596

Update api/ltx_server.py

Browse files
Files changed (1) hide show
  1. api/ltx_server.py +74 -65
api/ltx_server.py CHANGED
@@ -579,85 +579,94 @@ class VideoService:
579
  latents = None
580
  multi_scale_pipeline = None
581
 
 
582
  try:
583
  if improve_texture:
584
  if not self.latent_upsampler:
585
  raise ValueError("Upscaler espacial não carregado.")
586
- print("[DEBUG] Multi-escala: construindo pipeline...")
587
- multi_scale_pipeline = LTXMultiScalePipeline(self.pipeline, self.latent_upsampler)
 
 
588
  first_pass_args = self.config.get("first_pass", {}).copy()
589
- first_pass_args["guidance_scale"] = float(guidance_scale)
590
- second_pass_args = self.config.get("second_pass", {}).copy()
591
- second_pass_args["guidance_scale"] = float(guidance_scale)
592
-
593
- #multi_scale_call_kwargs = call_kwargs.copy()
594
- #multi_scale_call_kwargs.update(
595
- # {
596
- # "downscale_factor": self.config["downscale_factor"],
597
- # "first_pass": first_pass_args,
598
- # "second_pass": second_pass_args,
599
- # }
600
- #)
601
-
602
- #
603
  first_pass_kwargs = call_kwargs.copy()
604
- first_pass_kwargs.update(first_pass_args)
605
- second_pass_kwargs = call_kwargs.copy()
606
- second_pass_kwargs.update(second_pass_args)
 
 
 
 
 
 
 
 
607
 
608
- print("[DEBUG] Chamando multi_scale_pipeline...")
609
- t_ms = time.perf_counter()
610
- ctx = torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype) if self.device == "cuda" else contextlib.nullcontext()
 
 
 
611
 
612
- print("[DEBUG] Executando FIRST PASS (pipeline base)...")
 
 
 
613
  with ctx:
614
- result_first = self.pipeline(**first_pass_kwargs)
615
-
616
-
617
- if hasattr(result_first, "latents"):
618
- latents = result_first.latents
619
- elif hasattr(result_first, "images") and isinstance(result_first.images, torch.Tensor):
620
- latents = result_first.images
621
- else:
622
- latents = result_first
623
- print(f"[DEBUG] Latentes (single-pass): shape={tuple(latents.shape)}")
624
- latents_first = latents
625
-
626
 
627
- ctx = torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype) if self.device == "cuda" else contextlib.nullcontext()
 
 
 
 
 
 
 
 
 
 
 
628
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
629
 
630
- # --- SECOND PASS ---
631
- print("[DEBUG] Executando SECOND PASS (latent_upsampler)...")
632
  with ctx:
633
- result = self.latent_upsampler(
634
- #**second_pass_kwargs,
635
- #conditions=conditioning_items,
636
- prompt=prompt,
637
- negative_prompt=negative_prompt,
638
- width=width_padded,
639
- height=height_padded,
640
- num_frames=actual_num_frames,
641
- latents=latents_first,
642
- denoise_strength=0.4,
643
- num_inference_steps=10,
644
- decode_timestep=0.05,
645
- image_cond_noise_scale=0.025,
646
- generator=generator,
647
- output_type="latent",
648
- )
649
 
650
- #with ctx:
651
- # result = multi_scale_pipeline(**multi_scale_call_kwargs)
652
- #print(f"[DEBUG] multi_scale_pipeline tempo={time.perf_counter()-t_ms:.3f}s")
653
-
654
- if hasattr(result, "latents"):
655
- latents = result.latents
656
- elif hasattr(result, "images") and isinstance(result.images, torch.Tensor):
657
- latents = result.images
658
- else:
659
- latents = result
660
- print(f"[DEBUG] Latentes (multi-escala): shape={tuple(latents.shape)}")
661
  else:
662
  single_pass_kwargs = call_kwargs.copy()
663
  first_pass_config = self.config.get("first_pass", {})
 
579
  latents = None
580
  multi_scale_pipeline = None
581
 
582
+
583
  try:
584
  if improve_texture:
585
  if not self.latent_upsampler:
586
  raise ValueError("Upscaler espacial não carregado.")
587
+
588
+ print("[DEBUG] Multi-escala: Iniciando Passo 1 (geração de latentes base).")
589
+
590
+ # 1. Configurar e executar o primeiro passo
591
  first_pass_args = self.config.get("first_pass", {}).copy()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
592
  first_pass_kwargs = call_kwargs.copy()
593
+ first_pass_kwargs.update({
594
+ "guidance_scale": float(guidance_scale),
595
+ "stg_scale": first_pass_args.get("stg_scale"),
596
+ "rescaling_scale": first_pass_args.get("rescaling_scale"),
597
+ "skip_block_list": first_pass_args.get("skip_block_list"),
598
+ })
599
+ # Opcional: ajustar timesteps se especificado no config
600
+ schedule = first_pass_args.get("timesteps") or first_pass_args.get("guidance_timesteps")
601
+ if schedule:
602
+ first_pass_kwargs["timesteps"] = schedule
603
+ first_pass_kwargs["guidance_timesteps"] = schedule
604
 
605
+ # Reduzir dimensões para o primeiro passo
606
+ downscale_factor = self.config.get("downscale_factor", 2)
607
+ original_height = first_pass_kwargs["height"]
608
+ original_width = first_pass_kwargs["width"]
609
+ first_pass_kwargs["height"] = original_height // downscale_factor
610
+ first_pass_kwargs["width"] = original_width // downscale_factor
611
 
612
+ print(f"[DEBUG] Passo 1: Dimensões reduzidas para {first_pass_kwargs['height']}x{first_pass_kwargs['width']}")
613
+
614
+ t_p1 = time.perf_counter()
615
+ ctx = torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype) if self.device == "cuda" else contextlib.nullcontext()
616
  with ctx:
617
+ # Executa a pipeline principal para o primeiro passo
618
+ first_pass_result = self.pipeline(**first_pass_kwargs)
619
+
620
+ # Extrai os latentes do resultado
621
+ latents_low_res = first_pass_result.latents if hasattr(first_pass_result, "latents") else first_pass_result
622
+ print(f"[DEBUG] Passo 1 concluído em {time.perf_counter()-t_p1:.3f}s. Shape dos latentes de baixa resolução: {tuple(latents_low_res.shape)}")
623
+ log_tensor_info(latents_low_res, "Latentes (Passo 1)")
624
+
625
+ # Limpeza de memória entre os passos
626
+ del first_pass_result, first_pass_kwargs
627
+ gc.collect()
628
+ if self.device == "cuda": torch.cuda.empty_cache()
629
 
630
+ # 2. Upscale dos latentes
631
+ print("[DEBUG] Multi-escala: Fazendo upscale dos latentes com latent_upsampler.")
632
+ with ctx:
633
+ latents_high_res = self.latent_upsampler(
634
+ latents=latents_low_res,
635
+ output_height=original_height,
636
+ output_width=original_width,
637
+ )
638
+ log_tensor_info(latents_high_res, "Latentes (Pós-Upscale)")
639
+ del latents_low_res
640
+ gc.collect()
641
+ if self.device == "cuda": torch.cuda.empty_cache()
642
 
643
+ # 3. Configurar e executar o segundo passo
644
+ print("[DEBUG] Multi-escala: Iniciando Passo 2 (refinamento em alta resolução).")
645
+ second_pass_args = self.config.get("second_pass", {}).copy()
646
+ second_pass_kwargs = call_kwargs.copy()
647
+ second_pass_kwargs.update({
648
+ "guidance_scale": float(guidance_scale),
649
+ "stg_scale": second_pass_args.get("stg_scale"),
650
+ "rescaling_scale": second_pass_args.get("rescaling_scale"),
651
+ "skip_block_list": second_pass_args.get("skip_block_list"),
652
+ })
653
+ # O segundo passo geralmente usa uma fração dos timesteps totais (ex: 70%)
654
+ schedule_p2 = second_pass_args.get("timesteps") or second_pass_args.get("guidance_timesteps")
655
+ if schedule_p2:
656
+ second_pass_kwargs["timesteps"] = schedule_p2
657
+ second_pass_kwargs["guidance_timesteps"] = schedule_p2
658
+
659
+ # Adiciona os latentes do upscale como 'latents' iniciais para o segundo passo
660
+ second_pass_kwargs["latents"] = latents_high_res
661
 
662
+ t_p2 = time.perf_counter()
 
663
  with ctx:
664
+ # Executa a pipeline principal para o segundo passo
665
+ second_pass_result = self.pipeline(**second_pass_kwargs)
666
+
667
+ latents = second_pass_result.latents if hasattr(second_pass_result, "latents") else second_pass_result
668
+ print(f"[DEBUG] Passo 2 concluído em {time.perf_counter()-t_p2:.3f}s. Shape dos latentes finais: {tuple(latents.shape)}")
 
 
 
 
 
 
 
 
 
 
 
669
 
 
 
 
 
 
 
 
 
 
 
 
670
  else:
671
  single_pass_kwargs = call_kwargs.copy()
672
  first_pass_config = self.config.get("first_pass", {})