caarleexx commited on
Commit
c2679a7
·
verified ·
1 Parent(s): c4adc61

Update api/ltx_server_refactored.py

Browse files
Files changed (1) hide show
  1. api/ltx_server_refactored.py +111 -110
api/ltx_server_refactored.py CHANGED
@@ -452,128 +452,129 @@ class VideoService:
452
  return final_video_path, final_latents_path, used_seed
453
 
454
 
455
- # Em ltx_server_refactored.py, dentro da classe VideoService
456
-
457
- def apply_secondary_refinement(
458
- self,
459
- latents_path: str,
460
- prompt: str,
461
- negative_prompt: str,
462
- guidance_scale: float,
463
- seed: int,
464
- num_decode_chunks_per_worker: int = 2
465
- ) -> Tuple[str, str]:
466
- """
467
- Orquestra o pipeline de Pós-Produção: Upscale, Denoise em Chunks, e Costura final.
468
- Gerencia o estado da GPU explicitamente para cada etapa.
469
- """
470
- print("\n======================================================================")
471
- print("====== [INFO] Iniciando Pós-Produção: Refinamento em Chunks e Costura Final ======")
472
- print("======================================================================\n")
473
-
474
- temp_dir_orchestrator = tempfile.mkdtemp(prefix="refine_orchestrator_")
475
- self._register_tmp_dir(temp_dir_orchestrator)
476
-
477
- # --- ETAPA 1: Upscale Espacial do Tensor Completo ---
478
- print("[LOG] Etapa 1: Aplicando Upscale Espacial nos latentes de baixa resolução...")
479
 
480
- # --- Gerenciamento de VRAM para a Etapa de Upscale ---
481
- # Descarrega o Transformer (se a otimização estiver ativa) para dar espaço.
482
- if ENABLE_MEMORY_OPTIMIZATION:
483
- if next(self.pipeline.transformer.parameters()).is_cuda:
484
- self.pipeline.transformer.to('cpu')
485
- print(" [VRAM Manager] Transformer movido para a CPU para a etapa de Upscale.")
 
 
 
 
 
 
 
 
 
 
486
 
487
- # Garante que os modelos necessários para o upscale (VAE e Upsampler) estejam na GPU.
488
- if not next(self.pipeline.vae.parameters()).is_cuda:
489
- self.pipeline.vae.to(self.device)
490
- print(" [VRAM Manager] VAE movido para a GPU para a etapa de Upscale.")
491
- if self.latent_upsampler and not next(self.latent_upsampler.parameters()).is_cuda:
492
- self.latent_upsampler.to(self.device)
493
- torch.cuda.empty_cache()
494
- # --- Fim do Gerenciamento de VRAM ---
495
 
496
- low_res_latents = torch.load(latents_path)
497
- with torch.no_grad(), torch.autocast(device_type=self.device.split(':')[0], dtype=self.runtime_autocast_dtype, enabled=(self.device == 'cuda')):
498
- # Agora o VAE e o latents estarão ambos na GPU
499
- latents_hd_upscaled = self._upsample_and_filter_latents(low_res_latents.to(self.device))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
500
 
501
- latents_hd_upscaled_cpu = latents_hd_upscaled.cpu()
502
- print(f" [LOG] Upscale concluído. Novo shape de latents HD: {latents_hd_upscaled_cpu.shape}")
503
- del latents_hd_upscaled, low_res_latents
504
- torch.cuda.empty_cache()
505
-
506
- # --- ETAPA 2: Fragmentar, Processar em Chunks e Coletar Tensores ---
507
- print("\n[LOG] Etapa 2: Fragmentando e processando cada chunk para obter tensores de pixels e latentes...")
508
- total_latents = latents_hd_upscaled_cpu.shape[2]
509
- sobreposicao = 2
510
- num_divisoes = 3
511
- tamanho_base = (total_latents - 1) // num_divisoes
 
 
 
 
 
 
 
 
512
 
513
- if tamanho_base < sobreposicao:
514
- raise ValueError("Latentes muito curtos para dividir em 3. Use o refinamento direto ou reduza o número de chunks.")
 
 
 
515
 
516
- pontos_de_corte = [
517
- (0, tamanho_base + sobreposicao),
518
- (tamanho_base - sobreposicao, (2 * tamanho_base) + sobreposicao),
519
- ((2 * tamanho_base) - sobreposicao, total_latents)
520
- ]
521
- hd_chunks_to_process = [latents_hd_upscaled_cpu[:, :, s:e, :, :] for s, e in pontos_de_corte]
 
 
 
 
 
522
 
