Skip to content

Commit

Permalink
Remove attention map saving (#5845)
Browse files Browse the repository at this point in the history
## What type of PR is this? (check all applicable)

- [x] Refactor
- [ ] Feature
- [ ] Bug Fix
- [ ] Optimization
- [ ] Documentation Update
- [ ] Community Node Submission


## Have you discussed this change with the InvokeAI team?
- [x] Yes
- [ ] No, because

## Description

Attention map saving was a feature that existed a long time ago in
Invoke (>1 year ago). This PR strips out a bunch of dead code that still
remains from that feature and is polluting our diffusion implementation.

This change should not have any functional effect on the app.

## QA Instructions, Screenshots, Recordings

I did a quick smoke test of SD and SDXL image generation. All of the
deleted code was unused, so the risk should be relatively low.

## Merge Plan

- [x] Change target branch to `main` before merging.

## Added/updated tests?

- [ ] Yes
- [x] No: This PR just deletes a bunch of unused code.
  • Loading branch information
RyanJDick authored Mar 2, 2024
2 parents f8b5493 + cc45007 commit d8d7ddf
Show file tree
Hide file tree
Showing 7 changed files with 18 additions and 665 deletions.
5 changes: 1 addition & 4 deletions invokeai/app/invocations/latent.py
Original file line number Diff line number Diff line change
Expand Up @@ -775,10 +775,7 @@ def _lora_loader() -> Iterator[Tuple[LoRAModelRaw, float]]:
denoising_end=self.denoising_end,
)

