Spaces:
Paused
Paused
Update api/ltx_server_refactored.py
Browse files- api/ltx_server_refactored.py +12 -86
api/ltx_server_refactored.py
CHANGED
|
@@ -272,71 +272,6 @@ class VideoService:
|
|
| 272 |
# ==============================================================================
|
| 273 |
# --- FUNÇÕES DE GERAÇÃO ATUALIZADAS E MODULARES ---
|
| 274 |
# ==============================================================================
|
| 275 |
-
|
| 276 |
-
def _generate_single_chunk_low(
|
| 277 |
-
self, prompt, negative_prompt,
|
| 278 |
-
height, width, num_frames,
|
| 279 |
-
seed, ltx_configs_override=None):
|
| 280 |
-
"""
|
| 281 |
-
[NÓ DE GERAÇÃO] Gera um ÚNICO chunk de latentes brutos.
|
| 282 |
-
"""
|
| 283 |
-
print("\n" + "-"*20 + " INÍCIO: _generate_single_chunk_low " + "-"*20)
|
| 284 |
-
try:
|
| 285 |
-
height_padded = ((height - 1) // 8 + 1) * 8
|
| 286 |
-
width_padded = ((width - 1) // 8 + 1) * 8
|
| 287 |
-
generator = torch.Generator(device=self.device).manual_seed(seed)
|
| 288 |
-
downscale_factor = self.config.get("downscale_factor", 0.6666666)
|
| 289 |
-
vae_scale_factor = self.pipeline.vae_scale_factor
|
| 290 |
-
x_width = int(width_padded * downscale_factor)
|
| 291 |
-
downscaled_width = x_width - (x_width % vae_scale_factor)
|
| 292 |
-
x_height = int(height_padded * downscale_factor)
|
| 293 |
-
downscaled_height = x_height - (x_height % vae_scale_factor)
|
| 294 |
-
|
| 295 |
-
all_conditions = ltx_configs_override.get("conditioning_items", [])
|
| 296 |
-
pipeline_kwargs = self.config.get("first_pass", {}).copy()
|
| 297 |
-
if ltx_configs_override:
|
| 298 |
-
print("[DEBUG] Sobrepondo configurações do LTX com valores da UI...")
|
| 299 |
-
preset = ltx_configs_override.get("guidance_preset")
|
| 300 |
-
if preset == "Customizado":
|
| 301 |
-
try:
|
| 302 |
-
pipeline_kwargs["guidance_scale"] = json.loads(ltx_configs_override["guidance_scale_list"])
|
| 303 |
-
pipeline_kwargs["stg_scale"] = json.loads(ltx_configs_override["stg_scale_list"])
|
| 304 |
-
pipeline_kwargs["guidance_timesteps"] = json.loads(ltx_configs_override["timesteps_list"])
|
| 305 |
-
except Exception as e:
|
| 306 |
-
print(f" > ERRO ao parsear valores customizados: {e}. Usando Padrão.")
|
| 307 |
-
elif preset == "Agressivo":
|
| 308 |
-
pipeline_kwargs["guidance_scale"] = [1, 2, 8, 12, 8, 2, 1]
|
| 309 |
-
pipeline_kwargs["stg_scale"] = [0, 0, 5, 6, 5, 3, 2]
|
| 310 |
-
elif preset == "Suave":
|
| 311 |
-
pipeline_kwargs["guidance_scale"] = [1, 1, 4, 5, 4, 1, 1]
|
| 312 |
-
pipeline_kwargs["stg_scale"] = [0, 0, 2, 2, 2, 1, 0]
|
| 313 |
-
|
| 314 |
-
pipeline_kwargs["num_inference_steps"] = ltx_configs_override.get("fp_num_inference_steps", pipeline_kwargs.get("num_inference_steps"))
|
| 315 |
-
pipeline_kwargs["skip_initial_inference_steps"] = ltx_configs_override.get("ship_initial_inference_steps", pipeline_kwargs.get("skip_initial_inference_steps"))
|
| 316 |
-
pipeline_kwargs["skip_final_inference_steps"] = ltx_configs_override.get("ship_final_inference_steps", pipeline_kwargs.get("skip_final_inference_steps"))
|
| 317 |
-
|
| 318 |
-
pipeline_kwargs.update({
|
| 319 |
-
"prompt": prompt, "negative_prompt": negative_prompt, "height": downscaled_height, "width": downscaled_width,
|
| 320 |
-
"num_frames": num_frames, "frame_rate": 24, "generator": generator, "output_type": "latent",
|
| 321 |
-
"conditioning_items": all_conditions if all_conditions else None,
|
| 322 |
-
})
|
| 323 |
-
|
| 324 |
-
with torch.autocast(device_type="cuda", dtype=self.runtime_autocast_dtype, enabled=self.device.type == 'cuda'):
|
| 325 |
-
latents_bruto = self.pipeline(**pipeline_kwargs).images
|
| 326 |
-
log_tensor_info(latents_bruto, f"Latente Bruto Gerado para: '{prompt[:40]}...'")
|
| 327 |
-
|
| 328 |
-
print("-" * 20 + " FIM: _generate_single_chunk_low " + "-"*20)
|
| 329 |
-
return latents_bruto
|
| 330 |
-
|
| 331 |
-
except Exception as e:
|
| 332 |
-
print("-" * 20 + f" ERRO: _generate_single_chunk_low {e} " + "-"*20)
|
| 333 |
-
traceback.print_exc()
|
| 334 |
-
return None
|
| 335 |
-
finally:
|
| 336 |
-
torch.cuda.empty_cache()
|
| 337 |
-
torch.cuda.ipc_collect()
|
| 338 |
-
self.finalize(keep_paths=[])
|
| 339 |
-
|
| 340 |
|
| 341 |
def generate_narrative_low(
|
| 342 |
self, prompt: str, negative_prompt,
|
|
@@ -379,10 +314,6 @@ class VideoService:
|
|
| 379 |
#if eco_latents_condition_overlap: eco_current_conditions_list.append(eco_latents_condition_overlap)
|
| 380 |
#ltx_configs_override["conditioning_items"] = current_conditions
|
| 381 |
|
| 382 |
-
latentes_chunk = self.generate_low(
|
| 383 |
-
prompt, negative_prompt, height, width,
|
| 384 |
-
duration, seed, eco_current_conditions_list
|
| 385 |
-
)
|
| 386 |
|
| 387 |
video_path, tensor_path, final_seed = video_generation_service.generate_single_low(
|
| 388 |
prompt=prompt_x, negative_prompt=negative_prompt, height=height, width=width, duration=duration,
|
|
@@ -420,7 +351,6 @@ class VideoService:
|
|
| 420 |
final_latents_gpu = final_latents_cpu.to(self.device)
|
| 421 |
pixel_tensor = vae_manager_singleton.decode(final_latents_gpu, decode_timestep=float(self.config.get("decode_timestep", 0.05)))
|
| 422 |
video_path = self._save_and_log_video(pixel_tensor, "narrative_video", FPS, temp_dir, results_dir, used_seed)
|
| 423 |
-
|
| 424 |
self.finalize(keep_paths=[video_path, tensor_path])
|
| 425 |
return video_path, tensor_path, used_seed
|
| 426 |
|
|
@@ -429,11 +359,12 @@ class VideoService:
|
|
| 429 |
traceback.print_exc()
|
| 430 |
return None
|
| 431 |
finally:
|
|
|
|
| 432 |
torch.cuda.empty_cache()
|
| 433 |
torch.cuda.ipc_collect()
|
| 434 |
self.finalize(keep_paths=[])
|
| 435 |
-
|
| 436 |
-
|
| 437 |
def generate_single_low(
|
| 438 |
self, prompt: str, negative_prompt,
|
| 439 |
height, width, duration,
|
|
@@ -466,27 +397,22 @@ class VideoService:
|
|
| 466 |
print(f"ERRO FATAL: A geração do chunk único falhou. Abortando.")
|
| 467 |
self.finalize(keep_paths=[])
|
| 468 |
return None, None, None
|
| 469 |
-
|
| 470 |
-
final_latents_cpu = final_latents.cpu()
|
| 471 |
-
log_tensor_info(final_latents_cpu, "Tensor de Latentes Final (CPU)")
|
| 472 |
-
|
| 473 |
-
tensor_path = os.path.join(results_dir, f"latents_single_{used_seed}.pt")
|
| 474 |
-
torch.save(final_latents_cpu, tensor_path)
|
| 475 |
-
|
| 476 |
try:
|
| 477 |
-
|
| 478 |
-
|
| 479 |
-
|
| 480 |
-
|
| 481 |
-
|
| 482 |
-
|
|
|
|
| 483 |
return video_path, tensor_path, used_seed
|
| 484 |
-
|
| 485 |
except Exception as e:
|
| 486 |
print("-" * 20 + f" ERRO: generate_single_low {e} " + "-"*20)
|
| 487 |
traceback.print_exc()
|
| 488 |
return None
|
| 489 |
finally:
|
|
|
|
| 490 |
torch.cuda.empty_cache()
|
| 491 |
torch.cuda.ipc_collect()
|
| 492 |
self.finalize(keep_paths=[])
|
|
|
|
| 272 |
# ==============================================================================
|
| 273 |
# --- FUNÇÕES DE GERAÇÃO ATUALIZADAS E MODULARES ---
|
| 274 |
# ==============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 275 |
|
| 276 |
def generate_narrative_low(
|
| 277 |
self, prompt: str, negative_prompt,
|
|
|
|
| 314 |
#if eco_latents_condition_overlap: eco_current_conditions_list.append(eco_latents_condition_overlap)
|
| 315 |
#ltx_configs_override["conditioning_items"] = current_conditions
|
| 316 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 317 |
|
| 318 |
video_path, tensor_path, final_seed = video_generation_service.generate_single_low(
|
| 319 |
prompt=prompt_x, negative_prompt=negative_prompt, height=height, width=width, duration=duration,
|
|
|
|
| 351 |
final_latents_gpu = final_latents_cpu.to(self.device)
|
| 352 |
pixel_tensor = vae_manager_singleton.decode(final_latents_gpu, decode_timestep=float(self.config.get("decode_timestep", 0.05)))
|
| 353 |
video_path = self._save_and_log_video(pixel_tensor, "narrative_video", FPS, temp_dir, results_dir, used_seed)
|
|
|
|
| 354 |
self.finalize(keep_paths=[video_path, tensor_path])
|
| 355 |
return video_path, tensor_path, used_seed
|
| 356 |
|
|
|
|
| 359 |
traceback.print_exc()
|
| 360 |
return None
|
| 361 |
finally:
|
| 362 |
+
gc.collect()
|
| 363 |
torch.cuda.empty_cache()
|
| 364 |
torch.cuda.ipc_collect()
|
| 365 |
self.finalize(keep_paths=[])
|
| 366 |
+
|
| 367 |
+
|
| 368 |
def generate_single_low(
|
| 369 |
self, prompt: str, negative_prompt,
|
| 370 |
height, width, duration,
|
|
|
|
| 397 |
print(f"ERRO FATAL: A geração do chunk único falhou. Abortando.")
|
| 398 |
self.finalize(keep_paths=[])
|
| 399 |
return None, None, None
|
| 400 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 401 |
try:
|
| 402 |
+
pixel_tensor = vae_manager_singleton.decode(final_latents, decode_timestep=float(self.config.get("decode_timestep", 0.05)))
|
| 403 |
+
video_path = self._save_and_log_video(pixel_tensor, "single_video", FPS, temp_dir, results_dir, used_seed)
|
| 404 |
+
latents_cpu = final_latents.detach().to("cpu", non_blocking=True)
|
| 405 |
+
del pixel_tensor; gc.collect(); torch.cuda.empty_cache()
|
| 406 |
+
del final_latents; gc.collect(); torch.cuda.empty_cache()
|
| 407 |
+
tensor_path = os.path.join(results_dir, f"latents_single_{used_seed}.pt")
|
| 408 |
+
torch.save(latents_cpu, tensor_path)
|
| 409 |
return video_path, tensor_path, used_seed
|
|
|
|
| 410 |
except Exception as e:
|
| 411 |
print("-" * 20 + f" ERRO: generate_single_low {e} " + "-"*20)
|
| 412 |
traceback.print_exc()
|
| 413 |
return None
|
| 414 |
finally:
|
| 415 |
+
gc.collect()
|
| 416 |
torch.cuda.empty_cache()
|
| 417 |
torch.cuda.ipc_collect()
|
| 418 |
self.finalize(keep_paths=[])
|