EuuIia commited on
Commit
53be96b
·
verified ·
1 Parent(s): 0d469b1

Update api/ltx_server.py

Browse files
Files changed (1) hide show
  1. api/ltx_server.py +53 -69
api/ltx_server.py CHANGED
@@ -769,6 +769,8 @@ class VideoService:
769
  print("[DEBUG] EXCEÇÃO NA GERAÇÃO:")
770
  print("".join(traceback.format_exception(type(e), e, e.__traceback__)))
771
  raise
 
 
772
  # ltx_server.py
773
 
774
  def generate(
@@ -789,7 +791,7 @@ class VideoService:
789
  frames_to_use=9,
790
  seed=42,
791
  randomize_seed=True,
792
- guidance_scale=3.0,
793
  improve_texture=True,
794
  progress_callback=None,
795
  external_decode=True,
@@ -846,16 +848,16 @@ class VideoService:
846
  "output_type": "latent",
847
  "conditioning_items": conditioning_items if conditioning_items else None,
848
  "media_items": None,
849
- "decode_timestep": self.config["decode_timestep"],
850
- "decode_noise_scale": self.config["decode_noise_scale"],
851
- "stochastic_sampling": self.config["stochastic_sampling"],
852
- "image_cond_noise_scale": 0.01,
853
  "is_video": True,
854
- "vae_per_channel_normalize": True,
855
- "mixed_precision": (self.config["precision"] == "mixed_precision"),
856
  "offload_to_cpu": False,
857
  "enhance_prompt": False,
858
- "skip_layer_strategy": SkipLayerStrategy.AttentionValues,
859
  }
860
  print(f"[DEBUG] output_type={call_kwargs['output_type']} skip_layer_strategy={call_kwargs['skip_layer_strategy']}")
861
 
@@ -884,32 +886,29 @@ class VideoService:
884
 
885
  first_pass_args = self.config.get("first_pass", {}).copy()
886
  first_pass_kwargs = call_kwargs.copy()
 
887
  first_pass_kwargs.update({
888
- "guidance_scale": float(guidance_scale),
889
  "stg_scale": first_pass_args.get("stg_scale"),
890
  "rescaling_scale": first_pass_args.get("rescaling_scale"),
891
  "skip_block_list": first_pass_args.get("skip_block_list"),
 
 
892
  })
893
- schedule = first_pass_args.get("timesteps") or first_pass_args.get("guidance_timesteps")
894
- if schedule:
895
- first_pass_kwargs["timesteps"] = schedule
896
- first_pass_kwargs["guidance_timesteps"] = schedule
897
 
898
  downscale_factor = self.config.get("downscale_factor", 2)
899
  original_height = first_pass_kwargs["height"]
900
  original_width = first_pass_kwargs["width"]
901
  divisor = 24
902
-
903
  target_height_p1 = original_height // downscale_factor
904
  height_p1 = round(target_height_p1 / divisor) * divisor
905
  if height_p1 == 0: height_p1 = divisor
906
  first_pass_kwargs["height"] = height_p1
907
-
908
  target_width_p1 = original_width // downscale_factor
909
  width_p1 = round(target_width_p1 / divisor) * divisor
910
  if width_p1 == 0: width_p1 = divisor
911
  first_pass_kwargs["width"] = width_p1
912
-
913
  print(f"[DEBUG] Passo 1: Dimensões reduzidas e ajustadas para {height_p1}x{width_p1}")
914
 
915
  with ctx:
@@ -937,43 +936,23 @@ class VideoService:
937
  second_pass_args = self.config.get("second_pass", {}).copy()
938
  second_pass_kwargs = call_kwargs.copy()
939
 
940
- height_p2 = height_p1 * 2
941
- width_p2 = width_p1 * 2
942
- second_pass_kwargs["height"] = height_p2
943
- second_pass_kwargs["width"] = width_p2
944
- print(f"[DEBUG] Passo 2: Dimensões definidas para {height_p2}x{width_p2} para corresponder ao upscale.")
945
-
946
  second_pass_kwargs.update({
947
- "guidance_scale": float(guidance_scale),
948
  "stg_scale": second_pass_args.get("stg_scale"),
949
  "rescaling_scale": second_pass_args.get("rescaling_scale"),
950
  "skip_block_list": second_pass_args.get("skip_block_list"),
 
 
951
  })
 
952
 
