Carlos s
commited on
Update api/ltx_server.py
Browse files- api/ltx_server.py +41 -30
api/ltx_server.py
CHANGED
|
@@ -587,55 +587,66 @@ class VideoService:
|
|
| 587 |
|
| 588 |
print("[DEBUG] Multi-escala: Iniciando Passo 1 (geração de latentes base).")
|
| 589 |
|
| 590 |
-
|
| 591 |
-
|
| 592 |
-
|
| 593 |
-
|
| 594 |
-
|
| 595 |
-
|
| 596 |
-
|
| 597 |
-
|
| 598 |
-
|
| 599 |
-
|
| 600 |
-
|
| 601 |
-
|
| 602 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 603 |
# ==================== NOVA LÓGICA DE DIMENSÕES AQUI ====================
|
| 604 |
downscale_factor = self.config.get("downscale_factor", 2)
|
| 605 |
-
original_height =
|
| 606 |
-
original_width =
|
| 607 |
divisor = 24
|
| 608 |
|
| 609 |
# Calcula a altura para o primeiro passo, garantindo divisibilidade
|
| 610 |
target_height_p1 = original_height // downscale_factor
|
| 611 |
-
|
| 612 |
|
| 613 |
# Calcula a largura para o primeiro passo, garantindo divisibilidade
|
| 614 |
target_width_p1 = original_width // downscale_factor
|
| 615 |
-
|
| 616 |
|
| 617 |
# Medida de segurança para evitar dimensões zero
|
| 618 |
-
if
|
| 619 |
-
if
|
| 620 |
# =======================================================================
|
| 621 |
|
| 622 |
-
print(f"[DEBUG] Passo 1: Dimensões reduzidas e ajustadas para {
|
| 623 |
-
|
| 624 |
-
|
| 625 |
-
first_pass_kwargs["output_type"] = "latent"
|
| 626 |
-
|
| 627 |
-
print(f"[DEBUG][first_pass_kwargs] {first_pass_kwargs}")
|
| 628 |
|
| 629 |
-
|
|
|
|
|
|
|
| 630 |
ctx = torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype) if self.device == "cuda" else contextlib.nullcontext()
|
| 631 |
with ctx:
|
| 632 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 633 |
|
| 634 |
-
latents_low_res =
|
| 635 |
print(f"[DEBUG] Passo 1 concluído. Shape dos latentes de baixa resolução: {latents_low_res.shape}")
|
| 636 |
-
log_tensor_info(latents_low_res, "Latentes (Passo 1)")
|
| 637 |
|
| 638 |
-
del
|
| 639 |
gc.collect()
|
| 640 |
if self.device == "cuda": torch.cuda.empty_cache()
|
| 641 |
|
|
|
|
| 587 |
|
| 588 |
print("[DEBUG] Multi-escala: Iniciando Passo 1 (geração de latentes base).")
|
| 589 |
|
| 590 |
+
single_pass_kwargs = call_kwargs.copy()
|
| 591 |
+
first_pass_config = self.config.get("first_pass", {})
|
| 592 |
+
single_pass_kwargs.update(
|
| 593 |
+
{
|
| 594 |
+
"guidance_scale": float(guidance_scale),
|
| 595 |
+
"stg_scale": first_pass_config.get("stg_scale"),
|
| 596 |
+
"rescaling_scale": first_pass_config.get("rescaling_scale"),
|
| 597 |
+
"skip_block_list": first_pass_config.get("skip_block_list"),
|
| 598 |
+
}
|
| 599 |
+
)
|
| 600 |
+
schedule = first_pass_config.get("timesteps") or first_pass_config.get("guidance_timesteps")
|
| 601 |
+
if mode == "video-to-video":
|
| 602 |
+
schedule = [0.7]; print("[INFO] Modo video-to-video (etapa única): timesteps=[0.7]")
|
| 603 |
+
if isinstance(schedule, (list, tuple)) and len(schedule) > 0:
|
| 604 |
+
single_pass_kwargs["timesteps"] = schedule
|
| 605 |
+
single_pass_kwargs["guidance_timesteps"] = schedule
|
| 606 |
+
print(f"[DEBUG] Single-pass: timesteps_len={len(schedule) if schedule else 0}")
|
| 607 |
+
|
| 608 |
+
|
| 609 |
# ==================== NOVA LÓGICA DE DIMENSÕES AQUI ====================
|
| 610 |
downscale_factor = self.config.get("downscale_factor", 2)
|
| 611 |
+
original_height = single_pass_kwargs["height"]
|
| 612 |
+
original_width = single_pass_kwargs["width"]
|
| 613 |
divisor = 24
|
| 614 |
|
| 615 |
# Calcula a altura para o primeiro passo, garantindo divisibilidade
|
| 616 |
target_height_p1 = original_height // downscale_factor
|
| 617 |
+
single_pass_kwargs["height"] = round(target_height_p1 / divisor) * divisor
|
| 618 |
|
| 619 |
# Calcula a largura para o primeiro passo, garantindo divisibilidade
|
| 620 |
target_width_p1 = original_width // downscale_factor
|
| 621 |
+
single_pass_kwargs["width"] = round(target_width_p1 / divisor) * divisor
|
| 622 |
|
| 623 |
# Medida de segurança para evitar dimensões zero
|
| 624 |
+
if single_pass_kwargs["height"] == 0: first_pass_kwargs["height"] = divisor
|
| 625 |
+
if single_pass_kwargs["width"] == 0: first_pass_kwargs["width"] = divisor
|
| 626 |
# =======================================================================
|
| 627 |
|
| 628 |
+
print(f"[DEBUG] Passo 1: Dimensões reduzidas e ajustadas para {single_pass_kwargs['height']}x{single_pass_kwargs['width']}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 629 |
|
| 630 |
+
|
| 631 |
+
print("\n[INFO] Executando pipeline promeira etapa...")
|
| 632 |
+
t_sp = time.perf_counter()
|
| 633 |
ctx = torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype) if self.device == "cuda" else contextlib.nullcontext()
|
| 634 |
with ctx:
|
| 635 |
+
result = self.pipeline(**single_pass_kwargs)
|
| 636 |
+
print(f"[DEBUG] single-pass tempo={time.perf_counter()-t_sp:.3f}s")
|
| 637 |
+
|
| 638 |
+
if hasattr(result, "latents"):
|
| 639 |
+
latents = result.latents
|
| 640 |
+
elif hasattr(result, "images") and isinstance(result.images, torch.Tensor):
|
| 641 |
+
latents = result.images
|
| 642 |
+
else:
|
| 643 |
+
latents = result
|
| 644 |
+
#print(f"[DEBUG] Latentes (first_pass_kwargs): shape={tuple(latents.shape)}")
|
| 645 |
|
| 646 |
+
latents_low_res = latents
|
| 647 |
print(f"[DEBUG] Passo 1 concluído. Shape dos latentes de baixa resolução: {latents_low_res.shape}")
|
|
|
|
| 648 |
|
| 649 |
+
del result, single_pass_kwargs
|
| 650 |
gc.collect()
|
| 651 |
if self.device == "cuda": torch.cuda.empty_cache()
|
| 652 |
|