(
result_latents,
result_attention_map_saver,
) = pipeline.latents_from_embeddings(
result_latents = pipeline.latents_from_embeddings(
latents=latents,
timesteps=timesteps,
init_timestep=init_timestep,
Expand Down
2 changes: 0 additions & 2 deletions invokeai/backend/stable_diffusion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,11 @@

from .diffusers_pipeline import PipelineIntermediateState, StableDiffusionGeneratorPipeline # noqa: F401
from .diffusion import InvokeAIDiffuserComponent # noqa: F401
from .diffusion.cross_attention_map_saving import AttentionMapSaver # noqa: F401
from .seamless import set_seamless # noqa: F401

__all__ = [
"PipelineIntermediateState",
"StableDiffusionGeneratorPipeline",
"InvokeAIDiffuserComponent",
"AttentionMapSaver",
"set_seamless",
]
41 changes: 8 additions & 33 deletions invokeai/backend/stable_diffusion/diffusers_pipeline.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import torchvision.transforms as T
from diffusers.models import AutoencoderKL, UNet2DConditionModel
from diffusers.models.controlnet import ControlNetModel
from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput
from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion import StableDiffusionPipeline
from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
from diffusers.schedulers import KarrasDiffusionSchedulers
Expand All @@ -26,9 +25,9 @@
from invokeai.backend.ip_adapter.ip_adapter import IPAdapter
from invokeai.backend.ip_adapter.unet_patcher import UNetPatcher
from invokeai.backend.stable_diffusion.diffusion.conditioning_data import ConditioningData
from invokeai.backend.stable_diffusion.diffusion.shared_invokeai_diffusion import InvokeAIDiffuserComponent

from ..util import auto_detect_slice_size, normalize_device
from .diffusion import AttentionMapSaver, InvokeAIDiffuserComponent


@dataclass
Expand All @@ -39,7 +38,6 @@ class PipelineIntermediateState:
timestep: int
latents: torch.Tensor
predicted_original: Optional[torch.Tensor] = None
attention_map_saver: Optional[AttentionMapSaver] = None


@dataclass
Expand Down Expand Up @@ -190,19 +188,6 @@ class T2IAdapterData:
end_step_percent: float = Field(default=1.0)


@dataclass
class InvokeAIStableDiffusionPipelineOutput(StableDiffusionPipelineOutput):
r"""
Output class for InvokeAI's Stable Diffusion pipeline.
Args:
attention_map_saver (`AttentionMapSaver`): Object containing attention maps that can be displayed to the user
after generation completes. Optional.
"""

attention_map_saver: Optional[AttentionMapSaver]


class StableDiffusionGeneratorPipeline(StableDiffusionPipeline):
r"""
Pipeline for text-to-image generation using Stable Diffusion.
Expand Down Expand Up @@ -343,9 +328,9 @@ def latents_from_embeddings(
masked_latents: Optional[torch.Tensor] = None,
gradient_mask: Optional[bool] = False,
seed: Optional[int] = None,
) -> tuple[torch.Tensor, Optional[AttentionMapSaver]]:
) -> torch.Tensor:
if init_timestep.shape[0] == 0:
return latents, None
return latents

if additional_guidance is None:
additional_guidance = []
Expand Down Expand Up @@ -385,7 +370,7 @@ def latents_from_embeddings(
additional_guidance.append(AddsMaskGuidance(mask, orig_latents, self.scheduler, noise, gradient_mask))

try:
latents, attention_map_saver = self.generate_latents_from_embeddings(
latents = self.generate_latents_from_embeddings(
latents,
timesteps,
conditioning_data,
Expand All @@ -402,7 +387,7 @@ def latents_from_embeddings(
if mask is not None and not gradient_mask:
latents = torch.lerp(orig_latents, latents.to(dtype=orig_latents.dtype), mask.to(dtype=orig_latents.dtype))

return latents, attention_map_saver
return latents

def generate_latents_from_embeddings(
self,
Expand All @@ -415,24 +400,22 @@ def generate_latents_from_embeddings(
ip_adapter_data: Optional[list[IPAdapterData]] = None,
t2i_adapter_data: Optional[list[T2IAdapterData]] = None,
callback: Callable[[PipelineIntermediateState], None] = None,
):
) -> torch.Tensor:
self._adjust_memory_efficient_attention(latents)
if additional_guidance is None:
additional_guidance = []

batch_size = latents.shape[0]
attention_map_saver: Optional[AttentionMapSaver] = None

if timesteps.shape[0] == 0:
return latents, attention_map_saver
return latents

ip_adapter_unet_patcher = None
extra_conditioning_info = conditioning_data.text_embeddings.extra_conditioning
if extra_conditioning_info is not None and extra_conditioning_info.wants_cross_attention_control:
attn_ctx = self.invokeai_diffuser.custom_attention_context(
self.invokeai_diffuser.model,
extra_conditioning_info=extra_conditioning_info,
step_count=len(self.scheduler.timesteps),
)
self.use_ip_adapter = False
elif ip_adapter_data is not None:
Expand Down Expand Up @@ -483,13 +466,6 @@ def generate_latents_from_embeddings(

predicted_original = getattr(step_output, "pred_original_sample", None)

# TODO resuscitate attention map saving
# if i == len(timesteps)-1 and extra_conditioning_info is not None:
# eos_token_index = extra_conditioning_info.tokens_count_including_eos_bos - 1
# attention_map_token_ids = range(1, eos_token_index)
# attention_map_saver = AttentionMapSaver(token_ids=attention_map_token_ids, latents_shape=latents.shape[-2:])
# self.invokeai_diffuser.setup_attention_map_saving(attention_map_saver)

if callback is not None:
callback(
PipelineIntermediateState(
Expand All @@ -499,11 +475,10 @@ def generate_latents_from_embeddings(
timestep=int(t),
latents=latents,
predicted_original=predicted_original,
attention_map_saver=attention_map_saver,
)
)

return latents, attention_map_saver
return latents

@torch.inference_mode()
def step(
Expand Down
2 changes: 0 additions & 2 deletions invokeai/backend/stable_diffusion/diffusion/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,4 @@
Initialization file for invokeai.models.diffusion
"""

from .cross_attention_control import InvokeAICrossAttentionMixin # noqa: F401
from .cross_attention_map_saving import AttentionMapSaver # noqa: F401
from .shared_invokeai_diffusion import InvokeAIDiffuserComponent # noqa: F401
Loading

0 comments on commit d8d7ddf

Please sign in to comment.