Spaces:
Sleeping
Sleeping
Update ltx_worker_upscaler.py
Browse files- ltx_worker_upscaler.py +27 -18
ltx_worker_upscaler.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
| 1 |
-
|
| 2 |
# ltx_worker_upscaler.py
|
| 3 |
-
# Worker para fazer upscale
|
| 4 |
# Este arquivo é parte do projeto Euia-AducSdr e está sob a licença AGPL v3.
|
| 5 |
# Copyright (C) 4 de Agosto de 2025 Carlos Rodrigues dos Santos
|
| 6 |
|
|
@@ -15,7 +15,7 @@ import huggingface_hub
|
|
| 15 |
|
| 16 |
from inference import create_ltx_video_pipeline
|
| 17 |
from ltx_video.models.autoencoders.latent_upsampler import LatentUpsampler
|
| 18 |
-
from ltx_video.models.autoencoders.vae_encode import
|
| 19 |
|
| 20 |
class LtxUpscaler:
|
| 21 |
def __init__(self, device_id='cuda:0'):
|
|
@@ -72,28 +72,22 @@ class LtxUpscaler:
|
|
| 72 |
torch.cuda.empty_cache()
|
| 73 |
|
| 74 |
@torch.no_grad()
|
| 75 |
-
def
|
| 76 |
-
print(f"UPSCALER ({self.device}): Processando {os.path.basename(
|
| 77 |
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
video_np = np.stack(video_frames)
|
| 81 |
-
|
| 82 |
-
video_tensor = torch.from_numpy(video_np).permute(0, 3, 1, 2).float() / 255.0
|
| 83 |
-
video_tensor = (video_tensor * 2.0) - 1.0
|
| 84 |
-
video_tensor = video_tensor.unsqueeze(0).permute(0, 2, 1, 3, 4)
|
| 85 |
-
video_tensor = video_tensor.to(self.device, dtype=self.model_dtype)
|
| 86 |
|
| 87 |
-
|
| 88 |
upsampled_latents = self.latent_upsampler(latents)
|
| 89 |
|
| 90 |
-
#
|
| 91 |
-
|
|
|
|
| 92 |
decode_timestep = torch.tensor([0.0] * upsampled_latents.shape[0], device=self.device)
|
| 93 |
upsampled_video_tensor = vae_decode(
|
| 94 |
upsampled_latents, self.vae, is_video=True, timestep=decode_timestep
|
| 95 |
)
|
| 96 |
-
# --- FIM DA CORREÇÃO ---
|
| 97 |
|
| 98 |
upsampled_video_tensor = (upsampled_video_tensor.clamp(-1, 1) + 1) / 2.0
|
| 99 |
video_np_high_res = (upsampled_video_tensor[0].permute(1, 2, 3, 0).cpu().float().numpy() * 255).astype(np.uint8)
|
|
@@ -102,6 +96,21 @@ class LtxUpscaler:
|
|
| 102 |
for frame in video_np_high_res:
|
| 103 |
writer.append_data(frame)
|
| 104 |
|
| 105 |
-
print(f"UPSCALER ({self.device}): Arquivo salvo em {os.path.basename(output_path)}")
|
| 106 |
return output_path
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 107 |
#--- END OF MODIFIED FILE app_fluxContext_Ltx/ltx_worker_upscaler.py ---
|
|
|
|
| 1 |
+
#--- START OF MODIFIED FILE app_fluxContext_Ltx/ltx_worker_upscaler.py ---
|
| 2 |
# ltx_worker_upscaler.py
|
| 3 |
+
# Worker para fazer upscale de latentes de vídeo para alta resolução.
|
| 4 |
# Este arquivo é parte do projeto Euia-AducSdr e está sob a licença AGPL v3.
|
| 5 |
# Copyright (C) 4 de Agosto de 2025 Carlos Rodrigues dos Santos
|
| 6 |
|
|
|
|
| 15 |
|
| 16 |
from inference import create_ltx_video_pipeline
|
| 17 |
from ltx_video.models.autoencoders.latent_upsampler import LatentUpsampler
|
| 18 |
+
from ltx_video.models.autoencoders.vae_encode import vae_decode
|
| 19 |
|
| 20 |
class LtxUpscaler:
|
| 21 |
def __init__(self, device_id='cuda:0'):
|
|
|
|
| 72 |
torch.cuda.empty_cache()
|
| 73 |
|
| 74 |
@torch.no_grad()
|
| 75 |
+
def upscale_latents_to_video(self, latent_path: str, output_path: str, video_fps: int):
|
| 76 |
+
print(f"UPSCALER ({self.device}): Processando latentes de {os.path.basename(latent_path)}")
|
| 77 |
|
| 78 |
+
# Carrega os latentes do disco e os envia para a GPU
|
| 79 |
+
latents = torch.load(latent_path).to(self.device, dtype=self.model_dtype)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 80 |
|
| 81 |
+
# PASSO 1: Upscale Espacial (não precisamos mais de vae_encode)
|
| 82 |
upsampled_latents = self.latent_upsampler(latents)
|
| 83 |
|
| 84 |
+
# (Opcional: PASSO 2 - Upscale Temporal seria inserido aqui no futuro)
|
| 85 |
+
|
| 86 |
+
# PASSO 3: Decodificação Final
|
| 87 |
decode_timestep = torch.tensor([0.0] * upsampled_latents.shape[0], device=self.device)
|
| 88 |
upsampled_video_tensor = vae_decode(
|
| 89 |
upsampled_latents, self.vae, is_video=True, timestep=decode_timestep
|
| 90 |
)
|
|
|
|
| 91 |
|
| 92 |
upsampled_video_tensor = (upsampled_video_tensor.clamp(-1, 1) + 1) / 2.0
|
| 93 |
video_np_high_res = (upsampled_video_tensor[0].permute(1, 2, 3, 0).cpu().float().numpy() * 255).astype(np.uint8)
|
|
|
|
| 96 |
for frame in video_np_high_res:
|
| 97 |
writer.append_data(frame)
|
| 98 |
|
| 99 |
+
print(f"UPSCALER ({self.device}): Arquivo de vídeo salvo em {os.path.basename(output_path)}")
|
| 100 |
return output_path
|
| 101 |
+
|
| 102 |
+
@torch.no_grad()
|
| 103 |
+
def decode_single_latent_frame(self, latent_frame_tensor: torch.Tensor) -> Image.Image:
|
| 104 |
+
"""Decodifica um único frame latente para uma imagem PIL para o Gemini."""
|
| 105 |
+
latent_frame_tensor = latent_frame_tensor.to(self.device, dtype=self.model_dtype)
|
| 106 |
+
|
| 107 |
+
decode_timestep = torch.tensor([0.0] * latent_frame_tensor.shape[0], device=self.device)
|
| 108 |
+
decoded_tensor = vae_decode(
|
| 109 |
+
latent_frame_tensor, self.vae, is_video=True, timestep=decode_timestep
|
| 110 |
+
)
|
| 111 |
+
|
| 112 |
+
decoded_tensor = (decoded_tensor.clamp(-1, 1) + 1) / 2.0
|
| 113 |
+
# Shape: (B, C, F, H, W) -> (H, W, C)
|
| 114 |
+
numpy_image = (decoded_tensor[0].permute(2, 3, 1, 0).squeeze().cpu().float().numpy() * 255).astype(np.uint8)
|
| 115 |
+
return Image.fromarray(numpy_image)
|
| 116 |
#--- END OF MODIFIED FILE app_fluxContext_Ltx/ltx_worker_upscaler.py ---
|