Spaces:
Runtime error
Runtime error
Update deformes4D_engine.py
Browse files- deformes4D_engine.py +18 -25
deformes4D_engine.py
CHANGED
|
@@ -107,15 +107,16 @@ class Deformes4DEngine:
|
|
| 107 |
DEJAVU_FRAME_TARGET = frames_a_podar - 1 if frames_a_podar > 0 else 0
|
| 108 |
DESTINATION_FRAME_TARGET = total_frames_brutos - 1
|
| 109 |
|
|
|
|
| 110 |
base_ltx_params = {"guidance_scale": 2.0, "stg_scale": 0.025, "rescaling_scale": 0.15, "num_inference_steps": 20, "image_cond_noise_scale": 0.00}
|
|
|
|
|
|
|
| 111 |
keyframe_paths = [item[0] if isinstance(item, tuple) else item for item in keyframes]
|
| 112 |
story_history = ""
|
| 113 |
target_resolution_tuple = (video_resolution, video_resolution)
|
| 114 |
|
| 115 |
eco_latent_for_next_loop = None
|
| 116 |
dejavu_latent_for_next_loop = None
|
| 117 |
-
|
| 118 |
-
# [CORREÇÃO 1] Inicialização correta da lista
|
| 119 |
latent_fragments = []
|
| 120 |
|
| 121 |
if len(keyframe_paths) < 2:
|
|
@@ -172,11 +173,9 @@ class Deformes4DEngine:
|
|
| 172 |
|
| 173 |
latent_fragments.append(latents_video)
|
| 174 |
|
| 175 |
-
|
| 176 |
-
logger.info("--- CONCATENANDO nem TODOS OS FRAGMENTOS LATENTES ---")
|
| 177 |
tensors_para_concatenar = []
|
| 178 |
for idx, tensor_frag in enumerate(latent_fragments):
|
| 179 |
-
# Move cada tensor para o dispositivo de destino antes de adicioná-lo à lista.
|
| 180 |
target_device = self.device
|
| 181 |
tensor_on_target_device = tensor_frag.to(target_device)
|
| 182 |
if idx < len(latent_fragments) - 1:
|
|
@@ -185,24 +184,16 @@ class Deformes4DEngine:
|
|
| 185 |
tensors_para_concatenar.append(tensor_on_target_device)
|
| 186 |
|
| 187 |
processed_latents = torch.cat(tensors_para_concatenar, dim=2)
|
| 188 |
-
|
| 189 |
-
# [CORREÇÃO 2] Referência correta da variável no log
|
| 190 |
logger.info(f"Concatenação concluída. Shape final do tensor latente: {processed_latents.shape}")
|
| 191 |
|
| 192 |
if use_refiner:
|
| 193 |
-
|
| 194 |
-
|
| 195 |
-
motion_prompt="",
|
| 196 |
-
guidance_scale=1.0
|
| 197 |
-
)
|
| 198 |
|
| 199 |
-
# --- [INÍCIO DA SEÇÃO CORRIGIDA PARA EXECUÇÃO] ---
|
| 200 |
base_name = f"movie_{int(time.time())}"
|
| 201 |
-
# Define um caminho único para o vídeo que sai desta etapa, antes do HD.
|
| 202 |
intermediate_video_path = os.path.join(self.workspace_dir, f"{base_name}_intermediate.mp4")
|
| 203 |
|
| 204 |
if use_audio:
|
| 205 |
-
# A função de áudio agora salva o vídeo com áudio no caminho intermediário
|
| 206 |
intermediate_video_path = self._generate_video_and_audio_from_latents(processed_latents, global_prompt, base_name)
|
| 207 |
else:
|
| 208 |
logger.info("Etapa de sonoplastia desativada. Renderizando vídeo silencioso.")
|
|
@@ -212,13 +203,11 @@ class Deformes4DEngine:
|
|
| 212 |
|
| 213 |
del processed_latents; gc.collect(); torch.cuda.empty_cache()
|
| 214 |
|
| 215 |
-
# Define o caminho final
|
| 216 |
final_video_path = os.path.join(self.workspace_dir, f"{base_name}_FINAL.mp4")
|
| 217 |
|
| 218 |
if use_hd:
|
| 219 |
progress(0.9, desc="Masterização Final (HD)...")
|
| 220 |
try:
|
| 221 |
-
# O HD agora lê o intermediate_video_path e salva no final_video_path
|
| 222 |
hd_specialist_singleton.process_video(
|
| 223 |
input_video_path=intermediate_video_path,
|
| 224 |
output_video_path=final_video_path,
|
|
@@ -229,15 +218,12 @@ class Deformes4DEngine:
|
|
| 229 |
os.rename(intermediate_video_path, final_video_path)
|
| 230 |
else:
|
| 231 |
logger.info("Etapa de edição HD desativada.")
|
| 232 |
-
# Se o HD não for usado, o vídeo intermediário se torna o final.
|
| 233 |
os.rename(intermediate_video_path, final_video_path)
|
| 234 |
-
# --- [FIM DA SEÇÃO CORRIGIDA] ---
|
| 235 |
|
| 236 |
logger.info(f"Processo concluído! Vídeo final salvo em: {final_video_path}")
|
| 237 |
yield {"final_path": final_video_path}
|
| 238 |
|
| 239 |
def _generate_video_and_audio_from_latents(self, latent_tensor, audio_prompt, base_name):
|
| 240 |
-
# Esta função foi movida para cima, mas sua lógica interna permanece a mesma.
|
| 241 |
silent_video_path = os.path.join(self.workspace_dir, f"{base_name}_silent_for_audio.mp4")
|
| 242 |
pixel_tensor = self.latents_to_pixels(latent_tensor)
|
| 243 |
self.save_video_from_tensor(pixel_tensor, silent_video_path, fps=24)
|
|
@@ -261,7 +247,9 @@ class Deformes4DEngine:
|
|
| 261 |
os.remove(silent_video_path)
|
| 262 |
return video_with_audio_path
|
| 263 |
|
| 264 |
-
|
|
|
|
|
|
|
| 265 |
logger.info(f"Refinando tensor latente com shape {latents.shape}.")
|
| 266 |
_, _, num_latent_frames, latent_h, latent_w = latents.shape
|
| 267 |
video_scale_factor = getattr(self.vae.config, 'temporal_scale_factor', 8)
|
|
@@ -269,17 +257,22 @@ class Deformes4DEngine:
|
|
| 269 |
|
| 270 |
pixel_height = latent_h * vae_scale_factor
|
| 271 |
pixel_width = latent_w * vae_scale_factor
|
| 272 |
-
|
|
|
|
| 273 |
|
| 274 |
final_ltx_params = {
|
| 275 |
"height": pixel_height, "width": pixel_width, "video_total_frames": pixel_frames,
|
| 276 |
-
"video_fps": fps, "
|
| 277 |
-
|
| 278 |
-
"guidance_scale": kwargs.get('guidance_scale', 2.0)
|
| 279 |
}
|
| 280 |
|
| 281 |
refined_latents_tensor, _ = self.ltx_manager.refine_latents(latents, **final_ltx_params)
|
| 282 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 283 |
logger.info(f"Retornando tensor latente refinado com shape: {refined_latents_tensor.shape}")
|
| 284 |
return refined_latents_tensor
|
| 285 |
|
|
|
|
| 107 |
DEJAVU_FRAME_TARGET = frames_a_podar - 1 if frames_a_podar > 0 else 0
|
| 108 |
DESTINATION_FRAME_TARGET = total_frames_brutos - 1
|
| 109 |
|
| 110 |
+
# [MELHORIA] Centralização de todos os parâmetros da pipeline
|
| 111 |
base_ltx_params = {"guidance_scale": 2.0, "stg_scale": 0.025, "rescaling_scale": 0.15, "num_inference_steps": 20, "image_cond_noise_scale": 0.00}
|
| 112 |
+
refine_ltx_params = {"motion_prompt": "", "guidance_scale": 1.0, "denoise_strength": 0.35, "refine_steps": 12}
|
| 113 |
+
|
| 114 |
keyframe_paths = [item[0] if isinstance(item, tuple) else item for item in keyframes]
|
| 115 |
story_history = ""
|
| 116 |
target_resolution_tuple = (video_resolution, video_resolution)
|
| 117 |
|
| 118 |
eco_latent_for_next_loop = None
|
| 119 |
dejavu_latent_for_next_loop = None
|
|
|
|
|
|
|
| 120 |
latent_fragments = []
|
| 121 |
|
| 122 |
if len(keyframe_paths) < 2:
|
|
|
|
| 173 |
|
| 174 |
latent_fragments.append(latents_video)
|
| 175 |
|
| 176 |
+
logger.info("--- CONCATENANDO FRAGMENTOS LATENTES ---")
|
|
|
|
| 177 |
tensors_para_concatenar = []
|
| 178 |
for idx, tensor_frag in enumerate(latent_fragments):
|
|
|
|
| 179 |
target_device = self.device
|
| 180 |
tensor_on_target_device = tensor_frag.to(target_device)
|
| 181 |
if idx < len(latent_fragments) - 1:
|
|
|
|
| 184 |
tensors_para_concatenar.append(tensor_on_target_device)
|
| 185 |
|
| 186 |
processed_latents = torch.cat(tensors_para_concatenar, dim=2)
|
|
|
|
|
|
|
| 187 |
logger.info(f"Concatenação concluída. Shape final do tensor latente: {processed_latents.shape}")
|
| 188 |
|
| 189 |
if use_refiner:
|
| 190 |
+
# [MELHORIA] A chamada para refinar agora usa o dicionário de parâmetros centralizado
|
| 191 |
+
processed_latents = self.refine_latents(processed_latents, **refine_ltx_params)
|
|
|
|
|
|
|
|
|
|
| 192 |
|
|
|
|
| 193 |
base_name = f"movie_{int(time.time())}"
|
|
|
|
| 194 |
intermediate_video_path = os.path.join(self.workspace_dir, f"{base_name}_intermediate.mp4")
|
| 195 |
|
| 196 |
if use_audio:
|
|
|
|
| 197 |
intermediate_video_path = self._generate_video_and_audio_from_latents(processed_latents, global_prompt, base_name)
|
| 198 |
else:
|
| 199 |
logger.info("Etapa de sonoplastia desativada. Renderizando vídeo silencioso.")
|
|
|
|
| 203 |
|
| 204 |
del processed_latents; gc.collect(); torch.cuda.empty_cache()
|
| 205 |
|
|
|
|
| 206 |
final_video_path = os.path.join(self.workspace_dir, f"{base_name}_FINAL.mp4")
|
| 207 |
|
| 208 |
if use_hd:
|
| 209 |
progress(0.9, desc="Masterização Final (HD)...")
|
| 210 |
try:
|
|
|
|
| 211 |
hd_specialist_singleton.process_video(
|
| 212 |
input_video_path=intermediate_video_path,
|
| 213 |
output_video_path=final_video_path,
|
|
|
|
| 218 |
os.rename(intermediate_video_path, final_video_path)
|
| 219 |
else:
|
| 220 |
logger.info("Etapa de edição HD desativada.")
|
|
|
|
| 221 |
os.rename(intermediate_video_path, final_video_path)
|
|
|
|
| 222 |
|
| 223 |
logger.info(f"Processo concluído! Vídeo final salvo em: {final_video_path}")
|
| 224 |
yield {"final_path": final_video_path}
|
| 225 |
|
| 226 |
def _generate_video_and_audio_from_latents(self, latent_tensor, audio_prompt, base_name):
|
|
|
|
| 227 |
silent_video_path = os.path.join(self.workspace_dir, f"{base_name}_silent_for_audio.mp4")
|
| 228 |
pixel_tensor = self.latents_to_pixels(latent_tensor)
|
| 229 |
self.save_video_from_tensor(pixel_tensor, silent_video_path, fps=24)
|
|
|
|
| 247 |
os.remove(silent_video_path)
|
| 248 |
return video_with_audio_path
|
| 249 |
|
| 250 |
+
# [MELHORIA] Função de refinamento simplificada e mais robusta
|
| 251 |
+
def refine_latents(self, latents: torch.Tensor, fps: int = 24, **kwargs) -> torch.Tensor:
|
| 252 |
+
"""Invoca o LTX Pool Manager para refinar um tensor latente existente."""
|
| 253 |
logger.info(f"Refinando tensor latente com shape {latents.shape}.")
|
| 254 |
_, _, num_latent_frames, latent_h, latent_w = latents.shape
|
| 255 |
video_scale_factor = getattr(self.vae.config, 'temporal_scale_factor', 8)
|
|
|
|
| 257 |
|
| 258 |
pixel_height = latent_h * vae_scale_factor
|
| 259 |
pixel_width = latent_w * vae_scale_factor
|
| 260 |
+
# O refinamento opera sobre a duração exata do tensor latente concatenado.
|
| 261 |
+
pixel_frames = num_latent_frames * video_scale_factor
|
| 262 |
|
| 263 |
final_ltx_params = {
|
| 264 |
"height": pixel_height, "width": pixel_width, "video_total_frames": pixel_frames,
|
| 265 |
+
"video_fps": fps, "current_fragment_index": int(time.time()),
|
| 266 |
+
**kwargs # Passa todos os outros parâmetros (motion_prompt, denoise_strength, refine_steps, etc.)
|
|
|
|
| 267 |
}
|
| 268 |
|
| 269 |
refined_latents_tensor, _ = self.ltx_manager.refine_latents(latents, **final_ltx_params)
|
| 270 |
|
| 271 |
+
# [MELHORIA] Adiciona tratamento de falha de memória do refinador
|
| 272 |
+
if refined_latents_tensor is None:
|
| 273 |
+
logger.warning("O refinamento falhou (provavelmente por falta de memória). Retornando tensor original não refinado.")
|
| 274 |
+
return latents
|
| 275 |
+
|
| 276 |
logger.info(f"Retornando tensor latente refinado com shape: {refined_latents_tensor.shape}")
|
| 277 |
return refined_latents_tensor
|
| 278 |
|