523
- pixel_chunks_list = []
524
- refined_latent_chunks_list = []
525
-
526
- for i, chunk in enumerate(hd_chunks_to_process):
527
- print(f"\n --> Processando o Chunk {i+1}/{len(hd_chunks_to_process)}...")
528
- chunk_path = os.path.join(temp_dir_orchestrator, f"hd_chunk_to_process_{i}.pt")
529
- torch.save(chunk, chunk_path)
530
- chunk_seed = seed + i + 1
531
-
532
- # A chamada a `refine_texture_only` internamente chamará `_set_generation_environment`,
533
- # trazendo o Transformer de volta para a GPU e (se otimizado) movendo o VAE para a CPU.
534
- pixel_chunk, refined_latent_chunk = self.refine_texture_only(
535
- latents_path=chunk_path,
536
- prompt=prompt, negative_prompt=negative_prompt,
537
- guidance_scale=guidance_scale, seed=chunk_seed,
538
- num_decode_chunks=num_decode_chunks_per_worker
539
  )
540
- pixel_chunks_list.append(pixel_chunk)
541
- refined_latent_chunks_list.append(refined_latent_chunk)
542
- print(f" --> Tensores do Chunk {i+1} recebidos.")
543
-
544
- # --- ETAPA 3: Costurar os Tensores (Pixels e Latentes) ---
545
- print("\n[LOG] Etapa 3: Costurando os tensores de pixels e latentes...")
546
 
547
- final_pixel_tensor = self._stitch_chunks(
548
- chunks_list=pixel_chunks_list, num_divisoes=num_divisoes,
549
- total_original_items=total_latents, sobreposicao_items=sobreposicao,
550
- item_multiplier=8, domain_name="Pixels (Final)"
551
- )
552
-
553
- final_latents_hd = self._stitch_chunks(
554
- chunks_list=refined_latent_chunks_list, num_divisoes=num_divisoes,
555
- total_original_items=total_latents, sobreposicao_items=sobreposicao,
556
- item_multiplier=1, domain_name="Latentes (Final)"
557
- )
558
-
559
- # --- ETAPA 4: Salvar os Artefatos Finais ---
560
- print("\n[LOG] Etapa 4: Salvando o vídeo MP4 e o tensor de latentes finais...")
561
 
562
- final_video_path = self._save_video_from_tensor(
563
- final_pixel_tensor, f"final_progressive_stitched_{seed}",
564
- seed, temp_dir_orchestrator
565
- )
566
- final_latents_path = self._save_latents_to_disk(
567
- final_latents_hd, f"final_hd_stitched_{seed}",
568
- seed
569
- )
 
 
 
 
 
 
 
 
 
570
 
571
- # Limpeza final
572
- self._finalize()
573
 
