import json import logging import os import random import struct import subprocess import sys import tempfile import builtins from pathlib import Path import gradio as gr import numpy as np import spaces import torch from huggingface_hub import hf_hub_download LTX_REPO_URL = "https://github.com/Lightricks/LTX-2.git" LTX_COMMIT_SHA = "ae855f8538843825f9015a419cf4ba5edaf5eec2" HF_TOKEN = os.environ.get("HF_TOKEN") PERSISTENT = Path("/data") if Path("/data").exists() else Path(tempfile.gettempdir()) ASSETS_DIR = PERSISTENT / "sulphur_ltx" LTX_REPO_DIR = PERSISTENT / "LTX-2" OUTPUT_DIR = PERSISTENT / "sulphur_outputs" MAX_SEED = np.iinfo(np.int32).max DEFAULT_FRAME_RATE = 24.0 DEFAULT_PROMPT = "Make this image come alive with cinematic motion, smooth animation." RESOLUTIONS = { "high": {"16:9": (1536, 1024), "9:16": (1024, 1536), "1:1": (1024, 1024)}, "low": {"16:9": (768, 512), "9:16": (512, 768), "1:1": (768, 768)}, } def _run(cmd, cwd=None, check=True): print("[setup]", " ".join(str(part) for part in cmd)) return subprocess.run(cmd, cwd=cwd, check=check) def install_ltx_runtime(): if not (LTX_REPO_DIR / ".git").exists(): LTX_REPO_DIR.parent.mkdir(parents=True, exist_ok=True) if LTX_REPO_DIR.exists(): raise RuntimeError(f"{LTX_REPO_DIR} exists but is not a git checkout") _run(["git", "init", str(LTX_REPO_DIR)]) _run(["git", "remote", "add", "origin", LTX_REPO_URL], cwd=LTX_REPO_DIR) _run(["git", "fetch", "--depth", "1", "origin", LTX_COMMIT_SHA], cwd=LTX_REPO_DIR) _run(["git", "checkout", LTX_COMMIT_SHA], cwd=LTX_REPO_DIR) _run( [ sys.executable, "-m", "pip", "install", "--force-reinstall", "--no-deps", "-e", str(LTX_REPO_DIR / "packages" / "ltx-core"), "-e", str(LTX_REPO_DIR / "packages" / "ltx-pipelines"), ] ) sys.path.insert(0, str(LTX_REPO_DIR / "packages" / "ltx-pipelines" / "src")) sys.path.insert(0, str(LTX_REPO_DIR / "packages" / "ltx-core" / "src")) install_ltx_runtime() _real_import = builtins.__import__ def _import_without_xformers(name, globals=None, locals=None, fromlist=(), level=0): if name == "xformers" or name.startswith("xformers."): raise ImportError("xformers is disabled for this Space runtime") return _real_import(name, globals, locals, fromlist, level) builtins.__import__ = _import_without_xformers try: from ltx_core.loader import LTXV_LORA_COMFY_RENAMING_MAP, LoraPathStrengthAndSDOps from ltx_core.loader.primitives import StateDict from ltx_core.loader.sd_ops import KeyValueOperationResult, SDOps from ltx_core.loader.sft_loader import SafetensorsStateDictLoader from ltx_core.model.video_vae import TilingConfig, get_video_chunks_number from ltx_core.quantization import QuantizationPolicy import ltx_pipelines.utils.model_ledger as _model_ledger_mod from ltx_pipelines.distilled import DistilledPipeline from ltx_pipelines.utils.args import ImageConditioningInput from ltx_pipelines.utils.media_io import encode_video finally: builtins.__import__ = _real_import _model_ledger_mod.GEMMA_LLM_KEY_OPS = ( SDOps("GEMMA_LLM_KEY_OPS_SULPHUR") .with_matching(prefix="model.language_model.") .with_matching(prefix="model.vision_tower.") .with_matching(prefix="model.multi_modal_projector.") .with_replacement("model.language_model.", "model.model.language_model.") .with_replacement("model.vision_tower.", "model.model.vision_tower.") .with_replacement("model.multi_modal_projector.", "model.model.multi_modal_projector.") .with_kv_operation( operation=lambda key, value: [ KeyValueOperationResult(key, value), KeyValueOperationResult("model.lm_head.weight", value), ], key_prefix="model.model.language_model.embed_tokens.weight", ) ) _SAFETENSORS_DTYPE_MAP = { "F64": torch.float64, "F32": torch.float32, "F16": torch.float16, "BF16": torch.bfloat16, "F8_E5M2": torch.float8_e5m2, "F8_E4M3": torch.float8_e4m3fn, "I64": torch.int64, "I32": torch.int32, "I16": torch.int16, "I8": torch.int8, "U8": torch.uint8, "BOOL": torch.bool, } def _patched_safetensors_load(self, path, sd_ops, device=None): sd = {} size = 0 dtype = set() device = device or torch.device("cpu") model_paths = path if isinstance(path, list | tuple) else [path] for shard_path in model_paths: with open(shard_path, "rb") as reader: header_len = struct.unpack("