953
- schedule_p2 = second_pass_args.get("timesteps") or second_pass_args.get("guidance_timesteps")
954
- if schedule_p2:
955
- timesteps_para_refinamento = schedule_p2
956
- print(f"[DEBUG] Passo 2: Usando {len(timesteps_para_refinamento)} timesteps pré-definidos do config para refinamento.")
957
- else:
958
- strength_p2 = second_pass_args.get("strength", second_pass_args.get("denoising_strength", 0.4))
959
- num_steps_passo2_total = second_pass_args.get("num_inference_steps", 20)
960
-
961
- self.pipeline.scheduler.set_timesteps(num_steps_passo2_total, device=self.device)
962
- todos_os_timesteps_p2 = self.pipeline.scheduler.timesteps
963
-
964
- ponto_de_corte = int(len(todos_os_timesteps_p2) * (1.0 - strength_p2))
965
- timesteps_para_refinamento = todos_os_timesteps_p2[ponto_de_corte:]
966
- print(f"[DEBUG] Passo 2: Calculando {len(timesteps_para_refinamento)} timesteps manuais (strength ≈ {strength_p2})")
967
-
968
- second_pass_kwargs["timesteps"] = timesteps_para_refinamento
969
- if "strength" in second_pass_kwargs: del second_pass_kwargs["strength"]
970
-
971
- second_pass_kwargs["latents"] = latents_high_res
972
 
973
- num_timesteps_p2 = len(timesteps_para_refinamento)
974
- if 'guidance_mapping' not in second_pass_kwargs:
975
- second_pass_kwargs['guidance_mapping'] = list(range(num_timesteps_p2))
976
- print(f"[DEBUG] Passo 2: Injetando 'guidance_mapping' de identidade com {num_timesteps_p2} passos.")
977
 
978
  with ctx:
979
  second_pass_result = self.pipeline(**second_pass_kwargs)
@@ -984,20 +963,16 @@ class VideoService:
984
  else:
985
  # --- PASSO ÚNICO (SINGLE-PASS) ---
986
  single_pass_kwargs = call_kwargs.copy()
987
- first_pass_config = self.config.get("first_pass", {})
988
  single_pass_kwargs.update({
989
- "guidance_scale": float(guidance_scale),
990
- "stg_scale": first_pass_config.get("stg_scale"),
991
- "rescaling_scale": first_pass_config.get("rescaling_scale"),
992
- "skip_block_list": first_pass_config.get("skip_block_list"),
 
 
 
993
  })
994
- schedule = first_pass_config.get("timesteps") or first_pass_config.get("guidance_timesteps")
995
- if mode == "video-to-video":
996
- schedule = [0.7]; print("[INFO] Modo video-to-video (etapa única): timesteps=[0.7]")
997
- if isinstance(schedule, (list, tuple)) and len(schedule) > 0:
998
- single_pass_kwargs["timesteps"] = schedule
999
- single_pass_kwargs["guidance_timesteps"] = schedule
1000
- print(f"[DEBUG] Single-pass: timesteps_len={len(schedule) if schedule else 0}")
1001
 
1002
  print("\n[INFO] Executando pipeline de etapa única...")
1003
  with ctx:
@@ -1012,22 +987,28 @@ class VideoService:
1012
  torch.cuda.empty_cache()
1013
  try: torch.cuda.ipc_collect()
1014
  except Exception: pass
1015
-
1016
- lat_a, lat_b = self._dividir_latentes(latents_cpu)
1017
- lat_a1, lat_a2 = self._dividir_latentes(lat_a)
1018
- lat_b1, lat_b2 = self._dividir_latentes(lat_b)
1019
 
1020
- latents_parts = [lat_a1, lat_a2, lat_b1, lat_b2]
 
 
 
 
 
 
 
 
1021
 
 
 
 
 
1022
  temp_dir = tempfile.mkdtemp(prefix="ltxv_"); self._register_tmp_dir(temp_dir)
1023
  results_dir = "/app/output"; os.makedirs(results_dir, exist_ok=True)
1024
-
1025
  partes_mp4 = []
1026
  par = 0
1027
 
1028
  for part in latents_parts:
1029
  par += 1
1030
- if part is None: continue
1031
  print(f"[DEBUG] Partição {par}: {tuple(part.shape)}")
1032
  output_video_path = os.path.join(temp_dir, f"output_{used_seed}_{par}.mp4")
