Delete api/ltx_server_loader.py
Browse files- api/ltx_server_loader.py +0 -170
api/ltx_server_loader.py
DELETED
|
@@ -1,170 +0,0 @@
|
|
| 1 |
-
# ltx_server_loader.py
|
| 2 |
-
|
| 3 |
-
import os
|
| 4 |
-
import sys
|
| 5 |
-
import json
|
| 6 |
-
from pathlib import Path
|
| 7 |
-
import subprocess
|
| 8 |
-
|
| 9 |
-
import torch
|
| 10 |
-
from huggingface_hub import hf_hub_download
|
| 11 |
-
from safetensors import safe_open
|
| 12 |
-
|
| 13 |
-
# --- CONSTANTES DE SETUP ---
|
| 14 |
-
DEPS_DIR = Path("/data")
|
| 15 |
-
LTX_VIDEO_REPO_DIR = DEPS_DIR / "LTX-Video"
|
| 16 |
-
|
| 17 |
-
# --- 1. LÓGICA DE SETUP E MANIPULAÇÃO DE PATH ---
|
| 18 |
-
|
| 19 |
-
def _run_setup_script():
|
| 20 |
-
"""Executa o script setup.py se o repositório LTX-Video não existir."""
|
| 21 |
-
setup_script_path = "setup.py"
|
| 22 |
-
if not os.path.exists(setup_script_path):
|
| 23 |
-
print("[DEBUG] 'setup.py' não encontrado. Pulando clonagem de dependências.")
|
| 24 |
-
return
|
| 25 |
-
|
| 26 |
-
print(f"[DEBUG] Repositório não encontrado em {LTX_VIDEO_REPO_DIR}. Executando setup.py...")
|
| 27 |
-
try:
|
| 28 |
-
subprocess.run([sys.executable, setup_script_path], check=True, capture_output=True, text=True)
|
| 29 |
-
print("[DEBUG] Script 'setup.py' concluído com sucesso.")
|
| 30 |
-
except subprocess.CalledProcessError as e:
|
| 31 |
-
print(f"[ERROR] Falha ao executar 'setup.py' (código {e.returncode}).\nOutput:\n{e.stdout}\n{e.stderr}")
|
| 32 |
-
sys.exit(1)
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
def add_deps_to_path(repo_path: Path):
|
| 36 |
-
"""Adiciona o diretório do repositório ao sys.path."""
|
| 37 |
-
resolved_path = str(repo_path.resolve())
|
| 38 |
-
if resolved_path not in sys.path:
|
| 39 |
-
sys.path.insert(0, resolved_path)
|
| 40 |
-
|
| 41 |
-
# Executa o setup imediatamente na importação deste módulo
|
| 42 |
-
if not LTX_VIDEO_REPO_DIR.exists():
|
| 43 |
-
_run_setup_script()
|
| 44 |
-
add_deps_to_path(LTX_VIDEO_REPO_DIR)
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
# --- 2. IMPORTAÇÕES DEPENDENTES DO PATH ADICIONADO ---
|
| 48 |
-
# Agora, todas as importações "mágicas" do LTX estão isoladas aqui
|
| 49 |
-
from ltx_video.models.autoencoders.latent_upsampler import LatentUpsampler
|
| 50 |
-
from ltx_video.pipelines.pipeline_ltx_video import LTXVideoPipeline
|
| 51 |
-
from transformers import T5EncoderModel, T5Tokenizer
|
| 52 |
-
from ltx_video.models.autoencoders.causal_video_autoencoder import CausalVideoAutoencoder
|
| 53 |
-
from ltx_video.models.transformers.symmetric_patchifier import SymmetricPatchifier
|
| 54 |
-
from ltx_video.models.transformers.transformer3d import Transformer3DModel
|
| 55 |
-
from ltx_video.schedulers.rf import RectifiedFlowScheduler
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
# --- 3. FUNÇÕES DE CRIAÇÃO DE MODELOS (FACTORY) ---
|
| 59 |
-
|
| 60 |
-
def create_latent_upsampler(model_path: str, device: str):
|
| 61 |
-
"""Cria e retorna a instância do LatentUpsampler."""
|
| 62 |
-
latent_upsampler = LatentUpsampler.from_pretrained(model_path)
|
| 63 |
-
latent_upsampler.to(device)
|
| 64 |
-
latent_upsampler.eval()
|
| 65 |
-
return latent_upsampler
|
| 66 |
-
|
| 67 |
-
# ltx_server_loader.py
|
| 68 |
-
|
| 69 |
-
# ... (todas as outras importações e funções permanecem as mesmas) ...
|
| 70 |
-
|
| 71 |
-
def create_ltx_video_pipeline(ckpt_path: str, precision: str, text_encoder_path: str, device: str) -> LTXVideoPipeline:
|
| 72 |
-
"""
|
| 73 |
-
Cria e retorna a instância principal da LTXVideoPipeline.
|
| 74 |
-
VERSÃO CORRIGIDA.
|
| 75 |
-
"""
|
| 76 |
-
print(f"[LOADER] Criando pipeline a partir de: {ckpt_path}")
|
| 77 |
-
|
| 78 |
-
# --- FIX 1: Adicionar a leitura dos metadados, como no original ---
|
| 79 |
-
with safe_open(ckpt_path, framework="pt") as f:
|
| 80 |
-
metadata = f.metadata()
|
| 81 |
-
config_str = metadata.get("config")
|
| 82 |
-
# Adicionada verificação para caso 'config' não exista nos metadados
|
| 83 |
-
configs = json.loads(config_str) if config_str else {}
|
| 84 |
-
allowed_inference_steps = configs.get("allowed_inference_steps", None)
|
| 85 |
-
|
| 86 |
-
# O resto da criação dos submodelos permanece igual
|
| 87 |
-
vae = CausalVideoAutoencoder.from_pretrained(ckpt_path)
|
| 88 |
-
transformer = Transformer3DModel.from_pretrained(ckpt_path)
|
| 89 |
-
scheduler = RectifiedFlowScheduler.from_pretrained(ckpt_path)
|
| 90 |
-
text_encoder = T5EncoderModel.from_pretrained(text_encoder_path, subfolder="text_encoder")
|
| 91 |
-
patchifier = SymmetricPatchifier(patch_size=1)
|
| 92 |
-
tokenizer = T5Tokenizer.from_pretrained(text_encoder_path, subfolder="tokenizer")
|
| 93 |
-
|
| 94 |
-
# Move os modelos para CPU inicialmente, o serviço principal moverá para a GPU
|
| 95 |
-
vae = vae.to("cpu")
|
| 96 |
-
transformer = transformer.to("cpu")
|
| 97 |
-
text_encoder = text_encoder.to("cpu")
|
| 98 |
-
|
| 99 |
-
# Precisão será aplicada pelo serviço principal
|
| 100 |
-
if precision == "bfloat16":
|
| 101 |
-
transformer = transformer.to(torch.bfloat16)
|
| 102 |
-
text_encoder = text_encoder.to(torch.bfloat16)
|
| 103 |
-
vae = vae.to(torch.bfloat16)
|
| 104 |
-
|
| 105 |
-
# --- FIX 2: Adicionar os argumentos que estavam faltando no dicionário ---
|
| 106 |
-
submodel_dict = {
|
| 107 |
-
"transformer": transformer,
|
| 108 |
-
"patchifier": patchifier,
|
| 109 |
-
"text_encoder": text_encoder,
|
| 110 |
-
"tokenizer": tokenizer,
|
| 111 |
-
"scheduler": scheduler,
|
| 112 |
-
"vae": vae,
|
| 113 |
-
|
| 114 |
-
# CORREÇÃO: Adicionando os 4 argumentos faltantes com valor None
|
| 115 |
-
"prompt_enhancer_image_caption_model": None,
|
| 116 |
-
"prompt_enhancer_image_caption_processor": None,
|
| 117 |
-
"prompt_enhancer_llm_model": None,
|
| 118 |
-
"prompt_enhancer_llm_tokenizer": None,
|
| 119 |
-
|
| 120 |
-
# CORREÇÃO: Adicionando o argumento de metadados que também faltava
|
| 121 |
-
"allowed_inference_steps": allowed_inference_steps,
|
| 122 |
-
}
|
| 123 |
-
|
| 124 |
-
# A criação da pipeline agora funcionará
|
| 125 |
-
pipeline = LTXVideoPipeline(**submodel_dict)
|
| 126 |
-
# Deixamos o serviço principal mover a pipeline final para o dispositivo
|
| 127 |
-
# pipeline = pipeline.to(device)
|
| 128 |
-
|
| 129 |
-
return pipeline
|
| 130 |
-
|
| 131 |
-
|
| 132 |
-
# ... (o resto do arquivo ltx_server_loader.py permanece o mesmo) ...
|
| 133 |
-
|
| 134 |
-
|
| 135 |
-
def initialize_models(config: dict, device: str) -> tuple:
|
| 136 |
-
"""
|
| 137 |
-
Função principal deste módulo. Baixa os modelos do Hub e usa as funções
|
| 138 |
-
acima para criar e retornar as instâncias prontas para uso.
|
| 139 |
-
"""
|
| 140 |
-
LTX_REPO = "Lightricks/LTX-Video"
|
| 141 |
-
hf_token = os.getenv("HF_TOKEN")
|
| 142 |
-
|
| 143 |
-
print("[LOADER] Baixando checkpoint principal...")
|
| 144 |
-
ckpt_path = hf_hub_download(
|
| 145 |
-
repo_id=LTX_REPO, filename=config["checkpoint_path"], token=hf_token
|
| 146 |
-
)
|
| 147 |
-
print(f"[LOADER] Checkpoint em: {ckpt_path}")
|
| 148 |
-
|
| 149 |
-
print("[LOADER] Construindo pipeline...")
|
| 150 |
-
pipeline = create_ltx_video_pipeline(
|
| 151 |
-
ckpt_path=ckpt_path,
|
| 152 |
-
precision=config["precision"],
|
| 153 |
-
text_encoder_path=config["text_encoder_model_name_or_path"],
|
| 154 |
-
device="cpu", # Carrega em CPU primeiro para mover depois
|
| 155 |
-
)
|
| 156 |
-
print("[LOADER] Pipeline construída.")
|
| 157 |
-
|
| 158 |
-
latent_upsampler = None
|
| 159 |
-
if config.get("spatial_upscaler_model_path"):
|
| 160 |
-
print("[LOADER] Baixando upscaler espacial...")
|
| 161 |
-
upscaler_path = hf_hub_download(
|
| 162 |
-
repo_id=LTX_REPO, filename=config["spatial_upscaler_model_path"], token=hf_token
|
| 163 |
-
)
|
| 164 |
-
print(f"[LOADER] Upscaler em: {upscaler_path}")
|
| 165 |
-
|
| 166 |
-
print("[LOADER] Construindo latent_upsampler...")
|
| 167 |
-
latent_upsampler = create_latent_upsampler(upscaler_path, device="cpu")
|
| 168 |
-
print("[LOADER] Latent upsampler construído.")
|
| 169 |
-
|
| 170 |
-
return pipeline, latent_upsampler
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|