574
- print(f"\n[SUCCESS] Pós-Produção completa! Vídeo final: {final_video_path}")
575
- return final_video_path, final_latents_path
576
-
577
  def apply_secondary_refinement2(
578
  self,
579
  latents_path: str,
 
452
  return final_video_path, final_latents_path, used_seed
453
 
454
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
455
 
456
+ def apply_secondary_refinement(
457
+ self,
458
+ latents_path: str,
459
+ prompt: str,
460
+ negative_prompt: str,
461
+ guidance_scale: float,
462
+ seed: int,
463
+ num_decode_chunks_per_worker: int = 2
464
+ ) -> Tuple[str, str]:
465
+ """
466
+ Orquestra o pipeline de Pós-Produção: Upscale, Denoise em Chunks, e Costura final.
467
+ Gerencia o estado da GPU explicitamente para cada etapa.
468
+ """
469
+ print("\n======================================================================")
470
+ print("====== [INFO] Iniciando Pós-Produção: Refinamento em Chunks e Costura Final ======")
471
+ print("======================================================================\n")
472
 
473
+ temp_dir_orchestrator = tempfile.mkdtemp(prefix="refine_orchestrator_")
474
+ self._register_tmp_dir(temp_dir_orchestrator)
 
 
 
 
 
 
475
 
476
+ # --- ETAPA 1: Upscale Espacial do Tensor Completo ---
477
+ print("[LOG] Etapa 1: Aplicando Upscale Espacial nos latentes de baixa resolução...")
478
+
479
+ # --- Gerenciamento de VRAM para a Etapa de Upscale ---
480
+ # Descarrega o Transformer (se a otimização estiver ativa) para dar espaço.
481
+ if ENABLE_MEMORY_OPTIMIZATION:
482
+ if next(self.pipeline.transformer.parameters()).is_cuda:
483
+ self.pipeline.transformer.to('cpu')
484
+ print(" [VRAM Manager] Transformer movido para a CPU para a etapa de Upscale.")
485
+
486
+ # Garante que os modelos necessários para o upscale (VAE e Upsampler) estejam na GPU.
487
+ if not next(self.pipeline.vae.parameters()).is_cuda:
488
+ self.pipeline.vae.to(self.device)
489
+ print(" [VRAM Manager] VAE movido para a GPU para a etapa de Upscale.")
490
+ if self.latent_upsampler and not next(self.latent_upsampler.parameters()).is_cuda:
491
+ self.latent_upsampler.to(self.device)
492
+ torch.cuda.empty_cache()
493
+ # --- Fim do Gerenciamento de VRAM ---
494
+
495
+ low_res_latents = torch.load(latents_path)
496
+ with torch.no_grad(), torch.autocast(device_type=self.device.split(':')[0], dtype=self.runtime_autocast_dtype, enabled=(self.device == 'cuda')):
497
+ # Agora o VAE e o latents estarão ambos na GPU
498
+ latents_hd_upscaled = self._upsample_and_filter_latents(low_res_latents.to(self.device))
499
+
500
+ latents_hd_upscaled_cpu = latents_hd_upscaled.cpu()
501
+ print(f" [LOG] Upscale concluído. Novo shape de latents HD: {latents_hd_upscaled_cpu.shape}")
502
+ del latents_hd_upscaled, low_res_latents
503
+ torch.cuda.empty_cache()
504
 
505
+ # --- ETAPA 2: Fragmentar, Processar em Chunks e Coletar Tensores ---
506
+ print("\n[LOG] Etapa 2: Fragmentando e processando cada chunk para obter tensores de pixels e latentes...")
507
+ total_latents = latents_hd_upscaled_cpu.shape[2]
508
+ sobreposicao = 2
509
+ num_divisoes = 3
510
+ tamanho_base = (total_latents - 1) // num_divisoes
511
+
512
+ if tamanho_base < sobreposicao:
513
+ raise ValueError("Latentes muito curtos para dividir em 3. Use o refinamento direto ou reduza o número de chunks.")
514
+
515
+ pontos_de_corte = [
516
+ (0, tamanho_base + sobreposicao),
517
+ (tamanho_base - sobreposicao, (2 * tamanho_base) + sobreposicao),
518
+ ((2 * tamanho_base) - sobreposicao, total_latents)
519
+ ]
520
+ hd_chunks_to_process = [latents_hd_upscaled_cpu[:, :, s:e, :, :] for s, e in pontos_de_corte]
521
+
522
+ pixel_chunks_list = []
523
+ refined_latent_chunks_list = []
524
 
525
+ for i, chunk in enumerate(hd_chunks_to_process):
526
+ print(f"\n --> Processando o Chunk {i+1}/{len(hd_chunks_to_process)}...")
527
+ chunk_path = os.path.join(temp_dir_orchestrator, f"hd_chunk_to_process_{i}.pt")
528
+ torch.save(chunk, chunk_path)
529
+ chunk_seed = seed + i + 1
530
 
531
+ # A chamada a `refine_texture_only` internamente chamará `_set_generation_environment`,
532
+ # trazendo o Transformer de volta para a GPU e (se otimizado) movendo o VAE para a CPU.
533
+ pixel_chunk, refined_latent_chunk = self.refine_texture_only(
534
+ latents_path=chunk_path,
535
+ prompt=prompt, negative_prompt=negative_prompt,
536
+ guidance_scale=guidance_scale, seed=chunk_seed,
537
+ num_decode_chunks=num_decode_chunks_per_worker
538
+ )
539
+ pixel_chunks_list.append(pixel_chunk)
540
+ refined_latent_chunks_list.append(refined_latent_chunk)
541
+ print(f" --> Tensores do Chunk {i+1} recebidos.")
542
 
543
+ # --- ETAPA 3: Costurar os Tensores (Pixels e Latentes) ---
544
+ print("\n[LOG] Etapa 3: Costurando os tensores de pixels e latentes...")
545
+
546
+ final_pixel_tensor = self._stitch_chunks(
547
+ chunks_list=pixel_chunks_list, num_divisoes=num_divisoes,
548
+ total_original_items=total_latents, sobreposicao_items=sobreposicao,
549
+ item_multiplier=8, domain_name="Pixels (Final)"
 
 
 
 
 
 
 
 
 
550
  )
 
 
 
 
 
 
551
 
552
+ final_latents_hd = self._stitch_chunks(
553
+ chunks_list=refined_latent_chunks_list, num_divisoes=num_divisoes,
554
+ total_original_items=total_latents, sobreposicao_items=sobreposicao,
555
+ item_multiplier=1, domain_name="Latentes (Final)"
556
+ )
 
 
 
 
 
 
 
 
 
557
 
558
+ # --- ETAPA 4: Salvar os Artefatos Finais ---
559
+ print("\n[LOG] Etapa 4: Salvando o vídeo MP4 e o tensor de latentes finais...")
560
+
561
+ final_video_path = self._save_video_from_tensor(
562
+ final_pixel_tensor, f"final_progressive_stitched_{seed}",
563
+ seed, temp_dir_orchestrator
564
+ )
565
+ final_latents_path = self._save_latents_to_disk(
566
+ final_latents_hd, f"final_hd_stitched_{seed}",
567
+ seed
568
+ )
569
+
570
+ # Limpeza final
571
+ self._finalize()
572
+
573
+ print(f"\n[SUCCESS] Pós-Produção completa! Vídeo final: {final_video_path}")
574
+ return final_video_path, final_latents_path
575
 
 
 
576
 
577
+
 
 
578
  def apply_secondary_refinement2(
579
  self,
580
  latents_path: str,