1033
 
@@ -1074,10 +1055,12 @@ class VideoService:
1074
  print("".join(traceback.format_exception(type(e), e, e.__traceback__)))
1075
  raise
1076
  finally:
1077
- # Limpeza de variáveis para liberar memória
1078
- try: del latents, latents_low_res, latents_high_res, second_pass_result
1079
- except NameError: pass
1080
- except Exception as e: print(f"[DEBUG] Erro na limpeza de variáveis: {e}")
 
 
1081
 
1082
  gc.collect()
1083
  if self.device == "cuda":
@@ -1092,5 +1075,6 @@ class VideoService:
1092
  except Exception as e:
1093
  print(f"[DEBUG] finalize() no finally falhou: {e}")
1094
 
 
1095
  print("Criando instância do VideoService. O carregamento do modelo começará agora...")
1096
  video_generation_service = VideoService()
 
769
  print("[DEBUG] EXCEÇÃO NA GERAÇÃO:")
770
  print("".join(traceback.format_exception(type(e), e, e.__traceback__)))
771
  raise
772
+
773
+
774
  # ltx_server.py
775
 
776
  def generate(
 
791
  frames_to_use=9,
792
  seed=42,
793
  randomize_seed=True,
794
+ guidance_scale=3.0, # Valor de referência/fallback
795
  improve_texture=True,
796
  progress_callback=None,
797
  external_decode=True,
 
848
  "output_type": "latent",
849
  "conditioning_items": conditioning_items if conditioning_items else None,
850
  "media_items": None,
851
+ "decode_timestep": self.config.get("decode_timestep"),
852
+ "decode_noise_scale": self.config.get("decode_noise_scale"),
853
+ "stochastic_sampling": self.config.get("stochastic_sampling"),
854
+ "image_cond_noise_scale": self.config.get("image_cond_noise_scale", 0.01),
855
  "is_video": True,
856
+ "vae_per_channel_normalize": self.config.get("vae_per_channel_normalize", True),
857
+ "mixed_precision": (self.config.get("precision") == "mixed_precision"),
858
  "offload_to_cpu": False,
859
  "enhance_prompt": False,
860
+ "skip_layer_strategy": SkipLayerStrategy[self.config.get("stg_mode", "AttentionValues")],
861
  }
862
  print(f"[DEBUG] output_type={call_kwargs['output_type']} skip_layer_strategy={call_kwargs['skip_layer_strategy']}")
863
 
 
886
 
887
  first_pass_args = self.config.get("first_pass", {}).copy()
888
  first_pass_kwargs = call_kwargs.copy()
889
+
890
  first_pass_kwargs.update({
891
+ "guidance_scale": first_pass_args.get("guidance_scale", guidance_scale),
892
  "stg_scale": first_pass_args.get("stg_scale"),
893
  "rescaling_scale": first_pass_args.get("rescaling_scale"),
894
  "skip_block_list": first_pass_args.get("skip_block_list"),
895
+ "guidance_timesteps": first_pass_args.get("guidance_timesteps"),
896
+ "timesteps": first_pass_args.get("timesteps")
897
  })
898
+ print(f"[DEBUG] Passo 1: Parâmetros do config carregados: guidance_scale={first_pass_kwargs['guidance_scale']}, stg_scale={first_pass_kwargs['stg_scale']}")
 
 
 
899
 
900
  downscale_factor = self.config.get("downscale_factor", 2)
901
  original_height = first_pass_kwargs["height"]
902
  original_width = first_pass_kwargs["width"]
903
  divisor = 24
 
904
  target_height_p1 = original_height // downscale_factor
905
  height_p1 = round(target_height_p1 / divisor) * divisor
906
  if height_p1 == 0: height_p1 = divisor
907
  first_pass_kwargs["height"] = height_p1
 
908
  target_width_p1 = original_width // downscale_factor
909
  width_p1 = round(target_width_p1 / divisor) * divisor
910
  if width_p1 == 0: width_p1 = divisor
911
  first_pass_kwargs["width"] = width_p1
 
912
  print(f"[DEBUG] Passo 1: Dimensões reduzidas e ajustadas para {height_p1}x{width_p1}")
913
 
914
  with ctx:
 
936
  second_pass_args = self.config.get("second_pass", {}).copy()
937
  second_pass_kwargs = call_kwargs.copy()
