Files
wehub-resource-sync cddb07a176
docs / deploy (push) Has been cancelled
docs / changes (push) Has been cancelled
docs / check-and-build (push) Has been cancelled
build container image / cpu (push) Has been cancelled
build container image / cuda (push) Has been cancelled
build container image / rocm (push) Has been cancelled
frontend checks / frontend-checks (push) Has been cancelled
frontend tests / frontend-tests (push) Has been cancelled
lfs checks / lfs-check (push) Has been cancelled
python checks / python-checks (push) Has been cancelled
python tests / py3.12: macos-default (push) Has been cancelled
python tests / py3.11: windows-cpu (push) Has been cancelled
python tests / py3.12: windows-cpu (push) Has been cancelled
python tests / py3.11: linux-cpu (push) Has been cancelled
typegen checks / typegen-checks (push) Has been cancelled
uv lock checks / uv-lock-checks (push) Has been cancelled
openapi checks / openapi-checks (push) Has been cancelled
python tests / py3.11: macos-default (push) Has been cancelled
python tests / py3.12: linux-cpu (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 13:22:06 +08:00

114 lines
3.4 KiB
Python

"""DyPE extension for FLUX denoising pipeline."""
from dataclasses import dataclass
from typing import TYPE_CHECKING, Sequence
import torch
from invokeai.backend.flux.dype.base import DyPEConfig
from invokeai.backend.flux.dype.embed import DyPEEmbedND
if TYPE_CHECKING:
from invokeai.backend.flux.model import Flux
@dataclass
class DyPEExtension:
"""Extension for Dynamic Position Extrapolation in FLUX models.
This extension manages the patching of the FLUX model's position embedder
and updates the step state during denoising.
Usage:
1. Create extension with config and target dimensions
2. Call patch_model() to replace pe_embedder with DyPE version
3. Call update_step_state() before each denoising step
4. Call restore_model() after denoising to restore original embedder
"""
config: DyPEConfig
target_height: int
target_width: int
def patch_model(self, model: "Flux") -> tuple[DyPEEmbedND, object]:
"""Patch the model's position embedder with DyPE version.
Args:
model: The FLUX model to patch
Returns:
Tuple of (new DyPE embedder, original embedder for restoration)
"""
original_embedder = model.pe_embedder
dype_embedder = DyPEEmbedND.from_embednd(
embed_nd=original_embedder,
dype_config=self.config,
)
# Set initial state
dype_embedder.set_step_state(
sigma=1.0,
height=self.target_height,
width=self.target_width,
)
# Replace the embedder
model.pe_embedder = dype_embedder
return dype_embedder, original_embedder
def update_step_state(
self,
embedder: DyPEEmbedND,
sigma: float,
) -> None:
"""Update the step state in the DyPE embedder.
This should be called before each denoising step to update the
current noise level for timestep-dependent scaling.
Args:
embedder: The DyPE embedder to update
sigma: Current noise level for the active denoising step
"""
embedder.set_step_state(
sigma=sigma,
height=self.target_height,
width=self.target_width,
)
@staticmethod
def resolve_step_sigma(
fallback_sigma: float,
step_index: int,
scheduler_sigmas: Sequence[float] | torch.Tensor | None,
) -> float:
"""Resolve the actual sigma for the current denoising step.
Diffusers schedulers may expose both normalized timesteps and the underlying
sigma sequence. DyPE should follow the noise schedule, so prefer
``scheduler.sigmas`` when available and fall back to the provided value
otherwise.
"""
if scheduler_sigmas is None:
return fallback_sigma
if step_index >= len(scheduler_sigmas):
return fallback_sigma
sigma = scheduler_sigmas[step_index]
if isinstance(sigma, torch.Tensor):
return float(sigma.item())
return float(sigma)
@staticmethod
def restore_model(model: "Flux", original_embedder: object) -> None:
"""Restore the original position embedder.
Args:
model: The FLUX model to restore
original_embedder: The original embedder saved from patch_model()
"""
model.pe_embedder = original_embedder