John6666's picture
Upload 39 files
e8b6587 verified
Raw
History Blame Contribute Delete
4.57 kB
"""Shared IC-LoRA runtime primitives.
Keep task semantics (prompting, preprocessing, task evidence and UI policy) in the
individual task module. This module only owns reusable adapter/reference mechanics
that are expected to be shared by future IC-LoRA tabs.
"""
from __future__ import annotations
import gc
import time
from dataclasses import dataclass
from pathlib import Path
import numpy as np
import PIL.Image
import torch
from diffusers.pipelines.ltx2.pipeline_ltx2_ic_lora import LTX2ReferenceCondition
@dataclass(frozen=True)
class PreparedRequestFiles:
"""Validated request-local files needed by an IC task GPU callback."""
reference_cache: Path
local_lora: Path
video_path: Path
diagnostics_path: Path
def adapter_state(pipe) -> dict:
"""Return the public adapter inventory without assuming one Diffusers version."""
state = {}
for name in ("get_active_adapters", "get_list_adapters"):
fn = getattr(pipe, name, None)
if callable(fn):
try:
state[name] = fn()
except Exception as exc:
state[name] = {"error": f"{type(exc).__name__}: {exc}"}
return state
def adapter_names(state: dict) -> set[str]:
"""Return adapter names from Diffusers public adapter-state snapshots."""
names: set[str] = set()
def _collect(value) -> None:
if isinstance(value, dict):
for item in value.values():
_collect(item)
elif isinstance(value, (list, tuple, set)):
for item in value:
_collect(item)
elif isinstance(value, str) and value.strip() and not value.strip().lower().startswith("error"):
names.add(value.strip())
_collect(state.get("get_active_adapters"))
_collect(state.get("get_list_adapters"))
return names
def adapter_state_has_any(state: dict) -> bool:
"""True when a Diffusers adapter-state snapshot contains a real adapter."""
def _nonempty(value) -> bool:
if isinstance(value, dict):
return any(_nonempty(item) for item in value.values())
if isinstance(value, (list, tuple, set)):
return len(value) > 0
if isinstance(value, str):
return bool(value.strip()) and not value.strip().lower().startswith("error")
return bool(value)
return _nonempty(state.get("get_active_adapters")) or _nonempty(state.get("get_list_adapters"))
def load_adapter_weights(*, pipe, local_lora: Path, adapter_name: str) -> None:
"""Load one already-local IC adapter; never performs Hub I/O."""
pipe.load_lora_weights(
str(local_lora.parent),
weight_name=local_lora.name,
adapter_name=adapter_name,
)
def activate_adapter(*, pipe, adapter_name: str, strength: float) -> None:
"""Select and enable one loaded request-scoped IC adapter."""
pipe.set_adapters([adapter_name], adapter_weights=[float(strength)])
pipe.enable_lora()
def release_adapter(*, pipe, adapter_name: str, state_pipe=None) -> tuple[float, dict]:
"""Disable/delete one request-scoped IC adapter and release cached CUDA memory."""
started = time.monotonic()
pipe.disable_lora()
pipe.delete_adapters([adapter_name])
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
return time.monotonic() - started, adapter_state(state_pipe if state_pipe is not None else pipe)
def force_release_adapter(*, pipe, adapter_name: str) -> None:
"""Best-effort finalizer used only after an IC callback failed mid-lifecycle."""
try:
pipe.disable_lora()
pipe.delete_adapters([adapter_name])
finally:
gc.collect()
if torch.cuda.is_available():
torch.cuda.empty_cache()
def reference_condition_from_cache(
cache_path: Path,
*,
num_frames: int,
height: int,
width: int,
strength: float,
) -> LTX2ReferenceCondition:
"""Restore an RGB frame cache and build the standard LTX2 reference condition."""
with np.load(cache_path, allow_pickle=False) as cached:
reference_array = np.asarray(cached["frames"], dtype=np.uint8)
expected_shape = (int(num_frames), int(height), int(width), 3)
if tuple(reference_array.shape) != expected_shape:
raise RuntimeError(f"Prepared reference shape mismatch: {reference_array.shape} != {expected_shape}")
reference_frames = [PIL.Image.fromarray(frame).convert("RGB") for frame in reference_array]
return LTX2ReferenceCondition(frames=reference_frames, strength=float(strength))