938
 
 
 
 
 
 
 
939
  second_pass_kwargs.update({
940
+ "guidance_scale": second_pass_args.get("guidance_scale", guidance_scale),
941
  "stg_scale": second_pass_args.get("stg_scale"),
942
  "rescaling_scale": second_pass_args.get("rescaling_scale"),
943
  "skip_block_list": second_pass_args.get("skip_block_list"),
944
+ "guidance_timesteps": second_pass_args.get("guidance_timesteps"),
945
+ "timesteps": second_pass_args.get("timesteps")
946
  })
947
+ print(f"[DEBUG] Passo 2: Parâmetros do config carregados: guidance_scale={second_pass_kwargs['guidance_scale']}, stg_scale={second_pass_kwargs['stg_scale']}")
948
 
949
+ height_p2 = height_p1 * 2
950
+ width_p2 = width_p1 * 2
951
+ second_pass_kwargs["height"] = height_p2
952
+ second_pass_kwargs["width"] = width_p2
953
+ print(f"[DEBUG] Passo 2: Dimensões definidas para {height_p2}x{width_p2}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
954
 
955
+ second_pass_kwargs["latents"] = latents_high_res
 
 
 
956
 
957
  with ctx:
958
  second_pass_result = self.pipeline(**second_pass_kwargs)
 
963
  else:
964
  # --- PASSO ÚNICO (SINGLE-PASS) ---
965
  single_pass_kwargs = call_kwargs.copy()
966
+
967
  single_pass_kwargs.update({
968
+ "guidance_scale": self.config.get("guidance_scale", guidance_scale),
969
+ "stg_scale": self.config.get("stg_scale"),
970
+ "rescaling_scale": self.config.get("rescaling_scale"),
971
+ "skip_block_list": self.config.get("skip_block_list"),
972
+ "guidance_timesteps": self.config.get("guidance_timesteps"),
973
+ "timesteps": self.config.get("timesteps"),
974
+ "num_inference_steps": self.config.get("num_inference_steps", 20)
975
  })
 
 
 
 
 
 
 
976
 
977
  print("\n[INFO] Executando pipeline de etapa única...")
978
  with ctx:
 
987
  torch.cuda.empty_cache()
988
  try: torch.cuda.ipc_collect()
989
  except Exception: pass
 
 
 
 
990
 
991
+ lat_a, lat_b = self._dividir_latentes(latents_cpu)
992
+ if lat_a is not None:
993
+ lat_a1, lat_a2 = self._dividir_latentes(lat_a)
994
+ else:
995
+ lat_a1, lat_a2 = None, None
996
+ if lat_b is not None:
997
+ lat_b1, lat_b2 = self._dividir_latentes(lat_b)
998
+ else:
999
+ lat_b1, lat_b2 = None, None
1000
 
1001
+ latents_parts = [p for p in [lat_a1, lat_a2, lat_b1, lat_b2] if p is not None]
1002
+ if not latents_parts:
1003
+ latents_parts = [latents_cpu]
1004
+
1005
  temp_dir = tempfile.mkdtemp(prefix="ltxv_"); self._register_tmp_dir(temp_dir)
1006
  results_dir = "/app/output"; os.makedirs(results_dir, exist_ok=True)
 
1007
  partes_mp4 = []
1008
  par = 0
1009
 
1010
  for part in latents_parts:
1011
  par += 1
 
1012
  print(f"[DEBUG] Partição {par}: {tuple(part.shape)}")
1013
  output_video_path = os.path.join(temp_dir, f"output_{used_seed}_{par}.mp4")
1014
 
 
1055
  print("".join(traceback.format_exception(type(e), e, e.__traceback__)))
1056
  raise
1057
  finally:
1058
+ try:
1059
+ del latents, latents_low_res, latents_high_res, second_pass_result, first_pass_result, result
1060
+ except NameError:
1061
+ pass
1062
+ except Exception as e:
1063
+ print(f"[DEBUG] Erro na limpeza de variáveis: {e}")
1064
 
1065
  gc.collect()
1066
  if self.device == "cuda":
 
1075
  except Exception as e:
1076
  print(f"[DEBUG] finalize() no finally falhou: {e}")
1077
 
1078
+
1079
  print("Criando instância do VideoService. O carregamento do modelo começará agora...")
1080
  video_generation_service = VideoService()