diff --git a/app.py b/app.py
index 87951b7..236650f 100644
--- a/app.py
+++ b/app.py
@@ -13,10 +13,10 @@
from transformers import CLIPImageProcessor, CLIPVisionModelWithProjection
from diffusers import DDIMScheduler, EulerDiscreteScheduler, PNDMScheduler
+from foleycrafter.models.audio_generator.vocoder import Generator
from foleycrafter.models.onset import torch_utils
from foleycrafter.models.time_detector.model import VideoOnsetNet
-from foleycrafter.pipelines.auffusion_pipeline import Generator, denormalize_spectrogram
-from foleycrafter.utils.util import build_foleycrafter, read_frames_with_moviepy
+from foleycrafter.utils.util import build_foleycrafter, denormalize_spectrogram, read_frames_with_moviepy
os.environ["GRADIO_TEMP_DIR"] = "./tmp"
diff --git a/foleycrafter/models/adapters/attention_processor.py b/foleycrafter/models/adapters/attention_processor.py
deleted file mode 100644
index de3de05..0000000
--- a/foleycrafter/models/adapters/attention_processor.py
+++ /dev/null
@@ -1,655 +0,0 @@
-import torch
-import torch.nn as nn
-import torch.nn.functional as F
-
-from diffusers.utils import logging
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-class AttnProcessor(nn.Module):
- r"""
- Default processor for performing attention-related computations.
- """
-
- def __init__(
- self,
- hidden_size=None,
- cross_attention_dim=None,
- ):
- super().__init__()
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class IPAttnProcessor(nn.Module):
- r"""
- Attention processor for IP-Adapater.
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`):
- The number of channels in the `encoder_hidden_states`.
- scale (`float`, defaults to 1.0):
- the weight scale of image prompt.
- num_tokens (`int`, defaults to 4 when do ip_adapter_plus it should be 16):
- The context length of the image features.
- """
-
- def __init__(self, hidden_size, cross_attention_dim=None, scale=1.0, num_tokens=4):
- super().__init__()
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.scale = scale
- self.num_tokens = num_tokens
-
- self.to_k_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- else:
- # get encoder_hidden_states, ip_hidden_states
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens
- encoder_hidden_states, ip_hidden_states = (
- encoder_hidden_states[:, :end_pos, :],
- encoder_hidden_states[:, end_pos:, :],
- )
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # for ip-adapter
- ip_key = self.to_k_ip(ip_hidden_states)
- ip_value = self.to_v_ip(ip_hidden_states)
-
- ip_key = attn.head_to_batch_dim(ip_key)
- ip_value = attn.head_to_batch_dim(ip_value)
-
- ip_attention_probs = attn.get_attention_scores(query, ip_key, None)
- self.attn_map = ip_attention_probs
- ip_hidden_states = torch.bmm(ip_attention_probs, ip_value)
- ip_hidden_states = attn.batch_to_head_dim(ip_hidden_states)
-
- hidden_states = hidden_states + self.scale * ip_hidden_states
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class AttnProcessor2_0(torch.nn.Module):
- r"""
- Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
- """
-
- def __init__(
- self,
- hidden_size=None,
- cross_attention_dim=None,
- ):
- super().__init__()
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class AttnProcessor2_0WithProjection(torch.nn.Module):
- r"""
- Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
- """
-
- def __init__(
- self,
- hidden_size=None,
- cross_attention_dim=None,
- ):
- super().__init__()
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
- self.before_proj_size = 1024
- self.after_proj_size = 768
- self.visual_proj = nn.Linear(self.before_proj_size, self.after_proj_size)
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
- # encoder_hidden_states = self.visual_proj(encoder_hidden_states)
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class IPAttnProcessor2_0(torch.nn.Module):
- r"""
- Attention processor for IP-Adapater for PyTorch 2.0.
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`):
- The number of channels in the `encoder_hidden_states`.
- scale (`float`, defaults to 1.0):
- the weight scale of image prompt.
- num_tokens (`int`, defaults to 4 when do ip_adapter_plus it should be 16):
- The context length of the image features.
- """
-
- def __init__(self, hidden_size, cross_attention_dim=None, scale=1.0, num_tokens=4):
- super().__init__()
-
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.scale = scale
- self.num_tokens = num_tokens
-
- self.to_k_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- else:
- # get encoder_hidden_states, ip_hidden_states
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens
- encoder_hidden_states, ip_hidden_states = (
- encoder_hidden_states[:, :end_pos, :],
- encoder_hidden_states[:, end_pos:, :],
- )
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # for ip-adapter
- ip_key = self.to_k_ip(ip_hidden_states)
- ip_value = self.to_v_ip(ip_hidden_states)
-
- ip_key = ip_key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- ip_value = ip_value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- ip_hidden_states = F.scaled_dot_product_attention(
- query, ip_key, ip_value, attn_mask=None, dropout_p=0.0, is_causal=False
- )
- with torch.no_grad():
- self.attn_map = query @ ip_key.transpose(-2, -1).softmax(dim=-1)
- # print(self.attn_map.shape)
-
- ip_hidden_states = ip_hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- ip_hidden_states = ip_hidden_states.to(query.dtype)
-
- hidden_states = hidden_states + self.scale * ip_hidden_states
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-## for controlnet
-class CNAttnProcessor:
- r"""
- Default processor for performing attention-related computations.
- """
-
- def __init__(self, num_tokens=4):
- self.num_tokens = num_tokens
-
- def __call__(self, attn, hidden_states, encoder_hidden_states=None, attention_mask=None, temb=None):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- else:
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens
- encoder_hidden_states = encoder_hidden_states[:, :end_pos] # only use text
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class CNAttnProcessor2_0:
- r"""
- Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
- """
-
- def __init__(self, num_tokens=4):
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
- self.num_tokens = num_tokens
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- ):
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- else:
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens
- encoder_hidden_states = encoder_hidden_states[:, :end_pos] # only use text
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
diff --git a/foleycrafter/models/adapters/ip_adapter.py b/foleycrafter/models/adapters/ip_adapter.py
deleted file mode 100644
index 73d18f7..0000000
--- a/foleycrafter/models/adapters/ip_adapter.py
+++ /dev/null
@@ -1,189 +0,0 @@
-import torch
-import torch.nn as nn
-
-
-class IPAdapter(torch.nn.Module):
- """IP-Adapter"""
-
- def __init__(self, unet, image_proj_model, adapter_modules, ckpt_path=None):
- super().__init__()
- self.unet = unet
- self.image_proj_model = image_proj_model
- self.adapter_modules = adapter_modules
-
- if ckpt_path is not None:
- self.load_from_checkpoint(ckpt_path)
-
- def forward(self, noisy_latents, timesteps, encoder_hidden_states, image_embeds):
- ip_tokens = self.image_proj_model(image_embeds)
- encoder_hidden_states = torch.cat([encoder_hidden_states, ip_tokens], dim=1)
- # Predict the noise residual
- noise_pred = self.unet(noisy_latents, timesteps, encoder_hidden_states).sample
- return noise_pred
-
- def load_from_checkpoint(self, ckpt_path: str):
- # Calculate original checksums
- orig_ip_proj_sum = torch.sum(torch.stack([torch.sum(p) for p in self.image_proj_model.parameters()]))
- orig_adapter_sum = torch.sum(torch.stack([torch.sum(p) for p in self.adapter_modules.parameters()]))
-
- state_dict = torch.load(ckpt_path, map_location="cpu")
-
- # Load state dict for image_proj_model and adapter_modules
- self.image_proj_model.load_state_dict(state_dict["image_proj"], strict=True)
- self.adapter_modules.load_state_dict(state_dict["ip_adapter"], strict=True)
-
- # Calculate new checksums
- new_ip_proj_sum = torch.sum(torch.stack([torch.sum(p) for p in self.image_proj_model.parameters()]))
- new_adapter_sum = torch.sum(torch.stack([torch.sum(p) for p in self.adapter_modules.parameters()]))
-
- # Verify if the weights have changed
- assert orig_ip_proj_sum != new_ip_proj_sum, "Weights of image_proj_model did not change!"
- assert orig_adapter_sum != new_adapter_sum, "Weights of adapter_modules did not change!"
-
- print(f"Successfully loaded weights from checkpoint {ckpt_path}")
-
-
-class ImageProjModel(torch.nn.Module):
- """Projection Model"""
-
- def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4):
- super().__init__()
-
- self.cross_attention_dim = cross_attention_dim
- self.clip_extra_context_tokens = clip_extra_context_tokens
- self.proj = torch.nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim)
- self.norm = torch.nn.LayerNorm(cross_attention_dim)
-
- def forward(self, image_embeds):
- embeds = image_embeds
- clip_extra_context_tokens = self.proj(embeds).reshape(
- -1, self.clip_extra_context_tokens, self.cross_attention_dim
- )
- clip_extra_context_tokens = self.norm(clip_extra_context_tokens)
- return clip_extra_context_tokens
-
-
-class MLPProjModel(torch.nn.Module):
- """SD model with image prompt"""
-
- def zero_initialize(module):
- for param in module.parameters():
- param.data.zero_()
-
- def zero_initialize_last_layer(module):
- last_layer = None
- for module_name, layer in module.named_modules():
- if isinstance(layer, torch.nn.Linear):
- last_layer = layer
-
- if last_layer is not None:
- last_layer.weight.data.zero_()
- last_layer.bias.data.zero_()
-
- def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024):
- super().__init__()
-
- self.proj = torch.nn.Sequential(
- torch.nn.Linear(clip_embeddings_dim, clip_embeddings_dim),
- torch.nn.GELU(),
- torch.nn.Linear(clip_embeddings_dim, cross_attention_dim),
- torch.nn.LayerNorm(cross_attention_dim),
- )
- # zero initialize the last layer
- # self.zero_initialize_last_layer()
-
- def forward(self, image_embeds):
- clip_extra_context_tokens = self.proj(image_embeds)
- return clip_extra_context_tokens
-
-
-class V2AMapperMLP(torch.nn.Module):
- def __init__(self, cross_attention_dim=512, clip_embeddings_dim=512, mult=4):
- super().__init__()
- self.proj = torch.nn.Sequential(
- torch.nn.Linear(clip_embeddings_dim, clip_embeddings_dim * mult),
- torch.nn.GELU(),
- torch.nn.Linear(clip_embeddings_dim * mult, cross_attention_dim),
- torch.nn.LayerNorm(cross_attention_dim),
- )
-
- def forward(self, image_embeds):
- clip_extra_context_tokens = self.proj(image_embeds)
- return clip_extra_context_tokens
-
-
-class TimeProjModel(torch.nn.Module):
- def __init__(self, positive_len, out_dim, feature_type="text-only", frame_nums: int = 64):
- super().__init__()
- self.positive_len = positive_len
- self.out_dim = out_dim
-
- self.position_dim = frame_nums
-
- if isinstance(out_dim, tuple):
- out_dim = out_dim[0]
-
- if feature_type == "text-only":
- self.linears = nn.Sequential(
- nn.Linear(self.positive_len + self.position_dim, 512),
- nn.SiLU(),
- nn.Linear(512, 512),
- nn.SiLU(),
- nn.Linear(512, out_dim),
- )
- self.null_positive_feature = torch.nn.Parameter(torch.zeros([self.positive_len]))
-
- elif feature_type == "text-image":
- self.linears_text = nn.Sequential(
- nn.Linear(self.positive_len + self.position_dim, 512),
- nn.SiLU(),
- nn.Linear(512, 512),
- nn.SiLU(),
- nn.Linear(512, out_dim),
- )
- self.linears_image = nn.Sequential(
- nn.Linear(self.positive_len + self.position_dim, 512),
- nn.SiLU(),
- nn.Linear(512, 512),
- nn.SiLU(),
- nn.Linear(512, out_dim),
- )
- self.null_text_feature = torch.nn.Parameter(torch.zeros([self.positive_len]))
- self.null_image_feature = torch.nn.Parameter(torch.zeros([self.positive_len]))
-
- # self.null_position_feature = torch.nn.Parameter(torch.zeros([self.position_dim]))
-
- def forward(
- self,
- boxes,
- masks,
- positive_embeddings=None,
- ):
- masks = masks.unsqueeze(-1)
-
- # # embedding position (it may includes padding as placeholder)
- # xyxy_embedding = self.fourier_embedder(boxes) # B*N*4 -> B*N*C
-
- # # learnable null embedding
- # xyxy_null = self.null_position_feature.view(1, 1, -1)
-
- # # replace padding with learnable null embedding
- # xyxy_embedding = xyxy_embedding * masks + (1 - masks) * xyxy_null
-
- time_embeds = boxes
-
- # positionet with text only information
- if positive_embeddings is not None:
- # learnable null embedding
- positive_null = self.null_positive_feature.view(1, 1, -1)
-
- # replace padding with learnable null embedding
- positive_embeddings = positive_embeddings * masks + (1 - masks) * positive_null
-
- objs = self.linears(torch.cat([positive_embeddings, time_embeds], dim=-1))
-
- # positionet with text and image information
- else:
- raise NotImplementedError
-
- return objs
diff --git a/foleycrafter/models/adapters/resampler.py b/foleycrafter/models/adapters/resampler.py
deleted file mode 100644
index 2426667..0000000
--- a/foleycrafter/models/adapters/resampler.py
+++ /dev/null
@@ -1,158 +0,0 @@
-# modified from https://github.com/mlfoundations/open_flamingo/blob/main/open_flamingo/src/helpers.py
-# and https://github.com/lucidrains/imagen-pytorch/blob/main/imagen_pytorch/imagen_pytorch.py
-
-import math
-
-import torch
-import torch.nn as nn
-from einops import rearrange
-from einops.layers.torch import Rearrange
-
-
-# FFN
-def FeedForward(dim, mult=4):
- inner_dim = int(dim * mult)
- return nn.Sequential(
- nn.LayerNorm(dim),
- nn.Linear(dim, inner_dim, bias=False),
- nn.GELU(),
- nn.Linear(inner_dim, dim, bias=False),
- )
-
-
-def reshape_tensor(x, heads):
- bs, length, width = x.shape
- # (bs, length, width) --> (bs, length, n_heads, dim_per_head)
- x = x.view(bs, length, heads, -1)
- # (bs, length, n_heads, dim_per_head) --> (bs, n_heads, length, dim_per_head)
- x = x.transpose(1, 2)
- # (bs, n_heads, length, dim_per_head) --> (bs*n_heads, length, dim_per_head)
- x = x.reshape(bs, heads, length, -1)
- return x
-
-
-class PerceiverAttention(nn.Module):
- def __init__(self, *, dim, dim_head=64, heads=8):
- super().__init__()
- self.scale = dim_head**-0.5
- self.dim_head = dim_head
- self.heads = heads
- inner_dim = dim_head * heads
-
- self.norm1 = nn.LayerNorm(dim)
- self.norm2 = nn.LayerNorm(dim)
-
- self.to_q = nn.Linear(dim, inner_dim, bias=False)
- self.to_kv = nn.Linear(dim, inner_dim * 2, bias=False)
- self.to_out = nn.Linear(inner_dim, dim, bias=False)
-
- def forward(self, x, latents):
- """
- Args:
- x (torch.Tensor): image features
- shape (b, n1, D)
- latent (torch.Tensor): latent features
- shape (b, n2, D)
- """
- x = self.norm1(x)
- latents = self.norm2(latents)
-
- b, l, _ = latents.shape
-
- q = self.to_q(latents)
- kv_input = torch.cat((x, latents), dim=-2)
- k, v = self.to_kv(kv_input).chunk(2, dim=-1)
-
- q = reshape_tensor(q, self.heads)
- k = reshape_tensor(k, self.heads)
- v = reshape_tensor(v, self.heads)
-
- # attention
- scale = 1 / math.sqrt(math.sqrt(self.dim_head))
- weight = (q * scale) @ (k * scale).transpose(-2, -1) # More stable with f16 than dividing afterwards
- weight = torch.softmax(weight.float(), dim=-1).type(weight.dtype)
- out = weight @ v
-
- out = out.permute(0, 2, 1, 3).reshape(b, l, -1)
-
- return self.to_out(out)
-
-
-class Resampler(nn.Module):
- def __init__(
- self,
- dim=1024,
- depth=8,
- dim_head=64,
- heads=16,
- num_queries=8,
- embedding_dim=768,
- output_dim=1024,
- ff_mult=4,
- max_seq_len: int = 257, # CLIP tokens + CLS token
- apply_pos_emb: bool = False,
- num_latents_mean_pooled: int = 0, # number of latents derived from mean pooled representation of the sequence
- ):
- super().__init__()
- self.pos_emb = nn.Embedding(max_seq_len, embedding_dim) if apply_pos_emb else None
-
- self.latents = nn.Parameter(torch.randn(1, num_queries, dim) / dim**0.5)
-
- self.proj_in = nn.Linear(embedding_dim, dim)
-
- self.proj_out = nn.Linear(dim, output_dim)
- self.norm_out = nn.LayerNorm(output_dim)
-
- self.to_latents_from_mean_pooled_seq = (
- nn.Sequential(
- nn.LayerNorm(dim),
- nn.Linear(dim, dim * num_latents_mean_pooled),
- Rearrange("b (n d) -> b n d", n=num_latents_mean_pooled),
- )
- if num_latents_mean_pooled > 0
- else None
- )
-
- self.layers = nn.ModuleList([])
- for _ in range(depth):
- self.layers.append(
- nn.ModuleList(
- [
- PerceiverAttention(dim=dim, dim_head=dim_head, heads=heads),
- FeedForward(dim=dim, mult=ff_mult),
- ]
- )
- )
-
- def forward(self, x):
- if self.pos_emb is not None:
- n, device = x.shape[1], x.device
- pos_emb = self.pos_emb(torch.arange(n, device=device))
- x = x + pos_emb
-
- latents = self.latents.repeat(x.size(0), 1, 1)
-
- x = self.proj_in(x)
-
- if self.to_latents_from_mean_pooled_seq:
- meanpooled_seq = masked_mean(x, dim=1, mask=torch.ones(x.shape[:2], device=x.device, dtype=torch.bool))
- meanpooled_latents = self.to_latents_from_mean_pooled_seq(meanpooled_seq)
- latents = torch.cat((meanpooled_latents, latents), dim=-2)
-
- for attn, ff in self.layers:
- latents = attn(x, latents) + latents
- latents = ff(latents) + latents
-
- latents = self.proj_out(latents)
- return self.norm_out(latents)
-
-
-def masked_mean(t, *, dim, mask=None):
- if mask is None:
- return t.mean(dim=dim)
-
- denom = mask.sum(dim=dim, keepdim=True)
- mask = rearrange(mask, "b n -> b n 1")
- masked_t = t.masked_fill(~mask, 0.0)
-
- return masked_t.sum(dim=dim) / denom.clamp(min=1e-5)
diff --git a/foleycrafter/models/adapters/transformer.py b/foleycrafter/models/adapters/transformer.py
deleted file mode 100644
index 3141657..0000000
--- a/foleycrafter/models/adapters/transformer.py
+++ /dev/null
@@ -1,352 +0,0 @@
-from typing import Optional, Tuple
-
-import torch
-import torch.nn as nn
-import torch.utils.checkpoint
-
-
-class Attention(nn.Module):
- """Multi-headed attention from 'Attention Is All You Need' paper"""
-
- def __init__(self, hidden_size, num_attention_heads, attention_head_dim, attention_dropout=0.0):
- super().__init__()
- self.embed_dim = hidden_size
- self.num_heads = num_attention_heads
- self.head_dim = attention_head_dim
-
- self.scale = self.head_dim**-0.5
- self.dropout = attention_dropout
-
- self.inner_dim = self.head_dim * self.num_heads
-
- self.k_proj = nn.Linear(self.embed_dim, self.inner_dim)
- self.v_proj = nn.Linear(self.embed_dim, self.inner_dim)
- self.q_proj = nn.Linear(self.embed_dim, self.inner_dim)
- self.out_proj = nn.Linear(self.inner_dim, self.embed_dim)
-
- def _shape(self, tensor: torch.Tensor, seq_len: int, bsz: int):
- return tensor.view(bsz, seq_len, self.num_heads, self.head_dim).transpose(1, 2).contiguous()
-
- def forward(
- self,
- hidden_states: torch.Tensor,
- attention_mask: Optional[torch.Tensor] = None,
- causal_attention_mask: Optional[torch.Tensor] = None,
- output_attentions: Optional[bool] = False,
- ) -> Tuple[torch.Tensor, Optional[torch.Tensor], Optional[Tuple[torch.Tensor]]]:
- """Input shape: Batch x Time x Channel"""
-
- bsz, tgt_len, embed_dim = hidden_states.size()
-
- # get query proj
- query_states = self.q_proj(hidden_states) * self.scale
- key_states = self._shape(self.k_proj(hidden_states), -1, bsz)
- value_states = self._shape(self.v_proj(hidden_states), -1, bsz)
-
- proj_shape = (bsz * self.num_heads, -1, self.head_dim)
- query_states = self._shape(query_states, tgt_len, bsz).view(*proj_shape)
- key_states = key_states.view(*proj_shape)
- value_states = value_states.view(*proj_shape)
-
- src_len = key_states.size(1)
- attn_weights = torch.bmm(query_states, key_states.transpose(1, 2))
-
- if attn_weights.size() != (bsz * self.num_heads, tgt_len, src_len):
- raise ValueError(
- f"Attention weights should be of size {(bsz * self.num_heads, tgt_len, src_len)}, but is"
- f" {attn_weights.size()}"
- )
-
- # apply the causal_attention_mask first
- if causal_attention_mask is not None:
- if causal_attention_mask.size() != (bsz, 1, tgt_len, src_len):
- raise ValueError(
- f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is"
- f" {causal_attention_mask.size()}"
- )
- attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + causal_attention_mask
- attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len)
-
- if attention_mask is not None:
- if attention_mask.size() != (bsz, 1, tgt_len, src_len):
- raise ValueError(
- f"Attention mask should be of size {(bsz, 1, tgt_len, src_len)}, but is {attention_mask.size()}"
- )
- attn_weights = attn_weights.view(bsz, self.num_heads, tgt_len, src_len) + attention_mask
- attn_weights = attn_weights.view(bsz * self.num_heads, tgt_len, src_len)
-
- attn_weights = nn.functional.softmax(attn_weights, dim=-1)
-
- if output_attentions:
- # this operation is a bit akward, but it's required to
- # make sure that attn_weights keeps its gradient.
- # In order to do so, attn_weights have to reshaped
- # twice and have to be reused in the following
- attn_weights_reshaped = attn_weights.view(bsz, self.num_heads, tgt_len, src_len)
- attn_weights = attn_weights_reshaped.view(bsz * self.num_heads, tgt_len, src_len)
- else:
- attn_weights_reshaped = None
-
- attn_probs = nn.functional.dropout(attn_weights, p=self.dropout, training=self.training)
-
- attn_output = torch.bmm(attn_probs, value_states)
-
- if attn_output.size() != (bsz * self.num_heads, tgt_len, self.head_dim):
- raise ValueError(
- f"`attn_output` should be of size {(bsz, self.num_heads, tgt_len, self.head_dim)}, but is"
- f" {attn_output.size()}"
- )
-
- attn_output = attn_output.view(bsz, self.num_heads, tgt_len, self.head_dim)
- attn_output = attn_output.transpose(1, 2)
- attn_output = attn_output.reshape(bsz, tgt_len, self.inner_dim)
-
- attn_output = self.out_proj(attn_output)
-
- return attn_output, attn_weights_reshaped
-
-
-class MLP(nn.Module):
- def __init__(self, hidden_size, intermediate_size, mult=4):
- super().__init__()
- self.activation_fn = nn.SiLU()
- self.fc1 = nn.Linear(hidden_size, intermediate_size * mult)
- self.fc2 = nn.Linear(intermediate_size * mult, hidden_size)
-
- def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
- hidden_states = self.fc1(hidden_states)
- hidden_states = self.activation_fn(hidden_states)
- hidden_states = self.fc2(hidden_states)
- return hidden_states
-
-
-class Transformer(nn.Module):
- def __init__(self, depth=12):
- super().__init__()
- self.layers = nn.ModuleList([TransformerBlock() for _ in range(depth)])
-
- def forward(
- self,
- hidden_states: torch.Tensor,
- attention_mask: torch.Tensor = None,
- causal_attention_mask: torch.Tensor = None,
- output_attentions: Optional[bool] = False,
- ) -> Tuple[torch.FloatTensor]:
- """
- Args:
- hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
- attention_mask (`torch.FloatTensor`): attention mask of size
- `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
- `(config.encoder_attention_heads,)`.
- output_attentions (`bool`, *optional*):
- Whether or not to return the attentions tensors of all attention layers. See `attentions` under
- returned tensors for more detail.
- """
- for layer in self.layers:
- hidden_states = layer(
- hidden_states=hidden_states,
- attention_mask=attention_mask,
- causal_attention_mask=causal_attention_mask,
- output_attentions=output_attentions,
- )
-
- return hidden_states
-
-
-class TransformerBlock(nn.Module):
- def __init__(
- self,
- hidden_size=512,
- num_attention_heads=12,
- attention_head_dim=64,
- attention_dropout=0.0,
- dropout=0.0,
- eps=1e-5,
- ):
- super().__init__()
- self.embed_dim = hidden_size
- self.self_attn = Attention(
- hidden_size=hidden_size, num_attention_heads=num_attention_heads, attention_head_dim=attention_head_dim
- )
- self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=eps)
- self.mlp = MLP(hidden_size=hidden_size, intermediate_size=hidden_size)
- self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=eps)
-
- def forward(
- self,
- hidden_states: torch.Tensor,
- attention_mask: torch.Tensor = None,
- causal_attention_mask: torch.Tensor = None,
- output_attentions: Optional[bool] = False,
- ) -> Tuple[torch.FloatTensor]:
- """
- Args:
- hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
- attention_mask (`torch.FloatTensor`): attention mask of size
- `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
- `(config.encoder_attention_heads,)`.
- output_attentions (`bool`, *optional*):
- Whether or not to return the attentions tensors of all attention layers. See `attentions` under
- returned tensors for more detail.
- """
- residual = hidden_states
-
- hidden_states = self.layer_norm1(hidden_states)
- hidden_states, attn_weights = self.self_attn(
- hidden_states=hidden_states,
- attention_mask=attention_mask,
- causal_attention_mask=causal_attention_mask,
- output_attentions=output_attentions,
- )
- hidden_states = residual + hidden_states
-
- residual = hidden_states
- hidden_states = self.layer_norm2(hidden_states)
- hidden_states = self.mlp(hidden_states)
- hidden_states = residual + hidden_states
-
- outputs = (hidden_states,)
-
- if output_attentions:
- outputs += (attn_weights,)
-
- return outputs[0]
-
-
-class DiffusionTransformerBlock(nn.Module):
- def __init__(
- self,
- hidden_size=512,
- num_attention_heads=12,
- attention_head_dim=64,
- attention_dropout=0.0,
- dropout=0.0,
- eps=1e-5,
- ):
- super().__init__()
- self.embed_dim = hidden_size
- self.self_attn = Attention(
- hidden_size=hidden_size, num_attention_heads=num_attention_heads, attention_head_dim=attention_head_dim
- )
- self.layer_norm1 = nn.LayerNorm(self.embed_dim, eps=eps)
- self.mlp = MLP(hidden_size=hidden_size, intermediate_size=hidden_size)
- self.layer_norm2 = nn.LayerNorm(self.embed_dim, eps=eps)
- self.output_token = nn.Parameter(torch.randn(1, hidden_size))
-
- def forward(
- self,
- hidden_states: torch.Tensor,
- attention_mask: torch.Tensor = None,
- causal_attention_mask: torch.Tensor = None,
- output_attentions: Optional[bool] = False,
- ) -> Tuple[torch.FloatTensor]:
- """
- Args:
- hidden_states (`torch.FloatTensor`): input to the layer of shape `(batch, seq_len, embed_dim)`
- attention_mask (`torch.FloatTensor`): attention mask of size
- `(batch, 1, tgt_len, src_len)` where padding elements are indicated by very large negative values.
- `(config.encoder_attention_heads,)`.
- output_attentions (`bool`, *optional*):
- Whether or not to return the attentions tensors of all attention layers. See `attentions` under
- returned tensors for more detail.
- """
- output_token = self.output_token.unsqueeze(0).repeat(hidden_states.shape[0], 1, 1)
- hidden_states = torch.cat([output_token, hidden_states], dim=1)
- residual = hidden_states
-
- hidden_states = self.layer_norm1(hidden_states)
- hidden_states, attn_weights = self.self_attn(
- hidden_states=hidden_states,
- attention_mask=attention_mask,
- causal_attention_mask=causal_attention_mask,
- output_attentions=output_attentions,
- )
- hidden_states = residual + hidden_states
-
- residual = hidden_states
- hidden_states = self.layer_norm2(hidden_states)
- hidden_states = self.mlp(hidden_states)
- hidden_states = residual + hidden_states
-
- outputs = (hidden_states,)
-
- if output_attentions:
- outputs += (attn_weights,)
-
- return outputs[0][:, 0:1, ...]
-
-
-class V2AMapperMLP(nn.Module):
- def __init__(self, input_dim=512, output_dim=512, expansion_rate=4):
- super().__init__()
- self.linear = nn.Linear(input_dim, input_dim * expansion_rate)
- self.silu = nn.SiLU()
- self.layer_norm = nn.LayerNorm(input_dim * expansion_rate)
- self.linear2 = nn.Linear(input_dim * expansion_rate, output_dim)
-
- def forward(self, x):
- x = self.linear(x)
- x = self.silu(x)
- x = self.layer_norm(x)
- x = self.linear2(x)
-
- return x
-
-
-class ImageProjModel(torch.nn.Module):
- """Projection Model"""
-
- def __init__(self, cross_attention_dim=1024, clip_embeddings_dim=1024, clip_extra_context_tokens=4):
- super().__init__()
-
- self.cross_attention_dim = cross_attention_dim
- self.clip_extra_context_tokens = clip_extra_context_tokens
- self.proj = torch.nn.Linear(clip_embeddings_dim, self.clip_extra_context_tokens * cross_attention_dim)
- self.norm = torch.nn.LayerNorm(cross_attention_dim)
-
- self.zero_initialize_last_layer()
-
- def zero_initialize_last_layer(module):
- last_layer = None
- for module_name, layer in module.named_modules():
- if isinstance(layer, torch.nn.Linear):
- last_layer = layer
-
- if last_layer is not None:
- last_layer.weight.data.zero_()
- last_layer.bias.data.zero_()
-
- def forward(self, image_embeds):
- embeds = image_embeds
- clip_extra_context_tokens = self.proj(embeds).reshape(
- -1, self.clip_extra_context_tokens, self.cross_attention_dim
- )
- clip_extra_context_tokens = self.norm(clip_extra_context_tokens)
- return clip_extra_context_tokens
-
-
-class VisionAudioAdapter(torch.nn.Module):
- def __init__(
- self,
- embedding_size=768,
- expand_dim=4,
- token_num=4,
- ):
- super().__init__()
-
- self.mapper = V2AMapperMLP(
- embedding_size,
- embedding_size,
- expansion_rate=expand_dim,
- )
-
- self.proj = ImageProjModel(
- cross_attention_dim=embedding_size,
- clip_embeddings_dim=embedding_size,
- clip_extra_context_tokens=token_num,
- )
-
- def forward(self, image_embeds):
- image_embeds = self.mapper(image_embeds)
- image_embeds = self.proj(image_embeds)
- return image_embeds
diff --git a/foleycrafter/models/adapters/utils.py b/foleycrafter/models/adapters/utils.py
deleted file mode 100644
index 2b01fb3..0000000
--- a/foleycrafter/models/adapters/utils.py
+++ /dev/null
@@ -1,86 +0,0 @@
-import numpy as np
-import torch
-import torch.nn.functional as F
-from PIL import Image
-
-
-attn_maps = {}
-
-
-def hook_fn(name):
- def forward_hook(module, input, output):
- if hasattr(module.processor, "attn_map"):
- attn_maps[name] = module.processor.attn_map
- del module.processor.attn_map
-
- return forward_hook
-
-
-def register_cross_attention_hook(unet):
- for name, module in unet.named_modules():
- if name.split(".")[-1].startswith("attn2"):
- module.register_forward_hook(hook_fn(name))
-
- return unet
-
-
-def upscale(attn_map, target_size):
- attn_map = torch.mean(attn_map, dim=0)
- attn_map = attn_map.permute(1, 0)
- temp_size = None
-
- for i in range(0, 5):
- scale = 2**i
- if (target_size[0] // scale) * (target_size[1] // scale) == attn_map.shape[1] * 64:
- temp_size = (target_size[0] // (scale * 8), target_size[1] // (scale * 8))
- break
-
- assert temp_size is not None, "temp_size cannot is None"
-
- attn_map = attn_map.view(attn_map.shape[0], *temp_size)
-
- attn_map = F.interpolate(
- attn_map.unsqueeze(0).to(dtype=torch.float32), size=target_size, mode="bilinear", align_corners=False
- )[0]
-
- attn_map = torch.softmax(attn_map, dim=0)
- return attn_map
-
-
-def get_net_attn_map(image_size, batch_size=2, instance_or_negative=False, detach=True):
- idx = 0 if instance_or_negative else 1
- net_attn_maps = []
-
- for name, attn_map in attn_maps.items():
- attn_map = attn_map.cpu() if detach else attn_map
- attn_map = torch.chunk(attn_map, batch_size)[idx].squeeze()
- attn_map = upscale(attn_map, image_size)
- net_attn_maps.append(attn_map)
-
- net_attn_maps = torch.mean(torch.stack(net_attn_maps, dim=0), dim=0)
-
- return net_attn_maps
-
-
-def attnmaps2images(net_attn_maps):
- # total_attn_scores = 0
- images = []
-
- for attn_map in net_attn_maps:
- attn_map = attn_map.cpu().numpy()
- # total_attn_scores += attn_map.mean().item()
-
- normalized_attn_map = (attn_map - np.min(attn_map)) / (np.max(attn_map) - np.min(attn_map)) * 255
- normalized_attn_map = normalized_attn_map.astype(np.uint8)
- # print("norm: ", normalized_attn_map.shape)
- image = Image.fromarray(normalized_attn_map)
-
- # image = fix_save_attn_map(attn_map)
- images.append(image)
-
- # print(total_attn_scores)
- return images
-
-
-def is_torch2_available():
- return hasattr(F, "scaled_dot_product_attention")
diff --git a/foleycrafter/models/audio_generator/__init__.py b/foleycrafter/models/audio_generator/__init__.py
new file mode 100644
index 0000000..e69de29
diff --git a/foleycrafter/models/audio_generator/attention_processor.py b/foleycrafter/models/audio_generator/attention_processor.py
new file mode 100644
index 0000000..717837c
--- /dev/null
+++ b/foleycrafter/models/audio_generator/attention_processor.py
@@ -0,0 +1,306 @@
+# Copyright 2023 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from typing import List, Optional
+
+import torch
+import torch.nn.functional as F
+from torch import nn
+
+from diffusers.models.attention_processor import Attention
+from diffusers.utils import USE_PEFT_BACKEND, deprecate, logging
+
+
+logger = logging.get_logger(__name__) # pylint: disable=invalid-name
+
+
+class AttnProcessor2_0:
+ r"""
+ Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
+ """
+
+ def __init__(self):
+ if not hasattr(F, "scaled_dot_product_attention"):
+ raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
+
+ def __call__(
+ self,
+ attn: Attention,
+ hidden_states: torch.FloatTensor,
+ encoder_hidden_states: Optional[torch.FloatTensor] = None,
+ attention_mask: Optional[torch.FloatTensor] = None,
+ temb: Optional[torch.FloatTensor] = None,
+ scale: float = 1.0,
+ **kwargs,
+ ) -> torch.FloatTensor:
+ residual = hidden_states
+ if attn.spatial_norm is not None:
+ hidden_states = attn.spatial_norm(hidden_states, temb)
+
+ input_ndim = hidden_states.ndim
+
+ if input_ndim == 4:
+ batch_size, channel, height, width = hidden_states.shape
+ hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
+
+ batch_size, sequence_length, _ = (
+ hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
+ )
+
+ if attention_mask is not None:
+ attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
+ # scaled_dot_product_attention expects attention_mask shape to be
+ # (batch, heads, source_length, target_length)
+ attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
+
+ if attn.group_norm is not None:
+ hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
+
+ args = () if USE_PEFT_BACKEND else (scale,)
+ query = attn.to_q(hidden_states, *args)
+
+ if encoder_hidden_states is None:
+ encoder_hidden_states = hidden_states
+ elif attn.norm_cross:
+ encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
+
+ key = attn.to_k(encoder_hidden_states, *args)
+ value = attn.to_v(encoder_hidden_states, *args)
+
+ inner_dim = key.shape[-1]
+ head_dim = inner_dim // attn.heads
+
+ query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+
+ key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+ value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+
+ # the output of sdp = (batch, num_heads, seq_len, head_dim)
+ # TODO: add support for attn.scale when we move to Torch 2.1
+ hidden_states = F.scaled_dot_product_attention(
+ query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
+ )
+
+ hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
+ hidden_states = hidden_states.to(query.dtype)
+
+ # linear proj
+ hidden_states = attn.to_out[0](hidden_states, *args)
+ # dropout
+ hidden_states = attn.to_out[1](hidden_states)
+
+ if input_ndim == 4:
+ hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
+
+ if attn.residual_connection:
+ hidden_states = hidden_states + residual
+
+ hidden_states = hidden_states / attn.rescale_output_factor
+
+ return hidden_states
+
+
+class IPAdapterAttnProcessor2_0(torch.nn.Module):
+ r"""
+ Attention processor for IP-Adapter for PyTorch 2.0.
+
+ Args:
+ hidden_size (`int`):
+ The hidden size of the attention layer.
+ cross_attention_dim (`int`):
+ The number of channels in the `encoder_hidden_states`.
+ num_tokens (`int`, `Tuple[int]` or `List[int]`, defaults to `(4,)`):
+ The context length of the image features.
+ scale (`float` or `List[float]`, defaults to 1.0):
+ the weight scale of image prompt.
+ """
+
+ def __init__(self, hidden_size, cross_attention_dim=None, num_tokens=(4,), scale=1.0):
+ super().__init__()
+
+ if not hasattr(F, "scaled_dot_product_attention"):
+ raise ImportError(
+ f"{self.__class__.__name__} requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0."
+ )
+
+ self.hidden_size = hidden_size
+ self.cross_attention_dim = cross_attention_dim
+
+ if not isinstance(num_tokens, (tuple, list)):
+ num_tokens = [num_tokens]
+ self.num_tokens = num_tokens
+
+ if not isinstance(scale, list):
+ scale = [scale] * len(num_tokens)
+ if len(scale) != len(num_tokens):
+ raise ValueError("`scale` should be a list of integers with the same length as `num_tokens`.")
+ self.scale = scale
+ self.to_k_ip = nn.ModuleList(
+ [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
+ )
+ self.to_v_ip = nn.ModuleList(
+ [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
+ )
+
+ def __call__(
+ self,
+ attn: Attention,
+ hidden_states: torch.FloatTensor,
+ encoder_hidden_states: Optional[torch.FloatTensor] = None,
+ attention_mask: Optional[torch.FloatTensor] = None,
+ temb: Optional[torch.FloatTensor] = None,
+ scale: float = 1.0,
+ ip_adapter_masks: Optional[torch.FloatTensor] = None,
+ ):
+ residual = hidden_states
+
+ # separate ip_hidden_states from encoder_hidden_states
+ if encoder_hidden_states is not None:
+ if isinstance(encoder_hidden_states, tuple):
+ encoder_hidden_states, ip_hidden_states = encoder_hidden_states
+ else:
+ deprecation_message = (
+ "You have passed a tensor as `encoder_hidden_states`. This is deprecated and will be removed in a future release."
+ " Please make sure to update your script to pass `encoder_hidden_states` as a tuple to suppress this warning."
+ )
+ deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
+ end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
+ encoder_hidden_states, ip_hidden_states = (
+ encoder_hidden_states[:, :end_pos, :],
+ [encoder_hidden_states[:, end_pos:, :]],
+ )
+
+ if attn.spatial_norm is not None:
+ hidden_states = attn.spatial_norm(hidden_states, temb)
+
+ input_ndim = hidden_states.ndim
+
+ if input_ndim == 4:
+ batch_size, channel, height, width = hidden_states.shape
+ hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
+
+ batch_size, sequence_length, _ = (
+ hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
+ )
+
+ if attention_mask is not None:
+ attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
+ # scaled_dot_product_attention expects attention_mask shape to be
+ # (batch, heads, source_length, target_length)
+ attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
+
+ if attn.group_norm is not None:
+ hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
+
+ query = attn.to_q(hidden_states)
+
+ if encoder_hidden_states is None:
+ encoder_hidden_states = hidden_states
+ elif attn.norm_cross:
+ encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
+
+ key = attn.to_k(encoder_hidden_states)
+ value = attn.to_v(encoder_hidden_states)
+
+ inner_dim = key.shape[-1]
+ head_dim = inner_dim // attn.heads
+
+ query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+
+ key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+ value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+
+ # the output of sdp = (batch, num_heads, seq_len, head_dim)
+ # TODO: add support for attn.scale when we move to Torch 2.1
+ hidden_states = F.scaled_dot_product_attention(
+ query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
+ )
+
+ hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
+ hidden_states = hidden_states.to(query.dtype)
+
+ if ip_adapter_masks is not None:
+ if not isinstance(ip_adapter_masks, List):
+ # for backward compatibility, we accept `ip_adapter_mask` as a tensor of shape [num_ip_adapter, 1, height, width]
+ ip_adapter_masks = list(ip_adapter_masks.unsqueeze(1))
+ if not (len(ip_adapter_masks) == len(self.scale) == len(ip_hidden_states)):
+ raise ValueError(
+ f"Length of ip_adapter_masks array ({len(ip_adapter_masks)}) must match "
+ f"length of self.scale array ({len(self.scale)}) and number of ip_hidden_states "
+ f"({len(ip_hidden_states)})"
+ )
+ else:
+ for index, (mask, scale, ip_state) in enumerate(zip(ip_adapter_masks, self.scale, ip_hidden_states)):
+ if not isinstance(mask, torch.Tensor) or mask.ndim != 4:
+ raise ValueError(
+ "Each element of the ip_adapter_masks array should be a tensor with shape "
+ "[1, num_images_for_ip_adapter, height, width]."
+ " Please use `IPAdapterMaskProcessor` to preprocess your mask"
+ )
+ if mask.shape[1] != ip_state.shape[1]:
+ raise ValueError(
+ f"Number of masks ({mask.shape[1]}) does not match "
+ f"number of ip images ({ip_state.shape[1]}) at index {index}"
+ )
+ if isinstance(scale, list) and not len(scale) == mask.shape[1]:
+ raise ValueError(
+ f"Number of masks ({mask.shape[1]}) does not match "
+ f"number of scales ({len(scale)}) at index {index}"
+ )
+ else:
+ ip_adapter_masks = [None] * len(self.scale)
+
+ # for ip-adapter
+ for current_ip_hidden_states, scale, to_k_ip, to_v_ip, mask in zip(
+ ip_hidden_states, self.scale, self.to_k_ip, self.to_v_ip, ip_adapter_masks
+ ):
+ skip = False
+ if isinstance(scale, list):
+ if all(s == 0 for s in scale):
+ skip = True
+ elif scale == 0:
+ skip = True
+ if not skip:
+ ip_key = to_k_ip(current_ip_hidden_states)
+ ip_value = to_v_ip(current_ip_hidden_states)
+
+ ip_key = ip_key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+ ip_value = ip_value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
+
+ # the output of sdp = (batch, num_heads, seq_len, head_dim)
+ # TODO: add support for attn.scale when we move to Torch 2.1
+ current_ip_hidden_states = F.scaled_dot_product_attention(
+ query, ip_key, ip_value, attn_mask=None, dropout_p=0.0, is_causal=False
+ )
+
+ current_ip_hidden_states = current_ip_hidden_states.transpose(1, 2).reshape(
+ batch_size, -1, attn.heads * head_dim
+ )
+ current_ip_hidden_states = current_ip_hidden_states.to(query.dtype)
+
+ hidden_states = hidden_states + scale * current_ip_hidden_states
+
+ # linear proj
+ hidden_states = attn.to_out[0](hidden_states)
+ # dropout
+ hidden_states = attn.to_out[1](hidden_states)
+
+ if input_ndim == 4:
+ hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
+
+ if attn.residual_connection:
+ hidden_states = hidden_states + residual
+
+ hidden_states = hidden_states / attn.rescale_output_factor
+
+ return hidden_states
diff --git a/foleycrafter/models/auffusion/loaders/ip_adapter.py b/foleycrafter/models/audio_generator/loaders/ip_adapter.py
similarity index 52%
rename from foleycrafter/models/auffusion/loaders/ip_adapter.py
rename to foleycrafter/models/audio_generator/loaders/ip_adapter.py
index 0abdf4e..5fe208a 100644
--- a/foleycrafter/models/auffusion/loaders/ip_adapter.py
+++ b/foleycrafter/models/audio_generator/loaders/ip_adapter.py
@@ -39,9 +39,8 @@
IPAdapterAttnProcessor,
)
-from foleycrafter.models.auffusion.attention_processor import (
+from foleycrafter.models.audio_generator.attention_processor import (
IPAdapterAttnProcessor2_0,
- VPTemporalAdapterAttnProcessor2_0,
)
@@ -284,241 +283,3 @@ def unload_ip_adapter(self):
# restore original Unet attention processors layers
self.unet.set_default_attn_processor()
-
-
-class VPAdapterMixin:
- """Mixin for handling IP Adapters."""
-
- @validate_hf_hub_args
- def load_ip_adapter(
- self,
- pretrained_model_name_or_path_or_dict: Union[str, List[str], Dict[str, torch.Tensor]],
- subfolder: Union[str, List[str]],
- weight_name: Union[str, List[str]],
- image_encoder_folder: Optional[str] = "image_encoder",
- **kwargs,
- ):
- """
- Parameters:
- pretrained_model_name_or_path_or_dict (`str` or `List[str]` or `os.PathLike` or `List[os.PathLike]` or `dict` or `List[dict]`):
- Can be either:
-
- - A string, the *model id* (for example `google/ddpm-celebahq-256`) of a pretrained model hosted on
- the Hub.
- - A path to a *directory* (for example `./my_model_directory`) containing the model weights saved
- with [`ModelMixin.save_pretrained`].
- - A [torch state
- dict](https://pytorch.org/tutorials/beginner/saving_loading_models.html#what-is-a-state-dict).
- subfolder (`str` or `List[str]`):
- The subfolder location of a model file within a larger model repository on the Hub or locally.
- If a list is passed, it should have the same length as `weight_name`.
- weight_name (`str` or `List[str]`):
- The name of the weight file to load. If a list is passed, it should have the same length as
- `weight_name`.
- image_encoder_folder (`str`, *optional*, defaults to `image_encoder`):
- The subfolder location of the image encoder within a larger model repository on the Hub or locally.
- Pass `None` to not load the image encoder. If the image encoder is located in a folder inside `subfolder`,
- you only need to pass the name of the folder that contains image encoder weights, e.g. `image_encoder_folder="image_encoder"`.
- If the image encoder is located in a folder other than `subfolder`, you should pass the path to the folder that contains image encoder weights,
- for example, `image_encoder_folder="different_subfolder/image_encoder"`.
- cache_dir (`Union[str, os.PathLike]`, *optional*):
- Path to a directory where a downloaded pretrained model configuration is cached if the standard cache
- is not used.
- force_download (`bool`, *optional*, defaults to `False`):
- Whether or not to force the (re-)download of the model weights and configuration files, overriding the
- cached versions if they exist.
- resume_download (`bool`, *optional*, defaults to `False`):
- Whether or not to resume downloading the model weights and configuration files. If set to `False`, any
- incompletely downloaded files are deleted.
- proxies (`Dict[str, str]`, *optional*):
- A dictionary of proxy servers to use by protocol or endpoint, for example, `{'http': 'foo.bar:3128',
- 'http://hostname': 'foo.bar:4012'}`. The proxies are used on each request.
- local_files_only (`bool`, *optional*, defaults to `False`):
- Whether to only load local model weights and configuration files or not. If set to `True`, the model
- won't be downloaded from the Hub.
- token (`str` or *bool*, *optional*):
- The token to use as HTTP bearer authorization for remote files. If `True`, the token generated from
- `diffusers-cli login` (stored in `~/.huggingface`) is used.
- revision (`str`, *optional*, defaults to `"main"`):
- The specific model version to use. It can be a branch name, a tag name, a commit id, or any identifier
- allowed by Git.
- low_cpu_mem_usage (`bool`, *optional*, defaults to `True` if torch version >= 1.9.0 else `False`):
- Speed up model loading only loading the pretrained weights and not initializing the weights. This also
- tries to not use more than 1x model size in CPU memory (including peak memory) while loading the model.
- Only supported for PyTorch >= 1.9.0. If you are using an older version of PyTorch, setting this
- argument to `True` will raise an error.
- """
-
- # handle the list inputs for multiple IP Adapters
- if not isinstance(weight_name, list):
- weight_name = [weight_name]
-
- if not isinstance(pretrained_model_name_or_path_or_dict, list):
- pretrained_model_name_or_path_or_dict = [pretrained_model_name_or_path_or_dict]
- if len(pretrained_model_name_or_path_or_dict) == 1:
- pretrained_model_name_or_path_or_dict = pretrained_model_name_or_path_or_dict * len(weight_name)
-
- if not isinstance(subfolder, list):
- subfolder = [subfolder]
- if len(subfolder) == 1:
- subfolder = subfolder * len(weight_name)
-
- if len(weight_name) != len(pretrained_model_name_or_path_or_dict):
- raise ValueError("`weight_name` and `pretrained_model_name_or_path_or_dict` must have the same length.")
-
- if len(weight_name) != len(subfolder):
- raise ValueError("`weight_name` and `subfolder` must have the same length.")
-
- # Load the main state dict first.
- cache_dir = kwargs.pop("cache_dir", None)
- force_download = kwargs.pop("force_download", False)
- resume_download = kwargs.pop("resume_download", False)
- proxies = kwargs.pop("proxies", None)
- local_files_only = kwargs.pop("local_files_only", None)
- token = kwargs.pop("token", None)
- revision = kwargs.pop("revision", None)
- low_cpu_mem_usage = kwargs.pop("low_cpu_mem_usage", _LOW_CPU_MEM_USAGE_DEFAULT)
-
- if low_cpu_mem_usage and not is_accelerate_available():
- low_cpu_mem_usage = False
- logger.warning(
- "Cannot initialize model with low cpu memory usage because `accelerate` was not found in the"
- " environment. Defaulting to `low_cpu_mem_usage=False`. It is strongly recommended to install"
- " `accelerate` for faster and less memory-intense model loading. You can do so with: \n```\npip"
- " install accelerate\n```\n."
- )
-
- if low_cpu_mem_usage is True and not is_torch_version(">=", "1.9.0"):
- raise NotImplementedError(
- "Low memory initialization requires torch >= 1.9.0. Please either update your PyTorch version or set"
- " `low_cpu_mem_usage=False`."
- )
-
- user_agent = {
- "file_type": "attn_procs_weights",
- "framework": "pytorch",
- }
- state_dicts = []
- for pretrained_model_name_or_path_or_dict, weight_name, subfolder in zip(
- pretrained_model_name_or_path_or_dict, weight_name, subfolder
- ):
- if not isinstance(pretrained_model_name_or_path_or_dict, dict):
- model_file = _get_model_file(
- pretrained_model_name_or_path_or_dict,
- weights_name=weight_name,
- cache_dir=cache_dir,
- force_download=force_download,
- resume_download=resume_download,
- proxies=proxies,
- local_files_only=local_files_only,
- token=token,
- revision=revision,
- subfolder=subfolder,
- user_agent=user_agent,
- )
- if weight_name.endswith(".safetensors"):
- state_dict = {"image_proj": {}, "ip_adapter": {}}
- with safe_open(model_file, framework="pt", device="cpu") as f:
- for key in f.keys():
- if key.startswith("image_proj."):
- state_dict["image_proj"][key.replace("image_proj.", "")] = f.get_tensor(key)
- elif key.startswith("ip_adapter."):
- state_dict["ip_adapter"][key.replace("ip_adapter.", "")] = f.get_tensor(key)
- else:
- state_dict = torch.load(model_file, map_location="cpu")
- else:
- state_dict = pretrained_model_name_or_path_or_dict
-
- keys = list(state_dict.keys())
- if keys != ["image_proj", "ip_adapter"]:
- raise ValueError("Required keys are (`image_proj` and `ip_adapter`) missing from the state dict.")
-
- state_dicts.append(state_dict)
-
- # load CLIP image encoder here if it has not been registered to the pipeline yet
- if hasattr(self, "image_encoder") and getattr(self, "image_encoder", None) is None:
- if image_encoder_folder is not None:
- if not isinstance(pretrained_model_name_or_path_or_dict, dict):
- logger.info(f"loading image_encoder from {pretrained_model_name_or_path_or_dict}")
- if image_encoder_folder.count("/") == 0:
- image_encoder_subfolder = Path(subfolder, image_encoder_folder).as_posix()
- else:
- image_encoder_subfolder = Path(image_encoder_folder).as_posix()
-
- image_encoder = CLIPVisionModelWithProjection.from_pretrained(
- pretrained_model_name_or_path_or_dict,
- subfolder=image_encoder_subfolder,
- low_cpu_mem_usage=low_cpu_mem_usage,
- ).to(self.device, dtype=self.dtype)
- self.register_modules(image_encoder=image_encoder)
- else:
- raise ValueError(
- "`image_encoder` cannot be loaded because `pretrained_model_name_or_path_or_dict` is a state dict."
- )
- else:
- logger.warning(
- "image_encoder is not loaded since `image_encoder_folder=None` passed. You will not be able to use `ip_adapter_image` when calling the pipeline with IP-Adapter."
- "Use `ip_adapter_image_embeds` to pass pre-generated image embedding instead."
- )
-
- # create feature extractor if it has not been registered to the pipeline yet
- if hasattr(self, "feature_extractor") and getattr(self, "feature_extractor", None) is None:
- feature_extractor = CLIPImageProcessor()
- self.register_modules(feature_extractor=feature_extractor)
-
- # load ip-adapter into unet
- unet = getattr(self, self.unet_name) if not hasattr(self, "unet") else self.unet
- unet._load_ip_adapter_weights_VPAdapter(state_dicts)
-
- def set_ip_adapter_scale(self, scale):
- """
- Sets the conditioning scale between text and image.
-
- Example:
-
- ```py
- pipeline.set_ip_adapter_scale(0.5)
- ```
- """
- unet = getattr(self, self.unet_name) if not hasattr(self, "unet") else self.unet
- for attn_processor in unet.attn_processors.values():
- if isinstance(attn_processor, (IPAdapterAttnProcessor, VPTemporalAdapterAttnProcessor2_0)):
- if not isinstance(scale, list):
- scale = [scale] * len(attn_processor.scale)
- if len(attn_processor.scale) != len(scale):
- raise ValueError(
- f"`scale` should be a list of same length as the number if ip-adapters "
- f"Expected {len(attn_processor.scale)} but got {len(scale)}."
- )
- attn_processor.scale = scale
-
- def unload_ip_adapter(self):
- """
- Unloads the IP Adapter weights
-
- Examples:
-
- ```python
- >>> # Assuming `pipeline` is already loaded with the IP Adapter weights.
- >>> pipeline.unload_ip_adapter()
- >>> ...
- ```
- """
- # remove CLIP image encoder
- if hasattr(self, "image_encoder") and getattr(self, "image_encoder", None) is not None:
- self.image_encoder = None
- self.register_to_config(image_encoder=[None, None])
-
- # remove feature extractor only when safety_checker is None as safety_checker uses
- # the feature_extractor later
- if not hasattr(self, "safety_checker"):
- if hasattr(self, "feature_extractor") and getattr(self, "feature_extractor", None) is not None:
- self.feature_extractor = None
- self.register_to_config(feature_extractor=[None, None])
-
- # remove hidden encoder
- self.unet.encoder_hid_proj = None
- self.config.encoder_hid_dim_type = None
-
- # restore original Unet attention processors layers
- self.unet.set_default_attn_processor()
diff --git a/foleycrafter/models/auffusion/loaders/unet.py b/foleycrafter/models/audio_generator/loaders/unet.py
similarity index 84%
rename from foleycrafter/models/auffusion/loaders/unet.py
rename to foleycrafter/models/audio_generator/loaders/unet.py
index f29399c..e1f07f2 100644
--- a/foleycrafter/models/auffusion/loaders/unet.py
+++ b/foleycrafter/models/audio_generator/loaders/unet.py
@@ -36,10 +36,9 @@
set_adapter_layers,
set_weights_and_activate_adapters,
)
-from foleycrafter.models.auffusion.attention_processor import (
+from foleycrafter.models.audio_generator.attention_processor import (
AttnProcessor2_0,
IPAdapterAttnProcessor2_0,
- VPTemporalAdapterAttnProcessor2_0,
)
@@ -50,41 +49,6 @@
logger = logging.get_logger(__name__)
-class VPAdapterImageProjection(nn.Module):
- def __init__(self, IPAdapterImageProjectionLayers: Union[List[nn.Module], Tuple[nn.Module]]):
- super().__init__()
- self.image_projection_layers = nn.ModuleList(IPAdapterImageProjectionLayers)
-
- def forward(self, image_embeds: List[torch.FloatTensor]):
- projected_image_embeds = []
-
- # currently, we accept `image_embeds` as
- # 1. a tensor (deprecated) with shape [batch_size, embed_dim] or [batch_size, sequence_length, embed_dim]
- # 2. list of `n` tensors where `n` is number of ip-adapters, each tensor can hae shape [batch_size, num_images, embed_dim] or [batch_size, num_images, sequence_length, embed_dim]
- if not isinstance(image_embeds, list):
- # deprecation_message = (
- # "You have passed a tensor as `image_embeds`.This is deprecated and will be removed in a future release."
- # " Please make sure to update your script to pass `image_embeds` as a list of tensors to suppress this warning."
- # )
- image_embeds = [image_embeds.unsqueeze(1)]
-
- if len(image_embeds) != len(self.image_projection_layers):
- raise ValueError(
- f"image_embeds must have the same length as image_projection_layers, got {len(image_embeds)} and {len(self.image_projection_layers)}"
- )
-
- for image_embed, image_projection_layer in zip(image_embeds, self.image_projection_layers):
- image_embed = image_embed.squeeze(1)
- batch_size, num_images = image_embed.shape[0], image_embed.shape[1]
- image_embed = image_embed.reshape((batch_size * num_images,) + image_embed.shape[2:])
- image_embed = image_projection_layer(image_embed)
- image_embed = image_embed.reshape((batch_size, num_images) + image_embed.shape[1:])
-
- projected_image_embeds.append(image_embed)
-
- return projected_image_embeds
-
-
class MultiIPAdapterImageProjection(nn.Module):
def __init__(self, IPAdapterImageProjectionLayers: Union[List[nn.Module], Tuple[nn.Module]]):
super().__init__()
@@ -783,93 +747,6 @@ def _convert_ip_adapter_image_proj_to_diffusers(self, state_dict, low_cpu_mem_us
return image_projection
- def _convert_ip_adapter_attn_to_diffusers_VPAdapter(self, state_dicts, low_cpu_mem_usage=False):
- from diffusers.models.attention_processor import (
- AttnProcessor,
- IPAdapterAttnProcessor,
- )
-
- if low_cpu_mem_usage:
- if is_accelerate_available():
- from accelerate import init_empty_weights
-
- else:
- low_cpu_mem_usage = False
- logger.warning(
- "Cannot initialize model with low cpu memory usage because `accelerate` was not found in the"
- " environment. Defaulting to `low_cpu_mem_usage=False`. It is strongly recommended to install"
- " `accelerate` for faster and less memory-intense model loading. You can do so with: \n```\npip"
- " install accelerate\n```\n."
- )
-
- if low_cpu_mem_usage is True and not is_torch_version(">=", "1.9.0"):
- raise NotImplementedError(
- "Low memory initialization requires torch >= 1.9.0. Please either update your PyTorch version or set"
- " `low_cpu_mem_usage=False`."
- )
-
- # set ip-adapter cross-attention processors & load state_dict
- attn_procs = {}
- key_id = 1
- init_context = init_empty_weights if low_cpu_mem_usage else nullcontext
- for name in self.attn_processors.keys():
- cross_attention_dim = None if name.endswith("attn1.processor") else self.config.cross_attention_dim
- if name.startswith("mid_block"):
- hidden_size = self.config.block_out_channels[-1]
- elif name.startswith("up_blocks"):
- block_id = int(name[len("up_blocks.")])
- hidden_size = list(reversed(self.config.block_out_channels))[block_id]
- elif name.startswith("down_blocks"):
- block_id = int(name[len("down_blocks.")])
- hidden_size = self.config.block_out_channels[block_id]
-
- if cross_attention_dim is None or "motion_modules" in name or "fuser" in name:
- attn_processor_class = (
- AttnProcessor2_0 if hasattr(F, "scaled_dot_product_attention") else AttnProcessor
- )
- attn_procs[name] = attn_processor_class()
- else:
- attn_processor_class = (
- VPTemporalAdapterAttnProcessor2_0
- if hasattr(F, "scaled_dot_product_attention")
- else IPAdapterAttnProcessor
- )
- num_image_text_embeds = []
- for state_dict in state_dicts:
- if "proj.weight" in state_dict["image_proj"]:
- # IP-Adapter
- num_image_text_embeds += [4]
- elif "proj.3.weight" in state_dict["image_proj"]:
- # IP-Adapter Full Face
- num_image_text_embeds += [257] # 256 CLIP tokens + 1 CLS token
- else:
- # IP-Adapter Plus
- num_image_text_embeds += [state_dict["image_proj"]["latents"].shape[1]]
-
- with init_context():
- attn_procs[name] = attn_processor_class(
- hidden_size=hidden_size,
- cross_attention_dim=cross_attention_dim,
- scale=1.0,
- num_tokens=num_image_text_embeds,
- )
-
- value_dict = {}
- for i, state_dict in enumerate(state_dicts):
- value_dict.update({f"to_k_ip.{i}.weight": state_dict["ip_adapter"][f"{key_id}.to_k_ip.weight"]})
- value_dict.update({f"to_v_ip.{i}.weight": state_dict["ip_adapter"][f"{key_id}.to_v_ip.weight"]})
-
- if not low_cpu_mem_usage:
- attn_procs[name].load_state_dict(value_dict)
- else:
- device = next(iter(value_dict.values())).device
- dtype = next(iter(value_dict.values())).dtype
- load_model_dict_into_meta(attn_procs[name], value_dict, device=device, dtype=dtype)
-
- key_id += 2
-
- return attn_procs
-
def _convert_ip_adapter_attn_to_diffusers(self, state_dicts, low_cpu_mem_usage=False):
from diffusers.models.attention_processor import (
AttnProcessor,
@@ -971,22 +848,3 @@ def _load_ip_adapter_weights(self, state_dicts, low_cpu_mem_usage=False):
self.config.encoder_hid_dim_type = "ip_image_proj"
self.to(dtype=self.dtype, device=self.device)
-
- def _load_ip_adapter_weights_VPAdapter(self, state_dicts, low_cpu_mem_usage=False):
- attn_procs = self._convert_ip_adapter_attn_to_diffusers_VPAdapter(
- state_dicts, low_cpu_mem_usage=low_cpu_mem_usage
- )
- self.set_attn_processor(attn_procs)
-
- # convert IP-Adapter Image Projection layers to diffusers
- image_projection_layers = []
- for state_dict in state_dicts:
- image_projection_layer = self._convert_ip_adapter_image_proj_to_diffusers(
- state_dict["image_proj"], low_cpu_mem_usage=low_cpu_mem_usage
- )
- image_projection_layers.append(image_projection_layer)
-
- self.encoder_hid_proj = VPAdapterImageProjection(image_projection_layers)
- self.config.encoder_hid_dim_type = "ip_image_proj"
-
- self.to(dtype=self.dtype, device=self.device)
diff --git a/foleycrafter/models/audio_generator/unet.py b/foleycrafter/models/audio_generator/unet.py
new file mode 100644
index 0000000..e90cde1
--- /dev/null
+++ b/foleycrafter/models/audio_generator/unet.py
@@ -0,0 +1,518 @@
+# Copyright 2023 The HuggingFace Team. All rights reserved.
+
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+from typing import Any, Dict, Optional, Tuple, Union
+
+import torch
+import torch.utils.checkpoint
+
+import diffusers
+from diffusers.configuration_utils import register_to_config
+from diffusers.models.unet_2d_condition import UNet2DConditionOutput
+from diffusers.utils import USE_PEFT_BACKEND, deprecate, logging, scale_lora_layers, unscale_lora_layers
+from foleycrafter.models.audio_generator.loaders.unet import UNet2DConditionLoadersMixin
+
+
+logger = logging.get_logger(__name__) # pylint: disable=invalid-name
+
+
+class UNet2DConditionModel(UNet2DConditionLoadersMixin, diffusers.models.UNet2DConditionModel):
+ @register_to_config
+ def __init__(
+ self,
+ sample_size: Optional[int] = None,
+ in_channels: int = 4,
+ out_channels: int = 4,
+ center_input_sample: bool = False,
+ flip_sin_to_cos: bool = True,
+ freq_shift: int = 0,
+ down_block_types: Tuple[str] = (
+ "CrossAttnDownBlock2D",
+ "CrossAttnDownBlock2D",
+ "CrossAttnDownBlock2D",
+ "DownBlock2D",
+ ),
+ mid_block_type: Optional[str] = "UNetMidBlock2DCrossAttn",
+ up_block_types: Tuple[str] = ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"),
+ only_cross_attention: Union[bool, Tuple[bool]] = False,
+ block_out_channels: Tuple[int] = (320, 640, 1280, 1280),
+ layers_per_block: Union[int, Tuple[int]] = 2,
+ downsample_padding: int = 1,
+ mid_block_scale_factor: float = 1,
+ dropout: float = 0.0,
+ act_fn: str = "silu",
+ norm_num_groups: Optional[int] = 32,
+ norm_eps: float = 1e-5,
+ cross_attention_dim: Union[int, Tuple[int]] = 1280,
+ transformer_layers_per_block: Union[int, Tuple[int], Tuple[Tuple]] = 1,
+ reverse_transformer_layers_per_block: Optional[Tuple[Tuple[int]]] = None,
+ encoder_hid_dim: Optional[int] = None,
+ encoder_hid_dim_type: Optional[str] = None,
+ attention_head_dim: Union[int, Tuple[int]] = 8,
+ num_attention_heads: Optional[Union[int, Tuple[int]]] = None,
+ dual_cross_attention: bool = False,
+ use_linear_projection: bool = False,
+ class_embed_type: Optional[str] = None,
+ addition_embed_type: Optional[str] = None,
+ addition_time_embed_dim: Optional[int] = None,
+ num_class_embeds: Optional[int] = None,
+ upcast_attention: bool = False,
+ resnet_time_scale_shift: str = "default",
+ resnet_skip_time_act: bool = False,
+ resnet_out_scale_factor: int = 1.0,
+ time_embedding_type: str = "positional",
+ time_embedding_dim: Optional[int] = None,
+ time_embedding_act_fn: Optional[str] = None,
+ timestep_post_act: Optional[str] = None,
+ time_cond_proj_dim: Optional[int] = None,
+ conv_in_kernel: int = 3,
+ conv_out_kernel: int = 3,
+ projection_class_embeddings_input_dim: Optional[int] = None,
+ attention_type: str = "default",
+ class_embeddings_concat: bool = False,
+ mid_block_only_cross_attention: Optional[bool] = None,
+ cross_attention_norm: Optional[str] = None,
+ addition_embed_type_num_heads=64,
+ ):
+ super().__init__(
+ sample_size=sample_size,
+ in_channels=in_channels,
+ out_channels=out_channels,
+ center_input_sample=center_input_sample,
+ flip_sin_to_cos=flip_sin_to_cos,
+ freq_shift=freq_shift,
+ down_block_types=down_block_types,
+ mid_block_type=mid_block_type,
+ up_block_types=up_block_types,
+ only_cross_attention=only_cross_attention,
+ block_out_channels=block_out_channels,
+ layers_per_block=layers_per_block,
+ downsample_padding=downsample_padding,
+ mid_block_scale_factor=mid_block_scale_factor,
+ dropout=dropout,
+ act_fn=act_fn,
+ norm_num_groups=norm_num_groups,
+ norm_eps=norm_eps,
+ cross_attention_dim=cross_attention_dim,
+ transformer_layers_per_block=transformer_layers_per_block,
+ reverse_transformer_layers_per_block=reverse_transformer_layers_per_block,
+ encoder_hid_dim=encoder_hid_dim,
+ encoder_hid_dim_type=encoder_hid_dim_type,
+ attention_head_dim=attention_head_dim,
+ num_attention_heads=num_attention_heads,
+ dual_cross_attention=dual_cross_attention,
+ use_linear_projection=use_linear_projection,
+ class_embed_type=class_embed_type,
+ addition_embed_type=addition_embed_type,
+ addition_time_embed_dim=addition_time_embed_dim,
+ num_class_embeds=num_class_embeds,
+ upcast_attention=upcast_attention,
+ resnet_time_scale_shift=resnet_time_scale_shift,
+ resnet_skip_time_act=resnet_skip_time_act,
+ resnet_out_scale_factor=resnet_out_scale_factor,
+ time_embedding_type=time_embedding_type,
+ time_embedding_dim=time_embedding_dim,
+ time_embedding_act_fn=time_embedding_act_fn,
+ timestep_post_act=timestep_post_act,
+ time_cond_proj_dim=time_cond_proj_dim,
+ conv_in_kernel=conv_in_kernel,
+ conv_out_kernel=conv_out_kernel,
+ projection_class_embeddings_input_dim=projection_class_embeddings_input_dim,
+ attention_type=attention_type,
+ class_embeddings_concat=class_embeddings_concat,
+ mid_block_only_cross_attention=mid_block_only_cross_attention,
+ cross_attention_norm=cross_attention_norm,
+ addition_embed_type_num_heads=addition_embed_type_num_heads,
+ )
+
+ def forward(
+ self,
+ sample: torch.FloatTensor,
+ timestep: Union[torch.Tensor, float, int],
+ encoder_hidden_states: torch.Tensor,
+ class_labels: Optional[torch.Tensor] = None,
+ timestep_cond: Optional[torch.Tensor] = None,
+ attention_mask: Optional[torch.Tensor] = None,
+ cross_attention_kwargs: Optional[Dict[str, Any]] = None,
+ added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None,
+ down_block_additional_residuals: Optional[Tuple[torch.Tensor]] = None,
+ mid_block_additional_residual: Optional[torch.Tensor] = None,
+ down_intrablock_additional_residuals: Optional[Tuple[torch.Tensor]] = None,
+ encoder_attention_mask: Optional[torch.Tensor] = None,
+ return_dict: bool = True,
+ ) -> Union[UNet2DConditionOutput, Tuple]:
+ r"""
+ The [`UNet2DConditionModel`] forward method.
+
+ Args:
+ sample (`torch.FloatTensor`):
+ The noisy input tensor with the following shape `(batch, channel, height, width)`.
+ timestep (`torch.FloatTensor` or `float` or `int`): The number of timesteps to denoise an input.
+ encoder_hidden_states (`torch.FloatTensor`):
+ The encoder hidden states with shape `(batch, sequence_length, feature_dim)`.
+ class_labels (`torch.Tensor`, *optional*, defaults to `None`):
+ Optional class labels for conditioning. Their embeddings will be summed with the timestep embeddings.
+ timestep_cond: (`torch.Tensor`, *optional*, defaults to `None`):
+ Conditional embeddings for timestep. If provided, the embeddings will be summed with the samples passed
+ through the `self.time_embedding` layer to obtain the timestep embeddings.
+ attention_mask (`torch.Tensor`, *optional*, defaults to `None`):
+ An attention mask of shape `(batch, key_tokens)` is applied to `encoder_hidden_states`. If `1` the mask
+ is kept, otherwise if `0` it is discarded. Mask will be converted into a bias, which adds large
+ negative values to the attention scores corresponding to "discard" tokens.
+ cross_attention_kwargs (`dict`, *optional*):
+ A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
+ `self.processor` in
+ [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
+ added_cond_kwargs: (`dict`, *optional*):
+ A kwargs dictionary containing additional embeddings that if specified are added to the embeddings that
+ are passed along to the UNet blocks.
+ down_block_additional_residuals: (`tuple` of `torch.Tensor`, *optional*):
+ A tuple of tensors that if specified are added to the residuals of down unet blocks.
+ mid_block_additional_residual: (`torch.Tensor`, *optional*):
+ A tensor that if specified is added to the residual of the middle unet block.
+ encoder_attention_mask (`torch.Tensor`):
+ A cross-attention mask of shape `(batch, sequence_length)` is applied to `encoder_hidden_states`. If
+ `True` the mask is kept, otherwise if `False` it is discarded. Mask will be converted into a bias,
+ which adds large negative values to the attention scores corresponding to "discard" tokens.
+ return_dict (`bool`, *optional*, defaults to `True`):
+ Whether or not to return a [`~models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain
+ tuple.
+ cross_attention_kwargs (`dict`, *optional*):
+ A kwargs dictionary that if specified is passed along to the [`AttnProcessor`].
+ added_cond_kwargs: (`dict`, *optional*):
+ A kwargs dictionary containin additional embeddings that if specified are added to the embeddings that
+ are passed along to the UNet blocks.
+ down_block_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
+ additional residuals to be added to UNet long skip connections from down blocks to up blocks for
+ example from ControlNet side model(s)
+ mid_block_additional_residual (`torch.Tensor`, *optional*):
+ additional residual to be added to UNet mid block output, for example from ControlNet side model
+ down_intrablock_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
+ additional residuals to be added within UNet down blocks, for example from T2I-Adapter side model(s)
+
+ Returns:
+ [`~models.unet_2d_condition.UNet2DConditionOutput`] or `tuple`:
+ If `return_dict` is True, an [`~models.unet_2d_condition.UNet2DConditionOutput`] is returned, otherwise
+ a `tuple` is returned where the first element is the sample tensor.
+ """
+ # By default samples have to be AT least a multiple of the overall upsampling factor.
+ # The overall upsampling factor is equal to 2 ** (# num of upsampling layers).
+ # However, the upsampling interpolation output size can be forced to fit any upsampling size
+ # on the fly if necessary.
+ default_overall_up_factor = 2**self.num_upsamplers
+
+ # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor`
+ forward_upsample_size = False
+ upsample_size = None
+
+ for dim in sample.shape[-2:]:
+ if dim % default_overall_up_factor != 0:
+ # Forward upsample size to force interpolation output size.
+ forward_upsample_size = True
+ break
+
+ # ensure attention_mask is a bias, and give it a singleton query_tokens dimension
+ # expects mask of shape:
+ # [batch, key_tokens]
+ # adds singleton query_tokens dimension:
+ # [batch, 1, key_tokens]
+ # this helps to broadcast it as a bias over attention scores, which will be in one of the following shapes:
+ # [batch, heads, query_tokens, key_tokens] (e.g. torch sdp attn)
+ # [batch * heads, query_tokens, key_tokens] (e.g. xformers or classic attn)
+ if attention_mask is not None:
+ # assume that mask is expressed as:
+ # (1 = keep, 0 = discard)
+ # convert mask into a bias that can be added to attention scores:
+ # (keep = +0, discard = -10000.0)
+ attention_mask = (1 - attention_mask.to(sample.dtype)) * -10000.0
+ attention_mask = attention_mask.unsqueeze(1)
+
+ # convert encoder_attention_mask to a bias the same way we do for attention_mask
+ if encoder_attention_mask is not None:
+ encoder_attention_mask = (1 - encoder_attention_mask.to(sample.dtype)) * -10000.0
+ encoder_attention_mask = encoder_attention_mask.unsqueeze(1)
+
+ # 0. center input if necessary
+ if self.config.center_input_sample:
+ sample = 2 * sample - 1.0
+
+ # 1. time
+ timesteps = timestep
+ if not torch.is_tensor(timesteps):
+ # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can
+ # This would be a good case for the `match` statement (Python 3.10+)
+ is_mps = sample.device.type == "mps"
+ if isinstance(timestep, float):
+ dtype = torch.float32 if is_mps else torch.float64
+ else:
+ dtype = torch.int32 if is_mps else torch.int64
+ timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device)
+ elif len(timesteps.shape) == 0:
+ timesteps = timesteps[None].to(sample.device)
+
+ # broadcast to batch dimension in a way that's compatible with ONNX/Core ML
+ timesteps = timesteps.expand(sample.shape[0])
+
+ t_emb = self.time_proj(timesteps)
+
+ # `Timesteps` does not contain any weights and will always return f32 tensors
+ # but time_embedding might actually be running in fp16. so we need to cast here.
+ # there might be better ways to encapsulate this.
+ t_emb = t_emb.to(dtype=sample.dtype)
+
+ emb = self.time_embedding(t_emb, timestep_cond)
+ aug_emb = None
+
+ if self.class_embedding is not None:
+ if class_labels is None:
+ raise ValueError("class_labels should be provided when num_class_embeds > 0")
+
+ if self.config.class_embed_type == "timestep":
+ class_labels = self.time_proj(class_labels)
+
+ # `Timesteps` does not contain any weights and will always return f32 tensors
+ # there might be better ways to encapsulate this.
+ class_labels = class_labels.to(dtype=sample.dtype)
+
+ class_emb = self.class_embedding(class_labels).to(dtype=sample.dtype)
+
+ if self.config.class_embeddings_concat:
+ emb = torch.cat([emb, class_emb], dim=-1)
+ else:
+ emb = emb + class_emb
+
+ if self.config.addition_embed_type == "text":
+ aug_emb = self.add_embedding(encoder_hidden_states)
+ elif self.config.addition_embed_type == "text_image":
+ # Kandinsky 2.1 - style
+ if "image_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `addition_embed_type` set to 'text_image' which requires the keyword argument `image_embeds` to be passed in `added_cond_kwargs`"
+ )
+
+ image_embs = added_cond_kwargs.get("image_embeds")
+ text_embs = added_cond_kwargs.get("text_embeds", encoder_hidden_states)
+ aug_emb = self.add_embedding(text_embs, image_embs)
+ elif self.config.addition_embed_type == "text_time":
+ # SDXL - style
+ if "text_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `addition_embed_type` set to 'text_time' which requires the keyword argument `text_embeds` to be passed in `added_cond_kwargs`"
+ )
+ text_embeds = added_cond_kwargs.get("text_embeds")
+ if "time_ids" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `addition_embed_type` set to 'text_time' which requires the keyword argument `time_ids` to be passed in `added_cond_kwargs`"
+ )
+ time_ids = added_cond_kwargs.get("time_ids")
+ time_embeds = self.add_time_proj(time_ids.flatten())
+ time_embeds = time_embeds.reshape((text_embeds.shape[0], -1))
+ add_embeds = torch.concat([text_embeds, time_embeds], dim=-1)
+ add_embeds = add_embeds.to(emb.dtype)
+ aug_emb = self.add_embedding(add_embeds)
+ elif self.config.addition_embed_type == "image":
+ # Kandinsky 2.2 - style
+ if "image_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `addition_embed_type` set to 'image' which requires the keyword argument `image_embeds` to be passed in `added_cond_kwargs`"
+ )
+ image_embs = added_cond_kwargs.get("image_embeds")
+ aug_emb = self.add_embedding(image_embs)
+ elif self.config.addition_embed_type == "image_hint":
+ # Kandinsky 2.2 - style
+ if "image_embeds" not in added_cond_kwargs or "hint" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `addition_embed_type` set to 'image_hint' which requires the keyword arguments `image_embeds` and `hint` to be passed in `added_cond_kwargs`"
+ )
+ image_embs = added_cond_kwargs.get("image_embeds")
+ hint = added_cond_kwargs.get("hint")
+ aug_emb, hint = self.add_embedding(image_embs, hint)
+ sample = torch.cat([sample, hint], dim=1)
+
+ emb = emb + aug_emb if aug_emb is not None else emb
+
+ if self.time_embed_act is not None:
+ emb = self.time_embed_act(emb)
+
+ if self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_proj":
+ encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states)
+ elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_image_proj":
+ # Kadinsky 2.1 - style
+ if "image_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'text_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
+ )
+
+ image_embeds = added_cond_kwargs.get("image_embeds")
+ encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states, image_embeds)
+ elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "image_proj":
+ # Kandinsky 2.2 - style
+ if "image_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
+ )
+ image_embeds = added_cond_kwargs.get("image_embeds")
+ encoder_hidden_states = self.encoder_hid_proj(image_embeds)
+ elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "ip_image_proj":
+ if "image_embeds" not in added_cond_kwargs:
+ raise ValueError(
+ f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'ip_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
+ )
+ image_embeds = added_cond_kwargs.get("image_embeds")
+ image_embeds = self.encoder_hid_proj(image_embeds)
+ if isinstance(image_embeds, list):
+ image_embeds = [image_embed.to(encoder_hidden_states.dtype) for image_embed in image_embeds]
+ else:
+ image_embeds = image_embeds.to(encoder_hidden_states.dtype)
+ encoder_hidden_states = (encoder_hidden_states, image_embeds)
+ # encoder_hidden_states = torch.cat([encoder_hidden_states, image_embeds], dim=1)
+
+ # 2. pre-process
+ sample = self.conv_in(sample)
+
+ # 2.5 GLIGEN position net
+ if cross_attention_kwargs is not None and cross_attention_kwargs.get("gligen", None) is not None:
+ cross_attention_kwargs = cross_attention_kwargs.copy()
+ gligen_args = cross_attention_kwargs.pop("gligen")
+ cross_attention_kwargs["gligen"] = {"objs": self.position_net(**gligen_args)}
+
+ # 3. down
+ lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
+ if USE_PEFT_BACKEND:
+ # weight the lora layers by setting `lora_scale` for each PEFT layer
+ scale_lora_layers(self, lora_scale)
+
+ is_controlnet = mid_block_additional_residual is not None and down_block_additional_residuals is not None
+ # using new arg down_intrablock_additional_residuals for T2I-Adapters, to distinguish from controlnets
+ is_adapter = down_intrablock_additional_residuals is not None
+ # maintain backward compatibility for legacy usage, where
+ # T2I-Adapter and ControlNet both use down_block_additional_residuals arg
+ # but can only use one or the other
+ if not is_adapter and mid_block_additional_residual is None and down_block_additional_residuals is not None:
+ deprecate(
+ "T2I should not use down_block_additional_residuals",
+ "1.3.0",
+ "Passing intrablock residual connections with `down_block_additional_residuals` is deprecated \
+ and will be removed in diffusers 1.3.0. `down_block_additional_residuals` should only be used \
+ for ControlNet. Please make sure use `down_intrablock_additional_residuals` instead. ",
+ standard_warn=False,
+ )
+ down_intrablock_additional_residuals = down_block_additional_residuals
+ is_adapter = True
+
+ down_block_res_samples = (sample,)
+ for downsample_block in self.down_blocks:
+ if hasattr(downsample_block, "has_cross_attention") and downsample_block.has_cross_attention:
+ # For t2i-adapter CrossAttnDownBlock2D
+ additional_residuals = {}
+ if is_adapter and len(down_intrablock_additional_residuals) > 0:
+ additional_residuals["additional_residuals"] = down_intrablock_additional_residuals.pop(0)
+
+ sample, res_samples = downsample_block(
+ hidden_states=sample,
+ temb=emb,
+ encoder_hidden_states=encoder_hidden_states,
+ attention_mask=attention_mask,
+ cross_attention_kwargs=cross_attention_kwargs,
+ encoder_attention_mask=encoder_attention_mask,
+ **additional_residuals,
+ )
+
+ else:
+ sample, res_samples = downsample_block(hidden_states=sample, temb=emb, scale=lora_scale)
+ if is_adapter and len(down_intrablock_additional_residuals) > 0:
+ sample += down_intrablock_additional_residuals.pop(0)
+
+ down_block_res_samples += res_samples
+
+ if is_controlnet:
+ new_down_block_res_samples = ()
+
+ for down_block_res_sample, down_block_additional_residual in zip(
+ down_block_res_samples, down_block_additional_residuals
+ ):
+ down_block_res_sample = down_block_res_sample + down_block_additional_residual
+ new_down_block_res_samples = new_down_block_res_samples + (down_block_res_sample,)
+
+ down_block_res_samples = new_down_block_res_samples
+ # 4. mid
+ if self.mid_block is not None:
+ if hasattr(self.mid_block, "has_cross_attention") and self.mid_block.has_cross_attention:
+ sample = self.mid_block(
+ sample,
+ emb,
+ encoder_hidden_states=encoder_hidden_states,
+ attention_mask=attention_mask,
+ cross_attention_kwargs=cross_attention_kwargs,
+ encoder_attention_mask=encoder_attention_mask,
+ )
+ else:
+ sample = self.mid_block(sample, emb)
+
+ # To support T2I-Adapter-XL
+ if (
+ is_adapter
+ and len(down_intrablock_additional_residuals) > 0
+ and sample.shape == down_intrablock_additional_residuals[0].shape
+ ):
+ sample += down_intrablock_additional_residuals.pop(0)
+
+ if is_controlnet:
+ sample = sample + mid_block_additional_residual
+
+ # 5. up
+ for i, upsample_block in enumerate(self.up_blocks):
+ is_final_block = i == len(self.up_blocks) - 1
+
+ res_samples = down_block_res_samples[-len(upsample_block.resnets) :]
+ down_block_res_samples = down_block_res_samples[: -len(upsample_block.resnets)]
+
+ # if we have not reached the final block and need to forward the
+ # upsample size, we do it here
+ if not is_final_block and forward_upsample_size:
+ upsample_size = down_block_res_samples[-1].shape[2:]
+
+ if hasattr(upsample_block, "has_cross_attention") and upsample_block.has_cross_attention:
+ sample = upsample_block(
+ hidden_states=sample,
+ temb=emb,
+ res_hidden_states_tuple=res_samples,
+ encoder_hidden_states=encoder_hidden_states,
+ cross_attention_kwargs=cross_attention_kwargs,
+ upsample_size=upsample_size,
+ attention_mask=attention_mask,
+ encoder_attention_mask=encoder_attention_mask,
+ )
+ else:
+ sample = upsample_block(
+ hidden_states=sample,
+ temb=emb,
+ res_hidden_states_tuple=res_samples,
+ upsample_size=upsample_size,
+ scale=lora_scale,
+ )
+
+ # 6. post-process
+ if self.conv_norm_out:
+ sample = self.conv_norm_out(sample)
+ sample = self.conv_act(sample)
+ sample = self.conv_out(sample)
+
+ if USE_PEFT_BACKEND:
+ # remove `lora_scale` from each PEFT layer
+ unscale_lora_layers(self, lora_scale)
+
+ if not return_dict:
+ return (sample,)
+
+ return UNet2DConditionOutput(sample=sample)
diff --git a/foleycrafter/models/audio_generator/vocoder.py b/foleycrafter/models/audio_generator/vocoder.py
new file mode 100644
index 0000000..039e85e
--- /dev/null
+++ b/foleycrafter/models/audio_generator/vocoder.py
@@ -0,0 +1,267 @@
+import json
+import os
+
+import torch
+import torch.nn.functional as F
+from torch.nn import Conv1d, ConvTranspose1d
+from torch.nn.utils import remove_weight_norm, weight_norm
+
+
+def init_weights(m, mean=0.0, std=0.01):
+ classname = m.__class__.__name__
+ if classname.find("Conv") != -1:
+ m.weight.data.normal_(mean, std)
+
+
+def get_padding(kernel_size, dilation=1):
+ return int((kernel_size * dilation - dilation) / 2)
+
+
+LRELU_SLOPE = 0.1
+MAX_WAV_VALUE = 32768.0
+
+
+class AttrDict(dict):
+ def __init__(self, *args, **kwargs):
+ super(AttrDict, self).__init__(*args, **kwargs)
+ self.__dict__ = self
+
+
+def get_config(config_path):
+ config = json.loads(open(config_path).read())
+ config = AttrDict(config)
+ return config
+
+
+class ResBlock1(torch.nn.Module):
+ def __init__(self, h, channels, kernel_size=3, dilation=(1, 3, 5)):
+ super(ResBlock1, self).__init__()
+ self.h = h
+ self.convs1 = torch.nn.ModuleList(
+ [
+ weight_norm(
+ Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0]),
+ )
+ ),
+ weight_norm(
+ Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]),
+ )
+ ),
+ weight_norm(
+ Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[2],
+ padding=get_padding(kernel_size, dilation[2]),
+ )
+ ),
+ ]
+ )
+ self.convs1.apply(init_weights)
+
+ self.convs2 = torch.nn.ModuleList(
+ [
+ weight_norm(
+ Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
+ ),
+ weight_norm(
+ Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
+ ),
+ weight_norm(
+ Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
+ ),
+ ]
+ )
+ self.convs2.apply(init_weights)
+
+ def forward(self, x):
+ for c1, c2 in zip(self.convs1, self.convs2):
+ xt = F.leaky_relu(x, LRELU_SLOPE)
+ xt = c1(xt)
+ xt = F.leaky_relu(xt, LRELU_SLOPE)
+ xt = c2(xt)
+ x = xt + x
+ return x
+
+ def remove_weight_norm(self):
+ for l in self.convs1:
+ remove_weight_norm(l)
+ for l in self.convs2:
+ remove_weight_norm(l)
+
+
+class ResBlock2(torch.nn.Module):
+ def __init__(self, h, channels, kernel_size=3, dilation=(1, 3)):
+ super(ResBlock2, self).__init__()
+ self.h = h
+ self.convs = torch.nn.ModuleList(
+ [
+ weight_norm(
+ Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[0],
+ padding=get_padding(kernel_size, dilation[0]),
+ )
+ ),
+ weight_norm(
+ Conv1d(
+ channels,
+ channels,
+ kernel_size,
+ 1,
+ dilation=dilation[1],
+ padding=get_padding(kernel_size, dilation[1]),
+ )
+ ),
+ ]
+ )
+ self.convs.apply(init_weights)
+
+ def forward(self, x):
+ for c in self.convs:
+ xt = F.leaky_relu(x, LRELU_SLOPE)
+ xt = c(xt)
+ x = xt + x
+ return x
+
+ def remove_weight_norm(self):
+ for l in self.convs:
+ remove_weight_norm(l)
+
+
+class Generator(torch.nn.Module):
+ def __init__(self, h):
+ super(Generator, self).__init__()
+ self.h = h
+ self.num_kernels = len(h.resblock_kernel_sizes)
+ self.num_upsamples = len(h.upsample_rates)
+ # self.conv_pre = weight_norm(Conv1d(80, h.upsample_initial_channel, 7, 1, padding=3))
+ self.conv_pre = weight_norm(
+ Conv1d(h.num_mels, h.upsample_initial_channel, 7, 1, padding=3)
+ ) # change: 80 --> 512
+ resblock = ResBlock1 if h.resblock == "1" else ResBlock2
+
+ self._device = "cuda" if torch.cuda.is_available() else "cpu"
+
+ self.ups = torch.nn.ModuleList()
+ for i, (u, k) in enumerate(zip(h.upsample_rates, h.upsample_kernel_sizes)):
+ if (k - u) % 2 == 0:
+ self.ups.append(
+ weight_norm(
+ ConvTranspose1d(
+ h.upsample_initial_channel // (2**i),
+ h.upsample_initial_channel // (2 ** (i + 1)),
+ k,
+ u,
+ padding=(k - u) // 2,
+ )
+ )
+ )
+ else:
+ self.ups.append(
+ weight_norm(
+ ConvTranspose1d(
+ h.upsample_initial_channel // (2**i),
+ h.upsample_initial_channel // (2 ** (i + 1)),
+ k,
+ u,
+ padding=(k - u) // 2 + 1,
+ output_padding=1,
+ )
+ )
+ )
+
+ # self.ups.append(weight_norm(
+ # ConvTranspose1d(h.upsample_initial_channel//(2**i), h.upsample_initial_channel//(2**(i+1)),
+ # k, u, padding=(k-u)//2)))
+
+ self.resblocks = torch.nn.ModuleList()
+ for i in range(len(self.ups)):
+ ch = h.upsample_initial_channel // (2 ** (i + 1))
+ for j, (k, d) in enumerate(zip(h.resblock_kernel_sizes, h.resblock_dilation_sizes)):
+ self.resblocks.append(resblock(h, ch, k, d))
+
+ self.conv_post = weight_norm(Conv1d(ch, 1, 7, 1, padding=3))
+ self.ups.apply(init_weights)
+ self.conv_post.apply(init_weights)
+
+ @property
+ def device(self) -> torch.device:
+ return torch.device(self._device)
+
+ @property
+ def dtype(self):
+ return self.type
+
+ def forward(self, x):
+ x = self.conv_pre(x)
+ for i in range(self.num_upsamples):
+ x = F.leaky_relu(x, LRELU_SLOPE)
+ x = self.ups[i](x)
+ xs = None
+ for j in range(self.num_kernels):
+ if xs is None:
+ xs = self.resblocks[i * self.num_kernels + j](x)
+ else:
+ xs += self.resblocks[i * self.num_kernels + j](x)
+ x = xs / self.num_kernels
+ x = F.leaky_relu(x)
+ x = self.conv_post(x)
+ x = torch.tanh(x)
+
+ return x
+
+ def remove_weight_norm(self):
+ print("Removing weight norm...")
+ for l in self.ups:
+ remove_weight_norm(l)
+ for l in self.resblocks:
+ l.remove_weight_norm()
+ remove_weight_norm(self.conv_pre)
+ remove_weight_norm(self.conv_post)
+
+ @classmethod
+ def from_pretrained(cls, pretrained_model_name_or_path, subfolder=None):
+ if subfolder is not None:
+ pretrained_model_name_or_path = os.path.join(pretrained_model_name_or_path, subfolder)
+ config_path = os.path.join(pretrained_model_name_or_path, "config.json")
+ ckpt_path = os.path.join(pretrained_model_name_or_path, "vocoder.pt")
+
+ config = get_config(config_path)
+ vocoder = cls(config)
+
+ state_dict_g = torch.load(ckpt_path)
+ vocoder.load_state_dict(state_dict_g["generator"])
+ vocoder.eval()
+ vocoder.remove_weight_norm()
+ return vocoder
+
+ @torch.no_grad()
+ def inference(self, mels, lengths=None):
+ self.eval()
+ with torch.no_grad():
+ wavs = self(mels).squeeze(1)
+
+ wavs = (wavs.cpu().numpy() * MAX_WAV_VALUE).astype("int16")
+
+ if lengths is not None:
+ wavs = wavs[:, :lengths]
+
+ return wavs
diff --git a/foleycrafter/models/auffusion/attention.py b/foleycrafter/models/auffusion/attention.py
deleted file mode 100644
index 65c23b2..0000000
--- a/foleycrafter/models/auffusion/attention.py
+++ /dev/null
@@ -1,668 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from typing import Any, Dict, Optional
-
-import torch
-import torch.nn.functional as F
-from torch import nn
-
-from diffusers.models.activations import GEGLU, GELU, ApproximateGELU
-from diffusers.models.embeddings import SinusoidalPositionalEmbedding
-from diffusers.models.lora import LoRACompatibleLinear
-from diffusers.models.normalization import AdaLayerNorm, AdaLayerNormContinuous, AdaLayerNormZero, RMSNorm
-from diffusers.utils import USE_PEFT_BACKEND
-from diffusers.utils.torch_utils import maybe_allow_in_graph
-from foleycrafter.models.auffusion.attention_processor import Attention
-
-
-def _chunked_feed_forward(
- ff: nn.Module, hidden_states: torch.Tensor, chunk_dim: int, chunk_size: int, lora_scale: Optional[float] = None
-):
- # "feed_forward_chunk_size" can be used to save memory
- if hidden_states.shape[chunk_dim] % chunk_size != 0:
- raise ValueError(
- f"`hidden_states` dimension to be chunked: {hidden_states.shape[chunk_dim]} has to be divisible by chunk size: {chunk_size}. Make sure to set an appropriate `chunk_size` when calling `unet.enable_forward_chunking`."
- )
-
- num_chunks = hidden_states.shape[chunk_dim] // chunk_size
- if lora_scale is None:
- ff_output = torch.cat(
- [ff(hid_slice) for hid_slice in hidden_states.chunk(num_chunks, dim=chunk_dim)],
- dim=chunk_dim,
- )
- else:
- # TODO(Patrick): LoRA scale can be removed once PEFT refactor is complete
- ff_output = torch.cat(
- [ff(hid_slice, scale=lora_scale) for hid_slice in hidden_states.chunk(num_chunks, dim=chunk_dim)],
- dim=chunk_dim,
- )
-
- return ff_output
-
-
-@maybe_allow_in_graph
-class GatedSelfAttentionDense(nn.Module):
- r"""
- A gated self-attention dense layer that combines visual features and object features.
-
- Parameters:
- query_dim (`int`): The number of channels in the query.
- context_dim (`int`): The number of channels in the context.
- n_heads (`int`): The number of heads to use for attention.
- d_head (`int`): The number of channels in each head.
- """
-
- def __init__(self, query_dim: int, context_dim: int, n_heads: int, d_head: int):
- super().__init__()
-
- # we need a linear projection since we need cat visual feature and obj feature
- self.linear = nn.Linear(context_dim, query_dim)
-
- self.attn = Attention(query_dim=query_dim, heads=n_heads, dim_head=d_head)
- self.ff = FeedForward(query_dim, activation_fn="geglu")
-
- self.norm1 = nn.LayerNorm(query_dim)
- self.norm2 = nn.LayerNorm(query_dim)
-
- self.register_parameter("alpha_attn", nn.Parameter(torch.tensor(0.0)))
- self.register_parameter("alpha_dense", nn.Parameter(torch.tensor(0.0)))
-
- self.enabled = True
-
- def forward(self, x: torch.Tensor, objs: torch.Tensor) -> torch.Tensor:
- if not self.enabled:
- return x
-
- n_visual = x.shape[1]
- objs = self.linear(objs)
-
- x = x + self.alpha_attn.tanh() * self.attn(self.norm1(torch.cat([x, objs], dim=1)))[:, :n_visual, :]
- x = x + self.alpha_dense.tanh() * self.ff(self.norm2(x))
-
- return x
-
-
-@maybe_allow_in_graph
-class BasicTransformerBlock(nn.Module):
- r"""
- A basic Transformer block.
-
- Parameters:
- dim (`int`): The number of channels in the input and output.
- num_attention_heads (`int`): The number of heads to use for multi-head attention.
- attention_head_dim (`int`): The number of channels in each head.
- dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
- cross_attention_dim (`int`, *optional*): The size of the encoder_hidden_states vector for cross attention.
- activation_fn (`str`, *optional*, defaults to `"geglu"`): Activation function to be used in feed-forward.
- num_embeds_ada_norm (:
- obj: `int`, *optional*): The number of diffusion steps used during training. See `Transformer2DModel`.
- attention_bias (:
- obj: `bool`, *optional*, defaults to `False`): Configure if the attentions should contain a bias parameter.
- only_cross_attention (`bool`, *optional*):
- Whether to use only cross-attention layers. In this case two cross attention layers are used.
- double_self_attention (`bool`, *optional*):
- Whether to use two self-attention layers. In this case no cross attention layers are used.
- upcast_attention (`bool`, *optional*):
- Whether to upcast the attention computation to float32. This is useful for mixed precision training.
- norm_elementwise_affine (`bool`, *optional*, defaults to `True`):
- Whether to use learnable elementwise affine parameters for normalization.
- norm_type (`str`, *optional*, defaults to `"layer_norm"`):
- The normalization layer to use. Can be `"layer_norm"`, `"ada_norm"` or `"ada_norm_zero"`.
- final_dropout (`bool` *optional*, defaults to False):
- Whether to apply a final dropout after the last feed-forward layer.
- attention_type (`str`, *optional*, defaults to `"default"`):
- The type of attention to use. Can be `"default"` or `"gated"` or `"gated-text-image"`.
- positional_embeddings (`str`, *optional*, defaults to `None`):
- The type of positional embeddings to apply to.
- num_positional_embeddings (`int`, *optional*, defaults to `None`):
- The maximum number of positional embeddings to apply.
- """
-
- def __init__(
- self,
- dim: int,
- num_attention_heads: int,
- attention_head_dim: int,
- dropout=0.0,
- cross_attention_dim: Optional[int] = None,
- activation_fn: str = "geglu",
- num_embeds_ada_norm: Optional[int] = None,
- attention_bias: bool = False,
- only_cross_attention: bool = False,
- double_self_attention: bool = False,
- upcast_attention: bool = False,
- norm_elementwise_affine: bool = True,
- norm_type: str = "layer_norm", # 'layer_norm', 'ada_norm', 'ada_norm_zero', 'ada_norm_single'
- norm_eps: float = 1e-5,
- final_dropout: bool = False,
- attention_type: str = "default",
- positional_embeddings: Optional[str] = None,
- num_positional_embeddings: Optional[int] = None,
- ada_norm_continous_conditioning_embedding_dim: Optional[int] = None,
- ada_norm_bias: Optional[int] = None,
- ff_inner_dim: Optional[int] = None,
- ff_bias: bool = True,
- attention_out_bias: bool = True,
- ):
- super().__init__()
- self.only_cross_attention = only_cross_attention
-
- self.use_ada_layer_norm_zero = (num_embeds_ada_norm is not None) and norm_type == "ada_norm_zero"
- self.use_ada_layer_norm = (num_embeds_ada_norm is not None) and norm_type == "ada_norm"
- self.use_ada_layer_norm_single = norm_type == "ada_norm_single"
- self.use_layer_norm = norm_type == "layer_norm"
- self.use_ada_layer_norm_continuous = norm_type == "ada_norm_continuous"
-
- if norm_type in ("ada_norm", "ada_norm_zero") and num_embeds_ada_norm is None:
- raise ValueError(
- f"`norm_type` is set to {norm_type}, but `num_embeds_ada_norm` is not defined. Please make sure to"
- f" define `num_embeds_ada_norm` if setting `norm_type` to {norm_type}."
- )
-
- if positional_embeddings and (num_positional_embeddings is None):
- raise ValueError(
- "If `positional_embedding` type is defined, `num_positition_embeddings` must also be defined."
- )
-
- if positional_embeddings == "sinusoidal":
- self.pos_embed = SinusoidalPositionalEmbedding(dim, max_seq_length=num_positional_embeddings)
- else:
- self.pos_embed = None
-
- # Define 3 blocks. Each block has its own normalization layer.
- # 1. Self-Attn
- if self.use_ada_layer_norm:
- self.norm1 = AdaLayerNorm(dim, num_embeds_ada_norm)
- elif self.use_ada_layer_norm_zero:
- self.norm1 = AdaLayerNormZero(dim, num_embeds_ada_norm)
- elif self.use_ada_layer_norm_continuous:
- self.norm1 = AdaLayerNormContinuous(
- dim,
- ada_norm_continous_conditioning_embedding_dim,
- norm_elementwise_affine,
- norm_eps,
- ada_norm_bias,
- "rms_norm",
- )
- else:
- self.norm1 = nn.LayerNorm(dim, elementwise_affine=norm_elementwise_affine, eps=norm_eps)
-
- self.attn1 = Attention(
- query_dim=dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- cross_attention_dim=cross_attention_dim if (only_cross_attention and not double_self_attention) else None,
- upcast_attention=upcast_attention,
- out_bias=attention_out_bias,
- )
-
- # 2. Cross-Attn
- if cross_attention_dim is not None or double_self_attention:
- # We currently only use AdaLayerNormZero for self attention where there will only be one attention block.
- # I.e. the number of returned modulation chunks from AdaLayerZero would not make sense if returned during
- # the second cross attention block.
- if self.use_ada_layer_norm:
- self.norm2 = AdaLayerNorm(dim, num_embeds_ada_norm)
- elif self.use_ada_layer_norm_continuous:
- self.norm2 = AdaLayerNormContinuous(
- dim,
- ada_norm_continous_conditioning_embedding_dim,
- norm_elementwise_affine,
- norm_eps,
- ada_norm_bias,
- "rms_norm",
- )
- else:
- self.norm2 = nn.LayerNorm(dim, norm_eps, norm_elementwise_affine)
-
- self.attn2 = Attention(
- query_dim=dim,
- cross_attention_dim=cross_attention_dim if not double_self_attention else None,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- upcast_attention=upcast_attention,
- out_bias=attention_out_bias,
- ) # is self-attn if encoder_hidden_states is none
- else:
- self.norm2 = None
- self.attn2 = None
-
- # 3. Feed-forward
- if self.use_ada_layer_norm_continuous:
- self.norm3 = AdaLayerNormContinuous(
- dim,
- ada_norm_continous_conditioning_embedding_dim,
- norm_elementwise_affine,
- norm_eps,
- ada_norm_bias,
- "layer_norm",
- )
- elif not self.use_ada_layer_norm_single:
- self.norm3 = nn.LayerNorm(dim, norm_eps, norm_elementwise_affine)
-
- self.ff = FeedForward(
- dim,
- dropout=dropout,
- activation_fn=activation_fn,
- final_dropout=final_dropout,
- inner_dim=ff_inner_dim,
- bias=ff_bias,
- )
-
- # 4. Fuser
- if attention_type == "gated" or attention_type == "gated-text-image":
- self.fuser = GatedSelfAttentionDense(dim, cross_attention_dim, num_attention_heads, attention_head_dim)
-
- # 5. Scale-shift for PixArt-Alpha.
- if self.use_ada_layer_norm_single:
- self.scale_shift_table = nn.Parameter(torch.randn(6, dim) / dim**0.5)
-
- # let chunk size default to None
- self._chunk_size = None
- self._chunk_dim = 0
-
- def set_chunk_feed_forward(self, chunk_size: Optional[int], dim: int = 0):
- # Sets chunk feed-forward
- self._chunk_size = chunk_size
- self._chunk_dim = dim
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- attention_mask: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- timestep: Optional[torch.LongTensor] = None,
- cross_attention_kwargs: Dict[str, Any] = None,
- class_labels: Optional[torch.LongTensor] = None,
- added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None,
- ) -> torch.FloatTensor:
- # Notice that normalization is always applied before the real computation in the following blocks.
- # 0. Self-Attention
- batch_size = hidden_states.shape[0]
-
- if self.use_ada_layer_norm:
- norm_hidden_states = self.norm1(hidden_states, timestep)
- elif self.use_ada_layer_norm_zero:
- norm_hidden_states, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.norm1(
- hidden_states, timestep, class_labels, hidden_dtype=hidden_states.dtype
- )
- elif self.use_layer_norm:
- norm_hidden_states = self.norm1(hidden_states)
- elif self.use_ada_layer_norm_continuous:
- norm_hidden_states = self.norm1(hidden_states, added_cond_kwargs["pooled_text_emb"])
- elif self.use_ada_layer_norm_single:
- shift_msa, scale_msa, gate_msa, shift_mlp, scale_mlp, gate_mlp = (
- self.scale_shift_table[None] + timestep.reshape(batch_size, 6, -1)
- ).chunk(6, dim=1)
- norm_hidden_states = self.norm1(hidden_states)
- norm_hidden_states = norm_hidden_states * (1 + scale_msa) + shift_msa
- norm_hidden_states = norm_hidden_states.squeeze(1)
- else:
- raise ValueError("Incorrect norm used")
-
- if self.pos_embed is not None:
- norm_hidden_states = self.pos_embed(norm_hidden_states)
-
- # 1. Retrieve lora scale.
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
-
- # 2. Prepare GLIGEN inputs
- cross_attention_kwargs = cross_attention_kwargs.copy() if cross_attention_kwargs is not None else {}
- gligen_kwargs = cross_attention_kwargs.pop("gligen", None)
-
- attn_output = self.attn1(
- norm_hidden_states,
- encoder_hidden_states=encoder_hidden_states if self.only_cross_attention else None,
- attention_mask=attention_mask,
- **cross_attention_kwargs,
- )
- if self.use_ada_layer_norm_zero:
- attn_output = gate_msa.unsqueeze(1) * attn_output
- elif self.use_ada_layer_norm_single:
- attn_output = gate_msa * attn_output
-
- hidden_states = attn_output + hidden_states
- if hidden_states.ndim == 4:
- hidden_states = hidden_states.squeeze(1)
-
- # 2.5 GLIGEN Control
- if gligen_kwargs is not None:
- hidden_states = self.fuser(hidden_states, gligen_kwargs["objs"])
-
- # 3. Cross-Attention
- if self.attn2 is not None:
- if self.use_ada_layer_norm:
- norm_hidden_states = self.norm2(hidden_states, timestep)
- elif self.use_ada_layer_norm_zero or self.use_layer_norm:
- norm_hidden_states = self.norm2(hidden_states)
- elif self.use_ada_layer_norm_single:
- # For PixArt norm2 isn't applied here:
- # https://github.com/PixArt-alpha/PixArt-alpha/blob/0f55e922376d8b797edd44d25d0e7464b260dcab/diffusion/model/nets/PixArtMS.py#L70C1-L76C103
- norm_hidden_states = hidden_states
- elif self.use_ada_layer_norm_continuous:
- norm_hidden_states = self.norm2(hidden_states, added_cond_kwargs["pooled_text_emb"])
- else:
- raise ValueError("Incorrect norm")
-
- if self.pos_embed is not None and self.use_ada_layer_norm_single is False:
- norm_hidden_states = self.pos_embed(norm_hidden_states)
-
- attn_output = self.attn2(
- norm_hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=encoder_attention_mask,
- **cross_attention_kwargs,
- )
- hidden_states = attn_output + hidden_states
-
- # 4. Feed-forward
- if self.use_ada_layer_norm_continuous:
- norm_hidden_states = self.norm3(hidden_states, added_cond_kwargs["pooled_text_emb"])
- elif not self.use_ada_layer_norm_single:
- norm_hidden_states = self.norm3(hidden_states)
-
- if self.use_ada_layer_norm_zero:
- norm_hidden_states = norm_hidden_states * (1 + scale_mlp[:, None]) + shift_mlp[:, None]
-
- if self.use_ada_layer_norm_single:
- norm_hidden_states = self.norm2(hidden_states)
- norm_hidden_states = norm_hidden_states * (1 + scale_mlp) + shift_mlp
-
- if self._chunk_size is not None:
- # "feed_forward_chunk_size" can be used to save memory
- ff_output = _chunked_feed_forward(
- self.ff, norm_hidden_states, self._chunk_dim, self._chunk_size, lora_scale=lora_scale
- )
- else:
- ff_output = self.ff(norm_hidden_states, scale=lora_scale)
-
- if self.use_ada_layer_norm_zero:
- ff_output = gate_mlp.unsqueeze(1) * ff_output
- elif self.use_ada_layer_norm_single:
- ff_output = gate_mlp * ff_output
-
- hidden_states = ff_output + hidden_states
- if hidden_states.ndim == 4:
- hidden_states = hidden_states.squeeze(1)
-
- return hidden_states
-
-
-@maybe_allow_in_graph
-class TemporalBasicTransformerBlock(nn.Module):
- r"""
- A basic Transformer block for video like data.
-
- Parameters:
- dim (`int`): The number of channels in the input and output.
- time_mix_inner_dim (`int`): The number of channels for temporal attention.
- num_attention_heads (`int`): The number of heads to use for multi-head attention.
- attention_head_dim (`int`): The number of channels in each head.
- cross_attention_dim (`int`, *optional*): The size of the encoder_hidden_states vector for cross attention.
- """
-
- def __init__(
- self,
- dim: int,
- time_mix_inner_dim: int,
- num_attention_heads: int,
- attention_head_dim: int,
- cross_attention_dim: Optional[int] = None,
- ):
- super().__init__()
- self.is_res = dim == time_mix_inner_dim
-
- self.norm_in = nn.LayerNorm(dim)
-
- # Define 3 blocks. Each block has its own normalization layer.
- # 1. Self-Attn
- self.norm_in = nn.LayerNorm(dim)
- self.ff_in = FeedForward(
- dim,
- dim_out=time_mix_inner_dim,
- activation_fn="geglu",
- )
-
- self.norm1 = nn.LayerNorm(time_mix_inner_dim)
- self.attn1 = Attention(
- query_dim=time_mix_inner_dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- cross_attention_dim=None,
- )
-
- # 2. Cross-Attn
- if cross_attention_dim is not None:
- # We currently only use AdaLayerNormZero for self attention where there will only be one attention block.
- # I.e. the number of returned modulation chunks from AdaLayerZero would not make sense if returned during
- # the second cross attention block.
- self.norm2 = nn.LayerNorm(time_mix_inner_dim)
- self.attn2 = Attention(
- query_dim=time_mix_inner_dim,
- cross_attention_dim=cross_attention_dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- ) # is self-attn if encoder_hidden_states is none
- else:
- self.norm2 = None
- self.attn2 = None
-
- # 3. Feed-forward
- self.norm3 = nn.LayerNorm(time_mix_inner_dim)
- self.ff = FeedForward(time_mix_inner_dim, activation_fn="geglu")
-
- # let chunk size default to None
- self._chunk_size = None
- self._chunk_dim = None
-
- def set_chunk_feed_forward(self, chunk_size: Optional[int], **kwargs):
- # Sets chunk feed-forward
- self._chunk_size = chunk_size
- # chunk dim should be hardcoded to 1 to have better speed vs. memory trade-off
- self._chunk_dim = 1
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- num_frames: int,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- # Notice that normalization is always applied before the real computation in the following blocks.
- # 0. Self-Attention
- batch_size = hidden_states.shape[0]
-
- batch_frames, seq_length, channels = hidden_states.shape
- batch_size = batch_frames // num_frames
-
- hidden_states = hidden_states[None, :].reshape(batch_size, num_frames, seq_length, channels)
- hidden_states = hidden_states.permute(0, 2, 1, 3)
- hidden_states = hidden_states.reshape(batch_size * seq_length, num_frames, channels)
-
- residual = hidden_states
- hidden_states = self.norm_in(hidden_states)
-
- if self._chunk_size is not None:
- hidden_states = _chunked_feed_forward(self.ff_in, hidden_states, self._chunk_dim, self._chunk_size)
- else:
- hidden_states = self.ff_in(hidden_states)
-
- if self.is_res:
- hidden_states = hidden_states + residual
-
- norm_hidden_states = self.norm1(hidden_states)
- attn_output = self.attn1(norm_hidden_states, encoder_hidden_states=None)
- hidden_states = attn_output + hidden_states
-
- # 3. Cross-Attention
- if self.attn2 is not None:
- norm_hidden_states = self.norm2(hidden_states)
- attn_output = self.attn2(norm_hidden_states, encoder_hidden_states=encoder_hidden_states)
- hidden_states = attn_output + hidden_states
-
- # 4. Feed-forward
- norm_hidden_states = self.norm3(hidden_states)
-
- if self._chunk_size is not None:
- ff_output = _chunked_feed_forward(self.ff, norm_hidden_states, self._chunk_dim, self._chunk_size)
- else:
- ff_output = self.ff(norm_hidden_states)
-
- if self.is_res:
- hidden_states = ff_output + hidden_states
- else:
- hidden_states = ff_output
-
- hidden_states = hidden_states[None, :].reshape(batch_size, seq_length, num_frames, channels)
- hidden_states = hidden_states.permute(0, 2, 1, 3)
- hidden_states = hidden_states.reshape(batch_size * num_frames, seq_length, channels)
-
- return hidden_states
-
-
-class SkipFFTransformerBlock(nn.Module):
- def __init__(
- self,
- dim: int,
- num_attention_heads: int,
- attention_head_dim: int,
- kv_input_dim: int,
- kv_input_dim_proj_use_bias: bool,
- dropout=0.0,
- cross_attention_dim: Optional[int] = None,
- attention_bias: bool = False,
- attention_out_bias: bool = True,
- ):
- super().__init__()
- if kv_input_dim != dim:
- self.kv_mapper = nn.Linear(kv_input_dim, dim, kv_input_dim_proj_use_bias)
- else:
- self.kv_mapper = None
-
- self.norm1 = RMSNorm(dim, 1e-06)
-
- self.attn1 = Attention(
- query_dim=dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- cross_attention_dim=cross_attention_dim,
- out_bias=attention_out_bias,
- )
-
- self.norm2 = RMSNorm(dim, 1e-06)
-
- self.attn2 = Attention(
- query_dim=dim,
- cross_attention_dim=cross_attention_dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- out_bias=attention_out_bias,
- )
-
- def forward(self, hidden_states, encoder_hidden_states, cross_attention_kwargs):
- cross_attention_kwargs = cross_attention_kwargs.copy() if cross_attention_kwargs is not None else {}
-
- if self.kv_mapper is not None:
- encoder_hidden_states = self.kv_mapper(F.silu(encoder_hidden_states))
-
- norm_hidden_states = self.norm1(hidden_states)
-
- attn_output = self.attn1(
- norm_hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- **cross_attention_kwargs,
- )
-
- hidden_states = attn_output + hidden_states
-
- norm_hidden_states = self.norm2(hidden_states)
-
- attn_output = self.attn2(
- norm_hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- **cross_attention_kwargs,
- )
-
- hidden_states = attn_output + hidden_states
-
- return hidden_states
-
-
-class FeedForward(nn.Module):
- r"""
- A feed-forward layer.
-
- Parameters:
- dim (`int`): The number of channels in the input.
- dim_out (`int`, *optional*): The number of channels in the output. If not given, defaults to `dim`.
- mult (`int`, *optional*, defaults to 4): The multiplier to use for the hidden dimension.
- dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
- activation_fn (`str`, *optional*, defaults to `"geglu"`): Activation function to be used in feed-forward.
- final_dropout (`bool` *optional*, defaults to False): Apply a final dropout.
- bias (`bool`, defaults to True): Whether to use a bias in the linear layer.
- """
-
- def __init__(
- self,
- dim: int,
- dim_out: Optional[int] = None,
- mult: int = 4,
- dropout: float = 0.0,
- activation_fn: str = "geglu",
- final_dropout: bool = False,
- inner_dim=None,
- bias: bool = True,
- ):
- super().__init__()
- if inner_dim is None:
- inner_dim = int(dim * mult)
- dim_out = dim_out if dim_out is not None else dim
- linear_cls = LoRACompatibleLinear if not USE_PEFT_BACKEND else nn.Linear
-
- if activation_fn == "gelu":
- act_fn = GELU(dim, inner_dim, bias=bias)
- if activation_fn == "gelu-approximate":
- act_fn = GELU(dim, inner_dim, approximate="tanh", bias=bias)
- elif activation_fn == "geglu":
- act_fn = GEGLU(dim, inner_dim, bias=bias)
- elif activation_fn == "geglu-approximate":
- act_fn = ApproximateGELU(dim, inner_dim, bias=bias)
-
- self.net = nn.ModuleList([])
- # project in
- self.net.append(act_fn)
- # project dropout
- self.net.append(nn.Dropout(dropout))
- # project out
- self.net.append(linear_cls(inner_dim, dim_out, bias=bias))
- # FF as used in Vision Transformer, MLP-Mixer, etc. have a final dropout
- if final_dropout:
- self.net.append(nn.Dropout(dropout))
-
- def forward(self, hidden_states: torch.Tensor, scale: float = 1.0) -> torch.Tensor:
- compatible_cls = (GEGLU,) if USE_PEFT_BACKEND else (GEGLU, LoRACompatibleLinear)
- for module in self.net:
- if isinstance(module, compatible_cls):
- hidden_states = module(hidden_states, scale)
- else:
- hidden_states = module(hidden_states)
- return hidden_states
diff --git a/foleycrafter/models/auffusion/attention_processor.py b/foleycrafter/models/auffusion/attention_processor.py
deleted file mode 100644
index 45c1a0e..0000000
--- a/foleycrafter/models/auffusion/attention_processor.py
+++ /dev/null
@@ -1,2691 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-import math
-from importlib import import_module
-from typing import Callable, List, Optional, Union
-
-import torch
-import torch.nn.functional as F
-from einops import rearrange
-from torch import nn
-
-from diffusers.models.lora import LoRACompatibleLinear, LoRALinearLayer
-from diffusers.utils import USE_PEFT_BACKEND, deprecate, logging
-from diffusers.utils.import_utils import is_xformers_available
-from diffusers.utils.torch_utils import maybe_allow_in_graph
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-if is_xformers_available():
- import xformers
- import xformers.ops
-else:
- xformers = None
-
-
-@maybe_allow_in_graph
-class Attention(nn.Module):
- r"""
- A cross attention layer.
-
- Parameters:
- query_dim (`int`):
- The number of channels in the query.
- cross_attention_dim (`int`, *optional*):
- The number of channels in the encoder_hidden_states. If not given, defaults to `query_dim`.
- heads (`int`, *optional*, defaults to 8):
- The number of heads to use for multi-head attention.
- dim_head (`int`, *optional*, defaults to 64):
- The number of channels in each head.
- dropout (`float`, *optional*, defaults to 0.0):
- The dropout probability to use.
- bias (`bool`, *optional*, defaults to False):
- Set to `True` for the query, key, and value linear layers to contain a bias parameter.
- upcast_attention (`bool`, *optional*, defaults to False):
- Set to `True` to upcast the attention computation to `float32`.
- upcast_softmax (`bool`, *optional*, defaults to False):
- Set to `True` to upcast the softmax computation to `float32`.
- cross_attention_norm (`str`, *optional*, defaults to `None`):
- The type of normalization to use for the cross attention. Can be `None`, `layer_norm`, or `group_norm`.
- cross_attention_norm_num_groups (`int`, *optional*, defaults to 32):
- The number of groups to use for the group norm in the cross attention.
- added_kv_proj_dim (`int`, *optional*, defaults to `None`):
- The number of channels to use for the added key and value projections. If `None`, no projection is used.
- norm_num_groups (`int`, *optional*, defaults to `None`):
- The number of groups to use for the group norm in the attention.
- spatial_norm_dim (`int`, *optional*, defaults to `None`):
- The number of channels to use for the spatial normalization.
- out_bias (`bool`, *optional*, defaults to `True`):
- Set to `True` to use a bias in the output linear layer.
- scale_qk (`bool`, *optional*, defaults to `True`):
- Set to `True` to scale the query and key by `1 / sqrt(dim_head)`.
- only_cross_attention (`bool`, *optional*, defaults to `False`):
- Set to `True` to only use cross attention and not added_kv_proj_dim. Can only be set to `True` if
- `added_kv_proj_dim` is not `None`.
- eps (`float`, *optional*, defaults to 1e-5):
- An additional value added to the denominator in group normalization that is used for numerical stability.
- rescale_output_factor (`float`, *optional*, defaults to 1.0):
- A factor to rescale the output by dividing it with this value.
- residual_connection (`bool`, *optional*, defaults to `False`):
- Set to `True` to add the residual connection to the output.
- _from_deprecated_attn_block (`bool`, *optional*, defaults to `False`):
- Set to `True` if the attention block is loaded from a deprecated state dict.
- processor (`AttnProcessor`, *optional*, defaults to `None`):
- The attention processor to use. If `None`, defaults to `AttnProcessor2_0` if `torch 2.x` is used and
- `AttnProcessor` otherwise.
- """
-
- def __init__(
- self,
- query_dim: int,
- cross_attention_dim: Optional[int] = None,
- heads: int = 8,
- dim_head: int = 64,
- dropout: float = 0.0,
- bias: bool = False,
- upcast_attention: bool = False,
- upcast_softmax: bool = False,
- cross_attention_norm: Optional[str] = None,
- cross_attention_norm_num_groups: int = 32,
- added_kv_proj_dim: Optional[int] = None,
- norm_num_groups: Optional[int] = None,
- spatial_norm_dim: Optional[int] = None,
- out_bias: bool = True,
- scale_qk: bool = True,
- only_cross_attention: bool = False,
- eps: float = 1e-5,
- rescale_output_factor: float = 1.0,
- residual_connection: bool = False,
- _from_deprecated_attn_block: bool = False,
- processor: Optional["AttnProcessor"] = None,
- out_dim: int = None,
- ):
- super().__init__()
- self.inner_dim = out_dim if out_dim is not None else dim_head * heads
- self.query_dim = query_dim
- self.cross_attention_dim = cross_attention_dim if cross_attention_dim is not None else query_dim
- self.upcast_attention = upcast_attention
- self.upcast_softmax = upcast_softmax
- self.rescale_output_factor = rescale_output_factor
- self.residual_connection = residual_connection
- self.dropout = dropout
- self.fused_projections = False
- self.out_dim = out_dim if out_dim is not None else query_dim
-
- # we make use of this private variable to know whether this class is loaded
- # with an deprecated state dict so that we can convert it on the fly
- self._from_deprecated_attn_block = _from_deprecated_attn_block
-
- self.scale_qk = scale_qk
- self.scale = dim_head**-0.5 if self.scale_qk else 1.0
-
- self.heads = out_dim // dim_head if out_dim is not None else heads
- # for slice_size > 0 the attention score computation
- # is split across the batch axis to save memory
- # You can set slice_size with `set_attention_slice`
- self.sliceable_head_dim = heads
-
- self.added_kv_proj_dim = added_kv_proj_dim
- self.only_cross_attention = only_cross_attention
-
- if self.added_kv_proj_dim is None and self.only_cross_attention:
- raise ValueError(
- "`only_cross_attention` can only be set to True if `added_kv_proj_dim` is not None. Make sure to set either `only_cross_attention=False` or define `added_kv_proj_dim`."
- )
-
- if norm_num_groups is not None:
- self.group_norm = nn.GroupNorm(num_channels=query_dim, num_groups=norm_num_groups, eps=eps, affine=True)
- else:
- self.group_norm = None
-
- if spatial_norm_dim is not None:
- self.spatial_norm = SpatialNorm(f_channels=query_dim, zq_channels=spatial_norm_dim)
- else:
- self.spatial_norm = None
-
- if cross_attention_norm is None:
- self.norm_cross = None
- elif cross_attention_norm == "layer_norm":
- self.norm_cross = nn.LayerNorm(self.cross_attention_dim)
- elif cross_attention_norm == "group_norm":
- if self.added_kv_proj_dim is not None:
- # The given `encoder_hidden_states` are initially of shape
- # (batch_size, seq_len, added_kv_proj_dim) before being projected
- # to (batch_size, seq_len, cross_attention_dim). The norm is applied
- # before the projection, so we need to use `added_kv_proj_dim` as
- # the number of channels for the group norm.
- norm_cross_num_channels = added_kv_proj_dim
- else:
- norm_cross_num_channels = self.cross_attention_dim
-
- self.norm_cross = nn.GroupNorm(
- num_channels=norm_cross_num_channels, num_groups=cross_attention_norm_num_groups, eps=1e-5, affine=True
- )
- else:
- raise ValueError(
- f"unknown cross_attention_norm: {cross_attention_norm}. Should be None, 'layer_norm' or 'group_norm'"
- )
-
- if USE_PEFT_BACKEND:
- linear_cls = nn.Linear
- else:
- linear_cls = LoRACompatibleLinear
-
- self.linear_cls = linear_cls
- self.to_q = linear_cls(query_dim, self.inner_dim, bias=bias)
-
- if not self.only_cross_attention:
- # only relevant for the `AddedKVProcessor` classes
- self.to_k = linear_cls(self.cross_attention_dim, self.inner_dim, bias=bias)
- self.to_v = linear_cls(self.cross_attention_dim, self.inner_dim, bias=bias)
- else:
- self.to_k = None
- self.to_v = None
-
- if self.added_kv_proj_dim is not None:
- self.add_k_proj = linear_cls(added_kv_proj_dim, self.inner_dim)
- self.add_v_proj = linear_cls(added_kv_proj_dim, self.inner_dim)
-
- self.to_out = nn.ModuleList([])
- self.to_out.append(linear_cls(self.inner_dim, self.out_dim, bias=out_bias))
- self.to_out.append(nn.Dropout(dropout))
-
- # set attention processor
- # We use the AttnProcessor2_0 by default when torch 2.x is used which uses
- # torch.nn.functional.scaled_dot_product_attention for native Flash/memory_efficient_attention
- # but only if it has the default `scale` argument. TODO remove scale_qk check when we move to torch 2.1
- if processor is None:
- processor = (
- AttnProcessor2_0() if hasattr(F, "scaled_dot_product_attention") and self.scale_qk else AttnProcessor()
- )
- self.set_processor(processor)
-
- def set_use_memory_efficient_attention_xformers(
- self, use_memory_efficient_attention_xformers: bool, attention_op: Optional[Callable] = None
- ) -> None:
- r"""
- Set whether to use memory efficient attention from `xformers` or not.
-
- Args:
- use_memory_efficient_attention_xformers (`bool`):
- Whether to use memory efficient attention from `xformers` or not.
- attention_op (`Callable`, *optional*):
- The attention operation to use. Defaults to `None` which uses the default attention operation from
- `xformers`.
- """
- is_lora = hasattr(self, "processor") and isinstance(
- self.processor,
- LORA_ATTENTION_PROCESSORS,
- )
- is_custom_diffusion = hasattr(self, "processor") and isinstance(
- self.processor,
- (CustomDiffusionAttnProcessor, CustomDiffusionXFormersAttnProcessor, CustomDiffusionAttnProcessor2_0),
- )
- is_added_kv_processor = hasattr(self, "processor") and isinstance(
- self.processor,
- (
- AttnAddedKVProcessor,
- AttnAddedKVProcessor2_0,
- SlicedAttnAddedKVProcessor,
- XFormersAttnAddedKVProcessor,
- LoRAAttnAddedKVProcessor,
- ),
- )
-
- if use_memory_efficient_attention_xformers:
- if is_added_kv_processor and (is_lora or is_custom_diffusion):
- raise NotImplementedError(
- f"Memory efficient attention is currently not supported for LoRA or custom diffusion for attention processor type {self.processor}"
- )
- if not is_xformers_available():
- raise ModuleNotFoundError(
- (
- "Refer to https://github.com/facebookresearch/xformers for more information on how to install"
- " xformers"
- ),
- name="xformers",
- )
- elif not torch.cuda.is_available():
- raise ValueError(
- "torch.cuda.is_available() should be True but is False. xformers' memory efficient attention is"
- " only available for GPU "
- )
- else:
- try:
- # Make sure we can run the memory efficient attention
- _ = xformers.ops.memory_efficient_attention(
- torch.randn((1, 2, 40), device="cuda"),
- torch.randn((1, 2, 40), device="cuda"),
- torch.randn((1, 2, 40), device="cuda"),
- )
- except Exception as e:
- raise e
-
- if is_lora:
- # TODO (sayakpaul): should we throw a warning if someone wants to use the xformers
- # variant when using PT 2.0 now that we have LoRAAttnProcessor2_0?
- processor = LoRAXFormersAttnProcessor(
- hidden_size=self.processor.hidden_size,
- cross_attention_dim=self.processor.cross_attention_dim,
- rank=self.processor.rank,
- attention_op=attention_op,
- )
- processor.load_state_dict(self.processor.state_dict())
- processor.to(self.processor.to_q_lora.up.weight.device)
- elif is_custom_diffusion:
- processor = CustomDiffusionXFormersAttnProcessor(
- train_kv=self.processor.train_kv,
- train_q_out=self.processor.train_q_out,
- hidden_size=self.processor.hidden_size,
- cross_attention_dim=self.processor.cross_attention_dim,
- attention_op=attention_op,
- )
- processor.load_state_dict(self.processor.state_dict())
- if hasattr(self.processor, "to_k_custom_diffusion"):
- processor.to(self.processor.to_k_custom_diffusion.weight.device)
- elif is_added_kv_processor:
- # TODO(Patrick, Suraj, William) - currently xformers doesn't work for UnCLIP
- # which uses this type of cross attention ONLY because the attention mask of format
- # [0, ..., -10.000, ..., 0, ...,] is not supported
- # throw warning
- logger.info(
- "Memory efficient attention with `xformers` might currently not work correctly if an attention mask is required for the attention operation."
- )
- processor = XFormersAttnAddedKVProcessor(attention_op=attention_op)
- else:
- processor = XFormersAttnProcessor(attention_op=attention_op)
- else:
- if is_lora:
- attn_processor_class = (
- LoRAAttnProcessor2_0 if hasattr(F, "scaled_dot_product_attention") else LoRAAttnProcessor
- )
- processor = attn_processor_class(
- hidden_size=self.processor.hidden_size,
- cross_attention_dim=self.processor.cross_attention_dim,
- rank=self.processor.rank,
- )
- processor.load_state_dict(self.processor.state_dict())
- processor.to(self.processor.to_q_lora.up.weight.device)
- elif is_custom_diffusion:
- attn_processor_class = (
- CustomDiffusionAttnProcessor2_0
- if hasattr(F, "scaled_dot_product_attention")
- else CustomDiffusionAttnProcessor
- )
- processor = attn_processor_class(
- train_kv=self.processor.train_kv,
- train_q_out=self.processor.train_q_out,
- hidden_size=self.processor.hidden_size,
- cross_attention_dim=self.processor.cross_attention_dim,
- )
- processor.load_state_dict(self.processor.state_dict())
- if hasattr(self.processor, "to_k_custom_diffusion"):
- processor.to(self.processor.to_k_custom_diffusion.weight.device)
- else:
- # set attention processor
- # We use the AttnProcessor2_0 by default when torch 2.x is used which uses
- # torch.nn.functional.scaled_dot_product_attention for native Flash/memory_efficient_attention
- # but only if it has the default `scale` argument. TODO remove scale_qk check when we move to torch 2.1
- processor = (
- AttnProcessor2_0()
- if hasattr(F, "scaled_dot_product_attention") and self.scale_qk
- else AttnProcessor()
- )
-
- self.set_processor(processor)
-
- def set_attention_slice(self, slice_size: int) -> None:
- r"""
- Set the slice size for attention computation.
-
- Args:
- slice_size (`int`):
- The slice size for attention computation.
- """
- if slice_size is not None and slice_size > self.sliceable_head_dim:
- raise ValueError(f"slice_size {slice_size} has to be smaller or equal to {self.sliceable_head_dim}.")
-
- if slice_size is not None and self.added_kv_proj_dim is not None:
- processor = SlicedAttnAddedKVProcessor(slice_size)
- elif slice_size is not None:
- processor = SlicedAttnProcessor(slice_size)
- elif self.added_kv_proj_dim is not None:
- processor = AttnAddedKVProcessor()
- else:
- # set attention processor
- # We use the AttnProcessor2_0 by default when torch 2.x is used which uses
- # torch.nn.functional.scaled_dot_product_attention for native Flash/memory_efficient_attention
- # but only if it has the default `scale` argument. TODO remove scale_qk check when we move to torch 2.1
- processor = (
- AttnProcessor2_0() if hasattr(F, "scaled_dot_product_attention") and self.scale_qk else AttnProcessor()
- )
-
- self.set_processor(processor)
-
- def set_processor(self, processor: "AttnProcessor", _remove_lora: bool = False) -> None:
- r"""
- Set the attention processor to use.
-
- Args:
- processor (`AttnProcessor`):
- The attention processor to use.
- _remove_lora (`bool`, *optional*, defaults to `False`):
- Set to `True` to remove LoRA layers from the model.
- """
- if not USE_PEFT_BACKEND and hasattr(self, "processor") and _remove_lora and self.to_q.lora_layer is not None:
- deprecate(
- "set_processor to offload LoRA",
- "0.26.0",
- "In detail, removing LoRA layers via calling `set_default_attn_processor` is deprecated. Please make sure to call `pipe.unload_lora_weights()` instead.",
- )
- # TODO(Patrick, Sayak) - this can be deprecated once PEFT LoRA integration is complete
- # We need to remove all LoRA layers
- # Don't forget to remove ALL `_remove_lora` from the codebase
- for module in self.modules():
- if hasattr(module, "set_lora_layer"):
- module.set_lora_layer(None)
-
- # if current processor is in `self._modules` and if passed `processor` is not, we need to
- # pop `processor` from `self._modules`
- if (
- hasattr(self, "processor")
- and isinstance(self.processor, torch.nn.Module)
- and not isinstance(processor, torch.nn.Module)
- ):
- logger.info(f"You are removing possibly trained weights of {self.processor} with {processor}")
- self._modules.pop("processor")
-
- self.processor = processor
-
- def get_processor(self, return_deprecated_lora: bool = False) -> "AttentionProcessor":
- r"""
- Get the attention processor in use.
-
- Args:
- return_deprecated_lora (`bool`, *optional*, defaults to `False`):
- Set to `True` to return the deprecated LoRA attention processor.
-
- Returns:
- "AttentionProcessor": The attention processor in use.
- """
- if not return_deprecated_lora:
- return self.processor
-
- # TODO(Sayak, Patrick). The rest of the function is needed to ensure backwards compatible
- # serialization format for LoRA Attention Processors. It should be deleted once the integration
- # with PEFT is completed.
- is_lora_activated = {
- name: module.lora_layer is not None
- for name, module in self.named_modules()
- if hasattr(module, "lora_layer")
- }
-
- # 1. if no layer has a LoRA activated we can return the processor as usual
- if not any(is_lora_activated.values()):
- return self.processor
-
- # If doesn't apply LoRA do `add_k_proj` or `add_v_proj`
- is_lora_activated.pop("add_k_proj", None)
- is_lora_activated.pop("add_v_proj", None)
- # 2. else it is not possible that only some layers have LoRA activated
- if not all(is_lora_activated.values()):
- raise ValueError(
- f"Make sure that either all layers or no layers have LoRA activated, but have {is_lora_activated}"
- )
-
- # 3. And we need to merge the current LoRA layers into the corresponding LoRA attention processor
- non_lora_processor_cls_name = self.processor.__class__.__name__
- lora_processor_cls = getattr(import_module(__name__), "LoRA" + non_lora_processor_cls_name)
-
- hidden_size = self.inner_dim
-
- # now create a LoRA attention processor from the LoRA layers
- if lora_processor_cls in [LoRAAttnProcessor, LoRAAttnProcessor2_0, LoRAXFormersAttnProcessor]:
- kwargs = {
- "cross_attention_dim": self.cross_attention_dim,
- "rank": self.to_q.lora_layer.rank,
- "network_alpha": self.to_q.lora_layer.network_alpha,
- "q_rank": self.to_q.lora_layer.rank,
- "q_hidden_size": self.to_q.lora_layer.out_features,
- "k_rank": self.to_k.lora_layer.rank,
- "k_hidden_size": self.to_k.lora_layer.out_features,
- "v_rank": self.to_v.lora_layer.rank,
- "v_hidden_size": self.to_v.lora_layer.out_features,
- "out_rank": self.to_out[0].lora_layer.rank,
- "out_hidden_size": self.to_out[0].lora_layer.out_features,
- }
-
- if hasattr(self.processor, "attention_op"):
- kwargs["attention_op"] = self.processor.attention_op
-
- lora_processor = lora_processor_cls(hidden_size, **kwargs)
- lora_processor.to_q_lora.load_state_dict(self.to_q.lora_layer.state_dict())
- lora_processor.to_k_lora.load_state_dict(self.to_k.lora_layer.state_dict())
- lora_processor.to_v_lora.load_state_dict(self.to_v.lora_layer.state_dict())
- lora_processor.to_out_lora.load_state_dict(self.to_out[0].lora_layer.state_dict())
- elif lora_processor_cls == LoRAAttnAddedKVProcessor:
- lora_processor = lora_processor_cls(
- hidden_size,
- cross_attention_dim=self.add_k_proj.weight.shape[0],
- rank=self.to_q.lora_layer.rank,
- network_alpha=self.to_q.lora_layer.network_alpha,
- )
- lora_processor.to_q_lora.load_state_dict(self.to_q.lora_layer.state_dict())
- lora_processor.to_k_lora.load_state_dict(self.to_k.lora_layer.state_dict())
- lora_processor.to_v_lora.load_state_dict(self.to_v.lora_layer.state_dict())
- lora_processor.to_out_lora.load_state_dict(self.to_out[0].lora_layer.state_dict())
-
- # only save if used
- if self.add_k_proj.lora_layer is not None:
- lora_processor.add_k_proj_lora.load_state_dict(self.add_k_proj.lora_layer.state_dict())
- lora_processor.add_v_proj_lora.load_state_dict(self.add_v_proj.lora_layer.state_dict())
- else:
- lora_processor.add_k_proj_lora = None
- lora_processor.add_v_proj_lora = None
- else:
- raise ValueError(f"{lora_processor_cls} does not exist.")
-
- return lora_processor
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- **cross_attention_kwargs,
- ) -> torch.Tensor:
- r"""
- The forward method of the `Attention` class.
-
- Args:
- hidden_states (`torch.Tensor`):
- The hidden states of the query.
- encoder_hidden_states (`torch.Tensor`, *optional*):
- The hidden states of the encoder.
- attention_mask (`torch.Tensor`, *optional*):
- The attention mask to use. If `None`, no mask is applied.
- **cross_attention_kwargs:
- Additional keyword arguments to pass along to the cross attention.
-
- Returns:
- `torch.Tensor`: The output of the attention layer.
- """
- # The `Attention` class can call different attention processors / attention functions
- # here we simply pass along all tensors to the selected processor class
- # For standard processors that are defined here, `**cross_attention_kwargs` is empty
- return self.processor(
- self,
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=attention_mask,
- **cross_attention_kwargs,
- )
-
- def batch_to_head_dim(self, tensor: torch.Tensor) -> torch.Tensor:
- r"""
- Reshape the tensor from `[batch_size, seq_len, dim]` to `[batch_size // heads, seq_len, dim * heads]`. `heads`
- is the number of heads initialized while constructing the `Attention` class.
-
- Args:
- tensor (`torch.Tensor`): The tensor to reshape.
-
- Returns:
- `torch.Tensor`: The reshaped tensor.
- """
- head_size = self.heads
- batch_size, seq_len, dim = tensor.shape
- tensor = tensor.reshape(batch_size // head_size, head_size, seq_len, dim)
- tensor = tensor.permute(0, 2, 1, 3).reshape(batch_size // head_size, seq_len, dim * head_size)
- return tensor
-
- def head_to_batch_dim(self, tensor: torch.Tensor, out_dim: int = 3) -> torch.Tensor:
- r"""
- Reshape the tensor from `[batch_size, seq_len, dim]` to `[batch_size, seq_len, heads, dim // heads]` `heads` is
- the number of heads initialized while constructing the `Attention` class.
-
- Args:
- tensor (`torch.Tensor`): The tensor to reshape.
- out_dim (`int`, *optional*, defaults to `3`): The output dimension of the tensor. If `3`, the tensor is
- reshaped to `[batch_size * heads, seq_len, dim // heads]`.
-
- Returns:
- `torch.Tensor`: The reshaped tensor.
- """
- head_size = self.heads
- batch_size, seq_len, dim = tensor.shape
- tensor = tensor.reshape(batch_size, seq_len, head_size, dim // head_size)
- tensor = tensor.permute(0, 2, 1, 3)
-
- if out_dim == 3:
- tensor = tensor.reshape(batch_size * head_size, seq_len, dim // head_size)
-
- return tensor
-
- def get_attention_scores(
- self, query: torch.Tensor, key: torch.Tensor, attention_mask: torch.Tensor = None
- ) -> torch.Tensor:
- r"""
- Compute the attention scores.
-
- Args:
- query (`torch.Tensor`): The query tensor.
- key (`torch.Tensor`): The key tensor.
- attention_mask (`torch.Tensor`, *optional*): The attention mask to use. If `None`, no mask is applied.
-
- Returns:
- `torch.Tensor`: The attention probabilities/scores.
- """
- dtype = query.dtype
- if self.upcast_attention:
- query = query.float()
- key = key.float()
-
- if attention_mask is None:
- baddbmm_input = torch.empty(
- query.shape[0], query.shape[1], key.shape[1], dtype=query.dtype, device=query.device
- )
- beta = 0
- else:
- baddbmm_input = attention_mask
- beta = 1
-
- attention_scores = torch.baddbmm(
- baddbmm_input,
- query,
- key.transpose(-1, -2),
- beta=beta,
- alpha=self.scale,
- )
- del baddbmm_input
-
- if self.upcast_softmax:
- attention_scores = attention_scores.float()
-
- attention_probs = attention_scores.softmax(dim=-1)
- del attention_scores
-
- attention_probs = attention_probs.to(dtype)
-
- return attention_probs
-
- def prepare_attention_mask(
- self, attention_mask: torch.Tensor, target_length: int, batch_size: int, out_dim: int = 3
- ) -> torch.Tensor:
- r"""
- Prepare the attention mask for the attention computation.
-
- Args:
- attention_mask (`torch.Tensor`):
- The attention mask to prepare.
- target_length (`int`):
- The target length of the attention mask. This is the length of the attention mask after padding.
- batch_size (`int`):
- The batch size, which is used to repeat the attention mask.
- out_dim (`int`, *optional*, defaults to `3`):
- The output dimension of the attention mask. Can be either `3` or `4`.
-
- Returns:
- `torch.Tensor`: The prepared attention mask.
- """
- head_size = self.heads
- if attention_mask is None:
- return attention_mask
-
- current_length: int = attention_mask.shape[-1]
- if current_length != target_length:
- if attention_mask.device.type == "mps":
- # HACK: MPS: Does not support padding by greater than dimension of input tensor.
- # Instead, we can manually construct the padding tensor.
- padding_shape = (attention_mask.shape[0], attention_mask.shape[1], target_length)
- padding = torch.zeros(padding_shape, dtype=attention_mask.dtype, device=attention_mask.device)
- attention_mask = torch.cat([attention_mask, padding], dim=2)
- else:
- # TODO: for pipelines such as stable-diffusion, padding cross-attn mask:
- # we want to instead pad by (0, remaining_length), where remaining_length is:
- # remaining_length: int = target_length - current_length
- # TODO: re-enable tests/models/test_models_unet_2d_condition.py#test_model_xattn_padding
- attention_mask = F.pad(attention_mask, (0, target_length), value=0.0)
-
- if out_dim == 3:
- if attention_mask.shape[0] < batch_size * head_size:
- attention_mask = attention_mask.repeat_interleave(head_size, dim=0)
- elif out_dim == 4:
- attention_mask = attention_mask.unsqueeze(1)
- attention_mask = attention_mask.repeat_interleave(head_size, dim=1)
-
- return attention_mask
-
- def norm_encoder_hidden_states(self, encoder_hidden_states: torch.Tensor) -> torch.Tensor:
- r"""
- Normalize the encoder hidden states. Requires `self.norm_cross` to be specified when constructing the
- `Attention` class.
-
- Args:
- encoder_hidden_states (`torch.Tensor`): Hidden states of the encoder.
-
- Returns:
- `torch.Tensor`: The normalized encoder hidden states.
- """
- assert self.norm_cross is not None, "self.norm_cross must be defined to call self.norm_encoder_hidden_states"
-
- if isinstance(self.norm_cross, nn.LayerNorm):
- encoder_hidden_states = self.norm_cross(encoder_hidden_states)
- elif isinstance(self.norm_cross, nn.GroupNorm):
- # Group norm norms along the channels dimension and expects
- # input to be in the shape of (N, C, *). In this case, we want
- # to norm along the hidden dimension, so we need to move
- # (batch_size, sequence_length, hidden_size) ->
- # (batch_size, hidden_size, sequence_length)
- encoder_hidden_states = encoder_hidden_states.transpose(1, 2)
- encoder_hidden_states = self.norm_cross(encoder_hidden_states)
- encoder_hidden_states = encoder_hidden_states.transpose(1, 2)
- else:
- assert False
-
- return encoder_hidden_states
-
- @torch.no_grad()
- def fuse_projections(self, fuse=True):
- is_cross_attention = self.cross_attention_dim != self.query_dim
- device = self.to_q.weight.data.device
- dtype = self.to_q.weight.data.dtype
-
- if not is_cross_attention:
- # fetch weight matrices.
- concatenated_weights = torch.cat([self.to_q.weight.data, self.to_k.weight.data, self.to_v.weight.data])
- in_features = concatenated_weights.shape[1]
- out_features = concatenated_weights.shape[0]
-
- # create a new single projection layer and copy over the weights.
- self.to_qkv = self.linear_cls(in_features, out_features, bias=False, device=device, dtype=dtype)
- self.to_qkv.weight.copy_(concatenated_weights)
-
- else:
- concatenated_weights = torch.cat([self.to_k.weight.data, self.to_v.weight.data])
- in_features = concatenated_weights.shape[1]
- out_features = concatenated_weights.shape[0]
-
- self.to_kv = self.linear_cls(in_features, out_features, bias=False, device=device, dtype=dtype)
- self.to_kv.weight.copy_(concatenated_weights)
-
- self.fused_projections = fuse
-
-
-class AttnProcessor:
- r"""
- Default processor for performing attention-related computations.
- """
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> torch.Tensor:
- residual = hidden_states
-
- args = () if USE_PEFT_BACKEND else (scale,)
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states, *args)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states, *args)
- value = attn.to_v(encoder_hidden_states, *args)
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class CustomDiffusionAttnProcessor(nn.Module):
- r"""
- Processor for implementing attention for the Custom Diffusion method.
-
- Args:
- train_kv (`bool`, defaults to `True`):
- Whether to newly train the key and value matrices corresponding to the text features.
- train_q_out (`bool`, defaults to `True`):
- Whether to newly train query matrices corresponding to the latent image features.
- hidden_size (`int`, *optional*, defaults to `None`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*, defaults to `None`):
- The number of channels in the `encoder_hidden_states`.
- out_bias (`bool`, defaults to `True`):
- Whether to include the bias parameter in `train_q_out`.
- dropout (`float`, *optional*, defaults to 0.0):
- The dropout probability to use.
- """
-
- def __init__(
- self,
- train_kv: bool = True,
- train_q_out: bool = True,
- hidden_size: Optional[int] = None,
- cross_attention_dim: Optional[int] = None,
- out_bias: bool = True,
- dropout: float = 0.0,
- ):
- super().__init__()
- self.train_kv = train_kv
- self.train_q_out = train_q_out
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
-
- # `_custom_diffusion` id for easy serialization and loading.
- if self.train_kv:
- self.to_k_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- if self.train_q_out:
- self.to_q_custom_diffusion = nn.Linear(hidden_size, hidden_size, bias=False)
- self.to_out_custom_diffusion = nn.ModuleList([])
- self.to_out_custom_diffusion.append(nn.Linear(hidden_size, hidden_size, bias=out_bias))
- self.to_out_custom_diffusion.append(nn.Dropout(dropout))
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.Tensor:
- batch_size, sequence_length, _ = hidden_states.shape
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- if self.train_q_out:
- query = self.to_q_custom_diffusion(hidden_states).to(attn.to_q.weight.dtype)
- else:
- query = attn.to_q(hidden_states.to(attn.to_q.weight.dtype))
-
- if encoder_hidden_states is None:
- crossattn = False
- encoder_hidden_states = hidden_states
- else:
- crossattn = True
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- if self.train_kv:
- key = self.to_k_custom_diffusion(encoder_hidden_states.to(self.to_k_custom_diffusion.weight.dtype))
- value = self.to_v_custom_diffusion(encoder_hidden_states.to(self.to_v_custom_diffusion.weight.dtype))
- key = key.to(attn.to_q.weight.dtype)
- value = value.to(attn.to_q.weight.dtype)
- else:
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- if crossattn:
- detach = torch.ones_like(key)
- detach[:, :1, :] = detach[:, :1, :] * 0.0
- key = detach * key + (1 - detach) * key.detach()
- value = detach * value + (1 - detach) * value.detach()
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- if self.train_q_out:
- # linear proj
- hidden_states = self.to_out_custom_diffusion[0](hidden_states)
- # dropout
- hidden_states = self.to_out_custom_diffusion[1](hidden_states)
- else:
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- return hidden_states
-
-
-class AttnAddedKVProcessor:
- r"""
- Processor for performing attention-related computations with extra learnable key and value matrices for the text
- encoder.
- """
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> torch.Tensor:
- residual = hidden_states
-
- args = () if USE_PEFT_BACKEND else (scale,)
-
- hidden_states = hidden_states.view(hidden_states.shape[0], hidden_states.shape[1], -1).transpose(1, 2)
- batch_size, sequence_length, _ = hidden_states.shape
-
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states, *args)
- query = attn.head_to_batch_dim(query)
-
- encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states, *args)
- encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states, *args)
- encoder_hidden_states_key_proj = attn.head_to_batch_dim(encoder_hidden_states_key_proj)
- encoder_hidden_states_value_proj = attn.head_to_batch_dim(encoder_hidden_states_value_proj)
-
- if not attn.only_cross_attention:
- key = attn.to_k(hidden_states, *args)
- value = attn.to_v(hidden_states, *args)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
- key = torch.cat([encoder_hidden_states_key_proj, key], dim=1)
- value = torch.cat([encoder_hidden_states_value_proj, value], dim=1)
- else:
- key = encoder_hidden_states_key_proj
- value = encoder_hidden_states_value_proj
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- hidden_states = hidden_states.transpose(-1, -2).reshape(residual.shape)
- hidden_states = hidden_states + residual
-
- return hidden_states
-
-
-class AttnAddedKVProcessor2_0:
- r"""
- Processor for performing scaled dot-product attention (enabled by default if you're using PyTorch 2.0), with extra
- learnable key and value matrices for the text encoder.
- """
-
- def __init__(self):
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError(
- "AttnAddedKVProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0."
- )
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> torch.Tensor:
- residual = hidden_states
-
- args = () if USE_PEFT_BACKEND else (scale,)
-
- hidden_states = hidden_states.view(hidden_states.shape[0], hidden_states.shape[1], -1).transpose(1, 2)
- batch_size, sequence_length, _ = hidden_states.shape
-
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size, out_dim=4)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states, *args)
- query = attn.head_to_batch_dim(query, out_dim=4)
-
- encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states)
- encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states)
- encoder_hidden_states_key_proj = attn.head_to_batch_dim(encoder_hidden_states_key_proj, out_dim=4)
- encoder_hidden_states_value_proj = attn.head_to_batch_dim(encoder_hidden_states_value_proj, out_dim=4)
-
- if not attn.only_cross_attention:
- key = attn.to_k(hidden_states, *args)
- value = attn.to_v(hidden_states, *args)
- key = attn.head_to_batch_dim(key, out_dim=4)
- value = attn.head_to_batch_dim(value, out_dim=4)
- key = torch.cat([encoder_hidden_states_key_proj, key], dim=2)
- value = torch.cat([encoder_hidden_states_value_proj, value], dim=2)
- else:
- key = encoder_hidden_states_key_proj
- value = encoder_hidden_states_value_proj
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, residual.shape[1])
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- hidden_states = hidden_states.transpose(-1, -2).reshape(residual.shape)
- hidden_states = hidden_states + residual
-
- return hidden_states
-
-
-class XFormersAttnAddedKVProcessor:
- r"""
- Processor for implementing memory efficient attention using xFormers.
-
- Args:
- attention_op (`Callable`, *optional*, defaults to `None`):
- The base
- [operator](https://facebookresearch.github.io/xformers/components/ops.html#xformers.ops.AttentionOpBase) to
- use as the attention operator. It is recommended to set to `None`, and allow xFormers to choose the best
- operator.
- """
-
- def __init__(self, attention_op: Optional[Callable] = None):
- self.attention_op = attention_op
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.Tensor:
- residual = hidden_states
- hidden_states = hidden_states.view(hidden_states.shape[0], hidden_states.shape[1], -1).transpose(1, 2)
- batch_size, sequence_length, _ = hidden_states.shape
-
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
- query = attn.head_to_batch_dim(query)
-
- encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states)
- encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states)
- encoder_hidden_states_key_proj = attn.head_to_batch_dim(encoder_hidden_states_key_proj)
- encoder_hidden_states_value_proj = attn.head_to_batch_dim(encoder_hidden_states_value_proj)
-
- if not attn.only_cross_attention:
- key = attn.to_k(hidden_states)
- value = attn.to_v(hidden_states)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
- key = torch.cat([encoder_hidden_states_key_proj, key], dim=1)
- value = torch.cat([encoder_hidden_states_value_proj, value], dim=1)
- else:
- key = encoder_hidden_states_key_proj
- value = encoder_hidden_states_value_proj
-
- hidden_states = xformers.ops.memory_efficient_attention(
- query, key, value, attn_bias=attention_mask, op=self.attention_op, scale=attn.scale
- )
- hidden_states = hidden_states.to(query.dtype)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- hidden_states = hidden_states.transpose(-1, -2).reshape(residual.shape)
- hidden_states = hidden_states + residual
-
- return hidden_states
-
-
-class XFormersAttnProcessor:
- r"""
- Processor for implementing memory efficient attention using xFormers.
-
- Args:
- attention_op (`Callable`, *optional*, defaults to `None`):
- The base
- [operator](https://facebookresearch.github.io/xformers/components/ops.html#xformers.ops.AttentionOpBase) to
- use as the attention operator. It is recommended to set to `None`, and allow xFormers to choose the best
- operator.
- """
-
- def __init__(self, attention_op: Optional[Callable] = None):
- self.attention_op = attention_op
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- residual = hidden_states
-
- args = () if USE_PEFT_BACKEND else (scale,)
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, key_tokens, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- attention_mask = attn.prepare_attention_mask(attention_mask, key_tokens, batch_size)
- if attention_mask is not None:
- # expand our mask's singleton query_tokens dimension:
- # [batch*heads, 1, key_tokens] ->
- # [batch*heads, query_tokens, key_tokens]
- # so that it can be added as a bias onto the attention scores that xformers computes:
- # [batch*heads, query_tokens, key_tokens]
- # we do this explicitly because xformers doesn't broadcast the singleton dimension for us.
- _, query_tokens, _ = hidden_states.shape
- attention_mask = attention_mask.expand(-1, query_tokens, -1)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states, *args)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states, *args)
- value = attn.to_v(encoder_hidden_states, *args)
-
- query = attn.head_to_batch_dim(query).contiguous()
- key = attn.head_to_batch_dim(key).contiguous()
- value = attn.head_to_batch_dim(value).contiguous()
-
- hidden_states = xformers.ops.memory_efficient_attention(
- query, key, value, attn_bias=attention_mask, op=self.attention_op, scale=attn.scale
- )
- hidden_states = hidden_states.to(query.dtype)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class AttnProcessor2_0:
- r"""
- Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
- """
-
- def __init__(self):
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- **kwargs,
- ) -> torch.FloatTensor:
- residual = hidden_states
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- args = () if USE_PEFT_BACKEND else (scale,)
- query = attn.to_q(hidden_states, *args)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states, *args)
- value = attn.to_v(encoder_hidden_states, *args)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class FusedAttnProcessor2_0:
- r"""
- Processor for implementing scaled dot-product attention (enabled by default if you're using PyTorch 2.0).
- It uses fused projection layers. For self-attention modules, all projection matrices (i.e., query,
- key, value) are fused. For cross-attention modules, key and value projection matrices are fused.
-
-
-
- This API is currently 🧪 experimental in nature and can change in future.
-
-
- """
-
- def __init__(self):
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError(
- "FusedAttnProcessor2_0 requires at least PyTorch 2.0, to use it. Please upgrade PyTorch to > 2.0."
- )
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- residual = hidden_states
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- args = () if USE_PEFT_BACKEND else (scale,)
- if encoder_hidden_states is None:
- qkv = attn.to_qkv(hidden_states, *args)
- split_size = qkv.shape[-1] // 3
- query, key, value = torch.split(qkv, split_size, dim=-1)
- else:
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
- query = attn.to_q(hidden_states, *args)
-
- kv = attn.to_kv(encoder_hidden_states, *args)
- split_size = kv.shape[-1] // 2
- key, value = torch.split(kv, split_size, dim=-1)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states, *args)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class CustomDiffusionXFormersAttnProcessor(nn.Module):
- r"""
- Processor for implementing memory efficient attention using xFormers for the Custom Diffusion method.
-
- Args:
- train_kv (`bool`, defaults to `True`):
- Whether to newly train the key and value matrices corresponding to the text features.
- train_q_out (`bool`, defaults to `True`):
- Whether to newly train query matrices corresponding to the latent image features.
- hidden_size (`int`, *optional*, defaults to `None`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*, defaults to `None`):
- The number of channels in the `encoder_hidden_states`.
- out_bias (`bool`, defaults to `True`):
- Whether to include the bias parameter in `train_q_out`.
- dropout (`float`, *optional*, defaults to 0.0):
- The dropout probability to use.
- attention_op (`Callable`, *optional*, defaults to `None`):
- The base
- [operator](https://facebookresearch.github.io/xformers/components/ops.html#xformers.ops.AttentionOpBase) to use
- as the attention operator. It is recommended to set to `None`, and allow xFormers to choose the best operator.
- """
-
- def __init__(
- self,
- train_kv: bool = True,
- train_q_out: bool = False,
- hidden_size: Optional[int] = None,
- cross_attention_dim: Optional[int] = None,
- out_bias: bool = True,
- dropout: float = 0.0,
- attention_op: Optional[Callable] = None,
- ):
- super().__init__()
- self.train_kv = train_kv
- self.train_q_out = train_q_out
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.attention_op = attention_op
-
- # `_custom_diffusion` id for easy serialization and loading.
- if self.train_kv:
- self.to_k_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- if self.train_q_out:
- self.to_q_custom_diffusion = nn.Linear(hidden_size, hidden_size, bias=False)
- self.to_out_custom_diffusion = nn.ModuleList([])
- self.to_out_custom_diffusion.append(nn.Linear(hidden_size, hidden_size, bias=out_bias))
- self.to_out_custom_diffusion.append(nn.Dropout(dropout))
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if self.train_q_out:
- query = self.to_q_custom_diffusion(hidden_states).to(attn.to_q.weight.dtype)
- else:
- query = attn.to_q(hidden_states.to(attn.to_q.weight.dtype))
-
- if encoder_hidden_states is None:
- crossattn = False
- encoder_hidden_states = hidden_states
- else:
- crossattn = True
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- if self.train_kv:
- key = self.to_k_custom_diffusion(encoder_hidden_states.to(self.to_k_custom_diffusion.weight.dtype))
- value = self.to_v_custom_diffusion(encoder_hidden_states.to(self.to_v_custom_diffusion.weight.dtype))
- key = key.to(attn.to_q.weight.dtype)
- value = value.to(attn.to_q.weight.dtype)
- else:
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- if crossattn:
- detach = torch.ones_like(key)
- detach[:, :1, :] = detach[:, :1, :] * 0.0
- key = detach * key + (1 - detach) * key.detach()
- value = detach * value + (1 - detach) * value.detach()
-
- query = attn.head_to_batch_dim(query).contiguous()
- key = attn.head_to_batch_dim(key).contiguous()
- value = attn.head_to_batch_dim(value).contiguous()
-
- hidden_states = xformers.ops.memory_efficient_attention(
- query, key, value, attn_bias=attention_mask, op=self.attention_op, scale=attn.scale
- )
- hidden_states = hidden_states.to(query.dtype)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- if self.train_q_out:
- # linear proj
- hidden_states = self.to_out_custom_diffusion[0](hidden_states)
- # dropout
- hidden_states = self.to_out_custom_diffusion[1](hidden_states)
- else:
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- return hidden_states
-
-
-class CustomDiffusionAttnProcessor2_0(nn.Module):
- r"""
- Processor for implementing attention for the Custom Diffusion method using PyTorch 2.0’s memory-efficient scaled
- dot-product attention.
-
- Args:
- train_kv (`bool`, defaults to `True`):
- Whether to newly train the key and value matrices corresponding to the text features.
- train_q_out (`bool`, defaults to `True`):
- Whether to newly train query matrices corresponding to the latent image features.
- hidden_size (`int`, *optional*, defaults to `None`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*, defaults to `None`):
- The number of channels in the `encoder_hidden_states`.
- out_bias (`bool`, defaults to `True`):
- Whether to include the bias parameter in `train_q_out`.
- dropout (`float`, *optional*, defaults to 0.0):
- The dropout probability to use.
- """
-
- def __init__(
- self,
- train_kv: bool = True,
- train_q_out: bool = True,
- hidden_size: Optional[int] = None,
- cross_attention_dim: Optional[int] = None,
- out_bias: bool = True,
- dropout: float = 0.0,
- ):
- super().__init__()
- self.train_kv = train_kv
- self.train_q_out = train_q_out
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
-
- # `_custom_diffusion` id for easy serialization and loading.
- if self.train_kv:
- self.to_k_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_custom_diffusion = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- if self.train_q_out:
- self.to_q_custom_diffusion = nn.Linear(hidden_size, hidden_size, bias=False)
- self.to_out_custom_diffusion = nn.ModuleList([])
- self.to_out_custom_diffusion.append(nn.Linear(hidden_size, hidden_size, bias=out_bias))
- self.to_out_custom_diffusion.append(nn.Dropout(dropout))
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- batch_size, sequence_length, _ = hidden_states.shape
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- if self.train_q_out:
- query = self.to_q_custom_diffusion(hidden_states)
- else:
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- crossattn = False
- encoder_hidden_states = hidden_states
- else:
- crossattn = True
- if attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- if self.train_kv:
- key = self.to_k_custom_diffusion(encoder_hidden_states.to(self.to_k_custom_diffusion.weight.dtype))
- value = self.to_v_custom_diffusion(encoder_hidden_states.to(self.to_v_custom_diffusion.weight.dtype))
- key = key.to(attn.to_q.weight.dtype)
- value = value.to(attn.to_q.weight.dtype)
-
- else:
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- if crossattn:
- detach = torch.ones_like(key)
- detach[:, :1, :] = detach[:, :1, :] * 0.0
- key = detach * key + (1 - detach) * key.detach()
- value = detach * value + (1 - detach) * value.detach()
-
- inner_dim = hidden_states.shape[-1]
-
- head_dim = inner_dim // attn.heads
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- if self.train_q_out:
- # linear proj
- hidden_states = self.to_out_custom_diffusion[0](hidden_states)
- # dropout
- hidden_states = self.to_out_custom_diffusion[1](hidden_states)
- else:
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- return hidden_states
-
-
-class SlicedAttnProcessor:
- r"""
- Processor for implementing sliced attention.
-
- Args:
- slice_size (`int`, *optional*):
- The number of steps to compute attention. Uses as many slices as `attention_head_dim // slice_size`, and
- `attention_head_dim` must be a multiple of the `slice_size`.
- """
-
- def __init__(self, slice_size: int):
- self.slice_size = slice_size
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- residual = hidden_states
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
- dim = query.shape[-1]
- query = attn.head_to_batch_dim(query)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- batch_size_attention, query_tokens, _ = query.shape
- hidden_states = torch.zeros(
- (batch_size_attention, query_tokens, dim // attn.heads), device=query.device, dtype=query.dtype
- )
-
- for i in range(batch_size_attention // self.slice_size):
- start_idx = i * self.slice_size
- end_idx = (i + 1) * self.slice_size
-
- query_slice = query[start_idx:end_idx]
- key_slice = key[start_idx:end_idx]
- attn_mask_slice = attention_mask[start_idx:end_idx] if attention_mask is not None else None
-
- attn_slice = attn.get_attention_scores(query_slice, key_slice, attn_mask_slice)
-
- attn_slice = torch.bmm(attn_slice, value[start_idx:end_idx])
-
- hidden_states[start_idx:end_idx] = attn_slice
-
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class SlicedAttnAddedKVProcessor:
- r"""
- Processor for implementing sliced attention with extra learnable key and value matrices for the text encoder.
-
- Args:
- slice_size (`int`, *optional*):
- The number of steps to compute attention. Uses as many slices as `attention_head_dim // slice_size`, and
- `attention_head_dim` must be a multiple of the `slice_size`.
- """
-
- def __init__(self, slice_size):
- self.slice_size = slice_size
-
- def __call__(
- self,
- attn: "Attention",
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- hidden_states = hidden_states.view(hidden_states.shape[0], hidden_states.shape[1], -1).transpose(1, 2)
-
- batch_size, sequence_length, _ = hidden_states.shape
-
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
- dim = query.shape[-1]
- query = attn.head_to_batch_dim(query)
-
- encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states)
- encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states)
-
- encoder_hidden_states_key_proj = attn.head_to_batch_dim(encoder_hidden_states_key_proj)
- encoder_hidden_states_value_proj = attn.head_to_batch_dim(encoder_hidden_states_value_proj)
-
- if not attn.only_cross_attention:
- key = attn.to_k(hidden_states)
- value = attn.to_v(hidden_states)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
- key = torch.cat([encoder_hidden_states_key_proj, key], dim=1)
- value = torch.cat([encoder_hidden_states_value_proj, value], dim=1)
- else:
- key = encoder_hidden_states_key_proj
- value = encoder_hidden_states_value_proj
-
- batch_size_attention, query_tokens, _ = query.shape
- hidden_states = torch.zeros(
- (batch_size_attention, query_tokens, dim // attn.heads), device=query.device, dtype=query.dtype
- )
-
- for i in range(batch_size_attention // self.slice_size):
- start_idx = i * self.slice_size
- end_idx = (i + 1) * self.slice_size
-
- query_slice = query[start_idx:end_idx]
- key_slice = key[start_idx:end_idx]
- attn_mask_slice = attention_mask[start_idx:end_idx] if attention_mask is not None else None
-
- attn_slice = attn.get_attention_scores(query_slice, key_slice, attn_mask_slice)
-
- attn_slice = torch.bmm(attn_slice, value[start_idx:end_idx])
-
- hidden_states[start_idx:end_idx] = attn_slice
-
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- hidden_states = hidden_states.transpose(-1, -2).reshape(residual.shape)
- hidden_states = hidden_states + residual
-
- return hidden_states
-
-
-class SpatialNorm(nn.Module):
- """
- Spatially conditioned normalization as defined in https://arxiv.org/abs/2209.09002.
-
- Args:
- f_channels (`int`):
- The number of channels for input to group normalization layer, and output of the spatial norm layer.
- zq_channels (`int`):
- The number of channels for the quantized vector as described in the paper.
- """
-
- def __init__(
- self,
- f_channels: int,
- zq_channels: int,
- ):
- super().__init__()
- self.norm_layer = nn.GroupNorm(num_channels=f_channels, num_groups=32, eps=1e-6, affine=True)
- self.conv_y = nn.Conv2d(zq_channels, f_channels, kernel_size=1, stride=1, padding=0)
- self.conv_b = nn.Conv2d(zq_channels, f_channels, kernel_size=1, stride=1, padding=0)
-
- def forward(self, f: torch.FloatTensor, zq: torch.FloatTensor) -> torch.FloatTensor:
- f_size = f.shape[-2:]
- zq = F.interpolate(zq, size=f_size, mode="nearest")
- norm_f = self.norm_layer(f)
- new_f = norm_f * self.conv_y(zq) + self.conv_b(zq)
- return new_f
-
-
-## Deprecated
-class LoRAAttnProcessor(nn.Module):
- r"""
- Processor for implementing the LoRA attention mechanism.
-
- Args:
- hidden_size (`int`, *optional*):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*):
- The number of channels in the `encoder_hidden_states`.
- rank (`int`, defaults to 4):
- The dimension of the LoRA update matrices.
- network_alpha (`int`, *optional*):
- Equivalent to `alpha` but it's usage is specific to Kohya (A1111) style LoRAs.
- kwargs (`dict`):
- Additional keyword arguments to pass to the `LoRALinearLayer` layers.
- """
-
- def __init__(
- self,
- hidden_size: int,
- cross_attention_dim: Optional[int] = None,
- rank: int = 4,
- network_alpha: Optional[int] = None,
- **kwargs,
- ):
- super().__init__()
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.rank = rank
-
- q_rank = kwargs.pop("q_rank", None)
- q_hidden_size = kwargs.pop("q_hidden_size", None)
- q_rank = q_rank if q_rank is not None else rank
- q_hidden_size = q_hidden_size if q_hidden_size is not None else hidden_size
-
- v_rank = kwargs.pop("v_rank", None)
- v_hidden_size = kwargs.pop("v_hidden_size", None)
- v_rank = v_rank if v_rank is not None else rank
- v_hidden_size = v_hidden_size if v_hidden_size is not None else hidden_size
-
- out_rank = kwargs.pop("out_rank", None)
- out_hidden_size = kwargs.pop("out_hidden_size", None)
- out_rank = out_rank if out_rank is not None else rank
- out_hidden_size = out_hidden_size if out_hidden_size is not None else hidden_size
-
- self.to_q_lora = LoRALinearLayer(q_hidden_size, q_hidden_size, q_rank, network_alpha)
- self.to_k_lora = LoRALinearLayer(cross_attention_dim or hidden_size, hidden_size, rank, network_alpha)
- self.to_v_lora = LoRALinearLayer(cross_attention_dim or v_hidden_size, v_hidden_size, v_rank, network_alpha)
- self.to_out_lora = LoRALinearLayer(out_hidden_size, out_hidden_size, out_rank, network_alpha)
-
- def __call__(self, attn: Attention, hidden_states: torch.FloatTensor, *args, **kwargs) -> torch.FloatTensor:
- self_cls_name = self.__class__.__name__
- deprecate(
- self_cls_name,
- "0.26.0",
- (
- f"Make sure use {self_cls_name[4:]} instead by setting"
- "LoRA layers to `self.{to_q,to_k,to_v,to_out[0]}.lora_layer` respectively. This will be done automatically when using"
- " `LoraLoaderMixin.load_lora_weights`"
- ),
- )
- attn.to_q.lora_layer = self.to_q_lora.to(hidden_states.device)
- attn.to_k.lora_layer = self.to_k_lora.to(hidden_states.device)
- attn.to_v.lora_layer = self.to_v_lora.to(hidden_states.device)
- attn.to_out[0].lora_layer = self.to_out_lora.to(hidden_states.device)
-
- attn._modules.pop("processor")
- attn.processor = AttnProcessor()
- return attn.processor(attn, hidden_states, *args, **kwargs)
-
-
-class LoRAAttnProcessor2_0(nn.Module):
- r"""
- Processor for implementing the LoRA attention mechanism using PyTorch 2.0's memory-efficient scaled dot-product
- attention.
-
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*):
- The number of channels in the `encoder_hidden_states`.
- rank (`int`, defaults to 4):
- The dimension of the LoRA update matrices.
- network_alpha (`int`, *optional*):
- Equivalent to `alpha` but it's usage is specific to Kohya (A1111) style LoRAs.
- kwargs (`dict`):
- Additional keyword arguments to pass to the `LoRALinearLayer` layers.
- """
-
- def __init__(
- self,
- hidden_size: int,
- cross_attention_dim: Optional[int] = None,
- rank: int = 4,
- network_alpha: Optional[int] = None,
- **kwargs,
- ):
- super().__init__()
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError("AttnProcessor2_0 requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0.")
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.rank = rank
-
- q_rank = kwargs.pop("q_rank", None)
- q_hidden_size = kwargs.pop("q_hidden_size", None)
- q_rank = q_rank if q_rank is not None else rank
- q_hidden_size = q_hidden_size if q_hidden_size is not None else hidden_size
-
- v_rank = kwargs.pop("v_rank", None)
- v_hidden_size = kwargs.pop("v_hidden_size", None)
- v_rank = v_rank if v_rank is not None else rank
- v_hidden_size = v_hidden_size if v_hidden_size is not None else hidden_size
-
- out_rank = kwargs.pop("out_rank", None)
- out_hidden_size = kwargs.pop("out_hidden_size", None)
- out_rank = out_rank if out_rank is not None else rank
- out_hidden_size = out_hidden_size if out_hidden_size is not None else hidden_size
-
- self.to_q_lora = LoRALinearLayer(q_hidden_size, q_hidden_size, q_rank, network_alpha)
- self.to_k_lora = LoRALinearLayer(cross_attention_dim or hidden_size, hidden_size, rank, network_alpha)
- self.to_v_lora = LoRALinearLayer(cross_attention_dim or v_hidden_size, v_hidden_size, v_rank, network_alpha)
- self.to_out_lora = LoRALinearLayer(out_hidden_size, out_hidden_size, out_rank, network_alpha)
-
- def __call__(self, attn: Attention, hidden_states: torch.FloatTensor, *args, **kwargs) -> torch.FloatTensor:
- self_cls_name = self.__class__.__name__
- deprecate(
- self_cls_name,
- "0.26.0",
- (
- f"Make sure use {self_cls_name[4:]} instead by setting"
- "LoRA layers to `self.{to_q,to_k,to_v,to_out[0]}.lora_layer` respectively. This will be done automatically when using"
- " `LoraLoaderMixin.load_lora_weights`"
- ),
- )
- attn.to_q.lora_layer = self.to_q_lora.to(hidden_states.device)
- attn.to_k.lora_layer = self.to_k_lora.to(hidden_states.device)
- attn.to_v.lora_layer = self.to_v_lora.to(hidden_states.device)
- attn.to_out[0].lora_layer = self.to_out_lora.to(hidden_states.device)
-
- attn._modules.pop("processor")
- attn.processor = AttnProcessor2_0()
- return attn.processor(attn, hidden_states, *args, **kwargs)
-
-
-class LoRAXFormersAttnProcessor(nn.Module):
- r"""
- Processor for implementing the LoRA attention mechanism with memory efficient attention using xFormers.
-
- Args:
- hidden_size (`int`, *optional*):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*):
- The number of channels in the `encoder_hidden_states`.
- rank (`int`, defaults to 4):
- The dimension of the LoRA update matrices.
- attention_op (`Callable`, *optional*, defaults to `None`):
- The base
- [operator](https://facebookresearch.github.io/xformers/components/ops.html#xformers.ops.AttentionOpBase) to
- use as the attention operator. It is recommended to set to `None`, and allow xFormers to choose the best
- operator.
- network_alpha (`int`, *optional*):
- Equivalent to `alpha` but it's usage is specific to Kohya (A1111) style LoRAs.
- kwargs (`dict`):
- Additional keyword arguments to pass to the `LoRALinearLayer` layers.
- """
-
- def __init__(
- self,
- hidden_size: int,
- cross_attention_dim: int,
- rank: int = 4,
- attention_op: Optional[Callable] = None,
- network_alpha: Optional[int] = None,
- **kwargs,
- ):
- super().__init__()
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.rank = rank
- self.attention_op = attention_op
-
- q_rank = kwargs.pop("q_rank", None)
- q_hidden_size = kwargs.pop("q_hidden_size", None)
- q_rank = q_rank if q_rank is not None else rank
- q_hidden_size = q_hidden_size if q_hidden_size is not None else hidden_size
-
- v_rank = kwargs.pop("v_rank", None)
- v_hidden_size = kwargs.pop("v_hidden_size", None)
- v_rank = v_rank if v_rank is not None else rank
- v_hidden_size = v_hidden_size if v_hidden_size is not None else hidden_size
-
- out_rank = kwargs.pop("out_rank", None)
- out_hidden_size = kwargs.pop("out_hidden_size", None)
- out_rank = out_rank if out_rank is not None else rank
- out_hidden_size = out_hidden_size if out_hidden_size is not None else hidden_size
-
- self.to_q_lora = LoRALinearLayer(q_hidden_size, q_hidden_size, q_rank, network_alpha)
- self.to_k_lora = LoRALinearLayer(cross_attention_dim or hidden_size, hidden_size, rank, network_alpha)
- self.to_v_lora = LoRALinearLayer(cross_attention_dim or v_hidden_size, v_hidden_size, v_rank, network_alpha)
- self.to_out_lora = LoRALinearLayer(out_hidden_size, out_hidden_size, out_rank, network_alpha)
-
- def __call__(self, attn: Attention, hidden_states: torch.FloatTensor, *args, **kwargs) -> torch.FloatTensor:
- self_cls_name = self.__class__.__name__
- deprecate(
- self_cls_name,
- "0.26.0",
- (
- f"Make sure use {self_cls_name[4:]} instead by setting"
- "LoRA layers to `self.{to_q,to_k,to_v,add_k_proj,add_v_proj,to_out[0]}.lora_layer` respectively. This will be done automatically when using"
- " `LoraLoaderMixin.load_lora_weights`"
- ),
- )
- attn.to_q.lora_layer = self.to_q_lora.to(hidden_states.device)
- attn.to_k.lora_layer = self.to_k_lora.to(hidden_states.device)
- attn.to_v.lora_layer = self.to_v_lora.to(hidden_states.device)
- attn.to_out[0].lora_layer = self.to_out_lora.to(hidden_states.device)
-
- attn._modules.pop("processor")
- attn.processor = XFormersAttnProcessor()
- return attn.processor(attn, hidden_states, *args, **kwargs)
-
-
-class LoRAAttnAddedKVProcessor(nn.Module):
- r"""
- Processor for implementing the LoRA attention mechanism with extra learnable key and value matrices for the text
- encoder.
-
- Args:
- hidden_size (`int`, *optional*):
- The hidden size of the attention layer.
- cross_attention_dim (`int`, *optional*, defaults to `None`):
- The number of channels in the `encoder_hidden_states`.
- rank (`int`, defaults to 4):
- The dimension of the LoRA update matrices.
- network_alpha (`int`, *optional*):
- Equivalent to `alpha` but it's usage is specific to Kohya (A1111) style LoRAs.
- kwargs (`dict`):
- Additional keyword arguments to pass to the `LoRALinearLayer` layers.
- """
-
- def __init__(
- self,
- hidden_size: int,
- cross_attention_dim: Optional[int] = None,
- rank: int = 4,
- network_alpha: Optional[int] = None,
- ):
- super().__init__()
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.rank = rank
-
- self.to_q_lora = LoRALinearLayer(hidden_size, hidden_size, rank, network_alpha)
- self.add_k_proj_lora = LoRALinearLayer(cross_attention_dim or hidden_size, hidden_size, rank, network_alpha)
- self.add_v_proj_lora = LoRALinearLayer(cross_attention_dim or hidden_size, hidden_size, rank, network_alpha)
- self.to_k_lora = LoRALinearLayer(hidden_size, hidden_size, rank, network_alpha)
- self.to_v_lora = LoRALinearLayer(hidden_size, hidden_size, rank, network_alpha)
- self.to_out_lora = LoRALinearLayer(hidden_size, hidden_size, rank, network_alpha)
-
- def __call__(self, attn: Attention, hidden_states: torch.FloatTensor, *args, **kwargs) -> torch.FloatTensor:
- self_cls_name = self.__class__.__name__
- deprecate(
- self_cls_name,
- "0.26.0",
- (
- f"Make sure use {self_cls_name[4:]} instead by setting"
- "LoRA layers to `self.{to_q,to_k,to_v,add_k_proj,add_v_proj,to_out[0]}.lora_layer` respectively. This will be done automatically when using"
- " `LoraLoaderMixin.load_lora_weights`"
- ),
- )
- attn.to_q.lora_layer = self.to_q_lora.to(hidden_states.device)
- attn.to_k.lora_layer = self.to_k_lora.to(hidden_states.device)
- attn.to_v.lora_layer = self.to_v_lora.to(hidden_states.device)
- attn.to_out[0].lora_layer = self.to_out_lora.to(hidden_states.device)
-
- attn._modules.pop("processor")
- attn.processor = AttnAddedKVProcessor()
- return attn.processor(attn, hidden_states, *args, **kwargs)
-
-
-class IPAdapterAttnProcessor(nn.Module):
- r"""
- Attention processor for IP-Adapater.
-
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`):
- The number of channels in the `encoder_hidden_states`.
- num_tokens (`int`, defaults to 4):
- The context length of the image features.
- scale (`float`, defaults to 1.0):
- the weight scale of image prompt.
- """
-
- def __init__(self, hidden_size, cross_attention_dim=None, num_tokens=4, scale=1.0):
- super().__init__()
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
- self.num_tokens = num_tokens
- self.scale = scale
-
- self.to_k_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
- self.to_v_ip = nn.Linear(cross_attention_dim or hidden_size, hidden_size, bias=False)
-
- def __call__(
- self,
- attn,
- hidden_states,
- encoder_hidden_states=None,
- attention_mask=None,
- temb=None,
- scale=1.0,
- ):
- if scale != 1.0:
- logger.warning("`scale` of IPAttnProcessor should be set with `set_ip_adapter_scale`.")
- residual = hidden_states
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- # split hidden states
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens
- encoder_hidden_states, ip_hidden_states = (
- encoder_hidden_states[:, :end_pos, :],
- encoder_hidden_states[:, end_pos:, :],
- )
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- query = attn.head_to_batch_dim(query)
- key = attn.head_to_batch_dim(key)
- value = attn.head_to_batch_dim(value)
-
- attention_probs = attn.get_attention_scores(query, key, attention_mask)
- hidden_states = torch.bmm(attention_probs, value)
- hidden_states = attn.batch_to_head_dim(hidden_states)
-
- # for ip-adapter
- ip_key = self.to_k_ip(ip_hidden_states)
- ip_value = self.to_v_ip(ip_hidden_states)
-
- ip_key = attn.head_to_batch_dim(ip_key)
- ip_value = attn.head_to_batch_dim(ip_value)
-
- ip_attention_probs = attn.get_attention_scores(query, ip_key, None)
- ip_hidden_states = torch.bmm(ip_attention_probs, ip_value)
- ip_hidden_states = attn.batch_to_head_dim(ip_hidden_states)
-
- hidden_states = hidden_states + self.scale * ip_hidden_states
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class VPTemporalAdapterAttnProcessor2_0(torch.nn.Module):
- r"""
- Attention processor for IP-Adapter for PyTorch 2.0.
-
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`):
- The number of channels in the `encoder_hidden_states`.
- num_tokens (`int`, `Tuple[int]` or `List[int]`, defaults to `(4,)`):
- The context length of the image features.
- scale (`float` or `List[float]`, defaults to 1.0):
- the weight scale of image prompt.
- """
-
- """
- Support frame-wise VP-Adapter
- encoder_hidden_states : I(num of ip_adapters), B, N * T(num of time condition), C
- ip_adapter_masks(bool): (I, B, N * T, C) == encoder_hidden_states.shape
-
- """
-
- def __init__(self, hidden_size, cross_attention_dim=None, num_tokens=(4,), scale=1.0):
- super().__init__()
-
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError(
- f"{self.__class__.__name__} requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0."
- )
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
-
- if not isinstance(num_tokens, (tuple, list)):
- num_tokens = [num_tokens]
- self.num_tokens = num_tokens
-
- if not isinstance(scale, list):
- scale = [scale] * len(num_tokens)
- if len(scale) != len(num_tokens):
- raise ValueError("`scale` should be a list of integers with the same length as `num_tokens`.")
- self.scale = scale
-
- self.to_k_ip = nn.ModuleList(
- [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
- )
- self.to_v_ip = nn.ModuleList(
- [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
- )
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ip_adapter_masks: Optional[torch.FloatTensor] = None,
- time_conditions: Optional[list] = None,
- audio_length_in_s: Optional[int] = None,
- ):
- residual = hidden_states
-
- # separate ip_hidden_states from encoder_hidden_states
- if encoder_hidden_states is not None:
- if isinstance(encoder_hidden_states, tuple):
- encoder_hidden_states, ip_hidden_states = encoder_hidden_states
- else:
- deprecation_message = (
- "You have passed a tensor as `encoder_hidden_states`. This is deprecated and will be removed in a future release."
- " Please make sure to update your script to pass `encoder_hidden_states` as a tuple to suppress this warning."
- )
- deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
- encoder_hidden_states, ip_hidden_states = (
- encoder_hidden_states[:, :end_pos, :],
- [encoder_hidden_states[:, end_pos:, :]],
- )
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- if ip_adapter_masks is not None:
- if not isinstance(ip_adapter_masks, List):
- # for backward compatibility, we accept `ip_adapter_mask` as a tensor of shape [num_ip_adapter, 1, height, width]
- ip_adapter_masks = list(ip_adapter_masks.unsqueeze(1))
- if not (len(ip_adapter_masks) == len(self.scale) == len(ip_hidden_states)):
- raise ValueError(
- f"Length of ip_adapter_masks array ({len(ip_adapter_masks)}) must match "
- f"length of self.scale array ({len(self.scale)}) and number of ip_hidden_states "
- f"({len(ip_hidden_states)})"
- )
- else:
- for index, (mask, scale, ip_state) in enumerate(zip(ip_adapter_masks, self.scale, ip_hidden_states)):
- if not isinstance(mask, torch.Tensor) or mask.ndim != 4:
- raise ValueError(
- "Each element of the ip_adapter_masks array should be a tensor with shape "
- "[1, num_images_for_ip_adapter, height, width]."
- " Please use `IPAdapterMaskProcessor` to preprocess your mask"
- )
- if mask.shape[1] != ip_state.shape[1]:
- raise ValueError(
- f"Number of masks ({mask.shape[1]}) does not match "
- f"number of ip images ({ip_state.shape[1]}) at index {index}"
- )
- if isinstance(scale, list) and not len(scale) == mask.shape[1]:
- raise ValueError(
- f"Number of masks ({mask.shape[1]}) does not match "
- f"number of scales ({len(scale)}) at index {index}"
- )
- else:
- ip_adapter_masks = [None] * len(self.scale)
- # for ip-adapter
- for current_ip_hidden_states, scale, to_k_ip, to_v_ip, mask in zip(
- ip_hidden_states, self.scale, self.to_k_ip, self.to_v_ip, ip_adapter_masks
- ):
- skip = False
- if isinstance(scale, list):
- if all(s == 0 for s in scale):
- skip = True
- elif scale == 0:
- skip = True
- if not skip:
- time_condition_masks = None
- for time_condition in time_conditions:
- # hard code
- time_condition_mask = (
- torch.zeros(
- (
- batch_size,
- int(math.sqrt(hidden_states.shape[1]) // 2),
- int(2 * math.sqrt(hidden_states.shape[1])),
- )
- )
- .bool()
- .to(device=hidden_states.device)
- )
- mel_latent_length = time_condition_mask.shape[-1]
- time_start, time_end = (
- int(time_condition[0] // audio_length_in_s * mel_latent_length),
- int(time_condition[1] // audio_length_in_s * mel_latent_length),
- )
-
- time_condition_mask[:, :, time_start:time_end] = True
- time_condition_mask = time_condition_mask.flatten(-2).unsqueeze(-1).repeat(1, 1, 4)
- if time_condition_masks is None:
- time_condition_masks = time_condition_mask
- else:
- time_condition_masks = torch.cat([time_condition_masks, time_condition_mask], dim=-1)
-
- current_ip_hidden_states = rearrange(current_ip_hidden_states, "L B N C -> B (L N) C")
- ip_key = to_k_ip(current_ip_hidden_states)
- ip_value = to_v_ip(current_ip_hidden_states)
-
- ip_key = ip_key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- ip_value = ip_value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- time_condition_masks = time_condition_masks.unsqueeze(1).repeat(1, attn.heads, 1, 1)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- current_ip_hidden_states = F.scaled_dot_product_attention(
- query, ip_key, ip_value, attn_mask=time_condition_masks, dropout_p=0.0, is_causal=False
- )
-
- current_ip_hidden_states = current_ip_hidden_states.transpose(1, 2).reshape(
- batch_size, -1, attn.heads * head_dim
- )
- current_ip_hidden_states = current_ip_hidden_states.to(query.dtype)
-
- hidden_states = hidden_states + scale * current_ip_hidden_states
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-class IPAdapterAttnProcessor2_0(torch.nn.Module):
- r"""
- Attention processor for IP-Adapter for PyTorch 2.0.
-
- Args:
- hidden_size (`int`):
- The hidden size of the attention layer.
- cross_attention_dim (`int`):
- The number of channels in the `encoder_hidden_states`.
- num_tokens (`int`, `Tuple[int]` or `List[int]`, defaults to `(4,)`):
- The context length of the image features.
- scale (`float` or `List[float]`, defaults to 1.0):
- the weight scale of image prompt.
- """
-
- def __init__(self, hidden_size, cross_attention_dim=None, num_tokens=(4,), scale=1.0):
- super().__init__()
-
- if not hasattr(F, "scaled_dot_product_attention"):
- raise ImportError(
- f"{self.__class__.__name__} requires PyTorch 2.0, to use it, please upgrade PyTorch to 2.0."
- )
-
- self.hidden_size = hidden_size
- self.cross_attention_dim = cross_attention_dim
-
- if not isinstance(num_tokens, (tuple, list)):
- num_tokens = [num_tokens]
- self.num_tokens = num_tokens
-
- if not isinstance(scale, list):
- scale = [scale] * len(num_tokens)
- if len(scale) != len(num_tokens):
- raise ValueError("`scale` should be a list of integers with the same length as `num_tokens`.")
- self.scale = scale
- self.to_k_ip = nn.ModuleList(
- [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
- )
- self.to_v_ip = nn.ModuleList(
- [nn.Linear(cross_attention_dim, hidden_size, bias=False) for _ in range(len(num_tokens))]
- )
-
- def __call__(
- self,
- attn: Attention,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- temb: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ip_adapter_masks: Optional[torch.FloatTensor] = None,
- ):
- residual = hidden_states
-
- # separate ip_hidden_states from encoder_hidden_states
- if encoder_hidden_states is not None:
- if isinstance(encoder_hidden_states, tuple):
- encoder_hidden_states, ip_hidden_states = encoder_hidden_states
- else:
- deprecation_message = (
- "You have passed a tensor as `encoder_hidden_states`. This is deprecated and will be removed in a future release."
- " Please make sure to update your script to pass `encoder_hidden_states` as a tuple to suppress this warning."
- )
- deprecate("encoder_hidden_states not a tuple", "1.0.0", deprecation_message, standard_warn=False)
- end_pos = encoder_hidden_states.shape[1] - self.num_tokens[0]
- encoder_hidden_states, ip_hidden_states = (
- encoder_hidden_states[:, :end_pos, :],
- [encoder_hidden_states[:, end_pos:, :]],
- )
-
- if attn.spatial_norm is not None:
- hidden_states = attn.spatial_norm(hidden_states, temb)
-
- input_ndim = hidden_states.ndim
-
- if input_ndim == 4:
- batch_size, channel, height, width = hidden_states.shape
- hidden_states = hidden_states.view(batch_size, channel, height * width).transpose(1, 2)
-
- batch_size, sequence_length, _ = (
- hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
- )
-
- if attention_mask is not None:
- attention_mask = attn.prepare_attention_mask(attention_mask, sequence_length, batch_size)
- # scaled_dot_product_attention expects attention_mask shape to be
- # (batch, heads, source_length, target_length)
- attention_mask = attention_mask.view(batch_size, attn.heads, -1, attention_mask.shape[-1])
-
- if attn.group_norm is not None:
- hidden_states = attn.group_norm(hidden_states.transpose(1, 2)).transpose(1, 2)
-
- query = attn.to_q(hidden_states)
-
- if encoder_hidden_states is None:
- encoder_hidden_states = hidden_states
- elif attn.norm_cross:
- encoder_hidden_states = attn.norm_encoder_hidden_states(encoder_hidden_states)
-
- key = attn.to_k(encoder_hidden_states)
- value = attn.to_v(encoder_hidden_states)
-
- inner_dim = key.shape[-1]
- head_dim = inner_dim // attn.heads
-
- query = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- key = key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- value = value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- hidden_states = F.scaled_dot_product_attention(
- query, key, value, attn_mask=attention_mask, dropout_p=0.0, is_causal=False
- )
-
- hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
- hidden_states = hidden_states.to(query.dtype)
-
- if ip_adapter_masks is not None:
- if not isinstance(ip_adapter_masks, List):
- # for backward compatibility, we accept `ip_adapter_mask` as a tensor of shape [num_ip_adapter, 1, height, width]
- ip_adapter_masks = list(ip_adapter_masks.unsqueeze(1))
- if not (len(ip_adapter_masks) == len(self.scale) == len(ip_hidden_states)):
- raise ValueError(
- f"Length of ip_adapter_masks array ({len(ip_adapter_masks)}) must match "
- f"length of self.scale array ({len(self.scale)}) and number of ip_hidden_states "
- f"({len(ip_hidden_states)})"
- )
- else:
- for index, (mask, scale, ip_state) in enumerate(zip(ip_adapter_masks, self.scale, ip_hidden_states)):
- if not isinstance(mask, torch.Tensor) or mask.ndim != 4:
- raise ValueError(
- "Each element of the ip_adapter_masks array should be a tensor with shape "
- "[1, num_images_for_ip_adapter, height, width]."
- " Please use `IPAdapterMaskProcessor` to preprocess your mask"
- )
- if mask.shape[1] != ip_state.shape[1]:
- raise ValueError(
- f"Number of masks ({mask.shape[1]}) does not match "
- f"number of ip images ({ip_state.shape[1]}) at index {index}"
- )
- if isinstance(scale, list) and not len(scale) == mask.shape[1]:
- raise ValueError(
- f"Number of masks ({mask.shape[1]}) does not match "
- f"number of scales ({len(scale)}) at index {index}"
- )
- else:
- ip_adapter_masks = [None] * len(self.scale)
-
- # for ip-adapter
- for current_ip_hidden_states, scale, to_k_ip, to_v_ip, mask in zip(
- ip_hidden_states, self.scale, self.to_k_ip, self.to_v_ip, ip_adapter_masks
- ):
- skip = False
- if isinstance(scale, list):
- if all(s == 0 for s in scale):
- skip = True
- elif scale == 0:
- skip = True
- if not skip:
- ip_key = to_k_ip(current_ip_hidden_states)
- ip_value = to_v_ip(current_ip_hidden_states)
-
- ip_key = ip_key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
- ip_value = ip_value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
-
- # the output of sdp = (batch, num_heads, seq_len, head_dim)
- # TODO: add support for attn.scale when we move to Torch 2.1
- current_ip_hidden_states = F.scaled_dot_product_attention(
- query, ip_key, ip_value, attn_mask=None, dropout_p=0.0, is_causal=False
- )
-
- current_ip_hidden_states = current_ip_hidden_states.transpose(1, 2).reshape(
- batch_size, -1, attn.heads * head_dim
- )
- current_ip_hidden_states = current_ip_hidden_states.to(query.dtype)
-
- hidden_states = hidden_states + scale * current_ip_hidden_states
-
- # linear proj
- hidden_states = attn.to_out[0](hidden_states)
- # dropout
- hidden_states = attn.to_out[1](hidden_states)
-
- if input_ndim == 4:
- hidden_states = hidden_states.transpose(-1, -2).reshape(batch_size, channel, height, width)
-
- if attn.residual_connection:
- hidden_states = hidden_states + residual
-
- hidden_states = hidden_states / attn.rescale_output_factor
-
- return hidden_states
-
-
-LORA_ATTENTION_PROCESSORS = (
- LoRAAttnProcessor,
- LoRAAttnProcessor2_0,
- LoRAXFormersAttnProcessor,
- LoRAAttnAddedKVProcessor,
-)
-
-ADDED_KV_ATTENTION_PROCESSORS = (
- AttnAddedKVProcessor,
- SlicedAttnAddedKVProcessor,
- AttnAddedKVProcessor2_0,
- XFormersAttnAddedKVProcessor,
- LoRAAttnAddedKVProcessor,
-)
-
-CROSS_ATTENTION_PROCESSORS = (
- AttnProcessor,
- AttnProcessor2_0,
- XFormersAttnProcessor,
- SlicedAttnProcessor,
- LoRAAttnProcessor,
- LoRAAttnProcessor2_0,
- LoRAXFormersAttnProcessor,
- IPAdapterAttnProcessor,
- IPAdapterAttnProcessor2_0,
-)
-
-AttentionProcessor = Union[
- AttnProcessor,
- AttnProcessor2_0,
- FusedAttnProcessor2_0,
- XFormersAttnProcessor,
- SlicedAttnProcessor,
- AttnAddedKVProcessor,
- SlicedAttnAddedKVProcessor,
- AttnAddedKVProcessor2_0,
- XFormersAttnAddedKVProcessor,
- CustomDiffusionAttnProcessor,
- CustomDiffusionXFormersAttnProcessor,
- CustomDiffusionAttnProcessor2_0,
- # deprecated
- LoRAAttnProcessor,
- LoRAAttnProcessor2_0,
- LoRAXFormersAttnProcessor,
- LoRAAttnAddedKVProcessor,
-]
diff --git a/foleycrafter/models/auffusion/dual_transformer_2d.py b/foleycrafter/models/auffusion/dual_transformer_2d.py
deleted file mode 100644
index e190c5d..0000000
--- a/foleycrafter/models/auffusion/dual_transformer_2d.py
+++ /dev/null
@@ -1,155 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from typing import Optional
-
-from torch import nn
-
-from foleycrafter.models.auffusion.transformer_2d import Transformer2DModel, Transformer2DModelOutput
-
-
-class DualTransformer2DModel(nn.Module):
- """
- Dual transformer wrapper that combines two `Transformer2DModel`s for mixed inference.
-
- Parameters:
- num_attention_heads (`int`, *optional*, defaults to 16): The number of heads to use for multi-head attention.
- attention_head_dim (`int`, *optional*, defaults to 88): The number of channels in each head.
- in_channels (`int`, *optional*):
- Pass if the input is continuous. The number of channels in the input and output.
- num_layers (`int`, *optional*, defaults to 1): The number of layers of Transformer blocks to use.
- dropout (`float`, *optional*, defaults to 0.1): The dropout probability to use.
- cross_attention_dim (`int`, *optional*): The number of encoder_hidden_states dimensions to use.
- sample_size (`int`, *optional*): Pass if the input is discrete. The width of the latent images.
- Note that this is fixed at training time as it is used for learning a number of position embeddings. See
- `ImagePositionalEmbeddings`.
- num_vector_embeds (`int`, *optional*):
- Pass if the input is discrete. The number of classes of the vector embeddings of the latent pixels.
- Includes the class for the masked latent pixel.
- activation_fn (`str`, *optional*, defaults to `"geglu"`): Activation function to be used in feed-forward.
- num_embeds_ada_norm ( `int`, *optional*): Pass if at least one of the norm_layers is `AdaLayerNorm`.
- The number of diffusion steps used during training. Note that this is fixed at training time as it is used
- to learn a number of embeddings that are added to the hidden states. During inference, you can denoise for
- up to but not more than steps than `num_embeds_ada_norm`.
- attention_bias (`bool`, *optional*):
- Configure if the TransformerBlocks' attention should contain a bias parameter.
- """
-
- def __init__(
- self,
- num_attention_heads: int = 16,
- attention_head_dim: int = 88,
- in_channels: Optional[int] = None,
- num_layers: int = 1,
- dropout: float = 0.0,
- norm_num_groups: int = 32,
- cross_attention_dim: Optional[int] = None,
- attention_bias: bool = False,
- sample_size: Optional[int] = None,
- num_vector_embeds: Optional[int] = None,
- activation_fn: str = "geglu",
- num_embeds_ada_norm: Optional[int] = None,
- ):
- super().__init__()
- self.transformers = nn.ModuleList(
- [
- Transformer2DModel(
- num_attention_heads=num_attention_heads,
- attention_head_dim=attention_head_dim,
- in_channels=in_channels,
- num_layers=num_layers,
- dropout=dropout,
- norm_num_groups=norm_num_groups,
- cross_attention_dim=cross_attention_dim,
- attention_bias=attention_bias,
- sample_size=sample_size,
- num_vector_embeds=num_vector_embeds,
- activation_fn=activation_fn,
- num_embeds_ada_norm=num_embeds_ada_norm,
- )
- for _ in range(2)
- ]
- )
-
- # Variables that can be set by a pipeline:
-
- # The ratio of transformer1 to transformer2's output states to be combined during inference
- self.mix_ratio = 0.5
-
- # The shape of `encoder_hidden_states` is expected to be
- # `(batch_size, condition_lengths[0]+condition_lengths[1], num_features)`
- self.condition_lengths = [77, 257]
-
- # Which transformer to use to encode which condition.
- # E.g. `(1, 0)` means that we'll use `transformers[1](conditions[0])` and `transformers[0](conditions[1])`
- self.transformer_index_for_condition = [1, 0]
-
- def forward(
- self,
- hidden_states,
- encoder_hidden_states,
- timestep=None,
- attention_mask=None,
- cross_attention_kwargs=None,
- return_dict: bool = True,
- ):
- """
- Args:
- hidden_states ( When discrete, `torch.LongTensor` of shape `(batch size, num latent pixels)`.
- When continuous, `torch.FloatTensor` of shape `(batch size, channel, height, width)`): Input
- hidden_states.
- encoder_hidden_states ( `torch.LongTensor` of shape `(batch size, encoder_hidden_states dim)`, *optional*):
- Conditional embeddings for cross attention layer. If not given, cross-attention defaults to
- self-attention.
- timestep ( `torch.long`, *optional*):
- Optional timestep to be applied as an embedding in AdaLayerNorm's. Used to indicate denoising step.
- attention_mask (`torch.FloatTensor`, *optional*):
- Optional attention mask to be applied in Attention.
- cross_attention_kwargs (`dict`, *optional*):
- A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
- `self.processor` in
- [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
- return_dict (`bool`, *optional*, defaults to `True`):
- Whether or not to return a [`models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain tuple.
-
- Returns:
- [`~models.transformer_2d.Transformer2DModelOutput`] or `tuple`:
- [`~models.transformer_2d.Transformer2DModelOutput`] if `return_dict` is True, otherwise a `tuple`. When
- returning a tuple, the first element is the sample tensor.
- """
- input_states = hidden_states
-
- encoded_states = []
- tokens_start = 0
- # attention_mask is not used yet
- for i in range(2):
- # for each of the two transformers, pass the corresponding condition tokens
- condition_state = encoder_hidden_states[:, tokens_start : tokens_start + self.condition_lengths[i]]
- transformer_index = self.transformer_index_for_condition[i]
- encoded_state = self.transformers[transformer_index](
- input_states,
- encoder_hidden_states=condition_state,
- timestep=timestep,
- cross_attention_kwargs=cross_attention_kwargs,
- return_dict=False,
- )[0]
- encoded_states.append(encoded_state - input_states)
- tokens_start += self.condition_lengths[i]
-
- output_states = encoded_states[0] * self.mix_ratio + encoded_states[1] * (1 - self.mix_ratio)
- output_states = output_states + input_states
-
- if not return_dict:
- return (output_states,)
-
- return Transformer2DModelOutput(sample=output_states)
diff --git a/foleycrafter/models/auffusion/resnet.py b/foleycrafter/models/auffusion/resnet.py
deleted file mode 100644
index 76c71a7..0000000
--- a/foleycrafter/models/auffusion/resnet.py
+++ /dev/null
@@ -1,685 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-# `TemporalConvLayer` Copyright 2023 Alibaba DAMO-VILAB, The ModelScope Team and The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-from functools import partial
-from typing import Optional, Tuple, Union
-
-import torch
-import torch.nn as nn
-import torch.nn.functional as F
-
-from diffusers.models.activations import get_activation
-from diffusers.models.downsampling import ( # noqa
- Downsample1D,
- Downsample2D,
- FirDownsample2D,
- KDownsample2D,
- downsample_2d,
-)
-from diffusers.models.lora import LoRACompatibleConv, LoRACompatibleLinear
-from diffusers.models.normalization import AdaGroupNorm
-from diffusers.models.upsampling import ( # noqa
- FirUpsample2D,
- KUpsample2D,
- Upsample1D,
- Upsample2D,
- upfirdn2d_native,
- upsample_2d,
-)
-from diffusers.utils import USE_PEFT_BACKEND
-from foleycrafter.models.auffusion.attention_processor import SpatialNorm
-
-
-class ResnetBlock2D(nn.Module):
- r"""
- A Resnet block.
-
- Parameters:
- in_channels (`int`): The number of channels in the input.
- out_channels (`int`, *optional*, default to be `None`):
- The number of output channels for the first conv2d layer. If None, same as `in_channels`.
- dropout (`float`, *optional*, defaults to `0.0`): The dropout probability to use.
- temb_channels (`int`, *optional*, default to `512`): the number of channels in timestep embedding.
- groups (`int`, *optional*, default to `32`): The number of groups to use for the first normalization layer.
- groups_out (`int`, *optional*, default to None):
- The number of groups to use for the second normalization layer. if set to None, same as `groups`.
- eps (`float`, *optional*, defaults to `1e-6`): The epsilon to use for the normalization.
- non_linearity (`str`, *optional*, default to `"swish"`): the activation function to use.
- time_embedding_norm (`str`, *optional*, default to `"default"` ): Time scale shift config.
- By default, apply timestep embedding conditioning with a simple shift mechanism. Choose "scale_shift" or
- "ada_group" for a stronger conditioning with scale and shift.
- kernel (`torch.FloatTensor`, optional, default to None): FIR filter, see
- [`~models.resnet.FirUpsample2D`] and [`~models.resnet.FirDownsample2D`].
- output_scale_factor (`float`, *optional*, default to be `1.0`): the scale factor to use for the output.
- use_in_shortcut (`bool`, *optional*, default to `True`):
- If `True`, add a 1x1 nn.conv2d layer for skip-connection.
- up (`bool`, *optional*, default to `False`): If `True`, add an upsample layer.
- down (`bool`, *optional*, default to `False`): If `True`, add a downsample layer.
- conv_shortcut_bias (`bool`, *optional*, default to `True`): If `True`, adds a learnable bias to the
- `conv_shortcut` output.
- conv_2d_out_channels (`int`, *optional*, default to `None`): the number of channels in the output.
- If None, same as `out_channels`.
- """
-
- def __init__(
- self,
- *,
- in_channels: int,
- out_channels: Optional[int] = None,
- conv_shortcut: bool = False,
- dropout: float = 0.0,
- temb_channels: int = 512,
- groups: int = 32,
- groups_out: Optional[int] = None,
- pre_norm: bool = True,
- eps: float = 1e-6,
- non_linearity: str = "swish",
- skip_time_act: bool = False,
- time_embedding_norm: str = "default", # default, scale_shift, ada_group, spatial
- kernel: Optional[torch.FloatTensor] = None,
- output_scale_factor: float = 1.0,
- use_in_shortcut: Optional[bool] = None,
- up: bool = False,
- down: bool = False,
- conv_shortcut_bias: bool = True,
- conv_2d_out_channels: Optional[int] = None,
- ):
- super().__init__()
- self.pre_norm = pre_norm
- self.pre_norm = True
- self.in_channels = in_channels
- out_channels = in_channels if out_channels is None else out_channels
- self.out_channels = out_channels
- self.use_conv_shortcut = conv_shortcut
- self.up = up
- self.down = down
- self.output_scale_factor = output_scale_factor
- self.time_embedding_norm = time_embedding_norm
- self.skip_time_act = skip_time_act
-
- linear_cls = nn.Linear if USE_PEFT_BACKEND else LoRACompatibleLinear
- conv_cls = nn.Conv2d if USE_PEFT_BACKEND else LoRACompatibleConv
-
- if groups_out is None:
- groups_out = groups
-
- if self.time_embedding_norm == "ada_group":
- self.norm1 = AdaGroupNorm(temb_channels, in_channels, groups, eps=eps)
- elif self.time_embedding_norm == "spatial":
- self.norm1 = SpatialNorm(in_channels, temb_channels)
- else:
- self.norm1 = torch.nn.GroupNorm(num_groups=groups, num_channels=in_channels, eps=eps, affine=True)
-
- self.conv1 = conv_cls(in_channels, out_channels, kernel_size=3, stride=1, padding=1)
-
- if temb_channels is not None:
- if self.time_embedding_norm == "default":
- self.time_emb_proj = linear_cls(temb_channels, out_channels)
- elif self.time_embedding_norm == "scale_shift":
- self.time_emb_proj = linear_cls(temb_channels, 2 * out_channels)
- elif self.time_embedding_norm == "ada_group" or self.time_embedding_norm == "spatial":
- self.time_emb_proj = None
- else:
- raise ValueError(f"unknown time_embedding_norm : {self.time_embedding_norm} ")
- else:
- self.time_emb_proj = None
-
- if self.time_embedding_norm == "ada_group":
- self.norm2 = AdaGroupNorm(temb_channels, out_channels, groups_out, eps=eps)
- elif self.time_embedding_norm == "spatial":
- self.norm2 = SpatialNorm(out_channels, temb_channels)
- else:
- self.norm2 = torch.nn.GroupNorm(num_groups=groups_out, num_channels=out_channels, eps=eps, affine=True)
-
- self.dropout = torch.nn.Dropout(dropout)
- conv_2d_out_channels = conv_2d_out_channels or out_channels
- self.conv2 = conv_cls(out_channels, conv_2d_out_channels, kernel_size=3, stride=1, padding=1)
-
- self.nonlinearity = get_activation(non_linearity)
-
- self.upsample = self.downsample = None
- if self.up:
- if kernel == "fir":
- fir_kernel = (1, 3, 3, 1)
- self.upsample = lambda x: upsample_2d(x, kernel=fir_kernel)
- elif kernel == "sde_vp":
- self.upsample = partial(F.interpolate, scale_factor=2.0, mode="nearest")
- else:
- self.upsample = Upsample2D(in_channels, use_conv=False)
- elif self.down:
- if kernel == "fir":
- fir_kernel = (1, 3, 3, 1)
- self.downsample = lambda x: downsample_2d(x, kernel=fir_kernel)
- elif kernel == "sde_vp":
- self.downsample = partial(F.avg_pool2d, kernel_size=2, stride=2)
- else:
- self.downsample = Downsample2D(in_channels, use_conv=False, padding=1, name="op")
-
- self.use_in_shortcut = self.in_channels != conv_2d_out_channels if use_in_shortcut is None else use_in_shortcut
-
- self.conv_shortcut = None
- if self.use_in_shortcut:
- self.conv_shortcut = conv_cls(
- in_channels,
- conv_2d_out_channels,
- kernel_size=1,
- stride=1,
- padding=0,
- bias=conv_shortcut_bias,
- )
-
- def forward(
- self,
- input_tensor: torch.FloatTensor,
- temb: torch.FloatTensor,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- hidden_states = input_tensor
-
- if self.time_embedding_norm == "ada_group" or self.time_embedding_norm == "spatial":
- hidden_states = self.norm1(hidden_states, temb)
- else:
- hidden_states = self.norm1(hidden_states)
-
- hidden_states = self.nonlinearity(hidden_states)
-
- if self.upsample is not None:
- # upsample_nearest_nhwc fails with large batch sizes. see https://github.com/huggingface/diffusers/issues/984
- if hidden_states.shape[0] >= 64:
- input_tensor = input_tensor.contiguous()
- hidden_states = hidden_states.contiguous()
- input_tensor = (
- self.upsample(input_tensor, scale=scale)
- if isinstance(self.upsample, Upsample2D)
- else self.upsample(input_tensor)
- )
- hidden_states = (
- self.upsample(hidden_states, scale=scale)
- if isinstance(self.upsample, Upsample2D)
- else self.upsample(hidden_states)
- )
- elif self.downsample is not None:
- input_tensor = (
- self.downsample(input_tensor, scale=scale)
- if isinstance(self.downsample, Downsample2D)
- else self.downsample(input_tensor)
- )
- hidden_states = (
- self.downsample(hidden_states, scale=scale)
- if isinstance(self.downsample, Downsample2D)
- else self.downsample(hidden_states)
- )
-
- hidden_states = self.conv1(hidden_states, scale) if not USE_PEFT_BACKEND else self.conv1(hidden_states)
-
- if self.time_emb_proj is not None:
- if not self.skip_time_act:
- temb = self.nonlinearity(temb)
- temb = (
- self.time_emb_proj(temb, scale)[:, :, None, None]
- if not USE_PEFT_BACKEND
- # NOTE: Maybe we can use different prompt in different time
- else self.time_emb_proj(temb)[:, :, None, None]
- )
-
- if temb is not None and self.time_embedding_norm == "default":
- hidden_states = hidden_states + temb
-
- if self.time_embedding_norm == "ada_group" or self.time_embedding_norm == "spatial":
- hidden_states = self.norm2(hidden_states, temb)
- else:
- hidden_states = self.norm2(hidden_states)
-
- if temb is not None and self.time_embedding_norm == "scale_shift":
- scale, shift = torch.chunk(temb, 2, dim=1)
- hidden_states = hidden_states * (1 + scale) + shift
-
- hidden_states = self.nonlinearity(hidden_states)
-
- hidden_states = self.dropout(hidden_states)
- hidden_states = self.conv2(hidden_states, scale) if not USE_PEFT_BACKEND else self.conv2(hidden_states)
-
- if self.conv_shortcut is not None:
- input_tensor = (
- self.conv_shortcut(input_tensor, scale) if not USE_PEFT_BACKEND else self.conv_shortcut(input_tensor)
- )
-
- output_tensor = (input_tensor + hidden_states) / self.output_scale_factor
-
- return output_tensor
-
-
-# unet_rl.py
-def rearrange_dims(tensor: torch.Tensor) -> torch.Tensor:
- if len(tensor.shape) == 2:
- return tensor[:, :, None]
- if len(tensor.shape) == 3:
- return tensor[:, :, None, :]
- elif len(tensor.shape) == 4:
- return tensor[:, :, 0, :]
- else:
- raise ValueError(f"`len(tensor)`: {len(tensor)} has to be 2, 3 or 4.")
-
-
-class Conv1dBlock(nn.Module):
- """
- Conv1d --> GroupNorm --> Mish
-
- Parameters:
- inp_channels (`int`): Number of input channels.
- out_channels (`int`): Number of output channels.
- kernel_size (`int` or `tuple`): Size of the convolving kernel.
- n_groups (`int`, default `8`): Number of groups to separate the channels into.
- activation (`str`, defaults to `mish`): Name of the activation function.
- """
-
- def __init__(
- self,
- inp_channels: int,
- out_channels: int,
- kernel_size: Union[int, Tuple[int, int]],
- n_groups: int = 8,
- activation: str = "mish",
- ):
- super().__init__()
-
- self.conv1d = nn.Conv1d(inp_channels, out_channels, kernel_size, padding=kernel_size // 2)
- self.group_norm = nn.GroupNorm(n_groups, out_channels)
- self.mish = get_activation(activation)
-
- def forward(self, inputs: torch.Tensor) -> torch.Tensor:
- intermediate_repr = self.conv1d(inputs)
- intermediate_repr = rearrange_dims(intermediate_repr)
- intermediate_repr = self.group_norm(intermediate_repr)
- intermediate_repr = rearrange_dims(intermediate_repr)
- output = self.mish(intermediate_repr)
- return output
-
-
-# unet_rl.py
-class ResidualTemporalBlock1D(nn.Module):
- """
- Residual 1D block with temporal convolutions.
-
- Parameters:
- inp_channels (`int`): Number of input channels.
- out_channels (`int`): Number of output channels.
- embed_dim (`int`): Embedding dimension.
- kernel_size (`int` or `tuple`): Size of the convolving kernel.
- activation (`str`, defaults `mish`): It is possible to choose the right activation function.
- """
-
- def __init__(
- self,
- inp_channels: int,
- out_channels: int,
- embed_dim: int,
- kernel_size: Union[int, Tuple[int, int]] = 5,
- activation: str = "mish",
- ):
- super().__init__()
- self.conv_in = Conv1dBlock(inp_channels, out_channels, kernel_size)
- self.conv_out = Conv1dBlock(out_channels, out_channels, kernel_size)
-
- self.time_emb_act = get_activation(activation)
- self.time_emb = nn.Linear(embed_dim, out_channels)
-
- self.residual_conv = (
- nn.Conv1d(inp_channels, out_channels, 1) if inp_channels != out_channels else nn.Identity()
- )
-
- def forward(self, inputs: torch.Tensor, t: torch.Tensor) -> torch.Tensor:
- """
- Args:
- inputs : [ batch_size x inp_channels x horizon ]
- t : [ batch_size x embed_dim ]
-
- returns:
- out : [ batch_size x out_channels x horizon ]
- """
- t = self.time_emb_act(t)
- t = self.time_emb(t)
- out = self.conv_in(inputs) + rearrange_dims(t)
- out = self.conv_out(out)
- return out + self.residual_conv(inputs)
-
-
-class TemporalConvLayer(nn.Module):
- """
- Temporal convolutional layer that can be used for video (sequence of images) input Code mostly copied from:
- https://github.com/modelscope/modelscope/blob/1509fdb973e5871f37148a4b5e5964cafd43e64d/modelscope/models/multi_modal/video_synthesis/unet_sd.py#L1016
-
- Parameters:
- in_dim (`int`): Number of input channels.
- out_dim (`int`): Number of output channels.
- dropout (`float`, *optional*, defaults to `0.0`): The dropout probability to use.
- """
-
- def __init__(
- self,
- in_dim: int,
- out_dim: Optional[int] = None,
- dropout: float = 0.0,
- norm_num_groups: int = 32,
- ):
- super().__init__()
- out_dim = out_dim or in_dim
- self.in_dim = in_dim
- self.out_dim = out_dim
-
- # conv layers
- self.conv1 = nn.Sequential(
- nn.GroupNorm(norm_num_groups, in_dim),
- nn.SiLU(),
- nn.Conv3d(in_dim, out_dim, (3, 1, 1), padding=(1, 0, 0)),
- )
- self.conv2 = nn.Sequential(
- nn.GroupNorm(norm_num_groups, out_dim),
- nn.SiLU(),
- nn.Dropout(dropout),
- nn.Conv3d(out_dim, in_dim, (3, 1, 1), padding=(1, 0, 0)),
- )
- self.conv3 = nn.Sequential(
- nn.GroupNorm(norm_num_groups, out_dim),
- nn.SiLU(),
- nn.Dropout(dropout),
- nn.Conv3d(out_dim, in_dim, (3, 1, 1), padding=(1, 0, 0)),
- )
- self.conv4 = nn.Sequential(
- nn.GroupNorm(norm_num_groups, out_dim),
- nn.SiLU(),
- nn.Dropout(dropout),
- nn.Conv3d(out_dim, in_dim, (3, 1, 1), padding=(1, 0, 0)),
- )
-
- # zero out the last layer params,so the conv block is identity
- nn.init.zeros_(self.conv4[-1].weight)
- nn.init.zeros_(self.conv4[-1].bias)
-
- def forward(self, hidden_states: torch.Tensor, num_frames: int = 1) -> torch.Tensor:
- hidden_states = (
- hidden_states[None, :].reshape((-1, num_frames) + hidden_states.shape[1:]).permute(0, 2, 1, 3, 4)
- )
-
- identity = hidden_states
- hidden_states = self.conv1(hidden_states)
- hidden_states = self.conv2(hidden_states)
- hidden_states = self.conv3(hidden_states)
- hidden_states = self.conv4(hidden_states)
-
- hidden_states = identity + hidden_states
-
- hidden_states = hidden_states.permute(0, 2, 1, 3, 4).reshape(
- (hidden_states.shape[0] * hidden_states.shape[2], -1) + hidden_states.shape[3:]
- )
- return hidden_states
-
-
-class TemporalResnetBlock(nn.Module):
- r"""
- A Resnet block.
-
- Parameters:
- in_channels (`int`): The number of channels in the input.
- out_channels (`int`, *optional*, default to be `None`):
- The number of output channels for the first conv2d layer. If None, same as `in_channels`.
- temb_channels (`int`, *optional*, default to `512`): the number of channels in timestep embedding.
- eps (`float`, *optional*, defaults to `1e-6`): The epsilon to use for the normalization.
- """
-
- def __init__(
- self,
- in_channels: int,
- out_channels: Optional[int] = None,
- temb_channels: int = 512,
- eps: float = 1e-6,
- ):
- super().__init__()
- self.in_channels = in_channels
- out_channels = in_channels if out_channels is None else out_channels
- self.out_channels = out_channels
-
- kernel_size = (3, 1, 1)
- padding = [k // 2 for k in kernel_size]
-
- self.norm1 = torch.nn.GroupNorm(num_groups=32, num_channels=in_channels, eps=eps, affine=True)
- self.conv1 = nn.Conv3d(
- in_channels,
- out_channels,
- kernel_size=kernel_size,
- stride=1,
- padding=padding,
- )
-
- if temb_channels is not None:
- self.time_emb_proj = nn.Linear(temb_channels, out_channels)
- else:
- self.time_emb_proj = None
-
- self.norm2 = torch.nn.GroupNorm(num_groups=32, num_channels=out_channels, eps=eps, affine=True)
-
- self.dropout = torch.nn.Dropout(0.0)
- self.conv2 = nn.Conv3d(
- out_channels,
- out_channels,
- kernel_size=kernel_size,
- stride=1,
- padding=padding,
- )
-
- self.nonlinearity = get_activation("silu")
-
- self.use_in_shortcut = self.in_channels != out_channels
-
- self.conv_shortcut = None
- if self.use_in_shortcut:
- self.conv_shortcut = nn.Conv3d(
- in_channels,
- out_channels,
- kernel_size=1,
- stride=1,
- padding=0,
- )
-
- def forward(self, input_tensor: torch.FloatTensor, temb: torch.FloatTensor) -> torch.FloatTensor:
- hidden_states = input_tensor
-
- hidden_states = self.norm1(hidden_states)
- hidden_states = self.nonlinearity(hidden_states)
- hidden_states = self.conv1(hidden_states)
-
- if self.time_emb_proj is not None:
- temb = self.nonlinearity(temb)
- temb = self.time_emb_proj(temb)[:, :, :, None, None]
- temb = temb.permute(0, 2, 1, 3, 4)
- hidden_states = hidden_states + temb
-
- hidden_states = self.norm2(hidden_states)
- hidden_states = self.nonlinearity(hidden_states)
- hidden_states = self.dropout(hidden_states)
- hidden_states = self.conv2(hidden_states)
-
- if self.conv_shortcut is not None:
- input_tensor = self.conv_shortcut(input_tensor)
-
- output_tensor = input_tensor + hidden_states
-
- return output_tensor
-
-
-# VideoResBlock
-class SpatioTemporalResBlock(nn.Module):
- r"""
- A SpatioTemporal Resnet block.
-
- Parameters:
- in_channels (`int`): The number of channels in the input.
- out_channels (`int`, *optional*, default to be `None`):
- The number of output channels for the first conv2d layer. If None, same as `in_channels`.
- temb_channels (`int`, *optional*, default to `512`): the number of channels in timestep embedding.
- eps (`float`, *optional*, defaults to `1e-6`): The epsilon to use for the spatial resenet.
- temporal_eps (`float`, *optional*, defaults to `eps`): The epsilon to use for the temporal resnet.
- merge_factor (`float`, *optional*, defaults to `0.5`): The merge factor to use for the temporal mixing.
- merge_strategy (`str`, *optional*, defaults to `learned_with_images`):
- The merge strategy to use for the temporal mixing.
- switch_spatial_to_temporal_mix (`bool`, *optional*, defaults to `False`):
- If `True`, switch the spatial and temporal mixing.
- """
-
- def __init__(
- self,
- in_channels: int,
- out_channels: Optional[int] = None,
- temb_channels: int = 512,
- eps: float = 1e-6,
- temporal_eps: Optional[float] = None,
- merge_factor: float = 0.5,
- merge_strategy="learned_with_images",
- switch_spatial_to_temporal_mix: bool = False,
- ):
- super().__init__()
-
- self.spatial_res_block = ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=eps,
- )
-
- self.temporal_res_block = TemporalResnetBlock(
- in_channels=out_channels if out_channels is not None else in_channels,
- out_channels=out_channels if out_channels is not None else in_channels,
- temb_channels=temb_channels,
- eps=temporal_eps if temporal_eps is not None else eps,
- )
-
- self.time_mixer = AlphaBlender(
- alpha=merge_factor,
- merge_strategy=merge_strategy,
- switch_spatial_to_temporal_mix=switch_spatial_to_temporal_mix,
- )
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- image_only_indicator: Optional[torch.Tensor] = None,
- ):
- num_frames = image_only_indicator.shape[-1]
- hidden_states = self.spatial_res_block(hidden_states, temb)
-
- batch_frames, channels, height, width = hidden_states.shape
- batch_size = batch_frames // num_frames
-
- hidden_states_mix = (
- hidden_states[None, :].reshape(batch_size, num_frames, channels, height, width).permute(0, 2, 1, 3, 4)
- )
- hidden_states = (
- hidden_states[None, :].reshape(batch_size, num_frames, channels, height, width).permute(0, 2, 1, 3, 4)
- )
-
- if temb is not None:
- temb = temb.reshape(batch_size, num_frames, -1)
-
- hidden_states = self.temporal_res_block(hidden_states, temb)
- hidden_states = self.time_mixer(
- x_spatial=hidden_states_mix,
- x_temporal=hidden_states,
- image_only_indicator=image_only_indicator,
- )
-
- hidden_states = hidden_states.permute(0, 2, 1, 3, 4).reshape(batch_frames, channels, height, width)
- return hidden_states
-
-
-class AlphaBlender(nn.Module):
- r"""
- A module to blend spatial and temporal features.
-
- Parameters:
- alpha (`float`): The initial value of the blending factor.
- merge_strategy (`str`, *optional*, defaults to `learned_with_images`):
- The merge strategy to use for the temporal mixing.
- switch_spatial_to_temporal_mix (`bool`, *optional*, defaults to `False`):
- If `True`, switch the spatial and temporal mixing.
- """
-
- strategies = ["learned", "fixed", "learned_with_images"]
-
- def __init__(
- self,
- alpha: float,
- merge_strategy: str = "learned_with_images",
- switch_spatial_to_temporal_mix: bool = False,
- ):
- super().__init__()
- self.merge_strategy = merge_strategy
- self.switch_spatial_to_temporal_mix = switch_spatial_to_temporal_mix # For TemporalVAE
-
- if merge_strategy not in self.strategies:
- raise ValueError(f"merge_strategy needs to be in {self.strategies}")
-
- if self.merge_strategy == "fixed":
- self.register_buffer("mix_factor", torch.Tensor([alpha]))
- elif self.merge_strategy == "learned" or self.merge_strategy == "learned_with_images":
- self.register_parameter("mix_factor", torch.nn.Parameter(torch.Tensor([alpha])))
- else:
- raise ValueError(f"Unknown merge strategy {self.merge_strategy}")
-
- def get_alpha(self, image_only_indicator: torch.Tensor, ndims: int) -> torch.Tensor:
- if self.merge_strategy == "fixed":
- alpha = self.mix_factor
-
- elif self.merge_strategy == "learned":
- alpha = torch.sigmoid(self.mix_factor)
-
- elif self.merge_strategy == "learned_with_images":
- if image_only_indicator is None:
- raise ValueError("Please provide image_only_indicator to use learned_with_images merge strategy")
-
- alpha = torch.where(
- image_only_indicator.bool(),
- torch.ones(1, 1, device=image_only_indicator.device),
- torch.sigmoid(self.mix_factor)[..., None],
- )
-
- # (batch, channel, frames, height, width)
- if ndims == 5:
- alpha = alpha[:, None, :, None, None]
- # (batch*frames, height*width, channels)
- elif ndims == 3:
- alpha = alpha.reshape(-1)[:, None, None]
- else:
- raise ValueError(f"Unexpected ndims {ndims}. Dimensions should be 3 or 5")
-
- else:
- raise NotImplementedError
-
- return alpha
-
- def forward(
- self,
- x_spatial: torch.Tensor,
- x_temporal: torch.Tensor,
- image_only_indicator: Optional[torch.Tensor] = None,
- ) -> torch.Tensor:
- alpha = self.get_alpha(image_only_indicator, x_spatial.ndim)
- alpha = alpha.to(x_spatial.dtype)
-
- if self.switch_spatial_to_temporal_mix:
- alpha = 1.0 - alpha
-
- x = alpha * x_spatial + (1.0 - alpha) * x_temporal
- return x
diff --git a/foleycrafter/models/auffusion/transformer_2d.py b/foleycrafter/models/auffusion/transformer_2d.py
deleted file mode 100644
index 1e96f49..0000000
--- a/foleycrafter/models/auffusion/transformer_2d.py
+++ /dev/null
@@ -1,460 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from dataclasses import dataclass
-from typing import Any, Dict, Optional
-
-import torch
-import torch.nn.functional as F
-from torch import nn
-
-from diffusers.configuration_utils import ConfigMixin, register_to_config
-from diffusers.models.embeddings import ImagePositionalEmbeddings, PatchEmbed, PixArtAlphaTextProjection
-from diffusers.models.lora import LoRACompatibleConv, LoRACompatibleLinear
-from diffusers.models.modeling_utils import ModelMixin
-from diffusers.models.normalization import AdaLayerNormSingle
-from diffusers.utils import USE_PEFT_BACKEND, BaseOutput, deprecate, is_torch_version
-from foleycrafter.models.auffusion.attention import BasicTransformerBlock
-
-
-@dataclass
-class Transformer2DModelOutput(BaseOutput):
- """
- The output of [`Transformer2DModel`].
-
- Args:
- sample (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)` or `(batch size, num_vector_embeds - 1, num_latent_pixels)` if [`Transformer2DModel`] is discrete):
- The hidden states output conditioned on the `encoder_hidden_states` input. If discrete, returns probability
- distributions for the unnoised latent pixels.
- """
-
- sample: torch.FloatTensor
-
-
-class Transformer2DModel(ModelMixin, ConfigMixin):
- """
- A 2D Transformer model for image-like data.
-
- Parameters:
- num_attention_heads (`int`, *optional*, defaults to 16): The number of heads to use for multi-head attention.
- attention_head_dim (`int`, *optional*, defaults to 88): The number of channels in each head.
- in_channels (`int`, *optional*):
- The number of channels in the input and output (specify if the input is **continuous**).
- num_layers (`int`, *optional*, defaults to 1): The number of layers of Transformer blocks to use.
- dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
- cross_attention_dim (`int`, *optional*): The number of `encoder_hidden_states` dimensions to use.
- sample_size (`int`, *optional*): The width of the latent images (specify if the input is **discrete**).
- This is fixed during training since it is used to learn a number of position embeddings.
- num_vector_embeds (`int`, *optional*):
- The number of classes of the vector embeddings of the latent pixels (specify if the input is **discrete**).
- Includes the class for the masked latent pixel.
- activation_fn (`str`, *optional*, defaults to `"geglu"`): Activation function to use in feed-forward.
- num_embeds_ada_norm ( `int`, *optional*):
- The number of diffusion steps used during training. Pass if at least one of the norm_layers is
- `AdaLayerNorm`. This is fixed during training since it is used to learn a number of embeddings that are
- added to the hidden states.
-
- During inference, you can denoise for up to but not more steps than `num_embeds_ada_norm`.
- attention_bias (`bool`, *optional*):
- Configure if the `TransformerBlocks` attention should contain a bias parameter.
- """
-
- _supports_gradient_checkpointing = True
-
- @register_to_config
- def __init__(
- self,
- num_attention_heads: int = 16,
- attention_head_dim: int = 88,
- in_channels: Optional[int] = None,
- out_channels: Optional[int] = None,
- num_layers: int = 1,
- dropout: float = 0.0,
- norm_num_groups: int = 32,
- cross_attention_dim: Optional[int] = None,
- attention_bias: bool = False,
- sample_size: Optional[int] = None,
- num_vector_embeds: Optional[int] = None,
- patch_size: Optional[int] = None,
- activation_fn: str = "geglu",
- num_embeds_ada_norm: Optional[int] = None,
- use_linear_projection: bool = False,
- only_cross_attention: bool = False,
- double_self_attention: bool = False,
- upcast_attention: bool = False,
- norm_type: str = "layer_norm",
- norm_elementwise_affine: bool = True,
- norm_eps: float = 1e-5,
- attention_type: str = "default",
- caption_channels: int = None,
- ):
- super().__init__()
- self.use_linear_projection = use_linear_projection
- self.num_attention_heads = num_attention_heads
- self.attention_head_dim = attention_head_dim
- inner_dim = num_attention_heads * attention_head_dim
-
- conv_cls = nn.Conv2d if USE_PEFT_BACKEND else LoRACompatibleConv
- linear_cls = nn.Linear if USE_PEFT_BACKEND else LoRACompatibleLinear
-
- # 1. Transformer2DModel can process both standard continuous images of shape `(batch_size, num_channels, width, height)` as well as quantized image embeddings of shape `(batch_size, num_image_vectors)`
- # Define whether input is continuous or discrete depending on configuration
- self.is_input_continuous = (in_channels is not None) and (patch_size is None)
- self.is_input_vectorized = num_vector_embeds is not None
- self.is_input_patches = in_channels is not None and patch_size is not None
-
- if norm_type == "layer_norm" and num_embeds_ada_norm is not None:
- deprecation_message = (
- f"The configuration file of this model: {self.__class__} is outdated. `norm_type` is either not set or"
- " incorrectly set to `'layer_norm'`.Make sure to set `norm_type` to `'ada_norm'` in the config."
- " Please make sure to update the config accordingly as leaving `norm_type` might led to incorrect"
- " results in future versions. If you have downloaded this checkpoint from the Hugging Face Hub, it"
- " would be very nice if you could open a Pull request for the `transformer/config.json` file"
- )
- deprecate("norm_type!=num_embeds_ada_norm", "1.0.0", deprecation_message, standard_warn=False)
- norm_type = "ada_norm"
-
- if self.is_input_continuous and self.is_input_vectorized:
- raise ValueError(
- f"Cannot define both `in_channels`: {in_channels} and `num_vector_embeds`: {num_vector_embeds}. Make"
- " sure that either `in_channels` or `num_vector_embeds` is None."
- )
- elif self.is_input_vectorized and self.is_input_patches:
- raise ValueError(
- f"Cannot define both `num_vector_embeds`: {num_vector_embeds} and `patch_size`: {patch_size}. Make"
- " sure that either `num_vector_embeds` or `num_patches` is None."
- )
- elif not self.is_input_continuous and not self.is_input_vectorized and not self.is_input_patches:
- raise ValueError(
- f"Has to define `in_channels`: {in_channels}, `num_vector_embeds`: {num_vector_embeds}, or patch_size:"
- f" {patch_size}. Make sure that `in_channels`, `num_vector_embeds` or `num_patches` is not None."
- )
-
- # 2. Define input layers
- if self.is_input_continuous:
- self.in_channels = in_channels
-
- self.norm = torch.nn.GroupNorm(num_groups=norm_num_groups, num_channels=in_channels, eps=1e-6, affine=True)
- if use_linear_projection:
- self.proj_in = linear_cls(in_channels, inner_dim)
- else:
- self.proj_in = conv_cls(in_channels, inner_dim, kernel_size=1, stride=1, padding=0)
- elif self.is_input_vectorized:
- assert sample_size is not None, "Transformer2DModel over discrete input must provide sample_size"
- assert num_vector_embeds is not None, "Transformer2DModel over discrete input must provide num_embed"
-
- self.height = sample_size
- self.width = sample_size
- self.num_vector_embeds = num_vector_embeds
- self.num_latent_pixels = self.height * self.width
-
- self.latent_image_embedding = ImagePositionalEmbeddings(
- num_embed=num_vector_embeds, embed_dim=inner_dim, height=self.height, width=self.width
- )
- elif self.is_input_patches:
- assert sample_size is not None, "Transformer2DModel over patched input must provide sample_size"
-
- self.height = sample_size
- self.width = sample_size
-
- self.patch_size = patch_size
- interpolation_scale = self.config.sample_size // 64 # => 64 (= 512 pixart) has interpolation scale 1
- interpolation_scale = max(interpolation_scale, 1)
- self.pos_embed = PatchEmbed(
- height=sample_size,
- width=sample_size,
- patch_size=patch_size,
- in_channels=in_channels,
- embed_dim=inner_dim,
- interpolation_scale=interpolation_scale,
- )
-
- # 3. Define transformers blocks
- self.transformer_blocks = nn.ModuleList(
- [
- # NOTE: remember to change
- BasicTransformerBlock(
- inner_dim,
- num_attention_heads,
- attention_head_dim,
- dropout=dropout,
- cross_attention_dim=cross_attention_dim,
- activation_fn=activation_fn,
- num_embeds_ada_norm=num_embeds_ada_norm,
- attention_bias=attention_bias,
- only_cross_attention=only_cross_attention,
- double_self_attention=double_self_attention,
- upcast_attention=upcast_attention,
- norm_type=norm_type,
- norm_elementwise_affine=norm_elementwise_affine,
- norm_eps=norm_eps,
- attention_type=attention_type,
- )
- for d in range(num_layers)
- ]
- )
-
- # 4. Define output layers
- self.out_channels = in_channels if out_channels is None else out_channels
- if self.is_input_continuous:
- # TODO: should use out_channels for continuous projections
- if use_linear_projection:
- self.proj_out = linear_cls(inner_dim, in_channels)
- else:
- self.proj_out = conv_cls(inner_dim, in_channels, kernel_size=1, stride=1, padding=0)
- elif self.is_input_vectorized:
- self.norm_out = nn.LayerNorm(inner_dim)
- self.out = nn.Linear(inner_dim, self.num_vector_embeds - 1)
- elif self.is_input_patches and norm_type != "ada_norm_single":
- self.norm_out = nn.LayerNorm(inner_dim, elementwise_affine=False, eps=1e-6)
- self.proj_out_1 = nn.Linear(inner_dim, 2 * inner_dim)
- self.proj_out_2 = nn.Linear(inner_dim, patch_size * patch_size * self.out_channels)
- elif self.is_input_patches and norm_type == "ada_norm_single":
- self.norm_out = nn.LayerNorm(inner_dim, elementwise_affine=False, eps=1e-6)
- self.scale_shift_table = nn.Parameter(torch.randn(2, inner_dim) / inner_dim**0.5)
- self.proj_out = nn.Linear(inner_dim, patch_size * patch_size * self.out_channels)
-
- # 5. PixArt-Alpha blocks.
- self.adaln_single = None
- self.use_additional_conditions = False
- if norm_type == "ada_norm_single":
- self.use_additional_conditions = self.config.sample_size == 128
- # TODO(Sayak, PVP) clean this, for now we use sample size to determine whether to use
- # additional conditions until we find better name
- self.adaln_single = AdaLayerNormSingle(inner_dim, use_additional_conditions=self.use_additional_conditions)
-
- self.caption_projection = None
- if caption_channels is not None:
- self.caption_projection = PixArtAlphaTextProjection(in_features=caption_channels, hidden_size=inner_dim)
-
- self.gradient_checkpointing = False
-
- def _set_gradient_checkpointing(self, module, value=False):
- if hasattr(module, "gradient_checkpointing"):
- module.gradient_checkpointing = value
-
- def forward(
- self,
- hidden_states: torch.Tensor,
- encoder_hidden_states: Optional[torch.Tensor] = None,
- timestep: Optional[torch.LongTensor] = None,
- added_cond_kwargs: Dict[str, torch.Tensor] = None,
- class_labels: Optional[torch.LongTensor] = None,
- cross_attention_kwargs: Dict[str, Any] = None,
- attention_mask: Optional[torch.Tensor] = None,
- encoder_attention_mask: Optional[torch.Tensor] = None,
- return_dict: bool = True,
- ):
- """
- The [`Transformer2DModel`] forward method.
-
- Args:
- hidden_states (`torch.LongTensor` of shape `(batch size, num latent pixels)` if discrete, `torch.FloatTensor` of shape `(batch size, channel, height, width)` if continuous):
- Input `hidden_states`.
- encoder_hidden_states ( `torch.FloatTensor` of shape `(batch size, sequence len, embed dims)`, *optional*):
- Conditional embeddings for cross attention layer. If not given, cross-attention defaults to
- self-attention.
- timestep ( `torch.LongTensor`, *optional*):
- Used to indicate denoising step. Optional timestep to be applied as an embedding in `AdaLayerNorm`.
- class_labels ( `torch.LongTensor` of shape `(batch size, num classes)`, *optional*):
- Used to indicate class labels conditioning. Optional class labels to be applied as an embedding in
- `AdaLayerZeroNorm`.
- cross_attention_kwargs ( `Dict[str, Any]`, *optional*):
- A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
- `self.processor` in
- [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
- attention_mask ( `torch.Tensor`, *optional*):
- An attention mask of shape `(batch, key_tokens)` is applied to `encoder_hidden_states`. If `1` the mask
- is kept, otherwise if `0` it is discarded. Mask will be converted into a bias, which adds large
- negative values to the attention scores corresponding to "discard" tokens.
- encoder_attention_mask ( `torch.Tensor`, *optional*):
- Cross-attention mask applied to `encoder_hidden_states`. Two formats supported:
-
- * Mask `(batch, sequence_length)` True = keep, False = discard.
- * Bias `(batch, 1, sequence_length)` 0 = keep, -10000 = discard.
-
- If `ndim == 2`: will be interpreted as a mask, then converted into a bias consistent with the format
- above. This bias will be added to the cross-attention scores.
- return_dict (`bool`, *optional*, defaults to `True`):
- Whether or not to return a [`~models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain
- tuple.
-
- Returns:
- If `return_dict` is True, an [`~models.transformer_2d.Transformer2DModelOutput`] is returned, otherwise a
- `tuple` where the first element is the sample tensor.
- """
- # ensure attention_mask is a bias, and give it a singleton query_tokens dimension.
- # we may have done this conversion already, e.g. if we came here via UNet2DConditionModel#forward.
- # we can tell by counting dims; if ndim == 2: it's a mask rather than a bias.
- # expects mask of shape:
- # [batch, key_tokens]
- # adds singleton query_tokens dimension:
- # [batch, 1, key_tokens]
- # this helps to broadcast it as a bias over attention scores, which will be in one of the following shapes:
- # [batch, heads, query_tokens, key_tokens] (e.g. torch sdp attn)
- # [batch * heads, query_tokens, key_tokens] (e.g. xformers or classic attn)
- if attention_mask is not None and attention_mask.ndim == 2:
- # assume that mask is expressed as:
- # (1 = keep, 0 = discard)
- # convert mask into a bias that can be added to attention scores:
- # (keep = +0, discard = -10000.0)
- attention_mask = (1 - attention_mask.to(hidden_states.dtype)) * -10000.0
- attention_mask = attention_mask.unsqueeze(1)
-
- # convert encoder_attention_mask to a bias the same way we do for attention_mask
- if encoder_attention_mask is not None and encoder_attention_mask.ndim == 2:
- encoder_attention_mask = (1 - encoder_attention_mask.to(hidden_states.dtype)) * -10000.0
- encoder_attention_mask = encoder_attention_mask.unsqueeze(1)
-
- # Retrieve lora scale.
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
-
- # 1. Input
- if self.is_input_continuous:
- batch, _, height, width = hidden_states.shape
- inner_dim = hidden_states.shape[1]
- residual = hidden_states
-
- hidden_states = self.norm(hidden_states)
- if not self.use_linear_projection:
- hidden_states = (
- self.proj_in(hidden_states, scale=lora_scale)
- if not USE_PEFT_BACKEND
- else self.proj_in(hidden_states)
- )
- inner_dim = hidden_states.shape[1]
- hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * width, inner_dim)
- else:
- inner_dim = hidden_states.shape[1]
- hidden_states = hidden_states.permute(0, 2, 3, 1).reshape(batch, height * width, inner_dim)
- hidden_states = (
- self.proj_in(hidden_states, scale=lora_scale)
- if not USE_PEFT_BACKEND
- else self.proj_in(hidden_states)
- )
-
- elif self.is_input_vectorized:
- hidden_states = self.latent_image_embedding(hidden_states)
- elif self.is_input_patches:
- height, width = hidden_states.shape[-2] // self.patch_size, hidden_states.shape[-1] // self.patch_size
- self.height, self.width = height, width
- hidden_states = self.pos_embed(hidden_states)
-
- if self.adaln_single is not None:
- if self.use_additional_conditions and added_cond_kwargs is None:
- raise ValueError(
- "`added_cond_kwargs` cannot be None when using additional conditions for `adaln_single`."
- )
- batch_size = hidden_states.shape[0]
- timestep, embedded_timestep = self.adaln_single(
- timestep, added_cond_kwargs, batch_size=batch_size, hidden_dtype=hidden_states.dtype
- )
-
- if self.caption_projection is not None:
- batch_size = hidden_states.shape[0]
- encoder_hidden_states = self.caption_projection(encoder_hidden_states)
- encoder_hidden_states = encoder_hidden_states.view(batch_size, -1, hidden_states.shape[-1])
- # 2. Blocks
- for block in self.transformer_blocks:
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(block),
- hidden_states,
- attention_mask,
- encoder_hidden_states,
- encoder_attention_mask,
- timestep,
- cross_attention_kwargs,
- class_labels,
- **ckpt_kwargs,
- )
- else:
- hidden_states = block(
- hidden_states,
- attention_mask=attention_mask,
- encoder_hidden_states=encoder_hidden_states,
- encoder_attention_mask=encoder_attention_mask,
- timestep=timestep,
- cross_attention_kwargs=cross_attention_kwargs,
- class_labels=class_labels,
- )
-
- # 3. Output
- if self.is_input_continuous:
- if not self.use_linear_projection:
- hidden_states = hidden_states.reshape(batch, height, width, inner_dim).permute(0, 3, 1, 2).contiguous()
- hidden_states = (
- self.proj_out(hidden_states, scale=lora_scale)
- if not USE_PEFT_BACKEND
- else self.proj_out(hidden_states)
- )
- else:
- hidden_states = (
- self.proj_out(hidden_states, scale=lora_scale)
- if not USE_PEFT_BACKEND
- else self.proj_out(hidden_states)
- )
- hidden_states = hidden_states.reshape(batch, height, width, inner_dim).permute(0, 3, 1, 2).contiguous()
-
- output = hidden_states + residual
- elif self.is_input_vectorized:
- hidden_states = self.norm_out(hidden_states)
- logits = self.out(hidden_states)
- # (batch, self.num_vector_embeds - 1, self.num_latent_pixels)
- logits = logits.permute(0, 2, 1)
-
- # log(p(x_0))
- output = F.log_softmax(logits.double(), dim=1).float()
-
- if self.is_input_patches:
- if self.config.norm_type != "ada_norm_single":
- conditioning = self.transformer_blocks[0].norm1.emb(
- timestep, class_labels, hidden_dtype=hidden_states.dtype
- )
- shift, scale = self.proj_out_1(F.silu(conditioning)).chunk(2, dim=1)
- hidden_states = self.norm_out(hidden_states) * (1 + scale[:, None]) + shift[:, None]
- hidden_states = self.proj_out_2(hidden_states)
- elif self.config.norm_type == "ada_norm_single":
- shift, scale = (self.scale_shift_table[None] + embedded_timestep[:, None]).chunk(2, dim=1)
- hidden_states = self.norm_out(hidden_states)
- # Modulation
- hidden_states = hidden_states * (1 + scale) + shift
- hidden_states = self.proj_out(hidden_states)
- hidden_states = hidden_states.squeeze(1)
-
- # unpatchify
- if self.adaln_single is None:
- height = width = int(hidden_states.shape[1] ** 0.5)
- hidden_states = hidden_states.reshape(
- shape=(-1, height, width, self.patch_size, self.patch_size, self.out_channels)
- )
- hidden_states = torch.einsum("nhwpqc->nchpwq", hidden_states)
- output = hidden_states.reshape(
- shape=(-1, self.out_channels, height * self.patch_size, width * self.patch_size)
- )
-
- if not return_dict:
- return (output,)
-
- return Transformer2DModelOutput(sample=output)
diff --git a/foleycrafter/models/auffusion/unet_2d_blocks.py b/foleycrafter/models/auffusion/unet_2d_blocks.py
deleted file mode 100644
index a2887d0..0000000
--- a/foleycrafter/models/auffusion/unet_2d_blocks.py
+++ /dev/null
@@ -1,3501 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from typing import Any, Dict, Optional, Tuple, Union
-
-import numpy as np
-import torch
-import torch.nn.functional as F
-from torch import nn
-
-from diffusers.models.activations import get_activation
-from diffusers.models.normalization import AdaGroupNorm
-from diffusers.utils import is_torch_version, logging
-from diffusers.utils.torch_utils import apply_freeu
-from foleycrafter.models.auffusion.attention_processor import Attention, AttnAddedKVProcessor, AttnAddedKVProcessor2_0
-from foleycrafter.models.auffusion.dual_transformer_2d import DualTransformer2DModel
-from foleycrafter.models.auffusion.resnet import (
- Downsample2D,
- FirDownsample2D,
- FirUpsample2D,
- KDownsample2D,
- KUpsample2D,
- ResnetBlock2D,
- Upsample2D,
-)
-from foleycrafter.models.auffusion.transformer_2d import Transformer2DModel
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-def get_down_block(
- down_block_type: str,
- num_layers: int,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- add_downsample: bool,
- resnet_eps: float,
- resnet_act_fn: str,
- transformer_layers_per_block: int = 1,
- num_attention_heads: Optional[int] = None,
- resnet_groups: Optional[int] = None,
- cross_attention_dim: Optional[int] = None,
- downsample_padding: Optional[int] = None,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- only_cross_attention: bool = False,
- upcast_attention: bool = False,
- resnet_time_scale_shift: str = "default",
- attention_type: str = "default",
- resnet_skip_time_act: bool = False,
- resnet_out_scale_factor: float = 1.0,
- cross_attention_norm: Optional[str] = None,
- attention_head_dim: Optional[int] = None,
- downsample_type: Optional[str] = None,
- dropout: float = 0.0,
-):
- # If attn head dim is not defined, we default it to the number of heads
- if attention_head_dim is None:
- logger.warn(
- f"It is recommended to provide `attention_head_dim` when calling `get_down_block`. Defaulting `attention_head_dim` to {num_attention_heads}."
- )
- attention_head_dim = num_attention_heads
-
- down_block_type = down_block_type[7:] if down_block_type.startswith("UNetRes") else down_block_type
- if down_block_type == "DownBlock2D":
- return DownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- downsample_padding=downsample_padding,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif down_block_type == "ResnetDownsampleBlock2D":
- return ResnetDownsampleBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- skip_time_act=resnet_skip_time_act,
- output_scale_factor=resnet_out_scale_factor,
- )
- elif down_block_type == "AttnDownBlock2D":
- if add_downsample is False:
- downsample_type = None
- else:
- downsample_type = downsample_type or "conv" # default to 'conv'
- return AttnDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- downsample_padding=downsample_padding,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- downsample_type=downsample_type,
- )
- elif down_block_type == "CrossAttnDownBlock2D":
- if cross_attention_dim is None:
- raise ValueError("cross_attention_dim must be specified for CrossAttnDownBlock2D")
- return CrossAttnDownBlock2D(
- num_layers=num_layers,
- transformer_layers_per_block=transformer_layers_per_block,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- downsample_padding=downsample_padding,
- cross_attention_dim=cross_attention_dim,
- num_attention_heads=num_attention_heads,
- dual_cross_attention=dual_cross_attention,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention,
- upcast_attention=upcast_attention,
- resnet_time_scale_shift=resnet_time_scale_shift,
- attention_type=attention_type,
- )
- elif down_block_type == "SimpleCrossAttnDownBlock2D":
- if cross_attention_dim is None:
- raise ValueError("cross_attention_dim must be specified for SimpleCrossAttnDownBlock2D")
- return SimpleCrossAttnDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- cross_attention_dim=cross_attention_dim,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- skip_time_act=resnet_skip_time_act,
- output_scale_factor=resnet_out_scale_factor,
- only_cross_attention=only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- )
- elif down_block_type == "SkipDownBlock2D":
- return SkipDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- downsample_padding=downsample_padding,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif down_block_type == "AttnSkipDownBlock2D":
- return AttnSkipDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif down_block_type == "DownEncoderBlock2D":
- return DownEncoderBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- downsample_padding=downsample_padding,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif down_block_type == "AttnDownEncoderBlock2D":
- return AttnDownEncoderBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- downsample_padding=downsample_padding,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif down_block_type == "KDownBlock2D":
- return KDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- )
- elif down_block_type == "KCrossAttnDownBlock2D":
- return KCrossAttnDownBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- dropout=dropout,
- add_downsample=add_downsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- cross_attention_dim=cross_attention_dim,
- attention_head_dim=attention_head_dim,
- add_self_attention=True if not add_downsample else False,
- )
- raise ValueError(f"{down_block_type} does not exist.")
-
-
-def get_up_block(
- up_block_type: str,
- num_layers: int,
- in_channels: int,
- out_channels: int,
- prev_output_channel: int,
- temb_channels: int,
- add_upsample: bool,
- resnet_eps: float,
- resnet_act_fn: str,
- resolution_idx: Optional[int] = None,
- transformer_layers_per_block: int = 1,
- num_attention_heads: Optional[int] = None,
- resnet_groups: Optional[int] = None,
- cross_attention_dim: Optional[int] = None,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- only_cross_attention: bool = False,
- upcast_attention: bool = False,
- resnet_time_scale_shift: str = "default",
- attention_type: str = "default",
- resnet_skip_time_act: bool = False,
- resnet_out_scale_factor: float = 1.0,
- cross_attention_norm: Optional[str] = None,
- attention_head_dim: Optional[int] = None,
- upsample_type: Optional[str] = None,
- dropout: float = 0.0,
-) -> nn.Module:
- # If attn head dim is not defined, we default it to the number of heads
- if attention_head_dim is None:
- logger.warn(
- f"It is recommended to provide `attention_head_dim` when calling `get_up_block`. Defaulting `attention_head_dim` to {num_attention_heads}."
- )
- attention_head_dim = num_attention_heads
-
- up_block_type = up_block_type[7:] if up_block_type.startswith("UNetRes") else up_block_type
- if up_block_type == "UpBlock2D":
- return UpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif up_block_type == "ResnetUpsampleBlock2D":
- return ResnetUpsampleBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- skip_time_act=resnet_skip_time_act,
- output_scale_factor=resnet_out_scale_factor,
- )
- elif up_block_type == "CrossAttnUpBlock2D":
- if cross_attention_dim is None:
- raise ValueError("cross_attention_dim must be specified for CrossAttnUpBlock2D")
- return CrossAttnUpBlock2D(
- num_layers=num_layers,
- transformer_layers_per_block=transformer_layers_per_block,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- cross_attention_dim=cross_attention_dim,
- num_attention_heads=num_attention_heads,
- dual_cross_attention=dual_cross_attention,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention,
- upcast_attention=upcast_attention,
- resnet_time_scale_shift=resnet_time_scale_shift,
- attention_type=attention_type,
- )
- elif up_block_type == "SimpleCrossAttnUpBlock2D":
- if cross_attention_dim is None:
- raise ValueError("cross_attention_dim must be specified for SimpleCrossAttnUpBlock2D")
- return SimpleCrossAttnUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- cross_attention_dim=cross_attention_dim,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- skip_time_act=resnet_skip_time_act,
- output_scale_factor=resnet_out_scale_factor,
- only_cross_attention=only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- )
- elif up_block_type == "AttnUpBlock2D":
- if add_upsample is False:
- upsample_type = None
- else:
- upsample_type = upsample_type or "conv" # default to 'conv'
-
- return AttnUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- upsample_type=upsample_type,
- )
- elif up_block_type == "SkipUpBlock2D":
- return SkipUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif up_block_type == "AttnSkipUpBlock2D":
- return AttnSkipUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- prev_output_channel=prev_output_channel,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- )
- elif up_block_type == "UpDecoderBlock2D":
- return UpDecoderBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- temb_channels=temb_channels,
- )
- elif up_block_type == "AttnUpDecoderBlock2D":
- return AttnUpDecoderBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- resnet_groups=resnet_groups,
- attention_head_dim=attention_head_dim,
- resnet_time_scale_shift=resnet_time_scale_shift,
- temb_channels=temb_channels,
- )
- elif up_block_type == "KUpBlock2D":
- return KUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- )
- elif up_block_type == "KCrossAttnUpBlock2D":
- return KCrossAttnUpBlock2D(
- num_layers=num_layers,
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- resolution_idx=resolution_idx,
- dropout=dropout,
- add_upsample=add_upsample,
- resnet_eps=resnet_eps,
- resnet_act_fn=resnet_act_fn,
- cross_attention_dim=cross_attention_dim,
- attention_head_dim=attention_head_dim,
- )
-
- raise ValueError(f"{up_block_type} does not exist.")
-
-
-class AutoencoderTinyBlock(nn.Module):
- """
- Tiny Autoencoder block used in [`AutoencoderTiny`]. It is a mini residual module consisting of plain conv + ReLU
- blocks.
-
- Args:
- in_channels (`int`): The number of input channels.
- out_channels (`int`): The number of output channels.
- act_fn (`str`):
- ` The activation function to use. Supported values are `"swish"`, `"mish"`, `"gelu"`, and `"relu"`.
-
- Returns:
- `torch.FloatTensor`: A tensor with the same shape as the input tensor, but with the number of channels equal to
- `out_channels`.
- """
-
- def __init__(self, in_channels: int, out_channels: int, act_fn: str):
- super().__init__()
- act_fn = get_activation(act_fn)
- self.conv = nn.Sequential(
- nn.Conv2d(in_channels, out_channels, kernel_size=3, padding=1),
- act_fn,
- nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
- act_fn,
- nn.Conv2d(out_channels, out_channels, kernel_size=3, padding=1),
- )
- self.skip = (
- nn.Conv2d(in_channels, out_channels, kernel_size=1, bias=False)
- if in_channels != out_channels
- else nn.Identity()
- )
- self.fuse = nn.ReLU()
-
- def forward(self, x: torch.FloatTensor) -> torch.FloatTensor:
- return self.fuse(self.conv(x) + self.skip(x))
-
-
-class UNetMidBlock2D(nn.Module):
- """
- A 2D UNet mid-block [`UNetMidBlock2D`] with multiple residual blocks and optional attention blocks.
-
- Args:
- in_channels (`int`): The number of input channels.
- temb_channels (`int`): The number of temporal embedding channels.
- dropout (`float`, *optional*, defaults to 0.0): The dropout rate.
- num_layers (`int`, *optional*, defaults to 1): The number of residual blocks.
- resnet_eps (`float`, *optional*, 1e-6 ): The epsilon value for the resnet blocks.
- resnet_time_scale_shift (`str`, *optional*, defaults to `default`):
- The type of normalization to apply to the time embeddings. This can help to improve the performance of the
- model on tasks with long-range temporal dependencies.
- resnet_act_fn (`str`, *optional*, defaults to `swish`): The activation function for the resnet blocks.
- resnet_groups (`int`, *optional*, defaults to 32):
- The number of groups to use in the group normalization layers of the resnet blocks.
- attn_groups (`Optional[int]`, *optional*, defaults to None): The number of groups for the attention blocks.
- resnet_pre_norm (`bool`, *optional*, defaults to `True`):
- Whether to use pre-normalization for the resnet blocks.
- add_attention (`bool`, *optional*, defaults to `True`): Whether to add attention blocks.
- attention_head_dim (`int`, *optional*, defaults to 1):
- Dimension of a single attention head. The number of attention heads is determined based on this value and
- the number of input channels.
- output_scale_factor (`float`, *optional*, defaults to 1.0): The output scale factor.
-
- Returns:
- `torch.FloatTensor`: The output of the last residual block, which is a tensor of shape `(batch_size,
- in_channels, height, width)`.
-
- """
-
- def __init__(
- self,
- in_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default", # default, spatial
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- attn_groups: Optional[int] = None,
- resnet_pre_norm: bool = True,
- add_attention: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- ):
- super().__init__()
- resnet_groups = resnet_groups if resnet_groups is not None else min(in_channels // 4, 32)
- self.add_attention = add_attention
-
- if attn_groups is None:
- attn_groups = resnet_groups if resnet_time_scale_shift == "default" else None
-
- # there is always at least one resnet
- resnets = [
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- ]
- attentions = []
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `in_channels`: {in_channels}."
- )
- attention_head_dim = in_channels
-
- for _ in range(num_layers):
- if self.add_attention:
- attentions.append(
- Attention(
- in_channels,
- heads=in_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=attn_groups,
- spatial_norm_dim=temb_channels if resnet_time_scale_shift == "spatial" else None,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
- else:
- attentions.append(None)
-
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- def forward(self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None) -> torch.FloatTensor:
- hidden_states = self.resnets[0](hidden_states, temb)
- for attn, resnet in zip(self.attentions, self.resnets[1:]):
- if attn is not None:
- hidden_states = attn(hidden_states, temb=temb)
- hidden_states = resnet(hidden_states, temb)
-
- return hidden_states
-
-
-class UNetMidBlock2DCrossAttn(nn.Module):
- def __init__(
- self,
- in_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- transformer_layers_per_block: Union[int, Tuple[int]] = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- num_attention_heads: int = 1,
- output_scale_factor: float = 1.0,
- cross_attention_dim: int = 1280,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- upcast_attention: bool = False,
- attention_type: str = "default",
- ):
- super().__init__()
-
- self.has_cross_attention = True
- self.num_attention_heads = num_attention_heads
- resnet_groups = resnet_groups if resnet_groups is not None else min(in_channels // 4, 32)
-
- # support for variable transformer layers per block
- if isinstance(transformer_layers_per_block, int):
- transformer_layers_per_block = [transformer_layers_per_block] * num_layers
-
- # there is always at least one resnet
- resnets = [
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- ]
- attentions = []
-
- for i in range(num_layers):
- if not dual_cross_attention:
- attentions.append(
- Transformer2DModel(
- num_attention_heads,
- in_channels // num_attention_heads,
- in_channels=in_channels,
- num_layers=transformer_layers_per_block[i],
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- use_linear_projection=use_linear_projection,
- upcast_attention=upcast_attention,
- attention_type=attention_type,
- )
- )
- else:
- attentions.append(
- DualTransformer2DModel(
- num_attention_heads,
- in_channels // num_attention_heads,
- in_channels=in_channels,
- num_layers=1,
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- )
- )
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- self.gradient_checkpointing = False
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
- hidden_states = self.resnets[0](hidden_states, temb, scale=lora_scale)
- for attn, resnet in zip(self.attentions, self.resnets[1:]):
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet),
- hidden_states,
- temb,
- **ckpt_kwargs,
- )
- else:
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
-
- return hidden_states
-
-
-class UNetMidBlock2DSimpleCrossAttn(nn.Module):
- def __init__(
- self,
- in_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- cross_attention_dim: int = 1280,
- skip_time_act: bool = False,
- only_cross_attention: bool = False,
- cross_attention_norm: Optional[str] = None,
- ):
- super().__init__()
-
- self.has_cross_attention = True
-
- self.attention_head_dim = attention_head_dim
- resnet_groups = resnet_groups if resnet_groups is not None else min(in_channels // 4, 32)
-
- self.num_heads = in_channels // self.attention_head_dim
-
- # there is always at least one resnet
- resnets = [
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- ]
- attentions = []
-
- for _ in range(num_layers):
- processor = (
- AttnAddedKVProcessor2_0() if hasattr(F, "scaled_dot_product_attention") else AttnAddedKVProcessor()
- )
-
- attentions.append(
- Attention(
- query_dim=in_channels,
- cross_attention_dim=in_channels,
- heads=self.num_heads,
- dim_head=self.attention_head_dim,
- added_kv_proj_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- bias=True,
- upcast_softmax=True,
- only_cross_attention=only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- processor=processor,
- )
- )
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=in_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
- lora_scale = cross_attention_kwargs.get("scale", 1.0)
-
- if attention_mask is None:
- # if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
- mask = None if encoder_hidden_states is None else encoder_attention_mask
- else:
- # when attention_mask is defined: we don't even check for encoder_attention_mask.
- # this is to maintain compatibility with UnCLIP, which uses 'attention_mask' param for cross-attn masks.
- # TODO: UnCLIP should express cross-attn mask via encoder_attention_mask param instead of via attention_mask.
- # then we can simplify this whole if/else block to:
- # mask = attention_mask if encoder_hidden_states is None else encoder_attention_mask
- mask = attention_mask
-
- hidden_states = self.resnets[0](hidden_states, temb, scale=lora_scale)
- for attn, resnet in zip(self.attentions, self.resnets[1:]):
- # attn
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=mask,
- **cross_attention_kwargs,
- )
-
- # resnet
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
-
- return hidden_states
-
-
-class AttnDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- downsample_padding: int = 1,
- downsample_type: str = "conv",
- ):
- super().__init__()
- resnets = []
- attentions = []
- self.downsample_type = downsample_type
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `in_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=resnet_groups,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if downsample_type == "conv":
- self.downsamplers = nn.ModuleList(
- [
- Downsample2D(
- out_channels, use_conv=True, out_channels=out_channels, padding=downsample_padding, name="op"
- )
- ]
- )
- elif downsample_type == "resnet":
- self.downsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- down=True,
- )
- ]
- )
- else:
- self.downsamplers = None
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
-
- lora_scale = cross_attention_kwargs.get("scale", 1.0)
-
- output_states = ()
-
- for resnet, attn in zip(self.resnets, self.attentions):
- cross_attention_kwargs.update({"scale": lora_scale})
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
- hidden_states = attn(hidden_states, **cross_attention_kwargs)
- output_states = output_states + (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- if self.downsample_type == "resnet":
- hidden_states = downsampler(hidden_states, temb=temb, scale=lora_scale)
- else:
- hidden_states = downsampler(hidden_states, scale=lora_scale)
-
- output_states += (hidden_states,)
-
- return hidden_states, output_states
-
-
-class CrossAttnDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- transformer_layers_per_block: Union[int, Tuple[int]] = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- num_attention_heads: int = 1,
- cross_attention_dim: int = 1280,
- output_scale_factor: float = 1.0,
- downsample_padding: int = 1,
- add_downsample: bool = True,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- only_cross_attention: bool = False,
- upcast_attention: bool = False,
- attention_type: str = "default",
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- self.has_cross_attention = True
- self.num_attention_heads = num_attention_heads
- if isinstance(transformer_layers_per_block, int):
- transformer_layers_per_block = [transformer_layers_per_block] * num_layers
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- if not dual_cross_attention:
- # Transformer2DModelWithSwitcher
- attentions.append(
- Transformer2DModel(
- num_attention_heads,
- out_channels // num_attention_heads,
- in_channels=out_channels,
- num_layers=transformer_layers_per_block[i],
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention,
- upcast_attention=upcast_attention,
- attention_type=attention_type,
- )
- )
- else:
- attentions.append(
- DualTransformer2DModel(
- num_attention_heads,
- out_channels // num_attention_heads,
- in_channels=out_channels,
- num_layers=1,
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- )
- )
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- Downsample2D(
- out_channels, use_conv=True, out_channels=out_channels, padding=downsample_padding, name="op"
- )
- ]
- )
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- additional_residuals: Optional[torch.FloatTensor] = None,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
-
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
-
- blocks = list(zip(self.resnets, self.attentions))
-
- for i, (resnet, attn) in enumerate(blocks):
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet),
- hidden_states,
- temb,
- **ckpt_kwargs,
- )
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
-
- # apply additional residuals to the output of the last pair of resnet and attention blocks
- if i == len(blocks) - 1 and additional_residuals is not None:
- hidden_states = hidden_states + additional_residuals
-
- output_states = output_states + (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, scale=lora_scale)
-
- output_states = output_states + (hidden_states,)
-
- return hidden_states, output_states
-
-
-class DownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_downsample: bool = True,
- downsample_padding: int = 1,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- Downsample2D(
- out_channels, use_conv=True, out_channels=out_channels, padding=downsample_padding, name="op"
- )
- ]
- )
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None, scale: float = 1.0
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
-
- for resnet in self.resnets:
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- output_states = output_states + (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, scale=scale)
-
- output_states = output_states + (hidden_states,)
-
- return hidden_states, output_states
-
-
-class DownEncoderBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_downsample: bool = True,
- downsample_padding: int = 1,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=None,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- Downsample2D(
- out_channels, use_conv=True, out_channels=out_channels, padding=downsample_padding, name="op"
- )
- ]
- )
- else:
- self.downsamplers = None
-
- def forward(self, hidden_states: torch.FloatTensor, scale: float = 1.0) -> torch.FloatTensor:
- for resnet in self.resnets:
- hidden_states = resnet(hidden_states, temb=None, scale=scale)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, scale)
-
- return hidden_states
-
-
-class AttnDownEncoderBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- add_downsample: bool = True,
- downsample_padding: int = 1,
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `in_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=None,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=resnet_groups,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- Downsample2D(
- out_channels, use_conv=True, out_channels=out_channels, padding=downsample_padding, name="op"
- )
- ]
- )
- else:
- self.downsamplers = None
-
- def forward(self, hidden_states: torch.FloatTensor, scale: float = 1.0) -> torch.FloatTensor:
- for resnet, attn in zip(self.resnets, self.attentions):
- hidden_states = resnet(hidden_states, temb=None, scale=scale)
- cross_attention_kwargs = {"scale": scale}
- hidden_states = attn(hidden_states, **cross_attention_kwargs)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, scale)
-
- return hidden_states
-
-
-class AttnSkipDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = np.sqrt(2.0),
- add_downsample: bool = True,
- ):
- super().__init__()
- self.attentions = nn.ModuleList([])
- self.resnets = nn.ModuleList([])
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `in_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- self.resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(in_channels // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- self.attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=32,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- if add_downsample:
- self.resnet_down = ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- use_in_shortcut=True,
- down=True,
- kernel="fir",
- )
- self.downsamplers = nn.ModuleList([FirDownsample2D(out_channels, out_channels=out_channels)])
- self.skip_conv = nn.Conv2d(3, out_channels, kernel_size=(1, 1), stride=(1, 1))
- else:
- self.resnet_down = None
- self.downsamplers = None
- self.skip_conv = None
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- skip_sample: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...], torch.FloatTensor]:
- output_states = ()
-
- for resnet, attn in zip(self.resnets, self.attentions):
- hidden_states = resnet(hidden_states, temb, scale=scale)
- cross_attention_kwargs = {"scale": scale}
- hidden_states = attn(hidden_states, **cross_attention_kwargs)
- output_states += (hidden_states,)
-
- if self.downsamplers is not None:
- hidden_states = self.resnet_down(hidden_states, temb, scale=scale)
- for downsampler in self.downsamplers:
- skip_sample = downsampler(skip_sample)
-
- hidden_states = self.skip_conv(skip_sample) + hidden_states
-
- output_states += (hidden_states,)
-
- return hidden_states, output_states, skip_sample
-
-
-class SkipDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_pre_norm: bool = True,
- output_scale_factor: float = np.sqrt(2.0),
- add_downsample: bool = True,
- downsample_padding: int = 1,
- ):
- super().__init__()
- self.resnets = nn.ModuleList([])
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- self.resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(in_channels // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- if add_downsample:
- self.resnet_down = ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- use_in_shortcut=True,
- down=True,
- kernel="fir",
- )
- self.downsamplers = nn.ModuleList([FirDownsample2D(out_channels, out_channels=out_channels)])
- self.skip_conv = nn.Conv2d(3, out_channels, kernel_size=(1, 1), stride=(1, 1))
- else:
- self.resnet_down = None
- self.downsamplers = None
- self.skip_conv = None
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- skip_sample: Optional[torch.FloatTensor] = None,
- scale: float = 1.0,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...], torch.FloatTensor]:
- output_states = ()
-
- for resnet in self.resnets:
- hidden_states = resnet(hidden_states, temb, scale)
- output_states += (hidden_states,)
-
- if self.downsamplers is not None:
- hidden_states = self.resnet_down(hidden_states, temb, scale)
- for downsampler in self.downsamplers:
- skip_sample = downsampler(skip_sample)
-
- hidden_states = self.skip_conv(skip_sample) + hidden_states
-
- output_states += (hidden_states,)
-
- return hidden_states, output_states, skip_sample
-
-
-class ResnetDownsampleBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_downsample: bool = True,
- skip_time_act: bool = False,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- down=True,
- )
- ]
- )
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None, scale: float = 1.0
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
-
- for resnet in self.resnets:
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale)
-
- output_states = output_states + (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, temb, scale)
-
- output_states = output_states + (hidden_states,)
-
- return hidden_states, output_states
-
-
-class SimpleCrossAttnDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- cross_attention_dim: int = 1280,
- output_scale_factor: float = 1.0,
- add_downsample: bool = True,
- skip_time_act: bool = False,
- only_cross_attention: bool = False,
- cross_attention_norm: Optional[str] = None,
- ):
- super().__init__()
-
- self.has_cross_attention = True
-
- resnets = []
- attentions = []
-
- self.attention_head_dim = attention_head_dim
- self.num_heads = out_channels // self.attention_head_dim
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- )
-
- processor = (
- AttnAddedKVProcessor2_0() if hasattr(F, "scaled_dot_product_attention") else AttnAddedKVProcessor()
- )
-
- attentions.append(
- Attention(
- query_dim=out_channels,
- cross_attention_dim=out_channels,
- heads=self.num_heads,
- dim_head=attention_head_dim,
- added_kv_proj_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- bias=True,
- upcast_softmax=True,
- only_cross_attention=only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- processor=processor,
- )
- )
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- down=True,
- )
- ]
- )
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
- cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
-
- lora_scale = cross_attention_kwargs.get("scale", 1.0)
-
- if attention_mask is None:
- # if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
- mask = None if encoder_hidden_states is None else encoder_attention_mask
- else:
- # when attention_mask is defined: we don't even check for encoder_attention_mask.
- # this is to maintain compatibility with UnCLIP, which uses 'attention_mask' param for cross-attn masks.
- # TODO: UnCLIP should express cross-attn mask via encoder_attention_mask param instead of via attention_mask.
- # then we can simplify this whole if/else block to:
- # mask = attention_mask if encoder_hidden_states is None else encoder_attention_mask
- mask = attention_mask
-
- for resnet, attn in zip(self.resnets, self.attentions):
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=mask,
- **cross_attention_kwargs,
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
-
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=mask,
- **cross_attention_kwargs,
- )
-
- output_states = output_states + (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states, temb, scale=lora_scale)
-
- output_states = output_states + (hidden_states,)
-
- return hidden_states, output_states
-
-
-class KDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- dropout: float = 0.0,
- num_layers: int = 4,
- resnet_eps: float = 1e-5,
- resnet_act_fn: str = "gelu",
- resnet_group_size: int = 32,
- add_downsample: bool = False,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- groups = in_channels // resnet_group_size
- groups_out = out_channels // resnet_group_size
-
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- dropout=dropout,
- temb_channels=temb_channels,
- groups=groups,
- groups_out=groups_out,
- eps=resnet_eps,
- non_linearity=resnet_act_fn,
- time_embedding_norm="ada_group",
- conv_shortcut_bias=False,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_downsample:
- # YiYi's comments- might be able to use FirDownsample2D, look into details later
- self.downsamplers = nn.ModuleList([KDownsample2D()])
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None, scale: float = 1.0
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
-
- for resnet in self.resnets:
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale)
-
- output_states += (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states)
-
- return hidden_states, output_states
-
-
-class KCrossAttnDownBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- cross_attention_dim: int,
- dropout: float = 0.0,
- num_layers: int = 4,
- resnet_group_size: int = 32,
- add_downsample: bool = True,
- attention_head_dim: int = 64,
- add_self_attention: bool = False,
- resnet_eps: float = 1e-5,
- resnet_act_fn: str = "gelu",
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- self.has_cross_attention = True
-
- for i in range(num_layers):
- in_channels = in_channels if i == 0 else out_channels
- groups = in_channels // resnet_group_size
- groups_out = out_channels // resnet_group_size
-
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- dropout=dropout,
- temb_channels=temb_channels,
- groups=groups,
- groups_out=groups_out,
- eps=resnet_eps,
- non_linearity=resnet_act_fn,
- time_embedding_norm="ada_group",
- conv_shortcut_bias=False,
- )
- )
- attentions.append(
- KAttentionBlock(
- out_channels,
- out_channels // attention_head_dim,
- attention_head_dim,
- cross_attention_dim=cross_attention_dim,
- temb_channels=temb_channels,
- attention_bias=True,
- add_self_attention=add_self_attention,
- cross_attention_norm="layer_norm",
- group_size=resnet_group_size,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
- self.attentions = nn.ModuleList(attentions)
-
- if add_downsample:
- self.downsamplers = nn.ModuleList([KDownsample2D()])
- else:
- self.downsamplers = None
-
- self.gradient_checkpointing = False
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> Tuple[torch.FloatTensor, Tuple[torch.FloatTensor, ...]]:
- output_states = ()
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
-
- for resnet, attn in zip(self.resnets, self.attentions):
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet),
- hidden_states,
- temb,
- **ckpt_kwargs,
- )
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- emb=temb,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- emb=temb,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- )
-
- if self.downsamplers is None:
- output_states += (None,)
- else:
- output_states += (hidden_states,)
-
- if self.downsamplers is not None:
- for downsampler in self.downsamplers:
- hidden_states = downsampler(hidden_states)
-
- return hidden_states, output_states
-
-
-class AttnUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- prev_output_channel: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: int = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- upsample_type: str = "conv",
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- self.upsample_type = upsample_type
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `in_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=resnet_groups,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if upsample_type == "conv":
- self.upsamplers = nn.ModuleList([Upsample2D(out_channels, use_conv=True, out_channels=out_channels)])
- elif upsample_type == "resnet":
- self.upsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- up=True,
- )
- ]
- )
- else:
- self.upsamplers = None
-
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- for resnet, attn in zip(self.resnets, self.attentions):
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- hidden_states = resnet(hidden_states, temb, scale=scale)
- cross_attention_kwargs = {"scale": scale}
- hidden_states = attn(hidden_states, **cross_attention_kwargs)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- if self.upsample_type == "resnet":
- hidden_states = upsampler(hidden_states, temb=temb, scale=scale)
- else:
- hidden_states = upsampler(hidden_states, scale=scale)
-
- return hidden_states
-
-
-class CrossAttnUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- prev_output_channel: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- transformer_layers_per_block: Union[int, Tuple[int]] = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- num_attention_heads: int = 1,
- cross_attention_dim: int = 1280,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- only_cross_attention: bool = False,
- upcast_attention: bool = False,
- attention_type: str = "default",
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- self.has_cross_attention = True
- self.num_attention_heads = num_attention_heads
-
- if isinstance(transformer_layers_per_block, int):
- transformer_layers_per_block = [transformer_layers_per_block] * num_layers
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- if not dual_cross_attention:
- # Transformer2DModelWithSwitcher
- attentions.append(
- Transformer2DModel(
- num_attention_heads,
- out_channels // num_attention_heads,
- in_channels=out_channels,
- num_layers=transformer_layers_per_block[i],
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention,
- upcast_attention=upcast_attention,
- attention_type=attention_type,
- )
- )
- else:
- attentions.append(
- DualTransformer2DModel(
- num_attention_heads,
- out_channels // num_attention_heads,
- in_channels=out_channels,
- num_layers=1,
- cross_attention_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- )
- )
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([Upsample2D(out_channels, use_conv=True, out_channels=out_channels)])
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- upsample_size: Optional[int] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
- is_freeu_enabled = (
- getattr(self, "s1", None)
- and getattr(self, "s2", None)
- and getattr(self, "b1", None)
- and getattr(self, "b2", None)
- )
-
- for resnet, attn in zip(self.resnets, self.attentions):
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
-
- # FreeU: Only operate on the first two stages
- if is_freeu_enabled:
- hidden_states, res_hidden_states = apply_freeu(
- self.resolution_idx,
- hidden_states,
- res_hidden_states,
- s1=self.s1,
- s2=self.s2,
- b1=self.b1,
- b2=self.b2,
- )
-
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet),
- hidden_states,
- temb,
- **ckpt_kwargs,
- )
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- return_dict=False,
- )[0]
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states, upsample_size, scale=lora_scale)
-
- return hidden_states
-
-
-class UpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- prev_output_channel: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([Upsample2D(out_channels, use_conv=True, out_channels=out_channels)])
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- is_freeu_enabled = (
- getattr(self, "s1", None)
- and getattr(self, "s2", None)
- and getattr(self, "b1", None)
- and getattr(self, "b2", None)
- )
-
- for resnet in self.resnets:
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
-
- # FreeU: Only operate on the first two stages
- if is_freeu_enabled:
- hidden_states, res_hidden_states = apply_freeu(
- self.resolution_idx,
- hidden_states,
- res_hidden_states,
- s1=self.s1,
- s2=self.s2,
- b1=self.b1,
- b2=self.b2,
- )
-
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states, upsample_size, scale=scale)
-
- return hidden_states
-
-
-class UpDecoderBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default", # default, spatial
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- temb_channels: Optional[int] = None,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- input_channels = in_channels if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=input_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([Upsample2D(out_channels, use_conv=True, out_channels=out_channels)])
- else:
- self.upsamplers = None
-
- self.resolution_idx = resolution_idx
-
- def forward(
- self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None, scale: float = 1.0
- ) -> torch.FloatTensor:
- for resnet in self.resnets:
- hidden_states = resnet(hidden_states, temb=temb, scale=scale)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states)
-
- return hidden_states
-
-
-class AttnUpDecoderBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- temb_channels: Optional[int] = None,
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `out_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- for i in range(num_layers):
- input_channels = in_channels if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=input_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
- attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=resnet_groups if resnet_time_scale_shift != "spatial" else None,
- spatial_norm_dim=temb_channels if resnet_time_scale_shift == "spatial" else None,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([Upsample2D(out_channels, use_conv=True, out_channels=out_channels)])
- else:
- self.upsamplers = None
-
- self.resolution_idx = resolution_idx
-
- def forward(
- self, hidden_states: torch.FloatTensor, temb: Optional[torch.FloatTensor] = None, scale: float = 1.0
- ) -> torch.FloatTensor:
- for resnet, attn in zip(self.resnets, self.attentions):
- hidden_states = resnet(hidden_states, temb=temb, scale=scale)
- cross_attention_kwargs = {"scale": scale}
- hidden_states = attn(hidden_states, temb=temb, **cross_attention_kwargs)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states, scale=scale)
-
- return hidden_states
-
-
-class AttnSkipUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- prev_output_channel: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- output_scale_factor: float = np.sqrt(2.0),
- add_upsample: bool = True,
- ):
- super().__init__()
- self.attentions = nn.ModuleList([])
- self.resnets = nn.ModuleList([])
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- self.resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(resnet_in_channels + res_skip_channels // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- if attention_head_dim is None:
- logger.warn(
- f"It is not recommend to pass `attention_head_dim=None`. Defaulting `attention_head_dim` to `out_channels`: {out_channels}."
- )
- attention_head_dim = out_channels
-
- self.attentions.append(
- Attention(
- out_channels,
- heads=out_channels // attention_head_dim,
- dim_head=attention_head_dim,
- rescale_output_factor=output_scale_factor,
- eps=resnet_eps,
- norm_num_groups=32,
- residual_connection=True,
- bias=True,
- upcast_softmax=True,
- _from_deprecated_attn_block=True,
- )
- )
-
- self.upsampler = FirUpsample2D(in_channels, out_channels=out_channels)
- if add_upsample:
- self.resnet_up = ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(out_channels // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- use_in_shortcut=True,
- up=True,
- kernel="fir",
- )
- self.skip_conv = nn.Conv2d(out_channels, 3, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
- self.skip_norm = torch.nn.GroupNorm(
- num_groups=min(out_channels // 4, 32), num_channels=out_channels, eps=resnet_eps, affine=True
- )
- self.act = nn.SiLU()
- else:
- self.resnet_up = None
- self.skip_conv = None
- self.skip_norm = None
- self.act = None
-
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- skip_sample=None,
- scale: float = 1.0,
- ) -> Tuple[torch.FloatTensor, torch.FloatTensor]:
- for resnet in self.resnets:
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- cross_attention_kwargs = {"scale": scale}
- hidden_states = self.attentions[0](hidden_states, **cross_attention_kwargs)
-
- if skip_sample is not None:
- skip_sample = self.upsampler(skip_sample)
- else:
- skip_sample = 0
-
- if self.resnet_up is not None:
- skip_sample_states = self.skip_norm(hidden_states)
- skip_sample_states = self.act(skip_sample_states)
- skip_sample_states = self.skip_conv(skip_sample_states)
-
- skip_sample = skip_sample + skip_sample_states
-
- hidden_states = self.resnet_up(hidden_states, temb, scale=scale)
-
- return hidden_states, skip_sample
-
-
-class SkipUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- prev_output_channel: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_pre_norm: bool = True,
- output_scale_factor: float = np.sqrt(2.0),
- add_upsample: bool = True,
- upsample_padding: int = 1,
- ):
- super().__init__()
- self.resnets = nn.ModuleList([])
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- self.resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min((resnet_in_channels + res_skip_channels) // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- )
- )
-
- self.upsampler = FirUpsample2D(in_channels, out_channels=out_channels)
- if add_upsample:
- self.resnet_up = ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=min(out_channels // 4, 32),
- groups_out=min(out_channels // 4, 32),
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- use_in_shortcut=True,
- up=True,
- kernel="fir",
- )
- self.skip_conv = nn.Conv2d(out_channels, 3, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1))
- self.skip_norm = torch.nn.GroupNorm(
- num_groups=min(out_channels // 4, 32), num_channels=out_channels, eps=resnet_eps, affine=True
- )
- self.act = nn.SiLU()
- else:
- self.resnet_up = None
- self.skip_conv = None
- self.skip_norm = None
- self.act = None
-
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- skip_sample=None,
- scale: float = 1.0,
- ) -> Tuple[torch.FloatTensor, torch.FloatTensor]:
- for resnet in self.resnets:
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- if skip_sample is not None:
- skip_sample = self.upsampler(skip_sample)
- else:
- skip_sample = 0
-
- if self.resnet_up is not None:
- skip_sample_states = self.skip_norm(hidden_states)
- skip_sample_states = self.act(skip_sample_states)
- skip_sample_states = self.skip_conv(skip_sample_states)
-
- skip_sample = skip_sample + skip_sample_states
-
- hidden_states = self.resnet_up(hidden_states, temb, scale=scale)
-
- return hidden_states, skip_sample
-
-
-class ResnetUpsampleBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- prev_output_channel: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- skip_time_act: bool = False,
- ):
- super().__init__()
- resnets = []
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- up=True,
- )
- ]
- )
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- for resnet in self.resnets:
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states, temb, scale=scale)
-
- return hidden_states
-
-
-class SimpleCrossAttnUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- prev_output_channel: int,
- temb_channels: int,
- resolution_idx: Optional[int] = None,
- dropout: float = 0.0,
- num_layers: int = 1,
- resnet_eps: float = 1e-6,
- resnet_time_scale_shift: str = "default",
- resnet_act_fn: str = "swish",
- resnet_groups: int = 32,
- resnet_pre_norm: bool = True,
- attention_head_dim: int = 1,
- cross_attention_dim: int = 1280,
- output_scale_factor: float = 1.0,
- add_upsample: bool = True,
- skip_time_act: bool = False,
- only_cross_attention: bool = False,
- cross_attention_norm: Optional[str] = None,
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- self.has_cross_attention = True
- self.attention_head_dim = attention_head_dim
-
- self.num_heads = out_channels // self.attention_head_dim
-
- for i in range(num_layers):
- res_skip_channels = in_channels if (i == num_layers - 1) else out_channels
- resnet_in_channels = prev_output_channel if i == 0 else out_channels
-
- resnets.append(
- ResnetBlock2D(
- in_channels=resnet_in_channels + res_skip_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- )
- )
-
- processor = (
- AttnAddedKVProcessor2_0() if hasattr(F, "scaled_dot_product_attention") else AttnAddedKVProcessor()
- )
-
- attentions.append(
- Attention(
- query_dim=out_channels,
- cross_attention_dim=out_channels,
- heads=self.num_heads,
- dim_head=self.attention_head_dim,
- added_kv_proj_dim=cross_attention_dim,
- norm_num_groups=resnet_groups,
- bias=True,
- upcast_softmax=True,
- only_cross_attention=only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- processor=processor,
- )
- )
- self.attentions = nn.ModuleList(attentions)
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList(
- [
- ResnetBlock2D(
- in_channels=out_channels,
- out_channels=out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=resnet_groups,
- dropout=dropout,
- time_embedding_norm=resnet_time_scale_shift,
- non_linearity=resnet_act_fn,
- output_scale_factor=output_scale_factor,
- pre_norm=resnet_pre_norm,
- skip_time_act=skip_time_act,
- up=True,
- )
- ]
- )
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
-
- lora_scale = cross_attention_kwargs.get("scale", 1.0)
- if attention_mask is None:
- # if encoder_hidden_states is defined: we are doing cross-attn, so we should use cross-attn mask.
- mask = None if encoder_hidden_states is None else encoder_attention_mask
- else:
- # when attention_mask is defined: we don't even check for encoder_attention_mask.
- # this is to maintain compatibility with UnCLIP, which uses 'attention_mask' param for cross-attn masks.
- # TODO: UnCLIP should express cross-attn mask via encoder_attention_mask param instead of via attention_mask.
- # then we can simplify this whole if/else block to:
- # mask = attention_mask if encoder_hidden_states is None else encoder_attention_mask
- mask = attention_mask
-
- for resnet, attn in zip(self.resnets, self.attentions):
- # resnet
- # pop res hidden states
- res_hidden_states = res_hidden_states_tuple[-1]
- res_hidden_states_tuple = res_hidden_states_tuple[:-1]
- hidden_states = torch.cat([hidden_states, res_hidden_states], dim=1)
-
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- hidden_states = torch.utils.checkpoint.checkpoint(create_custom_forward(resnet), hidden_states, temb)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=mask,
- **cross_attention_kwargs,
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
-
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=mask,
- **cross_attention_kwargs,
- )
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states, temb, scale=lora_scale)
-
- return hidden_states
-
-
-class KUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: int,
- dropout: float = 0.0,
- num_layers: int = 5,
- resnet_eps: float = 1e-5,
- resnet_act_fn: str = "gelu",
- resnet_group_size: Optional[int] = 32,
- add_upsample: bool = True,
- ):
- super().__init__()
- resnets = []
- k_in_channels = 2 * out_channels
- k_out_channels = in_channels
- num_layers = num_layers - 1
-
- for i in range(num_layers):
- in_channels = k_in_channels if i == 0 else out_channels
- groups = in_channels // resnet_group_size
- groups_out = out_channels // resnet_group_size
-
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=k_out_channels if (i == num_layers - 1) else out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=groups,
- groups_out=groups_out,
- dropout=dropout,
- non_linearity=resnet_act_fn,
- time_embedding_norm="ada_group",
- conv_shortcut_bias=False,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([KUpsample2D()])
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- upsample_size: Optional[int] = None,
- scale: float = 1.0,
- ) -> torch.FloatTensor:
- res_hidden_states_tuple = res_hidden_states_tuple[-1]
- if res_hidden_states_tuple is not None:
- hidden_states = torch.cat([hidden_states, res_hidden_states_tuple], dim=1)
-
- for resnet in self.resnets:
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module):
- def custom_forward(*inputs):
- return module(*inputs)
-
- return custom_forward
-
- if is_torch_version(">=", "1.11.0"):
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb, use_reentrant=False
- )
- else:
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet), hidden_states, temb
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=scale)
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states)
-
- return hidden_states
-
-
-class KCrossAttnUpBlock2D(nn.Module):
- def __init__(
- self,
- in_channels: int,
- out_channels: int,
- temb_channels: int,
- resolution_idx: int,
- dropout: float = 0.0,
- num_layers: int = 4,
- resnet_eps: float = 1e-5,
- resnet_act_fn: str = "gelu",
- resnet_group_size: int = 32,
- attention_head_dim: int = 1, # attention dim_head
- cross_attention_dim: int = 768,
- add_upsample: bool = True,
- upcast_attention: bool = False,
- ):
- super().__init__()
- resnets = []
- attentions = []
-
- is_first_block = in_channels == out_channels == temb_channels
- is_middle_block = in_channels != out_channels
- add_self_attention = True if is_first_block else False
-
- self.has_cross_attention = True
- self.attention_head_dim = attention_head_dim
-
- # in_channels, and out_channels for the block (k-unet)
- k_in_channels = out_channels if is_first_block else 2 * out_channels
- k_out_channels = in_channels
-
- num_layers = num_layers - 1
-
- for i in range(num_layers):
- in_channels = k_in_channels if i == 0 else out_channels
- groups = in_channels // resnet_group_size
- groups_out = out_channels // resnet_group_size
-
- if is_middle_block and (i == num_layers - 1):
- conv_2d_out_channels = k_out_channels
- else:
- conv_2d_out_channels = None
-
- resnets.append(
- ResnetBlock2D(
- in_channels=in_channels,
- out_channels=out_channels,
- conv_2d_out_channels=conv_2d_out_channels,
- temb_channels=temb_channels,
- eps=resnet_eps,
- groups=groups,
- groups_out=groups_out,
- dropout=dropout,
- non_linearity=resnet_act_fn,
- time_embedding_norm="ada_group",
- conv_shortcut_bias=False,
- )
- )
- attentions.append(
- KAttentionBlock(
- k_out_channels if (i == num_layers - 1) else out_channels,
- k_out_channels // attention_head_dim
- if (i == num_layers - 1)
- else out_channels // attention_head_dim,
- attention_head_dim,
- cross_attention_dim=cross_attention_dim,
- temb_channels=temb_channels,
- attention_bias=True,
- add_self_attention=add_self_attention,
- cross_attention_norm="layer_norm",
- upcast_attention=upcast_attention,
- )
- )
-
- self.resnets = nn.ModuleList(resnets)
- self.attentions = nn.ModuleList(attentions)
-
- if add_upsample:
- self.upsamplers = nn.ModuleList([KUpsample2D()])
- else:
- self.upsamplers = None
-
- self.gradient_checkpointing = False
- self.resolution_idx = resolution_idx
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- res_hidden_states_tuple: Tuple[torch.FloatTensor, ...],
- temb: Optional[torch.FloatTensor] = None,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- upsample_size: Optional[int] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- res_hidden_states_tuple = res_hidden_states_tuple[-1]
- if res_hidden_states_tuple is not None:
- hidden_states = torch.cat([hidden_states, res_hidden_states_tuple], dim=1)
-
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
- for resnet, attn in zip(self.resnets, self.attentions):
- if self.training and self.gradient_checkpointing:
-
- def create_custom_forward(module, return_dict=None):
- def custom_forward(*inputs):
- if return_dict is not None:
- return module(*inputs, return_dict=return_dict)
- else:
- return module(*inputs)
-
- return custom_forward
-
- ckpt_kwargs: Dict[str, Any] = {"use_reentrant": False} if is_torch_version(">=", "1.11.0") else {}
- hidden_states = torch.utils.checkpoint.checkpoint(
- create_custom_forward(resnet),
- hidden_states,
- temb,
- **ckpt_kwargs,
- )
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- emb=temb,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- )
- else:
- hidden_states = resnet(hidden_states, temb, scale=lora_scale)
- hidden_states = attn(
- hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- emb=temb,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- )
-
- if self.upsamplers is not None:
- for upsampler in self.upsamplers:
- hidden_states = upsampler(hidden_states)
-
- return hidden_states
-
-
-# can potentially later be renamed to `No-feed-forward` attention
-class KAttentionBlock(nn.Module):
- r"""
- A basic Transformer block.
-
- Parameters:
- dim (`int`): The number of channels in the input and output.
- num_attention_heads (`int`): The number of heads to use for multi-head attention.
- attention_head_dim (`int`): The number of channels in each head.
- dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
- cross_attention_dim (`int`, *optional*): The size of the encoder_hidden_states vector for cross attention.
- attention_bias (`bool`, *optional*, defaults to `False`):
- Configure if the attention layers should contain a bias parameter.
- upcast_attention (`bool`, *optional*, defaults to `False`):
- Set to `True` to upcast the attention computation to `float32`.
- temb_channels (`int`, *optional*, defaults to 768):
- The number of channels in the token embedding.
- add_self_attention (`bool`, *optional*, defaults to `False`):
- Set to `True` to add self-attention to the block.
- cross_attention_norm (`str`, *optional*, defaults to `None`):
- The type of normalization to use for the cross attention. Can be `None`, `layer_norm`, or `group_norm`.
- group_size (`int`, *optional*, defaults to 32):
- The number of groups to separate the channels into for group normalization.
- """
-
- def __init__(
- self,
- dim: int,
- num_attention_heads: int,
- attention_head_dim: int,
- dropout: float = 0.0,
- cross_attention_dim: Optional[int] = None,
- attention_bias: bool = False,
- upcast_attention: bool = False,
- temb_channels: int = 768, # for ada_group_norm
- add_self_attention: bool = False,
- cross_attention_norm: Optional[str] = None,
- group_size: int = 32,
- ):
- super().__init__()
- self.add_self_attention = add_self_attention
-
- # 1. Self-Attn
- if add_self_attention:
- self.norm1 = AdaGroupNorm(temb_channels, dim, max(1, dim // group_size))
- self.attn1 = Attention(
- query_dim=dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- cross_attention_dim=None,
- cross_attention_norm=None,
- )
-
- # 2. Cross-Attn
- self.norm2 = AdaGroupNorm(temb_channels, dim, max(1, dim // group_size))
- self.attn2 = Attention(
- query_dim=dim,
- cross_attention_dim=cross_attention_dim,
- heads=num_attention_heads,
- dim_head=attention_head_dim,
- dropout=dropout,
- bias=attention_bias,
- upcast_attention=upcast_attention,
- cross_attention_norm=cross_attention_norm,
- )
-
- def _to_3d(self, hidden_states: torch.FloatTensor, height: int, weight: int) -> torch.FloatTensor:
- return hidden_states.permute(0, 2, 3, 1).reshape(hidden_states.shape[0], height * weight, -1)
-
- def _to_4d(self, hidden_states: torch.FloatTensor, height: int, weight: int) -> torch.FloatTensor:
- return hidden_states.permute(0, 2, 1).reshape(hidden_states.shape[0], -1, height, weight)
-
- def forward(
- self,
- hidden_states: torch.FloatTensor,
- encoder_hidden_states: Optional[torch.FloatTensor] = None,
- # TODO: mark emb as non-optional (self.norm2 requires it).
- # requires assessing impact of change to positional param interface.
- emb: Optional[torch.FloatTensor] = None,
- attention_mask: Optional[torch.FloatTensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- encoder_attention_mask: Optional[torch.FloatTensor] = None,
- ) -> torch.FloatTensor:
- cross_attention_kwargs = cross_attention_kwargs if cross_attention_kwargs is not None else {}
-
- # 1. Self-Attention
- if self.add_self_attention:
- norm_hidden_states = self.norm1(hidden_states, emb)
-
- height, weight = norm_hidden_states.shape[2:]
- norm_hidden_states = self._to_3d(norm_hidden_states, height, weight)
-
- attn_output = self.attn1(
- norm_hidden_states,
- encoder_hidden_states=None,
- attention_mask=attention_mask,
- **cross_attention_kwargs,
- )
- attn_output = self._to_4d(attn_output, height, weight)
-
- hidden_states = attn_output + hidden_states
-
- # 2. Cross-Attention/None
- norm_hidden_states = self.norm2(hidden_states, emb)
-
- height, weight = norm_hidden_states.shape[2:]
- norm_hidden_states = self._to_3d(norm_hidden_states, height, weight)
- attn_output = self.attn2(
- norm_hidden_states,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=attention_mask if encoder_hidden_states is None else encoder_attention_mask,
- **cross_attention_kwargs,
- )
- attn_output = self._to_4d(attn_output, height, weight)
-
- hidden_states = attn_output + hidden_states
-
- return hidden_states
diff --git a/foleycrafter/models/auffusion_unet.py b/foleycrafter/models/auffusion_unet.py
deleted file mode 100644
index dc40827..0000000
--- a/foleycrafter/models/auffusion_unet.py
+++ /dev/null
@@ -1,1257 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-from dataclasses import dataclass
-from typing import Any, Dict, List, Optional, Tuple, Union
-
-import torch
-import torch.nn as nn
-import torch.utils.checkpoint
-
-from diffusers.configuration_utils import ConfigMixin, register_to_config
-from diffusers.models.activations import get_activation
-
-# from diffusers import StableDiffusionGLIGENPipeline
-from diffusers.models.attention_processor import (
- ADDED_KV_ATTENTION_PROCESSORS,
- CROSS_ATTENTION_PROCESSORS,
- Attention,
- AttentionProcessor,
- AttnAddedKVProcessor,
- AttnProcessor,
- XFormersAttnProcessor,
-)
-from diffusers.models.embeddings import (
- GaussianFourierProjection,
- ImageHintTimeEmbedding,
- ImageProjection,
- ImageTimeEmbedding,
- TextImageProjection,
- TextImageTimeEmbedding,
- TextTimeEmbedding,
- TimestepEmbedding,
- Timesteps,
-)
-from diffusers.models.modeling_utils import ModelMixin
-from diffusers.utils import USE_PEFT_BACKEND, BaseOutput, deprecate, logging, scale_lora_layers, unscale_lora_layers
-from diffusers.utils.import_utils import is_xformers_available
-from foleycrafter.models.adapters.ip_adapter import TimeProjModel
-from foleycrafter.models.auffusion.attention_processor import AttnProcessor2_0
-from foleycrafter.models.auffusion.loaders.unet import UNet2DConditionLoadersMixin
-from foleycrafter.models.auffusion.unet_2d_blocks import (
- UNetMidBlock2D,
- UNetMidBlock2DCrossAttn,
- UNetMidBlock2DSimpleCrossAttn,
- get_down_block,
- get_up_block,
-)
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-@dataclass
-class UNet2DConditionOutput(BaseOutput):
- """
- The output of [`UNet2DConditionModel`].
-
- Args:
- sample (`torch.FloatTensor` of shape `(batch_size, num_channels, height, width)`):
- The hidden states output conditioned on `encoder_hidden_states` input. Output of last layer of model.
- """
-
- sample: torch.FloatTensor = None
-
-
-class UNet2DConditionModel(ModelMixin, ConfigMixin, UNet2DConditionLoadersMixin):
- r"""
- A conditional 2D UNet model that takes a noisy sample, conditional state, and a timestep and returns a sample
- shaped output.
-
- This model inherits from [`ModelMixin`]. Check the superclass documentation for it's generic methods implemented
- for all models (such as downloading or saving).
-
- Parameters:
- sample_size (`int` or `Tuple[int, int]`, *optional*, defaults to `None`):
- Height and width of input/output sample.
- in_channels (`int`, *optional*, defaults to 4): Number of channels in the input sample.
- out_channels (`int`, *optional*, defaults to 4): Number of channels in the output.
- center_input_sample (`bool`, *optional*, defaults to `False`): Whether to center the input sample.
- flip_sin_to_cos (`bool`, *optional*, defaults to `False`):
- Whether to flip the sin to cos in the time embedding.
- freq_shift (`int`, *optional*, defaults to 0): The frequency shift to apply to the time embedding.
- down_block_types (`Tuple[str]`, *optional*, defaults to `("CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "CrossAttnDownBlock2D", "DownBlock2D")`):
- The tuple of downsample blocks to use.
- mid_block_type (`str`, *optional*, defaults to `"UNetMidBlock2DCrossAttn"`):
- Block type for middle of UNet, it can be one of `UNetMidBlock2DCrossAttn`, `UNetMidBlock2D`, or
- `UNetMidBlock2DSimpleCrossAttn`. If `None`, the mid block layer is skipped.
- up_block_types (`Tuple[str]`, *optional*, defaults to `("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D")`):
- The tuple of upsample blocks to use.
- only_cross_attention(`bool` or `Tuple[bool]`, *optional*, default to `False`):
- Whether to include self-attention in the basic transformer blocks, see
- [`~models.attention.BasicTransformerBlock`].
- block_out_channels (`Tuple[int]`, *optional*, defaults to `(320, 640, 1280, 1280)`):
- The tuple of output channels for each block.
- layers_per_block (`int`, *optional*, defaults to 2): The number of layers per block.
- downsample_padding (`int`, *optional*, defaults to 1): The padding to use for the downsampling convolution.
- mid_block_scale_factor (`float`, *optional*, defaults to 1.0): The scale factor to use for the mid block.
- dropout (`float`, *optional*, defaults to 0.0): The dropout probability to use.
- act_fn (`str`, *optional*, defaults to `"silu"`): The activation function to use.
- norm_num_groups (`int`, *optional*, defaults to 32): The number of groups to use for the normalization.
- If `None`, normalization and activation layers is skipped in post-processing.
- norm_eps (`float`, *optional*, defaults to 1e-5): The epsilon to use for the normalization.
- cross_attention_dim (`int` or `Tuple[int]`, *optional*, defaults to 1280):
- The dimension of the cross attention features.
- transformer_layers_per_block (`int`, `Tuple[int]`, or `Tuple[Tuple]` , *optional*, defaults to 1):
- The number of transformer blocks of type [`~models.attention.BasicTransformerBlock`]. Only relevant for
- [`~models.unet_2d_blocks.CrossAttnDownBlock2D`], [`~models.unet_2d_blocks.CrossAttnUpBlock2D`],
- [`~models.unet_2d_blocks.UNetMidBlock2DCrossAttn`].
- reverse_transformer_layers_per_block : (`Tuple[Tuple]`, *optional*, defaults to None):
- The number of transformer blocks of type [`~models.attention.BasicTransformerBlock`], in the upsampling
- blocks of the U-Net. Only relevant if `transformer_layers_per_block` is of type `Tuple[Tuple]` and for
- [`~models.unet_2d_blocks.CrossAttnDownBlock2D`], [`~models.unet_2d_blocks.CrossAttnUpBlock2D`],
- [`~models.unet_2d_blocks.UNetMidBlock2DCrossAttn`].
- encoder_hid_dim (`int`, *optional*, defaults to None):
- If `encoder_hid_dim_type` is defined, `encoder_hidden_states` will be projected from `encoder_hid_dim`
- dimension to `cross_attention_dim`.
- encoder_hid_dim_type (`str`, *optional*, defaults to `None`):
- If given, the `encoder_hidden_states` and potentially other embeddings are down-projected to text
- embeddings of dimension `cross_attention` according to `encoder_hid_dim_type`.
- attention_head_dim (`int`, *optional*, defaults to 8): The dimension of the attention heads.
- num_attention_heads (`int`, *optional*):
- The number of attention heads. If not defined, defaults to `attention_head_dim`
- resnet_time_scale_shift (`str`, *optional*, defaults to `"default"`): Time scale shift config
- for ResNet blocks (see [`~models.resnet.ResnetBlock2D`]). Choose from `default` or `scale_shift`.
- class_embed_type (`str`, *optional*, defaults to `None`):
- The type of class embedding to use which is ultimately summed with the time embeddings. Choose from `None`,
- `"timestep"`, `"identity"`, `"projection"`, or `"simple_projection"`.
- addition_embed_type (`str`, *optional*, defaults to `None`):
- Configures an optional embedding which will be summed with the time embeddings. Choose from `None` or
- "text". "text" will use the `TextTimeEmbedding` layer.
- addition_time_embed_dim: (`int`, *optional*, defaults to `None`):
- Dimension for the timestep embeddings.
- num_class_embeds (`int`, *optional*, defaults to `None`):
- Input dimension of the learnable embedding matrix to be projected to `time_embed_dim`, when performing
- class conditioning with `class_embed_type` equal to `None`.
- time_embedding_type (`str`, *optional*, defaults to `positional`):
- The type of position embedding to use for timesteps. Choose from `positional` or `fourier`.
- time_embedding_dim (`int`, *optional*, defaults to `None`):
- An optional override for the dimension of the projected time embedding.
- time_embedding_act_fn (`str`, *optional*, defaults to `None`):
- Optional activation function to use only once on the time embeddings before they are passed to the rest of
- the UNet. Choose from `silu`, `mish`, `gelu`, and `swish`.
- timestep_post_act (`str`, *optional*, defaults to `None`):
- The second activation function to use in timestep embedding. Choose from `silu`, `mish` and `gelu`.
- time_cond_proj_dim (`int`, *optional*, defaults to `None`):
- The dimension of `cond_proj` layer in the timestep embedding.
- conv_in_kernel (`int`, *optional*, default to `3`): The kernel size of `conv_in` layer. conv_out_kernel (`int`,
- *optional*, default to `3`): The kernel size of `conv_out` layer. projection_class_embeddings_input_dim (`int`,
- *optional*): The dimension of the `class_labels` input when
- `class_embed_type="projection"`. Required when `class_embed_type="projection"`.
- class_embeddings_concat (`bool`, *optional*, defaults to `False`): Whether to concatenate the time
- embeddings with the class embeddings.
- mid_block_only_cross_attention (`bool`, *optional*, defaults to `None`):
- Whether to use cross attention with the mid block when using the `UNetMidBlock2DSimpleCrossAttn`. If
- `only_cross_attention` is given as a single boolean and `mid_block_only_cross_attention` is `None`, the
- `only_cross_attention` value is used as the value for `mid_block_only_cross_attention`. Default to `False`
- otherwise.
- """
-
- _supports_gradient_checkpointing = True
-
- @register_to_config
- def __init__(
- self,
- sample_size: Optional[int] = None,
- in_channels: int = 4,
- out_channels: int = 4,
- center_input_sample: bool = False,
- flip_sin_to_cos: bool = True,
- freq_shift: int = 0,
- down_block_types: Tuple[str] = (
- "CrossAttnDownBlock2D",
- "CrossAttnDownBlock2D",
- "CrossAttnDownBlock2D",
- "DownBlock2D",
- ),
- mid_block_type: Optional[str] = "UNetMidBlock2DCrossAttn",
- up_block_types: Tuple[str] = ("UpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D", "CrossAttnUpBlock2D"),
- only_cross_attention: Union[bool, Tuple[bool]] = False,
- block_out_channels: Tuple[int] = (320, 640, 1280, 1280),
- layers_per_block: Union[int, Tuple[int]] = 2,
- downsample_padding: int = 1,
- mid_block_scale_factor: float = 1,
- dropout: float = 0.0,
- act_fn: str = "silu",
- norm_num_groups: Optional[int] = 32,
- norm_eps: float = 1e-5,
- cross_attention_dim: Union[int, Tuple[int]] = 1280,
- transformer_layers_per_block: Union[int, Tuple[int], Tuple[Tuple]] = 1,
- reverse_transformer_layers_per_block: Optional[Tuple[Tuple[int]]] = None,
- encoder_hid_dim: Optional[int] = None,
- encoder_hid_dim_type: Optional[str] = None,
- attention_head_dim: Union[int, Tuple[int]] = 8,
- num_attention_heads: Optional[Union[int, Tuple[int]]] = None,
- dual_cross_attention: bool = False,
- use_linear_projection: bool = False,
- class_embed_type: Optional[str] = None,
- addition_embed_type: Optional[str] = None,
- addition_time_embed_dim: Optional[int] = None,
- num_class_embeds: Optional[int] = None,
- upcast_attention: bool = False,
- resnet_time_scale_shift: str = "default",
- resnet_skip_time_act: bool = False,
- resnet_out_scale_factor: int = 1.0,
- time_embedding_type: str = "positional",
- time_embedding_dim: Optional[int] = None,
- time_embedding_act_fn: Optional[str] = None,
- timestep_post_act: Optional[str] = None,
- time_cond_proj_dim: Optional[int] = None,
- conv_in_kernel: int = 3,
- conv_out_kernel: int = 3,
- projection_class_embeddings_input_dim: Optional[int] = None,
- attention_type: str = "default",
- class_embeddings_concat: bool = False,
- mid_block_only_cross_attention: Optional[bool] = None,
- cross_attention_norm: Optional[str] = None,
- addition_embed_type_num_heads=64,
- # param for joint
- video_feature_dim: tuple = (320, 640, 1280, 1280),
- video_cross_attn_dim: int = 1024,
- video_frame_nums: int = 16,
- ):
- super().__init__()
-
- self.sample_size = sample_size
-
- if num_attention_heads is not None:
- raise ValueError(
- "At the moment it is not possible to define the number of attention heads via `num_attention_heads` because of a naming issue as described in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131. Passing `num_attention_heads` will only be supported in diffusers v0.19."
- )
-
- # If `num_attention_heads` is not defined (which is the case for most models)
- # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.
- # The reason for this behavior is to correct for incorrectly named variables that were introduced
- # when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131
- # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking
- # which is why we correct for the naming here.
- num_attention_heads = num_attention_heads or attention_head_dim
-
- # Check inputs
- if len(down_block_types) != len(up_block_types):
- raise ValueError(
- f"Must provide the same number of `down_block_types` as `up_block_types`. `down_block_types`: {down_block_types}. `up_block_types`: {up_block_types}."
- )
-
- if len(block_out_channels) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `block_out_channels` as `down_block_types`. `block_out_channels`: {block_out_channels}. `down_block_types`: {down_block_types}."
- )
-
- if not isinstance(only_cross_attention, bool) and len(only_cross_attention) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `only_cross_attention` as `down_block_types`. `only_cross_attention`: {only_cross_attention}. `down_block_types`: {down_block_types}."
- )
-
- if not isinstance(num_attention_heads, int) and len(num_attention_heads) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `num_attention_heads` as `down_block_types`. `num_attention_heads`: {num_attention_heads}. `down_block_types`: {down_block_types}."
- )
-
- if not isinstance(attention_head_dim, int) and len(attention_head_dim) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `attention_head_dim` as `down_block_types`. `attention_head_dim`: {attention_head_dim}. `down_block_types`: {down_block_types}."
- )
-
- if isinstance(cross_attention_dim, list) and len(cross_attention_dim) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `cross_attention_dim` as `down_block_types`. `cross_attention_dim`: {cross_attention_dim}. `down_block_types`: {down_block_types}."
- )
-
- if not isinstance(layers_per_block, int) and len(layers_per_block) != len(down_block_types):
- raise ValueError(
- f"Must provide the same number of `layers_per_block` as `down_block_types`. `layers_per_block`: {layers_per_block}. `down_block_types`: {down_block_types}."
- )
- if isinstance(transformer_layers_per_block, list) and reverse_transformer_layers_per_block is None:
- for layer_number_per_block in transformer_layers_per_block:
- if isinstance(layer_number_per_block, list):
- raise ValueError("Must provide 'reverse_transformer_layers_per_block` if using asymmetrical UNet.")
-
- # input
- conv_in_padding = (conv_in_kernel - 1) // 2
- self.conv_in = nn.Conv2d(
- in_channels, block_out_channels[0], kernel_size=conv_in_kernel, padding=conv_in_padding
- )
-
- # time
- if time_embedding_type == "fourier":
- time_embed_dim = time_embedding_dim or block_out_channels[0] * 2
- if time_embed_dim % 2 != 0:
- raise ValueError(f"`time_embed_dim` should be divisible by 2, but is {time_embed_dim}.")
- self.time_proj = GaussianFourierProjection(
- time_embed_dim // 2, set_W_to_weight=False, log=False, flip_sin_to_cos=flip_sin_to_cos
- )
- timestep_input_dim = time_embed_dim
- elif time_embedding_type == "positional":
- time_embed_dim = time_embedding_dim or block_out_channels[0] * 4
-
- self.time_proj = Timesteps(block_out_channels[0], flip_sin_to_cos, freq_shift)
- timestep_input_dim = block_out_channels[0]
- else:
- raise ValueError(
- f"{time_embedding_type} does not exist. Please make sure to use one of `fourier` or `positional`."
- )
-
- self.time_embedding = TimestepEmbedding(
- timestep_input_dim,
- time_embed_dim,
- act_fn=act_fn,
- post_act_fn=timestep_post_act,
- cond_proj_dim=time_cond_proj_dim,
- )
-
- if encoder_hid_dim_type is None and encoder_hid_dim is not None:
- encoder_hid_dim_type = "text_proj"
- self.register_to_config(encoder_hid_dim_type=encoder_hid_dim_type)
- logger.info("encoder_hid_dim_type defaults to 'text_proj' as `encoder_hid_dim` is defined.")
-
- if encoder_hid_dim is None and encoder_hid_dim_type is not None:
- raise ValueError(
- f"`encoder_hid_dim` has to be defined when `encoder_hid_dim_type` is set to {encoder_hid_dim_type}."
- )
-
- if encoder_hid_dim_type == "text_proj":
- self.encoder_hid_proj = nn.Linear(encoder_hid_dim, cross_attention_dim)
- elif encoder_hid_dim_type == "text_image_proj":
- # image_embed_dim DOESN'T have to be `cross_attention_dim`. To not clutter the __init__ too much
- # they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
- # case when `addition_embed_type == "text_image_proj"` (Kadinsky 2.1)`
- self.encoder_hid_proj = TextImageProjection(
- text_embed_dim=encoder_hid_dim,
- image_embed_dim=cross_attention_dim,
- cross_attention_dim=cross_attention_dim,
- )
- elif encoder_hid_dim_type == "image_proj":
- # Kandinsky 2.2
- self.encoder_hid_proj = ImageProjection(
- image_embed_dim=encoder_hid_dim,
- cross_attention_dim=cross_attention_dim,
- )
- elif encoder_hid_dim_type is not None:
- raise ValueError(
- f"encoder_hid_dim_type: {encoder_hid_dim_type} must be None, 'text_proj' or 'text_image_proj'."
- )
- else:
- self.encoder_hid_proj = None
-
- # class embedding
- if class_embed_type is None and num_class_embeds is not None:
- self.class_embedding = nn.Embedding(num_class_embeds, time_embed_dim)
- elif class_embed_type == "timestep":
- self.class_embedding = TimestepEmbedding(timestep_input_dim, time_embed_dim, act_fn=act_fn)
- elif class_embed_type == "identity":
- self.class_embedding = nn.Identity(time_embed_dim, time_embed_dim)
- elif class_embed_type == "projection":
- if projection_class_embeddings_input_dim is None:
- raise ValueError(
- "`class_embed_type`: 'projection' requires `projection_class_embeddings_input_dim` be set"
- )
- # The projection `class_embed_type` is the same as the timestep `class_embed_type` except
- # 1. the `class_labels` inputs are not first converted to sinusoidal embeddings
- # 2. it projects from an arbitrary input dimension.
- #
- # Note that `TimestepEmbedding` is quite general, being mainly linear layers and activations.
- # When used for embedding actual timesteps, the timesteps are first converted to sinusoidal embeddings.
- # As a result, `TimestepEmbedding` can be passed arbitrary vectors.
- self.class_embedding = TimestepEmbedding(projection_class_embeddings_input_dim, time_embed_dim)
- elif class_embed_type == "simple_projection":
- if projection_class_embeddings_input_dim is None:
- raise ValueError(
- "`class_embed_type`: 'simple_projection' requires `projection_class_embeddings_input_dim` be set"
- )
- self.class_embedding = nn.Linear(projection_class_embeddings_input_dim, time_embed_dim)
- else:
- self.class_embedding = None
-
- if addition_embed_type == "text":
- if encoder_hid_dim is not None:
- text_time_embedding_from_dim = encoder_hid_dim
- else:
- text_time_embedding_from_dim = cross_attention_dim
-
- self.add_embedding = TextTimeEmbedding(
- text_time_embedding_from_dim, time_embed_dim, num_heads=addition_embed_type_num_heads
- )
- elif addition_embed_type == "text_image":
- # text_embed_dim and image_embed_dim DON'T have to be `cross_attention_dim`. To not clutter the __init__ too much
- # they are set to `cross_attention_dim` here as this is exactly the required dimension for the currently only use
- # case when `addition_embed_type == "text_image"` (Kadinsky 2.1)`
- self.add_embedding = TextImageTimeEmbedding(
- text_embed_dim=cross_attention_dim, image_embed_dim=cross_attention_dim, time_embed_dim=time_embed_dim
- )
- elif addition_embed_type == "text_time":
- self.add_time_proj = Timesteps(addition_time_embed_dim, flip_sin_to_cos, freq_shift)
- self.add_embedding = TimestepEmbedding(projection_class_embeddings_input_dim, time_embed_dim)
- elif addition_embed_type == "image":
- # Kandinsky 2.2
- self.add_embedding = ImageTimeEmbedding(image_embed_dim=encoder_hid_dim, time_embed_dim=time_embed_dim)
- elif addition_embed_type == "image_hint":
- # Kandinsky 2.2 ControlNet
- self.add_embedding = ImageHintTimeEmbedding(image_embed_dim=encoder_hid_dim, time_embed_dim=time_embed_dim)
- elif addition_embed_type is not None:
- raise ValueError(f"addition_embed_type: {addition_embed_type} must be None, 'text' or 'text_image'.")
-
- if time_embedding_act_fn is None:
- self.time_embed_act = None
- else:
- self.time_embed_act = get_activation(time_embedding_act_fn)
-
- self.down_blocks = nn.ModuleList([])
- self.up_blocks = nn.ModuleList([])
-
- if isinstance(only_cross_attention, bool):
- if mid_block_only_cross_attention is None:
- mid_block_only_cross_attention = only_cross_attention
-
- only_cross_attention = [only_cross_attention] * len(down_block_types)
-
- if mid_block_only_cross_attention is None:
- mid_block_only_cross_attention = False
-
- if isinstance(num_attention_heads, int):
- num_attention_heads = (num_attention_heads,) * len(down_block_types)
-
- if isinstance(attention_head_dim, int):
- attention_head_dim = (attention_head_dim,) * len(down_block_types)
-
- if isinstance(cross_attention_dim, int):
- cross_attention_dim = (cross_attention_dim,) * len(down_block_types)
-
- if isinstance(layers_per_block, int):
- layers_per_block = [layers_per_block] * len(down_block_types)
-
- if isinstance(transformer_layers_per_block, int):
- transformer_layers_per_block = [transformer_layers_per_block] * len(down_block_types)
-
- if class_embeddings_concat:
- # The time embeddings are concatenated with the class embeddings. The dimension of the
- # time embeddings passed to the down, middle, and up blocks is twice the dimension of the
- # regular time embeddings
- blocks_time_embed_dim = time_embed_dim * 2
- else:
- blocks_time_embed_dim = time_embed_dim
-
- # down
- output_channel = block_out_channels[0]
- for i, down_block_type in enumerate(down_block_types):
- input_channel = output_channel
- output_channel = block_out_channels[i]
- is_final_block = i == len(block_out_channels) - 1
-
- down_block = get_down_block(
- down_block_type,
- num_layers=layers_per_block[i],
- transformer_layers_per_block=transformer_layers_per_block[i],
- in_channels=input_channel,
- out_channels=output_channel,
- temb_channels=blocks_time_embed_dim,
- add_downsample=not is_final_block,
- resnet_eps=norm_eps,
- resnet_act_fn=act_fn,
- resnet_groups=norm_num_groups,
- cross_attention_dim=cross_attention_dim[i],
- num_attention_heads=num_attention_heads[i],
- downsample_padding=downsample_padding,
- dual_cross_attention=dual_cross_attention,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention[i],
- upcast_attention=upcast_attention,
- resnet_time_scale_shift=resnet_time_scale_shift,
- attention_type=attention_type,
- resnet_skip_time_act=resnet_skip_time_act,
- resnet_out_scale_factor=resnet_out_scale_factor,
- cross_attention_norm=cross_attention_norm,
- attention_head_dim=attention_head_dim[i] if attention_head_dim[i] is not None else output_channel,
- dropout=dropout,
- )
- self.down_blocks.append(down_block)
-
- # mid
- if mid_block_type == "UNetMidBlock2DCrossAttn":
- self.mid_block = UNetMidBlock2DCrossAttn(
- transformer_layers_per_block=transformer_layers_per_block[-1],
- in_channels=block_out_channels[-1],
- temb_channels=blocks_time_embed_dim,
- dropout=dropout,
- resnet_eps=norm_eps,
- resnet_act_fn=act_fn,
- output_scale_factor=mid_block_scale_factor,
- resnet_time_scale_shift=resnet_time_scale_shift,
- cross_attention_dim=cross_attention_dim[-1],
- num_attention_heads=num_attention_heads[-1],
- resnet_groups=norm_num_groups,
- dual_cross_attention=dual_cross_attention,
- use_linear_projection=use_linear_projection,
- upcast_attention=upcast_attention,
- attention_type=attention_type,
- )
- elif mid_block_type == "UNetMidBlock2DSimpleCrossAttn":
- self.mid_block = UNetMidBlock2DSimpleCrossAttn(
- in_channels=block_out_channels[-1],
- temb_channels=blocks_time_embed_dim,
- dropout=dropout,
- resnet_eps=norm_eps,
- resnet_act_fn=act_fn,
- output_scale_factor=mid_block_scale_factor,
- cross_attention_dim=cross_attention_dim[-1],
- attention_head_dim=attention_head_dim[-1],
- resnet_groups=norm_num_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- skip_time_act=resnet_skip_time_act,
- only_cross_attention=mid_block_only_cross_attention,
- cross_attention_norm=cross_attention_norm,
- )
- elif mid_block_type == "UNetMidBlock2D":
- self.mid_block = UNetMidBlock2D(
- in_channels=block_out_channels[-1],
- temb_channels=blocks_time_embed_dim,
- dropout=dropout,
- num_layers=0,
- resnet_eps=norm_eps,
- resnet_act_fn=act_fn,
- output_scale_factor=mid_block_scale_factor,
- resnet_groups=norm_num_groups,
- resnet_time_scale_shift=resnet_time_scale_shift,
- add_attention=False,
- )
- elif mid_block_type is None:
- self.mid_block = None
- else:
- raise ValueError(f"unknown mid_block_type : {mid_block_type}")
-
- # count how many layers upsample the images
- self.num_upsamplers = 0
-
- # up
- reversed_block_out_channels = list(reversed(block_out_channels))
- reversed_num_attention_heads = list(reversed(num_attention_heads))
- reversed_layers_per_block = list(reversed(layers_per_block))
- reversed_cross_attention_dim = list(reversed(cross_attention_dim))
- reversed_transformer_layers_per_block = (
- list(reversed(transformer_layers_per_block))
- if reverse_transformer_layers_per_block is None
- else reverse_transformer_layers_per_block
- )
- only_cross_attention = list(reversed(only_cross_attention))
-
- output_channel = reversed_block_out_channels[0]
- for i, up_block_type in enumerate(up_block_types):
- is_final_block = i == len(block_out_channels) - 1
-
- prev_output_channel = output_channel
- output_channel = reversed_block_out_channels[i]
- input_channel = reversed_block_out_channels[min(i + 1, len(block_out_channels) - 1)]
-
- # add upsample block for all BUT final layer
- if not is_final_block:
- add_upsample = True
- self.num_upsamplers += 1
- else:
- add_upsample = False
-
- up_block = get_up_block(
- up_block_type,
- num_layers=reversed_layers_per_block[i] + 1,
- transformer_layers_per_block=reversed_transformer_layers_per_block[i],
- in_channels=input_channel,
- out_channels=output_channel,
- prev_output_channel=prev_output_channel,
- temb_channels=blocks_time_embed_dim,
- add_upsample=add_upsample,
- resnet_eps=norm_eps,
- resnet_act_fn=act_fn,
- resolution_idx=i,
- resnet_groups=norm_num_groups,
- cross_attention_dim=reversed_cross_attention_dim[i],
- num_attention_heads=reversed_num_attention_heads[i],
- dual_cross_attention=dual_cross_attention,
- use_linear_projection=use_linear_projection,
- only_cross_attention=only_cross_attention[i],
- upcast_attention=upcast_attention,
- resnet_time_scale_shift=resnet_time_scale_shift,
- attention_type=attention_type,
- resnet_skip_time_act=resnet_skip_time_act,
- resnet_out_scale_factor=resnet_out_scale_factor,
- cross_attention_norm=cross_attention_norm,
- attention_head_dim=attention_head_dim[i] if attention_head_dim[i] is not None else output_channel,
- dropout=dropout,
- )
- self.up_blocks.append(up_block)
- prev_output_channel = output_channel
-
- # out
- if norm_num_groups is not None:
- self.conv_norm_out = nn.GroupNorm(
- num_channels=block_out_channels[0], num_groups=norm_num_groups, eps=norm_eps
- )
-
- self.conv_act = get_activation(act_fn)
-
- else:
- self.conv_norm_out = None
- self.conv_act = None
-
- conv_out_padding = (conv_out_kernel - 1) // 2
- self.conv_out = nn.Conv2d(
- block_out_channels[0], out_channels, kernel_size=conv_out_kernel, padding=conv_out_padding
- )
-
- if attention_type in ["gated", "gated-text-image"]:
- positive_len = 768
- if isinstance(cross_attention_dim, int):
- positive_len = cross_attention_dim
- elif isinstance(cross_attention_dim, tuple) or isinstance(cross_attention_dim, list):
- positive_len = cross_attention_dim[0]
-
- feature_type = "text-only" if attention_type == "gated" else "text-image"
- self.position_net = TimeProjModel(
- positive_len=positive_len, out_dim=cross_attention_dim, feature_type=feature_type
- )
-
- # additional settings
- self.video_feature_dim = video_feature_dim
- self.cross_attention_dim = cross_attention_dim
- self.video_cross_attn_dim = video_cross_attn_dim
- self.video_frame_nums = video_frame_nums
-
- self.multi_frames_condition = False
-
- def load_attention(self):
- attn_dict = {}
- for name in self.attn_processors.keys():
- # if self-attention, save feature
- if name.endswith("attn1.processor"):
- if is_xformers_available():
- attn_dict[name] = XFormersAttnProcessor()
- else:
- attn_dict[name] = AttnProcessor()
- else:
- attn_dict[name] = AttnProcessor2_0()
- self.set_attn_processor(attn_dict)
-
- def get_writer_feature(self):
- return self.attn_feature_writer.get_cross_attention_feature()
-
- def clear_writer_feature(self):
- self.attn_feature_writer.clear_cross_attention_feature()
-
- def disable_feature_adapters(self):
- raise NotImplementedError
-
- def set_reader_feature(self, features: list):
- return self.attn_feature_reader.set_cross_attention_feature(features)
-
- @property
- def attn_processors(self) -> Dict[str, AttentionProcessor]:
- r"""
- Returns:
- `dict` of attention processors: A dictionary containing all attention processors used in the model with
- indexed by its weight name.
- """
- # set recursively
- processors = {}
-
- def fn_recursive_add_processors(name: str, module: torch.nn.Module, processors: Dict[str, AttentionProcessor]):
- if hasattr(module, "get_processor"):
- processors[f"{name}.processor"] = module.get_processor(return_deprecated_lora=True)
-
- for sub_name, child in module.named_children():
- fn_recursive_add_processors(f"{name}.{sub_name}", child, processors)
-
- return processors
-
- for name, module in self.named_children():
- fn_recursive_add_processors(name, module, processors)
-
- return processors
-
- def set_attn_processor(
- self, processor: Union[AttentionProcessor, Dict[str, AttentionProcessor]], _remove_lora=False
- ):
- r"""
- Sets the attention processor to use to compute attention.
-
- Parameters:
- processor (`dict` of `AttentionProcessor` or only `AttentionProcessor`):
- The instantiated processor class or a dictionary of processor classes that will be set as the processor
- for **all** `Attention` layers.
-
- If `processor` is a dict, the key needs to define the path to the corresponding cross attention
- processor. This is strongly recommended when setting trainable attention processors.
-
- """
- count = len(self.attn_processors.keys())
-
- if isinstance(processor, dict) and len(processor) != count:
- raise ValueError(
- f"A dict of processors was passed, but the number of processors {len(processor)} does not match the"
- f" number of attention layers: {count}. Please make sure to pass {count} processor classes."
- )
-
- def fn_recursive_attn_processor(name: str, module: torch.nn.Module, processor):
- if hasattr(module, "set_processor"):
- if not isinstance(processor, dict):
- module.set_processor(processor, _remove_lora=_remove_lora)
- else:
- module.set_processor(processor.pop(f"{name}.processor"), _remove_lora=_remove_lora)
-
- for sub_name, child in module.named_children():
- fn_recursive_attn_processor(f"{name}.{sub_name}", child, processor)
-
- for name, module in self.named_children():
- fn_recursive_attn_processor(name, module, processor)
-
- def set_default_attn_processor(self):
- """
- Disables custom attention processors and sets the default attention implementation.
- """
- if all(proc.__class__ in ADDED_KV_ATTENTION_PROCESSORS for proc in self.attn_processors.values()):
- processor = AttnAddedKVProcessor()
- elif all(proc.__class__ in CROSS_ATTENTION_PROCESSORS for proc in self.attn_processors.values()):
- processor = AttnProcessor()
- else:
- raise ValueError(
- f"Cannot call `set_default_attn_processor` when attention processors are of type {next(iter(self.attn_processors.values()))}"
- )
-
- self.set_attn_processor(processor, _remove_lora=True)
-
- def set_attention_slice(self, slice_size):
- r"""
- Enable sliced attention computation.
-
- When this option is enabled, the attention module splits the input tensor in slices to compute attention in
- several steps. This is useful for saving some memory in exchange for a small decrease in speed.
-
- Args:
- slice_size (`str` or `int` or `list(int)`, *optional*, defaults to `"auto"`):
- When `"auto"`, input to the attention heads is halved, so attention is computed in two steps. If
- `"max"`, maximum amount of memory is saved by running only one slice at a time. If a number is
- provided, uses as many slices as `attention_head_dim // slice_size`. In this case, `attention_head_dim`
- must be a multiple of `slice_size`.
- """
- sliceable_head_dims = []
-
- def fn_recursive_retrieve_sliceable_dims(module: torch.nn.Module):
- if hasattr(module, "set_attention_slice"):
- sliceable_head_dims.append(module.sliceable_head_dim)
-
- for child in module.children():
- fn_recursive_retrieve_sliceable_dims(child)
-
- # retrieve number of attention layers
- for module in self.children():
- fn_recursive_retrieve_sliceable_dims(module)
-
- num_sliceable_layers = len(sliceable_head_dims)
-
- if slice_size == "auto":
- # half the attention head size is usually a good trade-off between
- # speed and memory
- slice_size = [dim // 2 for dim in sliceable_head_dims]
- elif slice_size == "max":
- # make smallest slice possible
- slice_size = num_sliceable_layers * [1]
-
- slice_size = num_sliceable_layers * [slice_size] if not isinstance(slice_size, list) else slice_size
-
- if len(slice_size) != len(sliceable_head_dims):
- raise ValueError(
- f"You have provided {len(slice_size)}, but {self.config} has {len(sliceable_head_dims)} different"
- f" attention layers. Make sure to match `len(slice_size)` to be {len(sliceable_head_dims)}."
- )
-
- for i in range(len(slice_size)):
- size = slice_size[i]
- dim = sliceable_head_dims[i]
- if size is not None and size > dim:
- raise ValueError(f"size {size} has to be smaller or equal to {dim}.")
-
- # Recursively walk through all the children.
- # Any children which exposes the set_attention_slice method
- # gets the message
- def fn_recursive_set_attention_slice(module: torch.nn.Module, slice_size: List[int]):
- if hasattr(module, "set_attention_slice"):
- module.set_attention_slice(slice_size.pop())
-
- for child in module.children():
- fn_recursive_set_attention_slice(child, slice_size)
-
- reversed_slice_size = list(reversed(slice_size))
- for module in self.children():
- fn_recursive_set_attention_slice(module, reversed_slice_size)
-
- def _set_gradient_checkpointing(self, module, value=False):
- if hasattr(module, "gradient_checkpointing"):
- module.gradient_checkpointing = value
-
- def enable_freeu(self, s1, s2, b1, b2):
- r"""Enables the FreeU mechanism from https://arxiv.org/abs/2309.11497.
-
- The suffixes after the scaling factors represent the stage blocks where they are being applied.
-
- Please refer to the [official repository](https://github.com/ChenyangSi/FreeU) for combinations of values that
- are known to work well for different pipelines such as Stable Diffusion v1, v2, and Stable Diffusion XL.
-
- Args:
- s1 (`float`):
- Scaling factor for stage 1 to attenuate the contributions of the skip features. This is done to
- mitigate the "oversmoothing effect" in the enhanced denoising process.
- s2 (`float`):
- Scaling factor for stage 2 to attenuate the contributions of the skip features. This is done to
- mitigate the "oversmoothing effect" in the enhanced denoising process.
- b1 (`float`): Scaling factor for stage 1 to amplify the contributions of backbone features.
- b2 (`float`): Scaling factor for stage 2 to amplify the contributions of backbone features.
- """
- for i, upsample_block in enumerate(self.up_blocks):
- setattr(upsample_block, "s1", s1)
- setattr(upsample_block, "s2", s2)
- setattr(upsample_block, "b1", b1)
- setattr(upsample_block, "b2", b2)
-
- def disable_freeu(self):
- """Disables the FreeU mechanism."""
- freeu_keys = {"s1", "s2", "b1", "b2"}
- for i, upsample_block in enumerate(self.up_blocks):
- for k in freeu_keys:
- if hasattr(upsample_block, k) or getattr(upsample_block, k, None) is not None:
- setattr(upsample_block, k, None)
-
- def fuse_qkv_projections(self):
- """
- Enables fused QKV projections. For self-attention modules, all projection matrices (i.e., query,
- key, value) are fused. For cross-attention modules, key and value projection matrices are fused.
-
-
-
- This API is 🧪 experimental.
-
-
- """
- self.original_attn_processors = None
-
- for _, attn_processor in self.attn_processors.items():
- if "Added" in str(attn_processor.__class__.__name__):
- raise ValueError("`fuse_qkv_projections()` is not supported for models having added KV projections.")
-
- self.original_attn_processors = self.attn_processors
-
- for module in self.modules():
- if isinstance(module, Attention):
- module.fuse_projections(fuse=True)
-
- def unfuse_qkv_projections(self):
- """Disables the fused QKV projection if enabled.
-
-
-
- This API is 🧪 experimental.
-
-
-
- """
- if self.original_attn_processors is not None:
- self.set_attn_processor(self.original_attn_processors)
-
- def forward(
- self,
- sample: torch.FloatTensor,
- timestep: Union[torch.Tensor, float, int],
- encoder_hidden_states: torch.Tensor,
- class_labels: Optional[torch.Tensor] = None,
- timestep_cond: Optional[torch.Tensor] = None,
- attention_mask: Optional[torch.Tensor] = None,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- added_cond_kwargs: Optional[Dict[str, torch.Tensor]] = None,
- down_block_additional_residuals: Optional[Tuple[torch.Tensor]] = None,
- mid_block_additional_residual: Optional[torch.Tensor] = None,
- down_intrablock_additional_residuals: Optional[Tuple[torch.Tensor]] = None,
- encoder_attention_mask: Optional[torch.Tensor] = None,
- return_dict: bool = True,
- ) -> Union[UNet2DConditionOutput, Tuple]:
- # import ipdb; ipdb.set_trace()
- r"""
- The [`UNet2DConditionModel`] forward method.
-
- Args:
- sample (`torch.FloatTensor`):
- The noisy input tensor with the following shape `(batch, channel, height, width)`.
- timestep (`torch.FloatTensor` or `float` or `int`): The number of timesteps to denoise an input.
- encoder_hidden_states (`torch.FloatTensor`):
- The encoder hidden states with shape `(batch, sequence_length, feature_dim)`.
- class_labels (`torch.Tensor`, *optional*, defaults to `None`):
- Optional class labels for conditioning. Their embeddings will be summed with the timestep embeddings.
- timestep_cond: (`torch.Tensor`, *optional*, defaults to `None`):
- Conditional embeddings for timestep. If provided, the embeddings will be summed with the samples passed
- through the `self.time_embedding` layer to obtain the timestep embeddings.
- attention_mask (`torch.Tensor`, *optional*, defaults to `None`):
- An attention mask of shape `(batch, key_tokens)` is applied to `encoder_hidden_states`. If `1` the mask
- is kept, otherwise if `0` it is discarded. Mask will be converted into a bias, which adds large
- negative values to the attention scores corresponding to "discard" tokens.
- cross_attention_kwargs (`dict`, *optional*):
- A kwargs dictionary that if specified is passed along to the `AttentionProcessor` as defined under
- `self.processor` in
- [diffusers.models.attention_processor](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
- added_cond_kwargs: (`dict`, *optional*):
- A kwargs dictionary containing additional embeddings that if specified are added to the embeddings that
- are passed along to the UNet blocks.
- down_block_additional_residuals: (`tuple` of `torch.Tensor`, *optional*):
- A tuple of tensors that if specified are added to the residuals of down unet blocks.
- mid_block_additional_residual: (`torch.Tensor`, *optional*):
- A tensor that if specified is added to the residual of the middle unet block.
- encoder_attention_mask (`torch.Tensor`):
- A cross-attention mask of shape `(batch, sequence_length)` is applied to `encoder_hidden_states`. If
- `True` the mask is kept, otherwise if `False` it is discarded. Mask will be converted into a bias,
- which adds large negative values to the attention scores corresponding to "discard" tokens.
- return_dict (`bool`, *optional*, defaults to `True`):
- Whether or not to return a [`~models.unet_2d_condition.UNet2DConditionOutput`] instead of a plain
- tuple.
- cross_attention_kwargs (`dict`, *optional*):
- A kwargs dictionary that if specified is passed along to the [`AttnProcessor`].
- added_cond_kwargs: (`dict`, *optional*):
- A kwargs dictionary containin additional embeddings that if specified are added to the embeddings that
- are passed along to the UNet blocks.
- down_block_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
- additional residuals to be added to UNet long skip connections from down blocks to up blocks for
- example from ControlNet side model(s)
- mid_block_additional_residual (`torch.Tensor`, *optional*):
- additional residual to be added to UNet mid block output, for example from ControlNet side model
- down_intrablock_additional_residuals (`tuple` of `torch.Tensor`, *optional*):
- additional residuals to be added within UNet down blocks, for example from T2I-Adapter side model(s)
-
- Returns:
- [`~models.unet_2d_condition.UNet2DConditionOutput`] or `tuple`:
- If `return_dict` is True, an [`~models.unet_2d_condition.UNet2DConditionOutput`] is returned, otherwise
- a `tuple` is returned where the first element is the sample tensor.
- """
- # By default samples have to be AT least a multiple of the overall upsampling factor.
- # The overall upsampling factor is equal to 2 ** (# num of upsampling layers).
- # However, the upsampling interpolation output size can be forced to fit any upsampling size
- # on the fly if necessary.
- default_overall_up_factor = 2**self.num_upsamplers
-
- # upsample size should be forwarded when sample is not a multiple of `default_overall_up_factor`
- forward_upsample_size = False
- upsample_size = None
-
- for dim in sample.shape[-2:]:
- if dim % default_overall_up_factor != 0:
- # Forward upsample size to force interpolation output size.
- forward_upsample_size = True
- break
-
- # ensure attention_mask is a bias, and give it a singleton query_tokens dimension
- # expects mask of shape:
- # [batch, key_tokens]
- # adds singleton query_tokens dimension:
- # [batch, 1, key_tokens]
- # this helps to broadcast it as a bias over attention scores, which will be in one of the following shapes:
- # [batch, heads, query_tokens, key_tokens] (e.g. torch sdp attn)
- # [batch * heads, query_tokens, key_tokens] (e.g. xformers or classic attn)
- if attention_mask is not None:
- # assume that mask is expressed as:
- # (1 = keep, 0 = discard)
- # convert mask into a bias that can be added to attention scores:
- # (keep = +0, discard = -10000.0)
- attention_mask = (1 - attention_mask.to(sample.dtype)) * -10000.0
- attention_mask = attention_mask.unsqueeze(1)
-
- # convert encoder_attention_mask to a bias the same way we do for attention_mask
- if encoder_attention_mask is not None:
- encoder_attention_mask = (1 - encoder_attention_mask.to(sample.dtype)) * -10000.0
- encoder_attention_mask = encoder_attention_mask.unsqueeze(1)
-
- # 0. center input if necessary
- if self.config.center_input_sample:
- sample = 2 * sample - 1.0
-
- # 1. time
- timesteps = timestep
- if not torch.is_tensor(timesteps):
- # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can
- # This would be a good case for the `match` statement (Python 3.10+)
- is_mps = sample.device.type == "mps"
- if isinstance(timestep, float):
- dtype = torch.float32 if is_mps else torch.float64
- else:
- dtype = torch.int32 if is_mps else torch.int64
- timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device)
- elif len(timesteps.shape) == 0:
- timesteps = timesteps[None].to(sample.device)
-
- # broadcast to batch dimension in a way that's compatible with ONNX/Core ML
- timesteps = timesteps.expand(sample.shape[0])
-
- t_emb = self.time_proj(timesteps)
-
- # `Timesteps` does not contain any weights and will always return f32 tensors
- # but time_embedding might actually be running in fp16. so we need to cast here.
- # there might be better ways to encapsulate this.
- t_emb = t_emb.to(dtype=sample.dtype)
-
- emb = self.time_embedding(t_emb, timestep_cond)
- aug_emb = None
-
- if self.class_embedding is not None:
- if class_labels is None:
- raise ValueError("class_labels should be provided when num_class_embeds > 0")
-
- if self.config.class_embed_type == "timestep":
- class_labels = self.time_proj(class_labels)
-
- # `Timesteps` does not contain any weights and will always return f32 tensors
- # there might be better ways to encapsulate this.
- class_labels = class_labels.to(dtype=sample.dtype)
-
- class_emb = self.class_embedding(class_labels).to(dtype=sample.dtype)
-
- if self.config.class_embeddings_concat:
- emb = torch.cat([emb, class_emb], dim=-1)
- else:
- emb = emb + class_emb
-
- if self.config.addition_embed_type == "text":
- aug_emb = self.add_embedding(encoder_hidden_states)
- elif self.config.addition_embed_type == "text_image":
- # Kandinsky 2.1 - style
- if "image_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `addition_embed_type` set to 'text_image' which requires the keyword argument `image_embeds` to be passed in `added_cond_kwargs`"
- )
-
- image_embs = added_cond_kwargs.get("image_embeds")
- text_embs = added_cond_kwargs.get("text_embeds", encoder_hidden_states)
- aug_emb = self.add_embedding(text_embs, image_embs)
- elif self.config.addition_embed_type == "text_time":
- # SDXL - style
- if "text_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `addition_embed_type` set to 'text_time' which requires the keyword argument `text_embeds` to be passed in `added_cond_kwargs`"
- )
- text_embeds = added_cond_kwargs.get("text_embeds")
- if "time_ids" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `addition_embed_type` set to 'text_time' which requires the keyword argument `time_ids` to be passed in `added_cond_kwargs`"
- )
- time_ids = added_cond_kwargs.get("time_ids")
- time_embeds = self.add_time_proj(time_ids.flatten())
- time_embeds = time_embeds.reshape((text_embeds.shape[0], -1))
- add_embeds = torch.concat([text_embeds, time_embeds], dim=-1)
- add_embeds = add_embeds.to(emb.dtype)
- aug_emb = self.add_embedding(add_embeds)
- elif self.config.addition_embed_type == "image":
- # Kandinsky 2.2 - style
- if "image_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `addition_embed_type` set to 'image' which requires the keyword argument `image_embeds` to be passed in `added_cond_kwargs`"
- )
- image_embs = added_cond_kwargs.get("image_embeds")
- aug_emb = self.add_embedding(image_embs)
- elif self.config.addition_embed_type == "image_hint":
- # Kandinsky 2.2 - style
- if "image_embeds" not in added_cond_kwargs or "hint" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `addition_embed_type` set to 'image_hint' which requires the keyword arguments `image_embeds` and `hint` to be passed in `added_cond_kwargs`"
- )
- image_embs = added_cond_kwargs.get("image_embeds")
- hint = added_cond_kwargs.get("hint")
- aug_emb, hint = self.add_embedding(image_embs, hint)
- sample = torch.cat([sample, hint], dim=1)
-
- emb = emb + aug_emb if aug_emb is not None else emb
-
- if self.time_embed_act is not None:
- emb = self.time_embed_act(emb)
-
- if self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_proj":
- encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states)
- elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "text_image_proj":
- # Kadinsky 2.1 - style
- if "image_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'text_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
- )
-
- image_embeds = added_cond_kwargs.get("image_embeds")
- encoder_hidden_states = self.encoder_hid_proj(encoder_hidden_states, image_embeds)
- elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "image_proj":
- # Kandinsky 2.2 - style
- if "image_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
- )
- image_embeds = added_cond_kwargs.get("image_embeds")
- encoder_hidden_states = self.encoder_hid_proj(image_embeds)
- elif self.encoder_hid_proj is not None and self.config.encoder_hid_dim_type == "ip_image_proj":
- if "image_embeds" not in added_cond_kwargs:
- raise ValueError(
- f"{self.__class__} has the config param `encoder_hid_dim_type` set to 'ip_image_proj' which requires the keyword argument `image_embeds` to be passed in `added_conditions`"
- )
- image_embeds = added_cond_kwargs.get("image_embeds")
- image_embeds = self.encoder_hid_proj(image_embeds)
- if isinstance(image_embeds, list):
- image_embeds = [image_embed.to(encoder_hidden_states.dtype) for image_embed in image_embeds]
- else:
- image_embeds = image_embeds.to(encoder_hidden_states.dtype)
- encoder_hidden_states = (encoder_hidden_states, image_embeds)
- # encoder_hidden_states = torch.cat([encoder_hidden_states, image_embeds], dim=1)
- # import ipdb; ipdb.set_trace()
- # 2. pre-process
- sample = self.conv_in(sample)
-
- # 2.5 GLIGEN position net
- if cross_attention_kwargs is not None and cross_attention_kwargs.get("gligen", None) is not None:
- cross_attention_kwargs = cross_attention_kwargs.copy()
- gligen_args = cross_attention_kwargs.pop("gligen")
- cross_attention_kwargs["gligen"] = {"objs": self.position_net(**gligen_args)}
-
- # 3. down
- lora_scale = cross_attention_kwargs.get("scale", 1.0) if cross_attention_kwargs is not None else 1.0
- if USE_PEFT_BACKEND:
- # weight the lora layers by setting `lora_scale` for each PEFT layer
- scale_lora_layers(self, lora_scale)
-
- is_controlnet = mid_block_additional_residual is not None and down_block_additional_residuals is not None
- # using new arg down_intrablock_additional_residuals for T2I-Adapters, to distinguish from controlnets
- is_adapter = down_intrablock_additional_residuals is not None
- # maintain backward compatibility for legacy usage, where
- # T2I-Adapter and ControlNet both use down_block_additional_residuals arg
- # but can only use one or the other
- if not is_adapter and mid_block_additional_residual is None and down_block_additional_residuals is not None:
- deprecate(
- "T2I should not use down_block_additional_residuals",
- "1.3.0",
- "Passing intrablock residual connections with `down_block_additional_residuals` is deprecated \
- and will be removed in diffusers 1.3.0. `down_block_additional_residuals` should only be used \
- for ControlNet. Please make sure use `down_intrablock_additional_residuals` instead. ",
- standard_warn=False,
- )
- down_intrablock_additional_residuals = down_block_additional_residuals
- is_adapter = True
- # import ipdb; ipdb.set_trace()
- down_block_res_samples = (sample,)
- for downsample_block in self.down_blocks:
- if hasattr(downsample_block, "has_cross_attention") and downsample_block.has_cross_attention:
- # For t2i-adapter CrossAttnDownBlock2D
- additional_residuals = {}
- if is_adapter and len(down_intrablock_additional_residuals) > 0:
- additional_residuals["additional_residuals"] = down_intrablock_additional_residuals.pop(0)
-
- sample, res_samples = downsample_block(
- hidden_states=sample,
- temb=emb,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- **additional_residuals,
- )
- # import ipdb; ipdb.set_trace()
- else:
- sample, res_samples = downsample_block(hidden_states=sample, temb=emb, scale=lora_scale)
- if is_adapter and len(down_intrablock_additional_residuals) > 0:
- sample += down_intrablock_additional_residuals.pop(0)
-
- down_block_res_samples += res_samples
-
- if is_controlnet:
- new_down_block_res_samples = ()
-
- for down_block_res_sample, down_block_additional_residual in zip(
- down_block_res_samples, down_block_additional_residuals
- ):
- down_block_res_sample = down_block_res_sample + down_block_additional_residual
- new_down_block_res_samples = new_down_block_res_samples + (down_block_res_sample,)
-
- down_block_res_samples = new_down_block_res_samples
- # 4. mid
- if self.mid_block is not None:
- if hasattr(self.mid_block, "has_cross_attention") and self.mid_block.has_cross_attention:
- sample = self.mid_block(
- sample,
- emb,
- encoder_hidden_states=encoder_hidden_states,
- attention_mask=attention_mask,
- cross_attention_kwargs=cross_attention_kwargs,
- encoder_attention_mask=encoder_attention_mask,
- )
- else:
- sample = self.mid_block(sample, emb)
-
- # To support T2I-Adapter-XL
- if (
- is_adapter
- and len(down_intrablock_additional_residuals) > 0
- and sample.shape == down_intrablock_additional_residuals[0].shape
- ):
- sample += down_intrablock_additional_residuals.pop(0)
-
- if is_controlnet:
- sample = sample + mid_block_additional_residual
- # import ipdb; ipdb.set_trace()
- # 5. up
- for i, upsample_block in enumerate(self.up_blocks):
- is_final_block = i == len(self.up_blocks) - 1
-
- res_samples = down_block_res_samples[-len(upsample_block.resnets) :]
- down_block_res_samples = down_block_res_samples[: -len(upsample_block.resnets)]
-
- # if we have not reached the final block and need to forward the
- # upsample size, we do it here
- if not is_final_block and forward_upsample_size:
- upsample_size = down_block_res_samples[-1].shape[2:]
-
- if hasattr(upsample_block, "has_cross_attention") and upsample_block.has_cross_attention:
- sample = upsample_block(
- hidden_states=sample,
- temb=emb,
- res_hidden_states_tuple=res_samples,
- encoder_hidden_states=encoder_hidden_states,
- cross_attention_kwargs=cross_attention_kwargs,
- upsample_size=upsample_size,
- attention_mask=attention_mask,
- encoder_attention_mask=encoder_attention_mask,
- )
- else:
- sample = upsample_block(
- hidden_states=sample,
- temb=emb,
- res_hidden_states_tuple=res_samples,
- upsample_size=upsample_size,
- scale=lora_scale,
- )
- # import ipdb; ipdb.set_trace()
- # 6. post-process
- if self.conv_norm_out:
- sample = self.conv_norm_out(sample)
- sample = self.conv_act(sample)
- sample = self.conv_out(sample)
-
- if USE_PEFT_BACKEND:
- # remove `lora_scale` from each PEFT layer
- unscale_lora_layers(self, lora_scale)
-
- if not return_dict:
- return (sample,)
- # import ipdb; ipdb.set_trace()
- return UNet2DConditionOutput(sample=sample)
diff --git a/foleycrafter/pipelines/auffusion_pipeline.py b/foleycrafter/pipelines/auffusion_pipeline.py
deleted file mode 100644
index 6d502cb..0000000
--- a/foleycrafter/pipelines/auffusion_pipeline.py
+++ /dev/null
@@ -1,2155 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-import inspect
-import json
-import os
-import warnings
-from dataclasses import dataclass
-from typing import Any, Callable, Dict, List, Optional, Union
-
-import matplotlib.pyplot as plt
-import numpy as np
-import PIL
-import torch
-import torch.nn as nn
-import torch.nn.functional as F
-from huggingface_hub import snapshot_download
-from packaging import version
-from torch.nn import Conv1d, ConvTranspose1d
-from torch.nn.utils import remove_weight_norm, weight_norm
-from transformers import (
- AutoTokenizer,
- CLIPImageProcessor,
- CLIPTextModel,
- CLIPTokenizer,
- CLIPVisionModelWithProjection,
- PretrainedConfig,
-)
-
-from diffusers import PNDMScheduler
-from diffusers.configuration_utils import FrozenDict
-from diffusers.image_processor import PipelineImageInput, VaeImageProcessor
-from diffusers.loaders import FromSingleFileMixin, LoraLoaderMixin, TextualInversionLoaderMixin
-from diffusers.models import AutoencoderKL, ImageProjection
-from diffusers.models.attention_processor import FusedAttnProcessor2_0
-from diffusers.pipelines.pipeline_utils import DiffusionPipeline
-from diffusers.pipelines.stable_diffusion import StableDiffusionPipelineOutput
-from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
-from diffusers.schedulers import KarrasDiffusionSchedulers
-from diffusers.utils import (
- deprecate,
- is_accelerate_available,
- is_accelerate_version,
- logging,
-)
-from diffusers.utils.outputs import BaseOutput
-from diffusers.utils.torch_utils import randn_tensor
-from foleycrafter.models.auffusion.loaders.ip_adapter import IPAdapterMixin
-from foleycrafter.models.auffusion_unet import UNet2DConditionModel
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-def json_dump(data_json, json_save_path):
- with open(json_save_path, "w") as f:
- json.dump(data_json, f, indent=4)
- f.close()
-
-
-def json_load(json_path):
- with open(json_path, "r") as f:
- data = json.load(f)
- f.close()
- return data
-
-
-def import_model_class_from_model_name_or_path(pretrained_model_name_or_path: str):
- text_encoder_config = PretrainedConfig.from_pretrained(pretrained_model_name_or_path)
- model_class = text_encoder_config.architectures[0]
-
- if model_class == "CLIPTextModel":
- from transformers import CLIPTextModel
-
- return CLIPTextModel
- if "t5" in model_class.lower():
- from transformers import T5EncoderModel
-
- return T5EncoderModel
- if "clap" in model_class.lower():
- from transformers import ClapTextModelWithProjection
-
- return ClapTextModelWithProjection
- else:
- raise ValueError(f"{model_class} is not supported.")
-
-
-class ConditionAdapter(nn.Module):
- def __init__(self, config):
- super(ConditionAdapter, self).__init__()
- self.config = config
- self.proj = nn.Linear(self.config["condition_dim"], self.config["cross_attention_dim"])
- self.norm = torch.nn.LayerNorm(self.config["cross_attention_dim"])
- print(f"INITIATED: ConditionAdapter: {self.config}")
-
- def forward(self, x):
- x = self.proj(x)
- x = self.norm(x)
- return x
-
- @classmethod
- def from_pretrained(cls, pretrained_model_name_or_path):
- config_path = os.path.join(pretrained_model_name_or_path, "config.json")
- ckpt_path = os.path.join(pretrained_model_name_or_path, "condition_adapter.pt")
- config = json.loads(open(config_path).read())
- instance = cls(config)
- instance.load_state_dict(torch.load(ckpt_path))
- print(f"LOADED: ConditionAdapter from {pretrained_model_name_or_path}")
- return instance
-
- def save_pretrained(self, pretrained_model_name_or_path):
- os.makedirs(pretrained_model_name_or_path, exist_ok=True)
- config_path = os.path.join(pretrained_model_name_or_path, "config.json")
- ckpt_path = os.path.join(pretrained_model_name_or_path, "condition_adapter.pt")
- json_dump(self.config, config_path)
- torch.save(self.state_dict(), ckpt_path)
- print(f"SAVED: ConditionAdapter {self.config['model_name']} to {pretrained_model_name_or_path}")
-
-
-def rescale_noise_cfg(noise_cfg, noise_pred_text, guidance_rescale=0.0):
- """
- Rescale `noise_cfg` according to `guidance_rescale`. Based on findings of [Common Diffusion Noise Schedules and
- Sample Steps are Flawed](https://arxiv.org/pdf/2305.08891.pdf). See Section 3.4
- """
- std_text = noise_pred_text.std(dim=list(range(1, noise_pred_text.ndim)), keepdim=True)
- std_cfg = noise_cfg.std(dim=list(range(1, noise_cfg.ndim)), keepdim=True)
- # rescale the results from guidance (fixes overexposure)
- noise_pred_rescaled = noise_cfg * (std_text / std_cfg)
- # mix with the original results from guidance by factor guidance_rescale to avoid "plain looking" images
- noise_cfg = guidance_rescale * noise_pred_rescaled + (1 - guidance_rescale) * noise_cfg
- return noise_cfg
-
-
-LRELU_SLOPE = 0.1
-MAX_WAV_VALUE = 32768.0
-
-
-class AttrDict(dict):
- def __init__(self, *args, **kwargs):
- super(AttrDict, self).__init__(*args, **kwargs)
- self.__dict__ = self
-
-
-def get_config(config_path):
- config = json.loads(open(config_path).read())
- config = AttrDict(config)
- return config
-
-
-def init_weights(m, mean=0.0, std=0.01):
- classname = m.__class__.__name__
- if classname.find("Conv") != -1:
- m.weight.data.normal_(mean, std)
-
-
-def apply_weight_norm(m):
- classname = m.__class__.__name__
- if classname.find("Conv") != -1:
- weight_norm(m)
-
-
-def get_padding(kernel_size, dilation=1):
- return int((kernel_size * dilation - dilation) / 2)
-
-
-class ResBlock1(torch.nn.Module):
- def __init__(self, h, channels, kernel_size=3, dilation=(1, 3, 5)):
- super(ResBlock1, self).__init__()
- self.h = h
- self.convs1 = nn.ModuleList(
- [
- weight_norm(
- Conv1d(
- channels,
- channels,
- kernel_size,
- 1,
- dilation=dilation[0],
- padding=get_padding(kernel_size, dilation[0]),
- )
- ),
- weight_norm(
- Conv1d(
- channels,
- channels,
- kernel_size,
- 1,
- dilation=dilation[1],
- padding=get_padding(kernel_size, dilation[1]),
- )
- ),
- weight_norm(
- Conv1d(
- channels,
- channels,
- kernel_size,
- 1,
- dilation=dilation[2],
- padding=get_padding(kernel_size, dilation[2]),
- )
- ),
- ]
- )
- self.convs1.apply(init_weights)
-
- self.convs2 = nn.ModuleList(
- [
- weight_norm(
- Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
- ),
- weight_norm(
- Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
- ),
- weight_norm(
- Conv1d(channels, channels, kernel_size, 1, dilation=1, padding=get_padding(kernel_size, 1))
- ),
- ]
- )
- self.convs2.apply(init_weights)
-
- def forward(self, x):
- for c1, c2 in zip(self.convs1, self.convs2):
- xt = F.leaky_relu(x, LRELU_SLOPE)
- xt = c1(xt)
- xt = F.leaky_relu(xt, LRELU_SLOPE)
- xt = c2(xt)
- x = xt + x
- return x
-
- def remove_weight_norm(self):
- for l in self.convs1:
- remove_weight_norm(l)
- for l in self.convs2:
- remove_weight_norm(l)
-
-
-class ResBlock2(torch.nn.Module):
- def __init__(self, h, channels, kernel_size=3, dilation=(1, 3)):
- super(ResBlock2, self).__init__()
- self.h = h
- self.convs = nn.ModuleList(
- [
- weight_norm(
- Conv1d(
- channels,
- channels,
- kernel_size,
- 1,
- dilation=dilation[0],
- padding=get_padding(kernel_size, dilation[0]),
- )
- ),
- weight_norm(
- Conv1d(
- channels,
- channels,
- kernel_size,
- 1,
- dilation=dilation[1],
- padding=get_padding(kernel_size, dilation[1]),
- )
- ),
- ]
- )
- self.convs.apply(init_weights)
-
- def forward(self, x):
- for c in self.convs:
- xt = F.leaky_relu(x, LRELU_SLOPE)
- xt = c(xt)
- x = xt + x
- return x
-
- def remove_weight_norm(self):
- for l in self.convs:
- remove_weight_norm(l)
-
-
-class Generator(torch.nn.Module):
- def __init__(self, h):
- super(Generator, self).__init__()
- self.h = h
- self.num_kernels = len(h.resblock_kernel_sizes)
- self.num_upsamples = len(h.upsample_rates)
- # self.conv_pre = weight_norm(Conv1d(80, h.upsample_initial_channel, 7, 1, padding=3))
- self.conv_pre = weight_norm(
- Conv1d(h.num_mels, h.upsample_initial_channel, 7, 1, padding=3)
- ) # change: 80 --> 512
- resblock = ResBlock1 if h.resblock == "1" else ResBlock2
-
- self._device = "cuda" if torch.cuda.is_available() else "cpu"
-
- self.ups = nn.ModuleList()
- for i, (u, k) in enumerate(zip(h.upsample_rates, h.upsample_kernel_sizes)):
- if (k - u) % 2 == 0:
- self.ups.append(
- weight_norm(
- ConvTranspose1d(
- h.upsample_initial_channel // (2**i),
- h.upsample_initial_channel // (2 ** (i + 1)),
- k,
- u,
- padding=(k - u) // 2,
- )
- )
- )
- else:
- self.ups.append(
- weight_norm(
- ConvTranspose1d(
- h.upsample_initial_channel // (2**i),
- h.upsample_initial_channel // (2 ** (i + 1)),
- k,
- u,
- padding=(k - u) // 2 + 1,
- output_padding=1,
- )
- )
- )
-
- # self.ups.append(weight_norm(
- # ConvTranspose1d(h.upsample_initial_channel//(2**i), h.upsample_initial_channel//(2**(i+1)),
- # k, u, padding=(k-u)//2)))
-
- self.resblocks = nn.ModuleList()
- for i in range(len(self.ups)):
- ch = h.upsample_initial_channel // (2 ** (i + 1))
- for j, (k, d) in enumerate(zip(h.resblock_kernel_sizes, h.resblock_dilation_sizes)):
- self.resblocks.append(resblock(h, ch, k, d))
-
- self.conv_post = weight_norm(Conv1d(ch, 1, 7, 1, padding=3))
- self.ups.apply(init_weights)
- self.conv_post.apply(init_weights)
-
- @property
- def device(self) -> torch.device:
- return torch.device(self._device)
-
- @property
- def dtype(self):
- return self.type
-
- def forward(self, x):
- x = self.conv_pre(x)
- for i in range(self.num_upsamples):
- x = F.leaky_relu(x, LRELU_SLOPE)
- x = self.ups[i](x)
- xs = None
- for j in range(self.num_kernels):
- if xs is None:
- xs = self.resblocks[i * self.num_kernels + j](x)
- else:
- xs += self.resblocks[i * self.num_kernels + j](x)
- x = xs / self.num_kernels
- x = F.leaky_relu(x)
- x = self.conv_post(x)
- x = torch.tanh(x)
-
- return x
-
- def remove_weight_norm(self):
- print("Removing weight norm...")
- for l in self.ups:
- remove_weight_norm(l)
- for l in self.resblocks:
- l.remove_weight_norm()
- remove_weight_norm(self.conv_pre)
- remove_weight_norm(self.conv_post)
-
- @classmethod
- def from_pretrained(cls, pretrained_model_name_or_path, subfolder=None):
- if subfolder is not None:
- pretrained_model_name_or_path = os.path.join(pretrained_model_name_or_path, subfolder)
- config_path = os.path.join(pretrained_model_name_or_path, "config.json")
- ckpt_path = os.path.join(pretrained_model_name_or_path, "vocoder.pt")
-
- config = get_config(config_path)
- vocoder = cls(config)
-
- state_dict_g = torch.load(ckpt_path)
- vocoder.load_state_dict(state_dict_g["generator"])
- vocoder.eval()
- vocoder.remove_weight_norm()
- return vocoder
-
- @torch.no_grad()
- def inference(self, mels, lengths=None):
- self.eval()
- with torch.no_grad():
- wavs = self(mels).squeeze(1)
-
- wavs = (wavs.cpu().numpy() * MAX_WAV_VALUE).astype("int16")
-
- if lengths is not None:
- wavs = wavs[:, :lengths]
-
- return wavs
-
-
-def normalize_spectrogram(
- spectrogram: torch.Tensor,
- max_value: float = 200,
- min_value: float = 1e-5,
- power: float = 1.0,
-) -> torch.Tensor:
- # Rescale to 0-1
- max_value = np.log(max_value) # 5.298317366548036
- min_value = np.log(min_value) # -11.512925464970229
- spectrogram = torch.clamp(spectrogram, min=min_value, max=max_value)
- data = (spectrogram - min_value) / (max_value - min_value)
- # Apply the power curve
- data = torch.pow(data, power)
- # 1D -> 3D
- data = data.repeat(3, 1, 1)
- # Flip Y axis: image origin at the top-left corner, spectrogram origin at the bottom-left corner
- data = torch.flip(data, [1])
-
- return data
-
-
-def denormalize_spectrogram(
- data: torch.Tensor,
- max_value: float = 200,
- min_value: float = 1e-5,
- power: float = 1,
-) -> torch.Tensor:
- assert len(data.shape) == 3, "Expected 3 dimensions, got {}".format(len(data.shape))
-
- max_value = np.log(max_value)
- min_value = np.log(min_value)
- # Flip Y axis: image origin at the top-left corner, spectrogram origin at the bottom-left corner
- data = torch.flip(data, [1])
- if data.shape[0] == 1:
- data = data.repeat(3, 1, 1)
- assert data.shape[0] == 3, "Expected 3 channels, got {}".format(data.shape[0])
- data = data[0]
- # Reverse the power curve
- data = torch.pow(data, 1 / power)
- # Rescale to max value
- spectrogram = data * (max_value - min_value) + min_value
-
- return spectrogram
-
-
-@staticmethod
-def pt_to_numpy(images: torch.FloatTensor) -> np.ndarray:
- """
- Convert a PyTorch tensor to a NumPy image.
- """
- images = images.cpu().permute(0, 2, 3, 1).float().numpy()
- return images
-
-
-@staticmethod
-def numpy_to_pil(images: np.ndarray) -> PIL.Image.Image:
- """
- Convert a numpy image or a batch of images to a PIL image.
- """
- if images.ndim == 3:
- images = images[None, ...]
- images = (images * 255).round().astype("uint8")
- if images.shape[-1] == 1:
- # special case for grayscale (single channel) images
- pil_images = [PIL.Image.fromarray(image.squeeze(), mode="L") for image in images]
- else:
- pil_images = [PIL.Image.fromarray(image) for image in images]
-
- return pil_images
-
-
-def image_add_color(spec_img):
- cmap = plt.get_cmap("viridis")
- # cmap_r = cmap.reversed()
- image = cmap(np.array(spec_img)[:, :, 0])[:, :, :3] # 省略透明度通道
- image = (image - image.min()) / (image.max() - image.min())
- image = PIL.Image.fromarray(np.uint8(image * 255))
- return image
-
-
-@dataclass
-class PipelineOutput(BaseOutput):
- """
- Output class for audio pipelines.
-
- Args:
- audios (`np.ndarray`)
- List of denoised audio samples of a NumPy array of shape `(batch_size, num_channels, sample_rate)`.
- """
-
- images: Union[List[PIL.Image.Image], np.ndarray]
- spectrograms: Union[List[np.ndarray], np.ndarray]
- audios: Union[List[np.ndarray], np.ndarray]
-
-
-class AuffusionPipeline(DiffusionPipeline):
- r"""
- Pipeline for text-to-image generation using Stable Diffusion.
-
- This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods the
- library implements for all the pipelines (such as downloading or saving, running on a particular device, etc.)
-
- In addition the pipeline inherits the following loading methods:
- - *Textual-Inversion*: [`loaders.TextualInversionLoaderMixin.load_textual_inversion`]
- - *LoRA*: [`loaders.LoraLoaderMixin.load_lora_weights`]
- - *Ckpt*: [`loaders.FromSingleFileMixin.from_single_file`]
-
- as well as the following saving methods:
- - *LoRA*: [`loaders.LoraLoaderMixin.save_lora_weights`]
-
- Args:
- vae ([`AutoencoderKL`]):
- Variational Auto-Encoder (VAE) Model to encode and decode images to and from latent representations.
- text_encoder ([`CLIPTextModel`]):
- Frozen text-encoder. Stable Diffusion uses the text portion of
- [CLIP](https://huggingface.co/docs/transformers/model_doc/clip#transformers.CLIPTextModel), specifically
- the [clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14) variant.
- tokenizer (`CLIPTokenizer`):
- Tokenizer of class
- [CLIPTokenizer](https://huggingface.co/docs/transformers/v4.21.0/en/model_doc/clip#transformers.CLIPTokenizer).
- unet ([`UNet2DConditionModel`]): Conditional U-Net architecture to denoise the encoded image latents.
- scheduler ([`SchedulerMixin`]):
- A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of
- [`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`].
- safety_checker ([`StableDiffusionSafetyChecker`]):
- Classification module that estimates whether generated images could be considered offensive or harmful.
- Please, refer to the [model card](https://huggingface.co/runwayml/stable-diffusion-v1-5) for details.
- feature_extractor ([`CLIPImageProcessor`]):
- Model that extracts features from generated images to be used as inputs for the `safety_checker`.
- """
-
- _optional_components = [
- "safety_checker",
- "feature_extractor",
- "text_encoder_list",
- "tokenizer_list",
- "adapter_list",
- "vocoder",
- ]
-
- def __init__(
- self,
- vae: AutoencoderKL,
- unet: UNet2DConditionModel,
- scheduler: KarrasDiffusionSchedulers,
- safety_checker: StableDiffusionSafetyChecker,
- feature_extractor: CLIPImageProcessor,
- text_encoder_list: Optional[List[Callable]] = None,
- tokenizer_list: Optional[List[Callable]] = None,
- vocoder: Generator = None,
- requires_safety_checker: bool = False,
- adapter_list: Optional[List[Callable]] = None,
- tokenizer_model_max_length: Optional[
- int
- ] = 77, # 77 is the default value for the CLIPTokenizer(and set for other models)
- ):
- super().__init__()
-
- self.text_encoder_list = text_encoder_list
- self.tokenizer_list = tokenizer_list
- self.vocoder = vocoder
- self.adapter_list = adapter_list
- self.tokenizer_model_max_length = tokenizer_model_max_length
-
- self.register_modules(
- vae=vae,
- unet=unet,
- scheduler=scheduler,
- safety_checker=safety_checker,
- feature_extractor=feature_extractor,
- )
-
- self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
- self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor)
- self.register_to_config(requires_safety_checker=requires_safety_checker)
-
- @classmethod
- def from_pretrained(
- cls,
- pretrained_model_name_or_path: str = "auffusion/auffusion-full-no-adapter",
- dtype: torch.dtype = torch.float16,
- device: str = "cuda",
- ):
- if not os.path.isdir(pretrained_model_name_or_path):
- pretrained_model_name_or_path = snapshot_download(pretrained_model_name_or_path)
-
- vae = AutoencoderKL.from_pretrained(pretrained_model_name_or_path, subfolder="vae")
- unet = UNet2DConditionModel.from_pretrained(pretrained_model_name_or_path, subfolder="unet")
- feature_extractor = CLIPImageProcessor.from_pretrained(
- pretrained_model_name_or_path, subfolder="feature_extractor"
- )
- scheduler = PNDMScheduler.from_pretrained(pretrained_model_name_or_path, subfolder="scheduler")
-
- vocoder = Generator.from_pretrained(pretrained_model_name_or_path, subfolder="vocoder").to(device, dtype)
-
- text_encoder_list, tokenizer_list, adapter_list = [], [], []
-
- condition_json_path = os.path.join(pretrained_model_name_or_path, "condition_config.json")
- condition_json_list = json.loads(open(condition_json_path).read())
-
- for i, condition_item in enumerate(condition_json_list):
- # Load Condition Adapter
- text_encoder_path = os.path.join(pretrained_model_name_or_path, condition_item["text_encoder_name"])
- tokenizer = AutoTokenizer.from_pretrained(text_encoder_path)
- tokenizer_list.append(tokenizer)
- text_encoder_cls = import_model_class_from_model_name_or_path(text_encoder_path)
- text_encoder = text_encoder_cls.from_pretrained(text_encoder_path).to(device, dtype)
- text_encoder_list.append(text_encoder)
- print(f"LOADING CONDITION ENCODER {i}")
-
- # Load Condition Adapter
- adapter_path = os.path.join(pretrained_model_name_or_path, condition_item["condition_adapter_name"])
- adapter = ConditionAdapter.from_pretrained(adapter_path).to(device, dtype)
- adapter_list.append(adapter)
- print(f"LOADING CONDITION ADAPTER {i}")
-
- pipeline = cls(
- vae=vae,
- unet=unet,
- text_encoder_list=text_encoder_list,
- tokenizer_list=tokenizer_list,
- vocoder=vocoder,
- adapter_list=adapter_list,
- scheduler=scheduler,
- safety_checker=None,
- feature_extractor=feature_extractor,
- )
- pipeline = pipeline.to(device, dtype)
-
- return pipeline
-
- def to(self, device, dtype=None):
- super().to(device, dtype)
-
- self.vocoder.to(device, dtype)
-
- for text_encoder in self.text_encoder_list:
- text_encoder.to(device, dtype)
-
- if self.adapter_list is not None:
- for adapter in self.adapter_list:
- adapter.to(device, dtype)
-
- return self
-
- def enable_vae_slicing(self):
- r"""
- Enable sliced VAE decoding.
-
- When this option is enabled, the VAE will split the input tensor in slices to compute decoding in several
- steps. This is useful to save some memory and allow larger batch sizes.
- """
- self.vae.enable_slicing()
-
- def disable_vae_slicing(self):
- r"""
- Disable sliced VAE decoding. If `enable_vae_slicing` was previously invoked, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_slicing()
-
- def enable_vae_tiling(self):
- r"""
- Enable tiled VAE decoding.
-
- When this option is enabled, the VAE will split the input tensor into tiles to compute decoding and encoding in
- several steps. This is useful to save a large amount of memory and to allow the processing of larger images.
- """
- self.vae.enable_tiling()
-
- def disable_vae_tiling(self):
- r"""
- Disable tiled VAE decoding. If `enable_vae_tiling` was previously invoked, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_tiling()
-
- def enable_sequential_cpu_offload(self, gpu_id=0):
- r"""
- Offloads all models to CPU using accelerate, significantly reducing memory usage. When called, unet,
- text_encoder, vae and safety checker have their state dicts saved to CPU and then are moved to a
- `torch.device('meta') and loaded to GPU only when their specific submodule has its `forward` method called.
- Note that offloading happens on a submodule basis. Memory savings are higher than with
- `enable_model_cpu_offload`, but performance is lower.
- """
- if is_accelerate_available() and is_accelerate_version(">=", "0.14.0"):
- from accelerate import cpu_offload
- else:
- raise ImportError("`enable_sequential_cpu_offload` requires `accelerate v0.14.0` or higher")
-
- device = torch.device(f"cuda:{gpu_id}")
-
- if self.device.type != "cpu":
- self.to("cpu", silence_dtype_warnings=True)
- torch.cuda.empty_cache() # otherwise we don't see the memory savings (but they probably exist)
-
- for cpu_offloaded_model in [self.unet, self.text_encoder, self.vae]:
- cpu_offload(cpu_offloaded_model, device)
-
- if self.safety_checker is not None:
- cpu_offload(self.safety_checker, execution_device=device, offload_buffers=True)
-
- def enable_model_cpu_offload(self, gpu_id=0):
- r"""
- Offloads all models to CPU using accelerate, reducing memory usage with a low impact on performance. Compared
- to `enable_sequential_cpu_offload`, this method moves one whole model at a time to the GPU when its `forward`
- method is called, and the model remains in GPU until the next model runs. Memory savings are lower than with
- `enable_sequential_cpu_offload`, but performance is much better due to the iterative execution of the `unet`.
- """
- if is_accelerate_available() and is_accelerate_version(">=", "0.17.0.dev0"):
- from accelerate import cpu_offload_with_hook
- else:
- raise ImportError("`enable_model_cpu_offload` requires `accelerate v0.17.0` or higher.")
-
- device = torch.device(f"cuda:{gpu_id}")
-
- if self.device.type != "cpu":
- self.to("cpu", silence_dtype_warnings=True)
- torch.cuda.empty_cache() # otherwise we don't see the memory savings (but they probably exist)
-
- hook = None
- for cpu_offloaded_model in [self.text_encoder, self.unet, self.vae]:
- _, hook = cpu_offload_with_hook(cpu_offloaded_model, device, prev_module_hook=hook)
-
- if self.safety_checker is not None:
- _, hook = cpu_offload_with_hook(self.safety_checker, device, prev_module_hook=hook)
-
- # We'll offload the last model manually.
- self.final_offload_hook = hook
-
- @property
- def _execution_device(self):
- r"""
- Returns the device on which the pipeline's models will be executed. After calling
- `pipeline.enable_sequential_cpu_offload()` the execution device can only be inferred from Accelerate's module
- hooks.
- """
- if not hasattr(self.unet, "_hf_hook"):
- return self.device
- for module in self.unet.modules():
- if (
- hasattr(module, "_hf_hook")
- and hasattr(module._hf_hook, "execution_device")
- and module._hf_hook.execution_device is not None
- ):
- return torch.device(module._hf_hook.execution_device)
- return self.device
-
- def _encode_prompt(
- self,
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt=None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- ):
- assert len(self.text_encoder_list) == len(
- self.tokenizer_list
- ), "Number of text_encoders must match number of tokenizers"
- if self.adapter_list is not None:
- assert len(self.text_encoder_list) == len(
- self.adapter_list
- ), "Number of text_encoders must match number of adapters"
-
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- def get_prompt_embeds(prompt_list, device):
- if isinstance(prompt_list, str):
- prompt_list = [prompt_list]
-
- prompt_embeds_list = []
- for prompt in prompt_list:
- encoder_hidden_states_list = []
-
- # Generate condition embedding
- for j in range(len(self.text_encoder_list)):
- # get condition embedding using condition encoder
- input_ids = self.tokenizer_list[j](prompt, return_tensors="pt").input_ids.to(device)
- cond_embs = self.text_encoder_list[j](input_ids).last_hidden_state # [bz, text_len, text_dim]
- # padding to max_length
- if cond_embs.shape[1] < self.tokenizer_model_max_length:
- cond_embs = torch.functional.F.pad(
- cond_embs, (0, 0, 0, self.tokenizer_model_max_length - cond_embs.shape[1]), value=0
- )
- else:
- cond_embs = cond_embs[:, : self.tokenizer_model_max_length, :]
-
- # use condition adapter
- if self.adapter_list is not None:
- cond_embs = self.adapter_list[j](cond_embs)
- encoder_hidden_states_list.append(cond_embs)
-
- prompt_embeds = torch.cat(encoder_hidden_states_list, dim=1)
- prompt_embeds_list.append(prompt_embeds)
-
- prompt_embeds = torch.cat(prompt_embeds_list, dim=0)
- return prompt_embeds
-
- if prompt_embeds is None:
- prompt_embeds = get_prompt_embeds(prompt, device)
-
- prompt_embeds = prompt_embeds.to(dtype=self.unet.dtype, device=device)
-
- bs_embed, seq_len, _ = prompt_embeds.shape
- # duplicate text embeddings for each generation per prompt, using mps friendly method
- prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1)
- prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1)
-
- if do_classifier_free_guidance and negative_prompt_embeds is None:
- if negative_prompt is None:
- negative_prompt_embeds = torch.zeros_like(prompt_embeds).to(dtype=prompt_embeds.dtype, device=device)
-
- elif prompt is not None and type(prompt) is not type(negative_prompt):
- raise TypeError(
- f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !="
- f" {type(prompt)}."
- )
- elif isinstance(negative_prompt, str):
- negative_prompt = [negative_prompt]
- elif batch_size != len(negative_prompt):
- raise ValueError(
- f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"
- f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"
- " the batch size of `prompt`."
- )
- else:
- negative_prompt_embeds = get_prompt_embeds(negative_prompt, device)
-
- if do_classifier_free_guidance:
- # duplicate unconditional embeddings for each generation per prompt, using mps friendly method
- seq_len = negative_prompt_embeds.shape[1]
-
- negative_prompt_embeds = negative_prompt_embeds.to(dtype=self.unet.dtype, device=device)
-
- negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1)
- negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1)
-
- # For classifier free guidance, we need to do two forward passes.
- # Here we concatenate the unconditional and text embeddings into a single batch
- # to avoid doing two forward passes
- prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
-
- return prompt_embeds
-
- def run_safety_checker(self, image, device, dtype):
- if self.safety_checker is None:
- has_nsfw_concept = None
- else:
- if torch.is_tensor(image):
- feature_extractor_input = self.image_processor.postprocess(image, output_type="pil")
- else:
- feature_extractor_input = self.image_processor.numpy_to_pil(image)
- safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device)
- image, has_nsfw_concept = self.safety_checker(
- images=image, clip_input=safety_checker_input.pixel_values.to(dtype)
- )
- return image, has_nsfw_concept
-
- def decode_latents(self, latents):
- warnings.warn(
- "The decode_latents method is deprecated and will be removed in a future version. Please"
- " use VaeImageProcessor instead",
- FutureWarning,
- )
- latents = 1 / self.vae.config.scaling_factor * latents
- image = self.vae.decode(latents, return_dict=False)[0]
- image = (image / 2 + 0.5).clamp(0, 1)
- # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16
- image = image.cpu().permute(0, 2, 3, 1).float().numpy()
- return image
-
- def prepare_extra_step_kwargs(self, generator, eta):
- # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
- # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
- # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
- # and should be between [0, 1]
-
- accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys())
- extra_step_kwargs = {}
- if accepts_eta:
- extra_step_kwargs["eta"] = eta
-
- # check if the scheduler accepts generator
- accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys())
- if accepts_generator:
- extra_step_kwargs["generator"] = generator
- return extra_step_kwargs
-
- def check_inputs(
- self,
- prompt,
- height,
- width,
- callback_steps,
- negative_prompt=None,
- prompt_embeds=None,
- negative_prompt_embeds=None,
- ):
- if height % 8 != 0 or width % 8 != 0:
- raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.")
-
- if (callback_steps is None) or (
- callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0)
- ):
- raise ValueError(
- f"`callback_steps` has to be a positive integer but is {callback_steps} of type"
- f" {type(callback_steps)}."
- )
-
- if prompt is not None and prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
- " only forward one of the two."
- )
- elif prompt is None and prompt_embeds is None:
- raise ValueError(
- "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
- )
- elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)):
- raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")
-
- if negative_prompt is not None and negative_prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
- f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
- )
-
- if prompt_embeds is not None and negative_prompt_embeds is not None:
- if prompt_embeds.shape != negative_prompt_embeds.shape:
- raise ValueError(
- "`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but"
- f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`"
- f" {negative_prompt_embeds.shape}."
- )
-
- def prepare_latents(self, batch_size, num_channels_latents, height, width, dtype, device, generator, latents=None):
- shape = (batch_size, num_channels_latents, height // self.vae_scale_factor, width // self.vae_scale_factor)
- if isinstance(generator, list) and len(generator) != batch_size:
- raise ValueError(
- f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
- f" size of {batch_size}. Make sure the batch size matches the length of the generators."
- )
-
- if latents is None:
- latents = torch.randn(shape, generator=generator, device=device, dtype=dtype)
- else:
- latents = latents.to(device)
-
- # scale the initial noise by the standard deviation required by the scheduler
- latents = latents * self.scheduler.init_noise_sigma
- return latents
-
- @torch.no_grad()
- def __call__(
- self,
- prompt: Union[str, List[str]] = None,
- height: Optional[int] = 256,
- width: Optional[int] = 1024,
- num_inference_steps: int = 100,
- guidance_scale: float = 7.5,
- negative_prompt: Optional[Union[str, List[str]]] = None,
- num_images_per_prompt: Optional[int] = 1,
- eta: float = 0.0,
- generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
- latents: Optional[torch.FloatTensor] = None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- output_type: Optional[str] = "pt",
- return_dict: bool = True,
- callback: Optional[Callable[[int, int, torch.FloatTensor], None]] = None,
- callback_steps: int = 1,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- guidance_rescale: float = 0.0,
- duration: Optional[float] = 10,
- ):
- # 0. Default height and width to unet
- height = height or self.unet.config.sample_size * self.vae_scale_factor
- width = width or self.unet.config.sample_size * self.vae_scale_factor
- audio_length = int(duration * 16000)
-
- # 1. Check inputs. Raise error if not correct
- self.check_inputs(
- prompt, height, width, callback_steps, negative_prompt, prompt_embeds, negative_prompt_embeds
- )
-
- # 2. Define call parameters
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- device = self._execution_device
- # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
- # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
- # corresponds to doing no classifier free guidance.
- do_classifier_free_guidance = guidance_scale > 1.0
-
- # 3. Encode input prompt
- prompt_embeds = self._encode_prompt(
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt,
- prompt_embeds=prompt_embeds,
- negative_prompt_embeds=negative_prompt_embeds,
- )
-
- # 4. Prepare timesteps
- self.scheduler.set_timesteps(num_inference_steps, device=device)
- timesteps = self.scheduler.timesteps
-
- # 5. Prepare latent variables
- num_channels_latents = self.unet.config.in_channels
- latents = self.prepare_latents(
- batch_size * num_images_per_prompt,
- num_channels_latents,
- height,
- width,
- prompt_embeds.dtype,
- device,
- generator,
- latents,
- )
-
- # 6. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
- extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
-
- # 7. Denoising loop
- num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
- with self.progress_bar(total=num_inference_steps) as progress_bar:
- for i, t in enumerate(timesteps):
- # expand the latents if we are doing classifier free guidance
- latent_model_input = torch.cat([latents] * 2) if do_classifier_free_guidance else latents
- latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
-
- # predict the noise residual
- noise_pred = self.unet(
- latent_model_input,
- t,
- encoder_hidden_states=prompt_embeds,
- cross_attention_kwargs=cross_attention_kwargs,
- return_dict=False,
- )[0]
-
- # perform guidance
- if do_classifier_free_guidance:
- noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
- noise_pred = noise_pred_uncond + guidance_scale * (noise_pred_text - noise_pred_uncond)
-
- if do_classifier_free_guidance and guidance_rescale > 0.0:
- # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf
- noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=guidance_rescale)
-
- # compute the previous noisy sample x_t -> x_t-1
- latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0]
-
- # call the callback, if provided
- if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
- progress_bar.update()
- if callback is not None and i % callback_steps == 0:
- callback(i, t, latents)
-
- if not output_type == "latent":
- image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False)[0]
- image, has_nsfw_concept = self.run_safety_checker(image, device, prompt_embeds.dtype)
- else:
- image = latents
- has_nsfw_concept = None
-
- if has_nsfw_concept is None:
- do_denormalize = [True] * image.shape[0]
- else:
- do_denormalize = [not has_nsfw for has_nsfw in has_nsfw_concept]
-
- image = self.image_processor.postprocess(image, output_type=output_type, do_denormalize=do_denormalize)
-
- # Offload last model to CPU
- if hasattr(self, "final_offload_hook") and self.final_offload_hook is not None:
- self.final_offload_hook.offload()
-
- # Generate audio
- spectrograms, audios = [], []
- for img in image:
- spectrogram = denormalize_spectrogram(img)
- audio = self.vocoder.inference(spectrogram, lengths=audio_length)[0]
- audios.append(audio)
- spectrograms.append(spectrogram)
-
- # Convert to PIL
- images = pt_to_numpy(image)
- images = numpy_to_pil(images)
- images = [image_add_color(image) for image in images]
-
- if not return_dict:
- return (images, audios, spectrograms)
-
- return PipelineOutput(images=images, audios=audios, spectrograms=spectrograms)
-
-
-def retrieve_timesteps(
- scheduler,
- num_inference_steps: Optional[int] = None,
- device: Optional[Union[str, torch.device]] = None,
- timesteps: Optional[List[int]] = None,
- **kwargs,
-):
- """
- Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles
- custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`.
-
- Args:
- scheduler (`SchedulerMixin`):
- The scheduler to get timesteps from.
- num_inference_steps (`int`):
- The number of diffusion steps used when generating samples with a pre-trained model. If used,
- `timesteps` must be `None`.
- device (`str` or `torch.device`, *optional*):
- The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
- timesteps (`List[int]`, *optional*):
- Custom timesteps used to support arbitrary spacing between timesteps. If `None`, then the default
- timestep spacing strategy of the scheduler is used. If `timesteps` is passed, `num_inference_steps`
- must be `None`.
-
- Returns:
- `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the
- second element is the number of inference steps.
- """
- if timesteps is not None:
- accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
- if not accepts_timesteps:
- raise ValueError(
- f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
- f" timestep schedules. Please check whether you are using the correct scheduler."
- )
- scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
- timesteps = scheduler.timesteps
- num_inference_steps = len(timesteps)
- else:
- scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
- timesteps = scheduler.timesteps
- return timesteps, num_inference_steps
-
-
-class AuffusionNoAdapterPipeline(
- DiffusionPipeline, TextualInversionLoaderMixin, LoraLoaderMixin, IPAdapterMixin, FromSingleFileMixin
-):
- r"""
- Pipeline for text-to-image generation using Stable Diffusion.
-
- This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods
- implemented for all pipelines (downloading, saving, running on a particular device, etc.).
-
- The pipeline also inherits the following loading methods:
- - [`~loaders.TextualInversionLoaderMixin.load_textual_inversion`] for loading textual inversion embeddings
- - [`~loaders.LoraLoaderMixin.load_lora_weights`] for loading LoRA weights
- - [`~loaders.LoraLoaderMixin.save_lora_weights`] for saving LoRA weights
- - [`~loaders.FromSingleFileMixin.from_single_file`] for loading `.ckpt` files
- - [`~loaders.IPAdapterMixin.load_ip_adapter`] for loading IP Adapters
-
- Args:
- vae ([`AutoencoderKL`]):
- Variational Auto-Encoder (VAE) model to encode and decode images to and from latent representations.
- text_encoder ([`~transformers.CLIPTextModel`]):
- Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)).
- tokenizer ([`~transformers.CLIPTokenizer`]):
- A `CLIPTokenizer` to tokenize text.
- unet ([`UNet2DConditionModel`]):
- A `UNet2DConditionModel` to denoise the encoded image latents.
- scheduler ([`SchedulerMixin`]):
- A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of
- [`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`].
- safety_checker ([`StableDiffusionSafetyChecker`]):
- Classification module that estimates whether generated images could be considered offensive or harmful.
- Please refer to the [model card](https://huggingface.co/runwayml/stable-diffusion-v1-5) for more details
- about a model's potential harms.
- feature_extractor ([`~transformers.CLIPImageProcessor`]):
- A `CLIPImageProcessor` to extract features from generated images; used as inputs to the `safety_checker`.
- """
-
- model_cpu_offload_seq = "text_encoder->image_encoder->unet->vae"
- _optional_components = ["safety_checker", "feature_extractor", "image_encoder"]
- _exclude_from_cpu_offload = ["safety_checker"]
- _callback_tensor_inputs = ["latents", "prompt_embeds", "negative_prompt_embeds"]
-
- def __init__(
- self,
- vae: AutoencoderKL,
- text_encoder: CLIPTextModel,
- tokenizer: CLIPTokenizer,
- unet: UNet2DConditionModel,
- scheduler: KarrasDiffusionSchedulers,
- safety_checker: StableDiffusionSafetyChecker,
- feature_extractor: CLIPImageProcessor,
- image_encoder: CLIPVisionModelWithProjection = None,
- requires_safety_checker: bool = True,
- ):
- super().__init__()
-
- if hasattr(scheduler.config, "steps_offset") and scheduler.config.steps_offset != 1:
- deprecation_message = (
- f"The configuration file of this scheduler: {scheduler} is outdated. `steps_offset`"
- f" should be set to 1 instead of {scheduler.config.steps_offset}. Please make sure "
- "to update the config accordingly as leaving `steps_offset` might led to incorrect results"
- " in future versions. If you have downloaded this checkpoint from the Hugging Face Hub,"
- " it would be very nice if you could open a Pull request for the `scheduler/scheduler_config.json`"
- " file"
- )
- deprecate("steps_offset!=1", "1.0.0", deprecation_message, standard_warn=False)
- new_config = dict(scheduler.config)
- new_config["steps_offset"] = 1
- scheduler._internal_dict = FrozenDict(new_config)
-
- if hasattr(scheduler.config, "clip_sample") and scheduler.config.clip_sample is True:
- deprecation_message = (
- f"The configuration file of this scheduler: {scheduler} has not set the configuration `clip_sample`."
- " `clip_sample` should be set to False in the configuration file. Please make sure to update the"
- " config accordingly as not setting `clip_sample` in the config might lead to incorrect results in"
- " future versions. If you have downloaded this checkpoint from the Hugging Face Hub, it would be very"
- " nice if you could open a Pull request for the `scheduler/scheduler_config.json` file"
- )
- deprecate("clip_sample not set", "1.0.0", deprecation_message, standard_warn=False)
- new_config = dict(scheduler.config)
- new_config["clip_sample"] = False
- scheduler._internal_dict = FrozenDict(new_config)
-
- if safety_checker is None and requires_safety_checker:
- logger.warning(
- f"You have disabled the safety checker for {self.__class__} by passing `safety_checker=None`. Ensure"
- " that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered"
- " results in services or applications open to the public. Both the diffusers team and Hugging Face"
- " strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling"
- " it only for use-cases that involve analyzing network behavior or auditing its results. For more"
- " information, please have a look at https://github.com/huggingface/diffusers/pull/254 ."
- )
-
- if safety_checker is not None and feature_extractor is None:
- raise ValueError(
- "Make sure to define a feature extractor when loading {self.__class__} if you want to use the safety"
- " checker. If you do not want to use the safety checker, you can pass `'safety_checker=None'` instead."
- )
-
- is_unet_version_less_0_9_0 = hasattr(unet.config, "_diffusers_version") and version.parse(
- version.parse(unet.config._diffusers_version).base_version
- ) < version.parse("0.9.0.dev0")
- is_unet_sample_size_less_64 = hasattr(unet.config, "sample_size") and unet.config.sample_size < 64
- if is_unet_version_less_0_9_0 and is_unet_sample_size_less_64:
- deprecation_message = (
- "The configuration file of the unet has set the default `sample_size` to smaller than"
- " 64 which seems highly unlikely. If your checkpoint is a fine-tuned version of any of the"
- " following: \n- CompVis/stable-diffusion-v1-4 \n- CompVis/stable-diffusion-v1-3 \n-"
- " CompVis/stable-diffusion-v1-2 \n- CompVis/stable-diffusion-v1-1 \n- runwayml/stable-diffusion-v1-5"
- " \n- runwayml/stable-diffusion-inpainting \n you should change 'sample_size' to 64 in the"
- " configuration file. Please make sure to update the config accordingly as leaving `sample_size=32`"
- " in the config might lead to incorrect results in future versions. If you have downloaded this"
- " checkpoint from the Hugging Face Hub, it would be very nice if you could open a Pull request for"
- " the `unet/config.json` file"
- )
- deprecate("sample_size<64", "1.0.0", deprecation_message, standard_warn=False)
- new_config = dict(unet.config)
- new_config["sample_size"] = 64
- unet._internal_dict = FrozenDict(new_config)
-
- self.register_modules(
- vae=vae,
- text_encoder=text_encoder,
- tokenizer=tokenizer,
- unet=unet,
- scheduler=scheduler,
- safety_checker=safety_checker,
- feature_extractor=feature_extractor,
- image_encoder=image_encoder,
- )
- self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
- self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor)
- self.register_to_config(requires_safety_checker=requires_safety_checker)
-
- def enable_vae_slicing(self):
- r"""
- Enable sliced VAE decoding. When this option is enabled, the VAE will split the input tensor in slices to
- compute decoding in several steps. This is useful to save some memory and allow larger batch sizes.
- """
- self.vae.enable_slicing()
-
- def disable_vae_slicing(self):
- r"""
- Disable sliced VAE decoding. If `enable_vae_slicing` was previously enabled, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_slicing()
-
- def enable_vae_tiling(self):
- r"""
- Enable tiled VAE decoding. When this option is enabled, the VAE will split the input tensor into tiles to
- compute decoding and encoding in several steps. This is useful for saving a large amount of memory and to allow
- processing larger images.
- """
- self.vae.enable_tiling()
-
- def disable_vae_tiling(self):
- r"""
- Disable tiled VAE decoding. If `enable_vae_tiling` was previously enabled, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_tiling()
-
- def _encode_prompt(
- self,
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt=None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- lora_scale: Optional[float] = None,
- **kwargs,
- ):
- deprecation_message = "`_encode_prompt()` is deprecated and it will be removed in a future version. Use `encode_prompt()` instead. Also, be aware that the output format changed from a concatenated tensor to a tuple."
- deprecate("_encode_prompt()", "1.0.0", deprecation_message, standard_warn=False)
-
- prompt_embeds_tuple = self.encode_prompt(
- prompt=prompt,
- device=device,
- num_images_per_prompt=num_images_per_prompt,
- do_classifier_free_guidance=do_classifier_free_guidance,
- negative_prompt=negative_prompt,
- prompt_embeds=prompt_embeds,
- negative_prompt_embeds=negative_prompt_embeds,
- lora_scale=lora_scale,
- **kwargs,
- )
-
- # concatenate for backwards comp
- prompt_embeds = torch.cat([prompt_embeds_tuple[1], prompt_embeds_tuple[0]])
-
- return prompt_embeds
-
- def encode_prompt(
- self,
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt=None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- lora_scale: Optional[float] = None,
- clip_skip: Optional[int] = None,
- ):
- r"""
- Encodes the prompt into text encoder hidden states.
-
- Args:
- prompt (`str` or `List[str]`, *optional*):
- prompt to be encoded
- device: (`torch.device`):
- torch device
- num_images_per_prompt (`int`):
- number of images that should be generated per prompt
- do_classifier_free_guidance (`bool`):
- whether to use classifier free guidance or not
- negative_prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts not to guide the image generation. If not defined, one has to pass
- `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is
- less than `1`).
- prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
- provided, text embeddings will be generated from `prompt` input argument.
- negative_prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
- weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
- argument.
- lora_scale (`float`, *optional*):
- A LoRA scale that will be applied to all LoRA layers of the text encoder if LoRA layers are loaded.
- clip_skip (`int`, *optional*):
- Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
- the output of the pre-final layer will be used for computing the prompt embeddings.
- """
- # set lora scale so that monkey patched LoRA
- # function of text encoder can correctly access it
- if lora_scale is not None and isinstance(self, LoraLoaderMixin):
- self._lora_scale = lora_scale
-
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- if prompt_embeds is None:
- # textual inversion: procecss multi-vector tokens if necessary
- if isinstance(self, TextualInversionLoaderMixin):
- prompt = self.maybe_convert_prompt(prompt, self.tokenizer)
-
- text_inputs = self.tokenizer(
- prompt,
- padding="max_length",
- max_length=self.tokenizer.model_max_length,
- truncation=True,
- return_tensors="pt",
- )
- text_input_ids = text_inputs.input_ids
- untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids
-
- if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(
- text_input_ids, untruncated_ids
- ):
- removed_text = self.tokenizer.batch_decode(
- untruncated_ids[:, self.tokenizer.model_max_length - 1 : -1]
- )
- logger.warning(
- "The following part of your input was truncated because CLIP can only handle sequences up to"
- f" {self.tokenizer.model_max_length} tokens: {removed_text}"
- )
-
- if hasattr(self.text_encoder.config, "use_attention_mask") and self.text_encoder.config.use_attention_mask:
- attention_mask = text_inputs.attention_mask.to(device)
- else:
- attention_mask = None
-
- if clip_skip is None:
- prompt_embeds = self.text_encoder(text_input_ids.to(device), attention_mask=attention_mask)
- prompt_embeds = prompt_embeds[0]
- else:
- prompt_embeds = self.text_encoder(
- text_input_ids.to(device), attention_mask=attention_mask, output_hidden_states=True
- )
- # Access the `hidden_states` first, that contains a tuple of
- # all the hidden states from the encoder layers. Then index into
- # the tuple to access the hidden states from the desired layer.
- prompt_embeds = prompt_embeds[-1][-(clip_skip + 1)]
- # We also need to apply the final LayerNorm here to not mess with the
- # representations. The `last_hidden_states` that we typically use for
- # obtaining the final prompt representations passes through the LayerNorm
- # layer.
- prompt_embeds = self.text_encoder.text_model.final_layer_norm(prompt_embeds)
-
- if self.text_encoder is not None:
- prompt_embeds_dtype = self.text_encoder.dtype
- elif self.unet is not None:
- prompt_embeds_dtype = self.unet.dtype
- else:
- prompt_embeds_dtype = prompt_embeds.dtype
-
- prompt_embeds = prompt_embeds.to(dtype=prompt_embeds_dtype, device=device)
-
- bs_embed, seq_len, _ = prompt_embeds.shape
- # duplicate text embeddings for each generation per prompt, using mps friendly method
- prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1)
- prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1)
-
- # get unconditional embeddings for classifier free guidance
- if do_classifier_free_guidance and negative_prompt_embeds is None:
- uncond_tokens: List[str]
- if negative_prompt is None:
- uncond_tokens = [""] * batch_size
- elif prompt is not None and type(prompt) is not type(negative_prompt):
- raise TypeError(
- f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !="
- f" {type(prompt)}."
- )
- elif isinstance(negative_prompt, str):
- uncond_tokens = [negative_prompt]
- elif batch_size != len(negative_prompt):
- raise ValueError(
- f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"
- f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"
- " the batch size of `prompt`."
- )
- else:
- uncond_tokens = negative_prompt
-
- # textual inversion: procecss multi-vector tokens if necessary
- if isinstance(self, TextualInversionLoaderMixin):
- uncond_tokens = self.maybe_convert_prompt(uncond_tokens, self.tokenizer)
-
- max_length = prompt_embeds.shape[1]
- uncond_input = self.tokenizer(
- uncond_tokens,
- padding="max_length",
- max_length=max_length,
- truncation=True,
- return_tensors="pt",
- )
-
- if hasattr(self.text_encoder.config, "use_attention_mask") and self.text_encoder.config.use_attention_mask:
- attention_mask = uncond_input.attention_mask.to(device)
- else:
- attention_mask = None
-
- negative_prompt_embeds = self.text_encoder(
- uncond_input.input_ids.to(device),
- attention_mask=attention_mask,
- )
- negative_prompt_embeds = negative_prompt_embeds[0]
-
- if do_classifier_free_guidance:
- # duplicate unconditional embeddings for each generation per prompt, using mps friendly method
- seq_len = negative_prompt_embeds.shape[1]
-
- negative_prompt_embeds = negative_prompt_embeds.to(dtype=prompt_embeds_dtype, device=device)
-
- negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1)
- negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1)
-
- return prompt_embeds, negative_prompt_embeds
-
- def prepare_ip_adapter_image_embeds(
- self, ip_adapter_image, ip_adapter_image_embeds, device, num_images_per_prompt, do_classifier_free_guidance
- ):
- if ip_adapter_image_embeds is None:
- if not isinstance(ip_adapter_image, list):
- ip_adapter_image = [ip_adapter_image]
-
- if len(ip_adapter_image) != len(self.unet.encoder_hid_proj.image_projection_layers):
- raise ValueError(
- f"`ip_adapter_image` must have same length as the number of IP Adapters. Got {len(ip_adapter_image)} images and {len(self.unet.encoder_hid_proj.image_projection_layers)} IP Adapters."
- )
-
- image_embeds = []
- for single_ip_adapter_image, image_proj_layer in zip(
- ip_adapter_image, self.unet.encoder_hid_proj.image_projection_layers
- ):
- output_hidden_state = not isinstance(image_proj_layer, ImageProjection)
- single_image_embeds, single_negative_image_embeds = self.encode_image(
- single_ip_adapter_image, device, 1, output_hidden_state
- )
- single_image_embeds = torch.stack([single_image_embeds] * num_images_per_prompt, dim=0)
- single_negative_image_embeds = torch.stack(
- [single_negative_image_embeds] * num_images_per_prompt, dim=0
- )
-
- if do_classifier_free_guidance:
- single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
- single_image_embeds = single_image_embeds.to(device)
-
- image_embeds.append(single_image_embeds)
- else:
- repeat_dims = [1]
- image_embeds = []
- for single_image_embeds in ip_adapter_image_embeds:
- if do_classifier_free_guidance:
- single_negative_image_embeds, single_image_embeds = single_image_embeds.chunk(2)
- single_image_embeds = single_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
- )
- single_negative_image_embeds = single_negative_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_negative_image_embeds.shape[1:]))
- )
- single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
- else:
- single_image_embeds = single_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
- )
- image_embeds.append(single_image_embeds)
-
- return image_embeds
-
- def encode_image(self, image, device, num_images_per_prompt, output_hidden_states=None):
- dtype = next(self.image_encoder.parameters()).dtype
-
- if not isinstance(image, torch.Tensor):
- image = self.feature_extractor(image, return_tensors="pt").pixel_values
-
- image = image.to(device=device, dtype=dtype)
- if output_hidden_states:
- image_enc_hidden_states = self.image_encoder(image, output_hidden_states=True).hidden_states[-2]
- image_enc_hidden_states = image_enc_hidden_states.repeat_interleave(num_images_per_prompt, dim=0)
- uncond_image_enc_hidden_states = self.image_encoder(
- torch.zeros_like(image), output_hidden_states=True
- ).hidden_states[-2]
- uncond_image_enc_hidden_states = uncond_image_enc_hidden_states.repeat_interleave(
- num_images_per_prompt, dim=0
- )
- return image_enc_hidden_states, uncond_image_enc_hidden_states
- else:
- image_embeds = self.image_encoder(image).image_embeds
- image_embeds = image_embeds.repeat_interleave(num_images_per_prompt, dim=0)
- uncond_image_embeds = torch.zeros_like(image_embeds)
-
- return image_embeds, uncond_image_embeds
-
- def run_safety_checker(self, image, device, dtype):
- if self.safety_checker is None:
- has_nsfw_concept = None
- else:
- if torch.is_tensor(image):
- feature_extractor_input = self.image_processor.postprocess(image, output_type="pil")
- else:
- feature_extractor_input = self.image_processor.numpy_to_pil(image)
- safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device)
- image, has_nsfw_concept = self.safety_checker(
- images=image, clip_input=safety_checker_input.pixel_values.to(dtype)
- )
- return image, has_nsfw_concept
-
- def decode_latents(self, latents):
- deprecation_message = "The decode_latents method is deprecated and will be removed in 1.0.0. Please use VaeImageProcessor.postprocess(...) instead"
- deprecate("decode_latents", "1.0.0", deprecation_message, standard_warn=False)
-
- latents = 1 / self.vae.config.scaling_factor * latents
- image = self.vae.decode(latents, return_dict=False)[0]
- image = (image / 2 + 0.5).clamp(0, 1)
- # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16
- image = image.cpu().permute(0, 2, 3, 1).float().numpy()
- return image
-
- def prepare_extra_step_kwargs(self, generator, eta):
- # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
- # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
- # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
- # and should be between [0, 1]
-
- accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys())
- extra_step_kwargs = {}
- if accepts_eta:
- extra_step_kwargs["eta"] = eta
-
- # check if the scheduler accepts generator
- accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys())
- if accepts_generator:
- extra_step_kwargs["generator"] = generator
- return extra_step_kwargs
-
- def check_inputs(
- self,
- prompt,
- height,
- width,
- callback_steps,
- negative_prompt=None,
- prompt_embeds=None,
- negative_prompt_embeds=None,
- callback_on_step_end_tensor_inputs=None,
- ):
- if height % 8 != 0 or width % 8 != 0:
- raise ValueError(f"`height` and `width` have to be divisible by 8 but are {height} and {width}.")
-
- if callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0):
- raise ValueError(
- f"`callback_steps` has to be a positive integer but is {callback_steps} of type"
- f" {type(callback_steps)}."
- )
- if callback_on_step_end_tensor_inputs is not None and not all(
- k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs
- ):
- raise ValueError(
- f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}"
- )
-
- if prompt is not None and prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
- " only forward one of the two."
- )
- elif prompt is None and prompt_embeds is None:
- raise ValueError(
- "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
- )
- elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)):
- raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")
-
- if negative_prompt is not None and negative_prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
- f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
- )
-
- if prompt_embeds is not None and negative_prompt_embeds is not None:
- if prompt_embeds.shape != negative_prompt_embeds.shape:
- raise ValueError(
- "`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but"
- f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`"
- f" {negative_prompt_embeds.shape}."
- )
-
- def prepare_latents(self, batch_size, num_channels_latents, height, width, dtype, device, generator, latents=None):
- shape = (batch_size, num_channels_latents, height // self.vae_scale_factor, width // self.vae_scale_factor)
- if isinstance(generator, list) and len(generator) != batch_size:
- raise ValueError(
- f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
- f" size of {batch_size}. Make sure the batch size matches the length of the generators."
- )
-
- if latents is None:
- latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
- else:
- latents = latents.to(device)
-
- # scale the initial noise by the standard deviation required by the scheduler
- latents = latents * self.scheduler.init_noise_sigma
- return latents
-
- def enable_freeu(self, s1: float, s2: float, b1: float, b2: float):
- r"""Enables the FreeU mechanism as in https://arxiv.org/abs/2309.11497.
-
- The suffixes after the scaling factors represent the stages where they are being applied.
-
- Please refer to the [official repository](https://github.com/ChenyangSi/FreeU) for combinations of the values
- that are known to work well for different pipelines such as Stable Diffusion v1, v2, and Stable Diffusion XL.
-
- Args:
- s1 (`float`):
- Scaling factor for stage 1 to attenuate the contributions of the skip features. This is done to
- mitigate "oversmoothing effect" in the enhanced denoising process.
- s2 (`float`):
- Scaling factor for stage 2 to attenuate the contributions of the skip features. This is done to
- mitigate "oversmoothing effect" in the enhanced denoising process.
- b1 (`float`): Scaling factor for stage 1 to amplify the contributions of backbone features.
- b2 (`float`): Scaling factor for stage 2 to amplify the contributions of backbone features.
- """
- if not hasattr(self, "unet"):
- raise ValueError("The pipeline must have `unet` for using FreeU.")
- self.unet.enable_freeu(s1=s1, s2=s2, b1=b1, b2=b2)
-
- def disable_freeu(self):
- """Disables the FreeU mechanism if enabled."""
- self.unet.disable_freeu()
-
- # Copied from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl.StableDiffusionXLPipeline.fuse_qkv_projections
- def fuse_qkv_projections(self, unet: bool = True, vae: bool = True):
- """
- Enables fused QKV projections. For self-attention modules, all projection matrices (i.e., query,
- key, value) are fused. For cross-attention modules, key and value projection matrices are fused.
-
-
-
- This API is 🧪 experimental.
-
-
-
- Args:
- unet (`bool`, defaults to `True`): To apply fusion on the UNet.
- vae (`bool`, defaults to `True`): To apply fusion on the VAE.
- """
- self.fusing_unet = False
- self.fusing_vae = False
-
- if unet:
- self.fusing_unet = True
- self.unet.fuse_qkv_projections()
- self.unet.set_attn_processor(FusedAttnProcessor2_0())
-
- if vae:
- if not isinstance(self.vae, AutoencoderKL):
- raise ValueError("`fuse_qkv_projections()` is only supported for the VAE of type `AutoencoderKL`.")
-
- self.fusing_vae = True
- self.vae.fuse_qkv_projections()
- self.vae.set_attn_processor(FusedAttnProcessor2_0())
-
- # Copied from diffusers.pipelines.stable_diffusion_xl.pipeline_stable_diffusion_xl.StableDiffusionXLPipeline.unfuse_qkv_projections
- def unfuse_qkv_projections(self, unet: bool = True, vae: bool = True):
- """Disable QKV projection fusion if enabled.
-
-
-
- This API is 🧪 experimental.
-
-
-
- Args:
- unet (`bool`, defaults to `True`): To apply fusion on the UNet.
- vae (`bool`, defaults to `True`): To apply fusion on the VAE.
-
- """
- if unet:
- if not self.fusing_unet:
- logger.warning("The UNet was not initially fused for QKV projections. Doing nothing.")
- else:
- self.unet.unfuse_qkv_projections()
- self.fusing_unet = False
-
- if vae:
- if not self.fusing_vae:
- logger.warning("The VAE was not initially fused for QKV projections. Doing nothing.")
- else:
- self.vae.unfuse_qkv_projections()
- self.fusing_vae = False
-
- # Copied from diffusers.pipelines.latent_consistency_models.pipeline_latent_consistency_text2img.LatentConsistencyModelPipeline.get_guidance_scale_embedding
- def get_guidance_scale_embedding(self, w, embedding_dim=512, dtype=torch.float32):
- """
- See https://github.com/google-research/vdm/blob/dc27b98a554f65cdc654b800da5aa1846545d41b/model_vdm.py#L298
-
- Args:
- timesteps (`torch.Tensor`):
- generate embedding vectors at these timesteps
- embedding_dim (`int`, *optional*, defaults to 512):
- dimension of the embeddings to generate
- dtype:
- data type of the generated embeddings
-
- Returns:
- `torch.FloatTensor`: Embedding vectors with shape `(len(timesteps), embedding_dim)`
- """
- assert len(w.shape) == 1
- w = w * 1000.0
-
- half_dim = embedding_dim // 2
- emb = torch.log(torch.tensor(10000.0)) / (half_dim - 1)
- emb = torch.exp(torch.arange(half_dim, dtype=dtype) * -emb)
- emb = w.to(dtype)[:, None] * emb[None, :]
- emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
- if embedding_dim % 2 == 1: # zero pad
- emb = torch.nn.functional.pad(emb, (0, 1))
- assert emb.shape == (w.shape[0], embedding_dim)
- return emb
-
- @property
- def guidance_scale(self):
- return self._guidance_scale
-
- @property
- def guidance_rescale(self):
- return self._guidance_rescale
-
- @property
- def clip_skip(self):
- return self._clip_skip
-
- # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
- # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
- # corresponds to doing no classifier free guidance.
- @property
- def do_classifier_free_guidance(self):
- return self._guidance_scale > 1 and self.unet.config.time_cond_proj_dim is None
-
- @property
- def cross_attention_kwargs(self):
- return self._cross_attention_kwargs
-
- @property
- def num_timesteps(self):
- return self._num_timesteps
-
- @property
- def interrupt(self):
- return self._interrupt
-
- @torch.no_grad()
- def __call__(
- self,
- prompt: Union[str, List[str]] = None,
- height: Optional[int] = None,
- width: Optional[int] = None,
- num_inference_steps: int = 50,
- timesteps: List[int] = None,
- guidance_scale: float = 7.5,
- negative_prompt: Optional[Union[str, List[str]]] = None,
- num_images_per_prompt: Optional[int] = 1,
- eta: float = 0.0,
- generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
- latents: Optional[torch.FloatTensor] = None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- ip_adapter_image: Optional[PipelineImageInput] = None,
- ip_adapter_image_embeds: Optional[List[torch.FloatTensor]] = None,
- output_type: Optional[str] = "pil",
- return_dict: bool = True,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- guidance_rescale: float = 0.0,
- clip_skip: Optional[int] = None,
- callback_on_step_end: Optional[Callable[[int, int, Dict], None]] = None,
- callback_on_step_end_tensor_inputs: List[str] = ["latents"],
- **kwargs,
- ):
- r"""
- The call function to the pipeline for generation.
-
- Args:
- prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`.
- height (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
- The height in pixels of the generated image.
- width (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
- The width in pixels of the generated image.
- num_inference_steps (`int`, *optional*, defaults to 50):
- The number of denoising steps. More denoising steps usually lead to a higher quality image at the
- expense of slower inference.
- timesteps (`List[int]`, *optional*):
- Custom timesteps to use for the denoising process with schedulers which support a `timesteps` argument
- in their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is
- passed will be used. Must be in descending order.
- guidance_scale (`float`, *optional*, defaults to 7.5):
- A higher guidance scale value encourages the model to generate images closely linked to the text
- `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.
- negative_prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts to guide what to not include in image generation. If not defined, you need to
- pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`).
- num_images_per_prompt (`int`, *optional*, defaults to 1):
- The number of images to generate per prompt.
- eta (`float`, *optional*, defaults to 0.0):
- Corresponds to parameter eta (η) from the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies
- to the [`~schedulers.DDIMScheduler`], and is ignored in other schedulers.
- generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
- A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
- generation deterministic.
- latents (`torch.FloatTensor`, *optional*):
- Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
- generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
- tensor is generated by sampling using the supplied random `generator`.
- prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
- provided, text embeddings are generated from the `prompt` input argument.
- negative_prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If
- not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument.
- ip_adapter_image: (`PipelineImageInput`, *optional*): Optional image input to work with IP Adapters.
- output_type (`str`, *optional*, defaults to `"pil"`):
- The output format of the generated image. Choose between `PIL.Image` or `np.array`.
- return_dict (`bool`, *optional*, defaults to `True`):
- Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a
- plain tuple.
- cross_attention_kwargs (`dict`, *optional*):
- A kwargs dictionary that if specified is passed along to the [`AttentionProcessor`] as defined in
- [`self.processor`](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
- guidance_rescale (`float`, *optional*, defaults to 0.0):
- Guidance rescale factor from [Common Diffusion Noise Schedules and Sample Steps are
- Flawed](https://arxiv.org/pdf/2305.08891.pdf). Guidance rescale factor should fix overexposure when
- using zero terminal SNR.
- clip_skip (`int`, *optional*):
- Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
- the output of the pre-final layer will be used for computing the prompt embeddings.
- callback_on_step_end (`Callable`, *optional*):
- A function that calls at the end of each denoising steps during the inference. The function is called
- with the following arguments: `callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int,
- callback_kwargs: Dict)`. `callback_kwargs` will include a list of all tensors as specified by
- `callback_on_step_end_tensor_inputs`.
- callback_on_step_end_tensor_inputs (`List`, *optional*):
- The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
- will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
- `._callback_tensor_inputs` attribute of your pipeline class.
-
- Examples:
-
- Returns:
- [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:
- If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned,
- otherwise a `tuple` is returned where the first element is a list with the generated images and the
- second element is a list of `bool`s indicating whether the corresponding generated image contains
- "not-safe-for-work" (nsfw) content.
- """
-
- callback = kwargs.pop("callback", None)
- callback_steps = kwargs.pop("callback_steps", None)
-
- if callback is not None:
- deprecate(
- "callback",
- "1.0.0",
- "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
- )
- if callback_steps is not None:
- deprecate(
- "callback_steps",
- "1.0.0",
- "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
- )
-
- # 0. Default height and width to unet
- height = height or self.unet.config.sample_size * self.vae_scale_factor
- width = width or self.unet.config.sample_size * self.vae_scale_factor
- # to deal with lora scaling and other possible forward hooks
-
- # 1. Check inputs. Raise error if not correct
- self.check_inputs(
- prompt,
- height,
- width,
- callback_steps,
- negative_prompt,
- prompt_embeds,
- negative_prompt_embeds,
- callback_on_step_end_tensor_inputs,
- )
-
- self._guidance_scale = guidance_scale
- self._guidance_rescale = guidance_rescale
- self._clip_skip = clip_skip
- self._cross_attention_kwargs = cross_attention_kwargs
- self._interrupt = False
-
- # 2. Define call parameters
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- device = self._execution_device
-
- # 3. Encode input prompt
- lora_scale = (
- self.cross_attention_kwargs.get("scale", None) if self.cross_attention_kwargs is not None else None
- )
-
- prompt_embeds, negative_prompt_embeds = self.encode_prompt(
- prompt,
- device,
- num_images_per_prompt,
- self.do_classifier_free_guidance,
- negative_prompt,
- prompt_embeds=prompt_embeds,
- negative_prompt_embeds=negative_prompt_embeds,
- lora_scale=lora_scale,
- clip_skip=self.clip_skip,
- )
-
- # For classifier free guidance, we need to do two forward passes.
- # Here we concatenate the unconditional and text embeddings into a single batch
- # to avoid doing two forward passes
- if self.do_classifier_free_guidance:
- if prompt_embeds.shape != negative_prompt_embeds.shape:
- tmp_embeds = negative_prompt_embeds.clone()
- tmp_embeds[:, 0:1, :] = prompt_embeds
- prompt_embeds = tmp_embeds
- prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
- # TODO
- if ip_adapter_image is not None or ip_adapter_image_embeds is not None:
- image_embeds = self.prepare_ip_adapter_image_embeds(
- ip_adapter_image,
- ip_adapter_image_embeds,
- device,
- batch_size * num_images_per_prompt,
- self.do_classifier_free_guidance,
- )
-
- # 4. Prepare timesteps
- timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps)
-
- # 5. Prepare latent variables
- num_channels_latents = self.unet.config.in_channels
- latents = self.prepare_latents(
- batch_size * num_images_per_prompt,
- num_channels_latents,
- height,
- width,
- prompt_embeds.dtype,
- device,
- generator,
- latents,
- )
-
- # 6. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
- extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
-
- # 6.1 Add image embeds for IP-Adapter
- added_cond_kwargs = {"image_embeds": image_embeds} if ip_adapter_image is not None else None
-
- # 6.2 Optionally get Guidance Scale Embedding
- timestep_cond = None
- if self.unet.config.time_cond_proj_dim is not None:
- guidance_scale_tensor = torch.tensor(self.guidance_scale - 1).repeat(batch_size * num_images_per_prompt)
- timestep_cond = self.get_guidance_scale_embedding(
- guidance_scale_tensor, embedding_dim=self.unet.config.time_cond_proj_dim
- ).to(device=device, dtype=latents.dtype)
-
- # 7. Denoising loop
- num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
- self._num_timesteps = len(timesteps)
- with self.progress_bar(total=num_inference_steps) as progress_bar:
- for i, t in enumerate(timesteps):
- if self.interrupt:
- continue
-
- # expand the latents if we are doing classifier free guidance
- latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents
- latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
-
- # predict the noise residual
- noise_pred = self.unet(
- latent_model_input,
- t,
- encoder_hidden_states=prompt_embeds,
- timestep_cond=timestep_cond,
- cross_attention_kwargs=self.cross_attention_kwargs,
- added_cond_kwargs=added_cond_kwargs,
- return_dict=False,
- )[0]
-
- # perform guidance
- if self.do_classifier_free_guidance:
- noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
- noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond)
-
- if self.do_classifier_free_guidance and self.guidance_rescale > 0.0:
- # Based on 3.4. in https://arxiv.org/pdf/2305.08891.pdf
- noise_pred = rescale_noise_cfg(noise_pred, noise_pred_text, guidance_rescale=self.guidance_rescale)
-
- # compute the previous noisy sample x_t -> x_t-1
- latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0]
-
- if callback_on_step_end is not None:
- callback_kwargs = {}
- for k in callback_on_step_end_tensor_inputs:
- callback_kwargs[k] = locals()[k]
- callback_outputs = callback_on_step_end(self, i, t, callback_kwargs)
-
- latents = callback_outputs.pop("latents", latents)
- prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds)
- negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds)
-
- # call the callback, if provided
- if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
- progress_bar.update()
- if callback is not None and i % callback_steps == 0:
- step_idx = i // getattr(self.scheduler, "order", 1)
- callback(step_idx, t, latents)
-
- if not output_type == "latent":
- image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False, generator=generator)[
- 0
- ]
- image, has_nsfw_concept = self.run_safety_checker(image, device, prompt_embeds.dtype)
- else:
- image = latents
- has_nsfw_concept = None
-
- if has_nsfw_concept is None:
- do_denormalize = [True] * image.shape[0]
- else:
- do_denormalize = [not has_nsfw for has_nsfw in has_nsfw_concept]
-
- image = self.image_processor.postprocess(image, output_type=output_type, do_denormalize=do_denormalize)
-
- # Offload all models
- self.maybe_free_model_hooks()
-
- if not return_dict:
- return (image, has_nsfw_concept)
-
- return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept)
diff --git a/foleycrafter/pipelines/foleycrafter_pipeline.py b/foleycrafter/pipelines/foleycrafter_pipeline.py
new file mode 100644
index 0000000..0b6e101
--- /dev/null
+++ b/foleycrafter/pipelines/foleycrafter_pipeline.py
@@ -0,0 +1,585 @@
+# Copyright 2023 The HuggingFace Team. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+
+import inspect
+from typing import Any, Callable, Dict, List, Optional, Tuple, Union
+
+import torch
+from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer, CLIPVisionModelWithProjection
+
+import diffusers
+from diffusers.image_processor import PipelineImageInput
+from diffusers.models import AutoencoderKL, ControlNetModel, ImageProjection
+from diffusers.pipelines.controlnet.multicontrolnet import MultiControlNetModel
+from diffusers.pipelines.stable_diffusion.pipeline_output import StableDiffusionPipelineOutput
+from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
+from diffusers.schedulers import KarrasDiffusionSchedulers
+from diffusers.utils import (
+ deprecate,
+ logging,
+)
+from diffusers.utils.torch_utils import is_compiled_module, is_torch_version
+from foleycrafter.models.audio_generator.loaders.ip_adapter import IPAdapterMixin
+from foleycrafter.models.audio_generator.unet import UNet2DConditionModel
+
+
+logger = logging.get_logger(__name__) # pylint: disable=invalid-name
+
+
+# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps
+def retrieve_timesteps(
+ scheduler,
+ num_inference_steps: Optional[int] = None,
+ device: Optional[Union[str, torch.device]] = None,
+ timesteps: Optional[List[int]] = None,
+ **kwargs,
+):
+ """
+ Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles
+ custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`.
+
+ Args:
+ scheduler (`SchedulerMixin`):
+ The scheduler to get timesteps from.
+ num_inference_steps (`int`):
+ The number of diffusion steps used when generating samples with a pre-trained model. If used,
+ `timesteps` must be `None`.
+ device (`str` or `torch.device`, *optional*):
+ The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
+ timesteps (`List[int]`, *optional*):
+ Custom timesteps used to support arbitrary spacing between timesteps. If `None`, then the default
+ timestep spacing strategy of the scheduler is used. If `timesteps` is passed, `num_inference_steps`
+ must be `None`.
+
+ Returns:
+ `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the
+ second element is the number of inference steps.
+ """
+ if timesteps is not None:
+ accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
+ if not accepts_timesteps:
+ raise ValueError(
+ f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
+ f" timestep schedules. Please check whether you are using the correct scheduler."
+ )
+ scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
+ timesteps = scheduler.timesteps
+ num_inference_steps = len(timesteps)
+ else:
+ scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
+ timesteps = scheduler.timesteps
+ return timesteps, num_inference_steps
+
+
+class StableDiffusionControlNetPipeline(IPAdapterMixin, diffusers.StableDiffusionControlNetPipeline):
+ def __init__(
+ self,
+ vae: AutoencoderKL,
+ text_encoder: CLIPTextModel,
+ tokenizer: CLIPTokenizer,
+ unet: UNet2DConditionModel,
+ controlnet: Union[ControlNetModel, List[ControlNetModel], Tuple[ControlNetModel], MultiControlNetModel],
+ scheduler: KarrasDiffusionSchedulers,
+ safety_checker: StableDiffusionSafetyChecker,
+ feature_extractor: CLIPImageProcessor,
+ image_encoder: CLIPVisionModelWithProjection = None,
+ requires_safety_checker: bool = True,
+ ):
+ super().__init__(
+ vae,
+ text_encoder,
+ tokenizer,
+ unet,
+ controlnet,
+ scheduler,
+ safety_checker,
+ feature_extractor,
+ image_encoder,
+ requires_safety_checker,
+ )
+
+ def prepare_ip_adapter_image_embeds(
+ self, ip_adapter_image, ip_adapter_image_embeds, device, num_images_per_prompt, do_classifier_free_guidance
+ ):
+ if ip_adapter_image_embeds is None:
+ if not isinstance(ip_adapter_image, list):
+ ip_adapter_image = [ip_adapter_image]
+
+ if len(ip_adapter_image) != len(self.unet.encoder_hid_proj.image_projection_layers):
+ raise ValueError(
+ f"`ip_adapter_image` must have same length as the number of IP Adapters. Got {len(ip_adapter_image)} images and {len(self.unet.encoder_hid_proj.image_projection_layers)} IP Adapters."
+ )
+
+ image_embeds = []
+ for single_ip_adapter_image, image_proj_layer in zip(
+ ip_adapter_image, self.unet.encoder_hid_proj.image_projection_layers
+ ):
+ output_hidden_state = not isinstance(image_proj_layer, ImageProjection)
+ single_image_embeds, single_negative_image_embeds = self.encode_image(
+ single_ip_adapter_image, device, 1, output_hidden_state
+ )
+ single_image_embeds = torch.stack([single_image_embeds] * num_images_per_prompt, dim=0)
+ single_negative_image_embeds = torch.stack(
+ [single_negative_image_embeds] * num_images_per_prompt, dim=0
+ )
+
+ if do_classifier_free_guidance:
+ single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
+ single_image_embeds = single_image_embeds.to(device)
+
+ image_embeds.append(single_image_embeds)
+ else:
+ repeat_dims = [1]
+ image_embeds = []
+ for single_image_embeds in ip_adapter_image_embeds:
+ if do_classifier_free_guidance:
+ single_negative_image_embeds, single_image_embeds = single_image_embeds.chunk(2)
+ single_image_embeds = single_image_embeds.repeat(
+ num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
+ )
+ single_negative_image_embeds = single_negative_image_embeds.repeat(
+ num_images_per_prompt, *(repeat_dims * len(single_negative_image_embeds.shape[1:]))
+ )
+ single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
+ else:
+ single_image_embeds = single_image_embeds.repeat(
+ num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
+ )
+ image_embeds.append(single_image_embeds)
+
+ return image_embeds
+
+ @torch.no_grad()
+ def __call__(
+ self,
+ prompt: Union[str, List[str]] = None,
+ image: PipelineImageInput = None,
+ height: Optional[int] = None,
+ width: Optional[int] = None,
+ num_inference_steps: int = 50,
+ timesteps: List[int] = None,
+ guidance_scale: float = 7.5,
+ negative_prompt: Optional[Union[str, List[str]]] = None,
+ num_images_per_prompt: Optional[int] = 1,
+ eta: float = 0.0,
+ generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
+ latents: Optional[torch.FloatTensor] = None,
+ prompt_embeds: Optional[torch.FloatTensor] = None,
+ negative_prompt_embeds: Optional[torch.FloatTensor] = None,
+ ip_adapter_image: Optional[PipelineImageInput] = None,
+ ip_adapter_image_embeds: Optional[List[torch.FloatTensor]] = None,
+ output_type: Optional[str] = "pil",
+ return_dict: bool = True,
+ cross_attention_kwargs: Optional[Dict[str, Any]] = None,
+ controlnet_conditioning_scale: Union[float, List[float]] = 1.0,
+ controlnet_prompt_embeds: Optional[List[torch.FloatTensor]] = None,
+ guess_mode: bool = False,
+ control_guidance_start: Union[float, List[float]] = 0.0,
+ control_guidance_end: Union[float, List[float]] = 1.0,
+ clip_skip: Optional[int] = None,
+ callback_on_step_end: Optional[Callable[[int, int, Dict], None]] = None,
+ callback_on_step_end_tensor_inputs: List[str] = ["latents"],
+ **kwargs,
+ ):
+ r"""
+ The call function to the pipeline for generation.
+
+ Args:
+ prompt (`str` or `List[str]`, *optional*):
+ The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`.
+ image (`torch.FloatTensor`, `PIL.Image.Image`, `np.ndarray`, `List[torch.FloatTensor]`, `List[PIL.Image.Image]`, `List[np.ndarray]`,:
+ `List[List[torch.FloatTensor]]`, `List[List[np.ndarray]]` or `List[List[PIL.Image.Image]]`):
+ The ControlNet input condition to provide guidance to the `unet` for generation. If the type is
+ specified as `torch.FloatTensor`, it is passed to ControlNet as is. `PIL.Image.Image` can also be
+ accepted as an image. The dimensions of the output image defaults to `image`'s dimensions. If height
+ and/or width are passed, `image` is resized accordingly. If multiple ControlNets are specified in
+ `init`, images must be passed as a list such that each element of the list can be correctly batched for
+ input to a single ControlNet.
+ height (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
+ The height in pixels of the generated image.
+ width (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
+ The width in pixels of the generated image.
+ num_inference_steps (`int`, *optional*, defaults to 50):
+ The number of denoising steps. More denoising steps usually lead to a higher quality image at the
+ expense of slower inference.
+ timesteps (`List[int]`, *optional*):
+ Custom timesteps to use for the denoising process with schedulers which support a `timesteps` argument
+ in their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is
+ passed will be used. Must be in descending order.
+ guidance_scale (`float`, *optional*, defaults to 7.5):
+ A higher guidance scale value encourages the model to generate images closely linked to the text
+ `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.
+ negative_prompt (`str` or `List[str]`, *optional*):
+ The prompt or prompts to guide what to not include in image generation. If not defined, you need to
+ pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`).
+ num_images_per_prompt (`int`, *optional*, defaults to 1):
+ The number of images to generate per prompt.
+ eta (`float`, *optional*, defaults to 0.0):
+ Corresponds to parameter eta (η) from the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies
+ to the [`~schedulers.DDIMScheduler`], and is ignored in other schedulers.
+ generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
+ A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
+ generation deterministic.
+ latents (`torch.FloatTensor`, *optional*):
+ Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
+ generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
+ tensor is generated by sampling using the supplied random `generator`.
+ prompt_embeds (`torch.FloatTensor`, *optional*):
+ Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
+ provided, text embeddings are generated from the `prompt` input argument.
+ negative_prompt_embeds (`torch.FloatTensor`, *optional*):
+ Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If
+ not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument.
+ ip_adapter_image: (`PipelineImageInput`, *optional*): Optional image input to work with IP Adapters.
+ output_type (`str`, *optional*, defaults to `"pil"`):
+ The output format of the generated image. Choose between `PIL.Image` or `np.array`.
+ return_dict (`bool`, *optional*, defaults to `True`):
+ Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a
+ plain tuple.
+ callback (`Callable`, *optional*):
+ A function that calls every `callback_steps` steps during inference. The function is called with the
+ following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.
+ callback_steps (`int`, *optional*, defaults to 1):
+ The frequency at which the `callback` function is called. If not specified, the callback is called at
+ every step.
+ cross_attention_kwargs (`dict`, *optional*):
+ A kwargs dictionary that if specified is passed along to the [`AttentionProcessor`] as defined in
+ [`self.processor`](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
+ controlnet_conditioning_scale (`float` or `List[float]`, *optional*, defaults to 1.0):
+ The outputs of the ControlNet are multiplied by `controlnet_conditioning_scale` before they are added
+ to the residual in the original `unet`. If multiple ControlNets are specified in `init`, you can set
+ the corresponding scale as a list.
+ guess_mode (`bool`, *optional*, defaults to `False`):
+ The ControlNet encoder tries to recognize the content of the input image even if you remove all
+ prompts. A `guidance_scale` value between 3.0 and 5.0 is recommended.
+ control_guidance_start (`float` or `List[float]`, *optional*, defaults to 0.0):
+ The percentage of total steps at which the ControlNet starts applying.
+ control_guidance_end (`float` or `List[float]`, *optional*, defaults to 1.0):
+ The percentage of total steps at which the ControlNet stops applying.
+ clip_skip (`int`, *optional*):
+ Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
+ the output of the pre-final layer will be used for computing the prompt embeddings.
+ callback_on_step_end (`Callable`, *optional*):
+ A function that calls at the end of each denoising steps during the inference. The function is called
+ with the following arguments: `callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int,
+ callback_kwargs: Dict)`. `callback_kwargs` will include a list of all tensors as specified by
+ `callback_on_step_end_tensor_inputs`.
+ callback_on_step_end_tensor_inputs (`List`, *optional*):
+ The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
+ will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
+ `._callback_tensor_inputs` attribute of your pipeline class.
+
+ Examples:
+
+ Returns:
+ [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:
+ If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned,
+ otherwise a `tuple` is returned where the first element is a list with the generated images and the
+ second element is a list of `bool`s indicating whether the corresponding generated image contains
+ "not-safe-for-work" (nsfw) content.
+ """
+
+ callback = kwargs.pop("callback", None)
+ callback_steps = kwargs.pop("callback_steps", None)
+
+ if callback is not None:
+ deprecate(
+ "callback",
+ "1.0.0",
+ "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
+ )
+ if callback_steps is not None:
+ deprecate(
+ "callback_steps",
+ "1.0.0",
+ "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
+ )
+
+ controlnet = self.controlnet._orig_mod if is_compiled_module(self.controlnet) else self.controlnet
+
+ # align format for control guidance
+ if not isinstance(control_guidance_start, list) and isinstance(control_guidance_end, list):
+ control_guidance_start = len(control_guidance_end) * [control_guidance_start]
+ elif not isinstance(control_guidance_end, list) and isinstance(control_guidance_start, list):
+ control_guidance_end = len(control_guidance_start) * [control_guidance_end]
+ elif not isinstance(control_guidance_start, list) and not isinstance(control_guidance_end, list):
+ mult = len(controlnet.nets) if isinstance(controlnet, MultiControlNetModel) else 1
+ control_guidance_start, control_guidance_end = (
+ mult * [control_guidance_start],
+ mult * [control_guidance_end],
+ )
+
+ # 1. Check inputs. Raise error if not correct
+ self.check_inputs(
+ prompt,
+ image,
+ callback_steps,
+ negative_prompt,
+ prompt_embeds,
+ negative_prompt_embeds,
+ controlnet_conditioning_scale,
+ control_guidance_start,
+ control_guidance_end,
+ callback_on_step_end_tensor_inputs,
+ )
+
+ self._guidance_scale = guidance_scale
+ self._clip_skip = clip_skip
+ self._cross_attention_kwargs = cross_attention_kwargs
+
+ # 2. Define call parameters
+ if prompt is not None and isinstance(prompt, str):
+ batch_size = 1
+ elif prompt is not None and isinstance(prompt, list):
+ batch_size = len(prompt)
+ else:
+ batch_size = prompt_embeds.shape[0]
+
+ device = self._execution_device
+
+ if isinstance(controlnet, MultiControlNetModel) and isinstance(controlnet_conditioning_scale, float):
+ controlnet_conditioning_scale = [controlnet_conditioning_scale] * len(controlnet.nets)
+
+ global_pool_conditions = (
+ controlnet.config.global_pool_conditions
+ if isinstance(controlnet, ControlNetModel)
+ else controlnet.nets[0].config.global_pool_conditions
+ )
+ guess_mode = guess_mode or global_pool_conditions
+
+ # 3. Encode input prompt
+ text_encoder_lora_scale = (
+ self.cross_attention_kwargs.get("scale", None) if self.cross_attention_kwargs is not None else None
+ )
+ prompt_embeds, negative_prompt_embeds = self.encode_prompt(
+ prompt,
+ device,
+ num_images_per_prompt,
+ self.do_classifier_free_guidance,
+ negative_prompt,
+ prompt_embeds=prompt_embeds,
+ negative_prompt_embeds=negative_prompt_embeds,
+ lora_scale=text_encoder_lora_scale,
+ clip_skip=self.clip_skip,
+ )
+ # For classifier free guidance, we need to do two forward passes.
+ # Here we concatenate the unconditional and text embeddings into a single batch
+ # to avoid doing two forward passes
+ if self.do_classifier_free_guidance:
+ prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
+
+ if ip_adapter_image is not None or ip_adapter_image_embeds is not None:
+ image_embeds = self.prepare_ip_adapter_image_embeds(
+ ip_adapter_image,
+ ip_adapter_image_embeds,
+ device,
+ batch_size * num_images_per_prompt,
+ self.do_classifier_free_guidance,
+ )
+
+ # 4. Prepare image
+ if isinstance(controlnet, ControlNetModel):
+ image = self.prepare_image(
+ image=image,
+ width=width,
+ height=height,
+ batch_size=batch_size * num_images_per_prompt,
+ num_images_per_prompt=num_images_per_prompt,
+ device=device,
+ dtype=controlnet.dtype,
+ do_classifier_free_guidance=self.do_classifier_free_guidance,
+ guess_mode=guess_mode,
+ )
+ height, width = image.shape[-2:]
+ elif isinstance(controlnet, MultiControlNetModel):
+ images = []
+
+ for image_ in image:
+ image_ = self.prepare_image(
+ image=image_,
+ width=width,
+ height=height,
+ batch_size=batch_size * num_images_per_prompt,
+ num_images_per_prompt=num_images_per_prompt,
+ device=device,
+ dtype=controlnet.dtype,
+ do_classifier_free_guidance=self.do_classifier_free_guidance,
+ guess_mode=guess_mode,
+ )
+
+ images.append(image_)
+
+ image = images
+ height, width = image[0].shape[-2:]
+ else:
+ assert False
+
+ # 5. Prepare timesteps
+ timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps)
+ self._num_timesteps = len(timesteps)
+
+ # 6. Prepare latent variables
+ num_channels_latents = self.unet.config.in_channels
+ latents = self.prepare_latents(
+ batch_size * num_images_per_prompt,
+ num_channels_latents,
+ height,
+ width,
+ prompt_embeds.dtype,
+ device,
+ generator,
+ latents,
+ )
+
+ # 6.5 Optionally get Guidance Scale Embedding
+ timestep_cond = None
+ if self.unet.config.time_cond_proj_dim is not None:
+ guidance_scale_tensor = torch.tensor(self.guidance_scale - 1).repeat(batch_size * num_images_per_prompt)
+ timestep_cond = self.get_guidance_scale_embedding(
+ guidance_scale_tensor, embedding_dim=self.unet.config.time_cond_proj_dim
+ ).to(device=device, dtype=latents.dtype)
+
+ # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
+ extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
+
+ # 7.1 Add image embeds for IP-Adapter
+ added_cond_kwargs = {"image_embeds": image_embeds} if image_embeds is not None else None
+
+ # 7.2 Create tensor stating which controlnets to keep
+ controlnet_keep = []
+ for i in range(len(timesteps)):
+ keeps = [
+ 1.0 - float(i / len(timesteps) < s or (i + 1) / len(timesteps) > e)
+ for s, e in zip(control_guidance_start, control_guidance_end)
+ ]
+ controlnet_keep.append(keeps[0] if isinstance(controlnet, ControlNetModel) else keeps)
+
+ # 8. Denoising loop
+ num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
+ is_unet_compiled = is_compiled_module(self.unet)
+ is_controlnet_compiled = is_compiled_module(self.controlnet)
+ is_torch_higher_equal_2_1 = is_torch_version(">=", "2.1")
+ with self.progress_bar(total=num_inference_steps) as progress_bar:
+ for i, t in enumerate(timesteps):
+ # Relevant thread:
+ # https://dev-discuss.pytorch.org/t/cudagraphs-in-pytorch-2-0/1428
+ if (is_unet_compiled and is_controlnet_compiled) and is_torch_higher_equal_2_1:
+ torch._inductor.cudagraph_mark_step_begin()
+ # expand the latents if we are doing classifier free guidance
+ latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents
+ latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
+
+ # controlnet(s) inference
+ if guess_mode and self.do_classifier_free_guidance:
+ # Infer ControlNet only for the conditional batch.
+ control_model_input = latents
+ control_model_input = self.scheduler.scale_model_input(control_model_input, t)
+ controlnet_prompt_embeds = prompt_embeds.chunk(2)[1]
+ else:
+ control_model_input = latent_model_input
+ controlnet_prompt_embeds = prompt_embeds
+
+ if isinstance(controlnet_keep[i], list):
+ cond_scale = [c * s for c, s in zip(controlnet_conditioning_scale, controlnet_keep[i])]
+ else:
+ controlnet_cond_scale = controlnet_conditioning_scale
+ if isinstance(controlnet_cond_scale, list):
+ controlnet_cond_scale = controlnet_cond_scale[0]
+ cond_scale = controlnet_cond_scale * controlnet_keep[i]
+
+ down_block_res_samples, mid_block_res_sample = self.controlnet(
+ control_model_input,
+ t,
+ encoder_hidden_states=controlnet_prompt_embeds,
+ controlnet_cond=image,
+ conditioning_scale=cond_scale,
+ guess_mode=guess_mode,
+ return_dict=False,
+ )
+
+ if guess_mode and self.do_classifier_free_guidance:
+ # Inferred ControlNet only for the conditional batch.
+ # To apply the output of ControlNet to both the unconditional and conditional batches,
+ # add 0 to the unconditional batch to keep it unchanged.
+ down_block_res_samples = [torch.cat([torch.zeros_like(d), d]) for d in down_block_res_samples]
+ mid_block_res_sample = torch.cat([torch.zeros_like(mid_block_res_sample), mid_block_res_sample])
+
+ # predict the noise residual
+ noise_pred = self.unet(
+ latent_model_input,
+ t,
+ encoder_hidden_states=prompt_embeds,
+ timestep_cond=timestep_cond,
+ cross_attention_kwargs=self.cross_attention_kwargs,
+ down_block_additional_residuals=down_block_res_samples,
+ mid_block_additional_residual=mid_block_res_sample,
+ added_cond_kwargs=added_cond_kwargs,
+ return_dict=False,
+ )[0]
+
+ # perform guidance
+ if self.do_classifier_free_guidance:
+ noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
+ noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond)
+
+ # compute the previous noisy sample x_t -> x_t-1
+ latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0]
+
+ if callback_on_step_end is not None:
+ callback_kwargs = {}
+ for k in callback_on_step_end_tensor_inputs:
+ callback_kwargs[k] = locals()[k]
+ callback_outputs = callback_on_step_end(self, i, t, callback_kwargs)
+
+ latents = callback_outputs.pop("latents", latents)
+ prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds)
+ negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds)
+
+ # call the callback, if provided
+ if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
+ progress_bar.update()
+ if callback is not None and i % callback_steps == 0:
+ step_idx = i // getattr(self.scheduler, "order", 1)
+ callback(step_idx, t, latents)
+
+ # If we do sequential model offloading, let's offload unet and controlnet
+ # manually for max memory savings
+ if hasattr(self, "final_offload_hook") and self.final_offload_hook is not None:
+ self.unet.to("cpu")
+ self.controlnet.to("cpu")
+ torch.cuda.empty_cache()
+
+ if not output_type == "latent":
+ image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False, generator=generator)[
+ 0
+ ]
+ image, has_nsfw_concept = self.run_safety_checker(image, device, prompt_embeds.dtype)
+ else:
+ image = latents
+ has_nsfw_concept = None
+
+ if has_nsfw_concept is None:
+ do_denormalize = [True] * image.shape[0]
+ else:
+ do_denormalize = [not has_nsfw for has_nsfw in has_nsfw_concept]
+
+ image = self.image_processor.postprocess(image, output_type=output_type, do_denormalize=do_denormalize)
+
+ # Offload all models
+ self.maybe_free_model_hooks()
+
+ if not return_dict:
+ return (image, has_nsfw_concept)
+
+ return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept)
diff --git a/foleycrafter/pipelines/pipeline_controlnet.py b/foleycrafter/pipelines/pipeline_controlnet.py
deleted file mode 100644
index 94b361d..0000000
--- a/foleycrafter/pipelines/pipeline_controlnet.py
+++ /dev/null
@@ -1,1341 +0,0 @@
-# Copyright 2023 The HuggingFace Team. All rights reserved.
-#
-# Licensed under the Apache License, Version 2.0 (the "License");
-# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
-#
-# Unless required by applicable law or agreed to in writing, software
-# distributed under the License is distributed on an "AS IS" BASIS,
-# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-# See the License for the specific language governing permissions and
-# limitations under the License.
-
-
-import inspect
-from typing import Any, Callable, Dict, List, Optional, Tuple, Union
-
-import numpy as np
-import PIL.Image
-import torch
-import torch.nn.functional as F
-from transformers import CLIPImageProcessor, CLIPTextModel, CLIPTokenizer, CLIPVisionModelWithProjection
-
-from diffusers.image_processor import PipelineImageInput, VaeImageProcessor
-from diffusers.loaders import FromSingleFileMixin, LoraLoaderMixin, TextualInversionLoaderMixin
-from diffusers.models import AutoencoderKL, ControlNetModel, ImageProjection
-from diffusers.models.lora import adjust_lora_scale_text_encoder
-from diffusers.pipelines.controlnet.multicontrolnet import MultiControlNetModel
-from diffusers.pipelines.pipeline_utils import DiffusionPipeline
-from diffusers.pipelines.stable_diffusion.pipeline_output import StableDiffusionPipelineOutput
-from diffusers.pipelines.stable_diffusion.safety_checker import StableDiffusionSafetyChecker
-from diffusers.schedulers import KarrasDiffusionSchedulers
-from diffusers.utils import (
- USE_PEFT_BACKEND,
- deprecate,
- logging,
- replace_example_docstring,
- scale_lora_layers,
- unscale_lora_layers,
-)
-from diffusers.utils.torch_utils import is_compiled_module, is_torch_version, randn_tensor
-from foleycrafter.models.auffusion.loaders.ip_adapter import IPAdapterMixin
-from foleycrafter.models.auffusion_unet import UNet2DConditionModel
-
-
-logger = logging.get_logger(__name__) # pylint: disable=invalid-name
-
-
-EXAMPLE_DOC_STRING = """
- Examples:
- ```py
- >>> # !pip install opencv-python transformers accelerate
- >>> from diffusers import StableDiffusionControlNetPipeline, ControlNetModel, UniPCMultistepScheduler
- >>> from diffusers.utils import load_image
- >>> import numpy as np
- >>> import torch
-
- >>> import cv2
- >>> from PIL import Image
-
- >>> # download an image
- >>> image = load_image(
- ... "https://hf.co/datasets/huggingface/documentation-images/resolve/main/diffusers/input_image_vermeer.png"
- ... )
- >>> image = np.array(image)
-
- >>> # get canny image
- >>> image = cv2.Canny(image, 100, 200)
- >>> image = image[:, :, None]
- >>> image = np.concatenate([image, image, image], axis=2)
- >>> canny_image = Image.fromarray(image)
-
- >>> # load control net and stable diffusion v1-5
- >>> controlnet = ControlNetModel.from_pretrained("lllyasviel/sd-controlnet-canny", torch_dtype=torch.float16)
- >>> pipe = StableDiffusionControlNetPipeline.from_pretrained(
- ... "runwayml/stable-diffusion-v1-5", controlnet=controlnet, torch_dtype=torch.float16
- ... )
-
- >>> # speed up diffusion process with faster scheduler and memory optimization
- >>> pipe.scheduler = UniPCMultistepScheduler.from_config(pipe.scheduler.config)
- >>> # remove following line if xformers is not installed
- >>> pipe.enable_xformers_memory_efficient_attention()
-
- >>> pipe.enable_model_cpu_offload()
-
- >>> # generate image
- >>> generator = torch.manual_seed(0)
- >>> image = pipe(
- ... "futuristic-looking woman", num_inference_steps=20, generator=generator, image=canny_image
- ... ).images[0]
- ```
-"""
-
-
-# Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.retrieve_timesteps
-def retrieve_timesteps(
- scheduler,
- num_inference_steps: Optional[int] = None,
- device: Optional[Union[str, torch.device]] = None,
- timesteps: Optional[List[int]] = None,
- **kwargs,
-):
- """
- Calls the scheduler's `set_timesteps` method and retrieves timesteps from the scheduler after the call. Handles
- custom timesteps. Any kwargs will be supplied to `scheduler.set_timesteps`.
-
- Args:
- scheduler (`SchedulerMixin`):
- The scheduler to get timesteps from.
- num_inference_steps (`int`):
- The number of diffusion steps used when generating samples with a pre-trained model. If used,
- `timesteps` must be `None`.
- device (`str` or `torch.device`, *optional*):
- The device to which the timesteps should be moved to. If `None`, the timesteps are not moved.
- timesteps (`List[int]`, *optional*):
- Custom timesteps used to support arbitrary spacing between timesteps. If `None`, then the default
- timestep spacing strategy of the scheduler is used. If `timesteps` is passed, `num_inference_steps`
- must be `None`.
-
- Returns:
- `Tuple[torch.Tensor, int]`: A tuple where the first element is the timestep schedule from the scheduler and the
- second element is the number of inference steps.
- """
- if timesteps is not None:
- accepts_timesteps = "timesteps" in set(inspect.signature(scheduler.set_timesteps).parameters.keys())
- if not accepts_timesteps:
- raise ValueError(
- f"The current scheduler class {scheduler.__class__}'s `set_timesteps` does not support custom"
- f" timestep schedules. Please check whether you are using the correct scheduler."
- )
- scheduler.set_timesteps(timesteps=timesteps, device=device, **kwargs)
- timesteps = scheduler.timesteps
- num_inference_steps = len(timesteps)
- else:
- scheduler.set_timesteps(num_inference_steps, device=device, **kwargs)
- timesteps = scheduler.timesteps
- return timesteps, num_inference_steps
-
-
-class StableDiffusionControlNetPipeline(
- DiffusionPipeline, TextualInversionLoaderMixin, LoraLoaderMixin, IPAdapterMixin, FromSingleFileMixin
-):
- r"""
- Pipeline for text-to-image generation using Stable Diffusion with ControlNet guidance.
-
- This model inherits from [`DiffusionPipeline`]. Check the superclass documentation for the generic methods
- implemented for all pipelines (downloading, saving, running on a particular device, etc.).
-
- The pipeline also inherits the following loading methods:
- - [`~loaders.TextualInversionLoaderMixin.load_textual_inversion`] for loading textual inversion embeddings
- - [`~loaders.LoraLoaderMixin.load_lora_weights`] for loading LoRA weights
- - [`~loaders.LoraLoaderMixin.save_lora_weights`] for saving LoRA weights
- - [`~loaders.FromSingleFileMixin.from_single_file`] for loading `.ckpt` files
- - [`~loaders.IPAdapterMixin.load_ip_adapter`] for loading IP Adapters
-
- Args:
- vae ([`AutoencoderKL`]):
- Variational Auto-Encoder (VAE) model to encode and decode images to and from latent representations.
- text_encoder ([`~transformers.CLIPTextModel`]):
- Frozen text-encoder ([clip-vit-large-patch14](https://huggingface.co/openai/clip-vit-large-patch14)).
- tokenizer ([`~transformers.CLIPTokenizer`]):
- A `CLIPTokenizer` to tokenize text.
- unet ([`UNet2DConditionModel`]):
- A `UNet2DConditionModel` to denoise the encoded image latents.
- controlnet ([`ControlNetModel`] or `List[ControlNetModel]`):
- Provides additional conditioning to the `unet` during the denoising process. If you set multiple
- ControlNets as a list, the outputs from each ControlNet are added together to create one combined
- additional conditioning.
- scheduler ([`SchedulerMixin`]):
- A scheduler to be used in combination with `unet` to denoise the encoded image latents. Can be one of
- [`DDIMScheduler`], [`LMSDiscreteScheduler`], or [`PNDMScheduler`].
- safety_checker ([`StableDiffusionSafetyChecker`]):
- Classification module that estimates whether generated images could be considered offensive or harmful.
- Please refer to the [model card](https://huggingface.co/runwayml/stable-diffusion-v1-5) for more details
- about a model's potential harms.
- feature_extractor ([`~transformers.CLIPImageProcessor`]):
- A `CLIPImageProcessor` to extract features from generated images; used as inputs to the `safety_checker`.
- """
-
- model_cpu_offload_seq = "text_encoder->image_encoder->unet->vae"
- _optional_components = ["safety_checker", "feature_extractor", "image_encoder"]
- _exclude_from_cpu_offload = ["safety_checker"]
- _callback_tensor_inputs = ["latents", "prompt_embeds", "negative_prompt_embeds"]
-
- def __init__(
- self,
- vae: AutoencoderKL,
- text_encoder: CLIPTextModel,
- tokenizer: CLIPTokenizer,
- unet: UNet2DConditionModel,
- controlnet: Union[ControlNetModel, List[ControlNetModel], Tuple[ControlNetModel], MultiControlNetModel],
- scheduler: KarrasDiffusionSchedulers,
- safety_checker: StableDiffusionSafetyChecker,
- feature_extractor: CLIPImageProcessor,
- image_encoder: CLIPVisionModelWithProjection = None,
- requires_safety_checker: bool = True,
- ):
- super().__init__()
-
- if safety_checker is None and requires_safety_checker:
- logger.warning(
- f"You have disabled the safety checker for {self.__class__} by passing `safety_checker=None`. Ensure"
- " that you abide to the conditions of the Stable Diffusion license and do not expose unfiltered"
- " results in services or applications open to the public. Both the diffusers team and Hugging Face"
- " strongly recommend to keep the safety filter enabled in all public facing circumstances, disabling"
- " it only for use-cases that involve analyzing network behavior or auditing its results. For more"
- " information, please have a look at https://github.com/huggingface/diffusers/pull/254 ."
- )
-
- if safety_checker is not None and feature_extractor is None:
- raise ValueError(
- "Make sure to define a feature extractor when loading {self.__class__} if you want to use the safety"
- " checker. If you do not want to use the safety checker, you can pass `'safety_checker=None'` instead."
- )
-
- if isinstance(controlnet, (list, tuple)):
- controlnet = MultiControlNetModel(controlnet)
-
- self.register_modules(
- vae=vae,
- text_encoder=text_encoder,
- tokenizer=tokenizer,
- unet=unet,
- controlnet=controlnet,
- scheduler=scheduler,
- safety_checker=safety_checker,
- feature_extractor=feature_extractor,
- image_encoder=image_encoder,
- )
- self.vae_scale_factor = 2 ** (len(self.vae.config.block_out_channels) - 1)
- self.image_processor = VaeImageProcessor(vae_scale_factor=self.vae_scale_factor, do_convert_rgb=True)
- self.control_image_processor = VaeImageProcessor(
- vae_scale_factor=self.vae_scale_factor, do_convert_rgb=True, do_normalize=False
- )
- self.register_to_config(requires_safety_checker=requires_safety_checker)
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_vae_slicing
- def enable_vae_slicing(self):
- r"""
- Enable sliced VAE decoding. When this option is enabled, the VAE will split the input tensor in slices to
- compute decoding in several steps. This is useful to save some memory and allow larger batch sizes.
- """
- self.vae.enable_slicing()
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.disable_vae_slicing
- def disable_vae_slicing(self):
- r"""
- Disable sliced VAE decoding. If `enable_vae_slicing` was previously enabled, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_slicing()
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_vae_tiling
- def enable_vae_tiling(self):
- r"""
- Enable tiled VAE decoding. When this option is enabled, the VAE will split the input tensor into tiles to
- compute decoding and encoding in several steps. This is useful for saving a large amount of memory and to allow
- processing larger images.
- """
- self.vae.enable_tiling()
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.disable_vae_tiling
- def disable_vae_tiling(self):
- r"""
- Disable tiled VAE decoding. If `enable_vae_tiling` was previously enabled, this method will go back to
- computing decoding in one step.
- """
- self.vae.disable_tiling()
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline._encode_prompt
- def _encode_prompt(
- self,
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt=None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- lora_scale: Optional[float] = None,
- **kwargs,
- ):
- deprecation_message = "`_encode_prompt()` is deprecated and it will be removed in a future version. Use `encode_prompt()` instead. Also, be aware that the output format changed from a concatenated tensor to a tuple."
- deprecate("_encode_prompt()", "1.0.0", deprecation_message, standard_warn=False)
-
- prompt_embeds_tuple = self.encode_prompt(
- prompt=prompt,
- device=device,
- num_images_per_prompt=num_images_per_prompt,
- do_classifier_free_guidance=do_classifier_free_guidance,
- negative_prompt=negative_prompt,
- prompt_embeds=prompt_embeds,
- negative_prompt_embeds=negative_prompt_embeds,
- lora_scale=lora_scale,
- **kwargs,
- )
-
- # concatenate for backwards comp
- prompt_embeds = torch.cat([prompt_embeds_tuple[1], prompt_embeds_tuple[0]])
-
- return prompt_embeds
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.encode_prompt
- def encode_prompt(
- self,
- prompt,
- device,
- num_images_per_prompt,
- do_classifier_free_guidance,
- negative_prompt=None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- lora_scale: Optional[float] = None,
- clip_skip: Optional[int] = None,
- ):
- r"""
- Encodes the prompt into text encoder hidden states.
-
- Args:
- prompt (`str` or `List[str]`, *optional*):
- prompt to be encoded
- device: (`torch.device`):
- torch device
- num_images_per_prompt (`int`):
- number of images that should be generated per prompt
- do_classifier_free_guidance (`bool`):
- whether to use classifier free guidance or not
- negative_prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts not to guide the image generation. If not defined, one has to pass
- `negative_prompt_embeds` instead. Ignored when not using guidance (i.e., ignored if `guidance_scale` is
- less than `1`).
- prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt weighting. If not
- provided, text embeddings will be generated from `prompt` input argument.
- negative_prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated negative text embeddings. Can be used to easily tweak text inputs, *e.g.* prompt
- weighting. If not provided, negative_prompt_embeds will be generated from `negative_prompt` input
- argument.
- lora_scale (`float`, *optional*):
- A LoRA scale that will be applied to all LoRA layers of the text encoder if LoRA layers are loaded.
- clip_skip (`int`, *optional*):
- Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
- the output of the pre-final layer will be used for computing the prompt embeddings.
- """
- # set lora scale so that monkey patched LoRA
- # function of text encoder can correctly access it
- if lora_scale is not None and isinstance(self, LoraLoaderMixin):
- self._lora_scale = lora_scale
-
- # dynamically adjust the LoRA scale
- if not USE_PEFT_BACKEND:
- adjust_lora_scale_text_encoder(self.text_encoder, lora_scale)
- else:
- scale_lora_layers(self.text_encoder, lora_scale)
-
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- if prompt_embeds is None:
- # textual inversion: procecss multi-vector tokens if necessary
- if isinstance(self, TextualInversionLoaderMixin):
- prompt = self.maybe_convert_prompt(prompt, self.tokenizer)
-
- text_inputs = self.tokenizer(
- prompt,
- padding="max_length",
- max_length=self.tokenizer.model_max_length,
- truncation=True,
- return_tensors="pt",
- )
- text_input_ids = text_inputs.input_ids
- untruncated_ids = self.tokenizer(prompt, padding="longest", return_tensors="pt").input_ids
-
- if untruncated_ids.shape[-1] >= text_input_ids.shape[-1] and not torch.equal(
- text_input_ids, untruncated_ids
- ):
- removed_text = self.tokenizer.batch_decode(
- untruncated_ids[:, self.tokenizer.model_max_length - 1 : -1]
- )
- logger.warning(
- "The following part of your input was truncated because CLIP can only handle sequences up to"
- f" {self.tokenizer.model_max_length} tokens: {removed_text}"
- )
-
- if hasattr(self.text_encoder.config, "use_attention_mask") and self.text_encoder.config.use_attention_mask:
- attention_mask = text_inputs.attention_mask.to(device)
- else:
- attention_mask = None
-
- if clip_skip is None:
- prompt_embeds = self.text_encoder(text_input_ids.to(device), attention_mask=attention_mask)
- prompt_embeds = prompt_embeds[0]
- else:
- prompt_embeds = self.text_encoder(
- text_input_ids.to(device), attention_mask=attention_mask, output_hidden_states=True
- )
- # Access the `hidden_states` first, that contains a tuple of
- # all the hidden states from the encoder layers. Then index into
- # the tuple to access the hidden states from the desired layer.
- prompt_embeds = prompt_embeds[-1][-(clip_skip + 1)]
- # We also need to apply the final LayerNorm here to not mess with the
- # representations. The `last_hidden_states` that we typically use for
- # obtaining the final prompt representations passes through the LayerNorm
- # layer.
- prompt_embeds = self.text_encoder.text_model.final_layer_norm(prompt_embeds)
-
- if self.text_encoder is not None:
- prompt_embeds_dtype = self.text_encoder.dtype
- elif self.unet is not None:
- prompt_embeds_dtype = self.unet.dtype
- else:
- prompt_embeds_dtype = prompt_embeds.dtype
-
- prompt_embeds = prompt_embeds.to(dtype=prompt_embeds_dtype, device=device)
-
- bs_embed, seq_len, _ = prompt_embeds.shape
- # duplicate text embeddings for each generation per prompt, using mps friendly method
- prompt_embeds = prompt_embeds.repeat(1, num_images_per_prompt, 1)
- prompt_embeds = prompt_embeds.view(bs_embed * num_images_per_prompt, seq_len, -1)
-
- # get unconditional embeddings for classifier free guidance
- if do_classifier_free_guidance and negative_prompt_embeds is None:
- uncond_tokens: List[str]
- if negative_prompt is None:
- uncond_tokens = [""] * batch_size
- elif prompt is not None and type(prompt) is not type(negative_prompt):
- raise TypeError(
- f"`negative_prompt` should be the same type to `prompt`, but got {type(negative_prompt)} !="
- f" {type(prompt)}."
- )
- elif isinstance(negative_prompt, str):
- uncond_tokens = [negative_prompt]
- elif batch_size != len(negative_prompt):
- raise ValueError(
- f"`negative_prompt`: {negative_prompt} has batch size {len(negative_prompt)}, but `prompt`:"
- f" {prompt} has batch size {batch_size}. Please make sure that passed `negative_prompt` matches"
- " the batch size of `prompt`."
- )
- else:
- uncond_tokens = negative_prompt
-
- # textual inversion: procecss multi-vector tokens if necessary
- if isinstance(self, TextualInversionLoaderMixin):
- uncond_tokens = self.maybe_convert_prompt(uncond_tokens, self.tokenizer)
-
- max_length = prompt_embeds.shape[1]
- uncond_input = self.tokenizer(
- uncond_tokens,
- padding="max_length",
- max_length=max_length,
- truncation=True,
- return_tensors="pt",
- )
-
- if hasattr(self.text_encoder.config, "use_attention_mask") and self.text_encoder.config.use_attention_mask:
- attention_mask = uncond_input.attention_mask.to(device)
- else:
- attention_mask = None
-
- negative_prompt_embeds = self.text_encoder(
- uncond_input.input_ids.to(device),
- attention_mask=attention_mask,
- )
- negative_prompt_embeds = negative_prompt_embeds[0]
-
- if do_classifier_free_guidance:
- # duplicate unconditional embeddings for each generation per prompt, using mps friendly method
- seq_len = negative_prompt_embeds.shape[1]
-
- negative_prompt_embeds = negative_prompt_embeds.to(dtype=prompt_embeds_dtype, device=device)
-
- negative_prompt_embeds = negative_prompt_embeds.repeat(1, num_images_per_prompt, 1)
- negative_prompt_embeds = negative_prompt_embeds.view(batch_size * num_images_per_prompt, seq_len, -1)
-
- if isinstance(self, LoraLoaderMixin) and USE_PEFT_BACKEND:
- # Retrieve the original scale by scaling back the LoRA layers
- unscale_lora_layers(self.text_encoder, lora_scale)
-
- return prompt_embeds, negative_prompt_embeds
-
- def prepare_ip_adapter_image_embeds(
- self, ip_adapter_image, ip_adapter_image_embeds, device, num_images_per_prompt, do_classifier_free_guidance
- ):
- if ip_adapter_image_embeds is None:
- if not isinstance(ip_adapter_image, list):
- ip_adapter_image = [ip_adapter_image]
-
- if len(ip_adapter_image) != len(self.unet.encoder_hid_proj.image_projection_layers):
- raise ValueError(
- f"`ip_adapter_image` must have same length as the number of IP Adapters. Got {len(ip_adapter_image)} images and {len(self.unet.encoder_hid_proj.image_projection_layers)} IP Adapters."
- )
-
- image_embeds = []
- for single_ip_adapter_image, image_proj_layer in zip(
- ip_adapter_image, self.unet.encoder_hid_proj.image_projection_layers
- ):
- output_hidden_state = not isinstance(image_proj_layer, ImageProjection)
- single_image_embeds, single_negative_image_embeds = self.encode_image(
- single_ip_adapter_image, device, 1, output_hidden_state
- )
- single_image_embeds = torch.stack([single_image_embeds] * num_images_per_prompt, dim=0)
- single_negative_image_embeds = torch.stack(
- [single_negative_image_embeds] * num_images_per_prompt, dim=0
- )
-
- if do_classifier_free_guidance:
- single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
- single_image_embeds = single_image_embeds.to(device)
-
- image_embeds.append(single_image_embeds)
- else:
- repeat_dims = [1]
- image_embeds = []
- for single_image_embeds in ip_adapter_image_embeds:
- if do_classifier_free_guidance:
- single_negative_image_embeds, single_image_embeds = single_image_embeds.chunk(2)
- single_image_embeds = single_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
- )
- single_negative_image_embeds = single_negative_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_negative_image_embeds.shape[1:]))
- )
- single_image_embeds = torch.cat([single_negative_image_embeds, single_image_embeds])
- else:
- single_image_embeds = single_image_embeds.repeat(
- num_images_per_prompt, *(repeat_dims * len(single_image_embeds.shape[1:]))
- )
- image_embeds.append(single_image_embeds)
-
- return image_embeds
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.encode_image
- def encode_image(self, image, device, num_images_per_prompt, output_hidden_states=None):
- dtype = next(self.image_encoder.parameters()).dtype
-
- if not isinstance(image, torch.Tensor):
- image = self.feature_extractor(image, return_tensors="pt").pixel_values
-
- image = image.to(device=device, dtype=dtype)
- if output_hidden_states:
- image_enc_hidden_states = self.image_encoder(image, output_hidden_states=True).hidden_states[-2]
- image_enc_hidden_states = image_enc_hidden_states.repeat_interleave(num_images_per_prompt, dim=0)
- uncond_image_enc_hidden_states = self.image_encoder(
- torch.zeros_like(image), output_hidden_states=True
- ).hidden_states[-2]
- uncond_image_enc_hidden_states = uncond_image_enc_hidden_states.repeat_interleave(
- num_images_per_prompt, dim=0
- )
- return image_enc_hidden_states, uncond_image_enc_hidden_states
- else:
- image_embeds = self.image_encoder(image).image_embeds
- image_embeds = image_embeds.repeat_interleave(num_images_per_prompt, dim=0)
- uncond_image_embeds = torch.zeros_like(image_embeds)
-
- return image_embeds, uncond_image_embeds
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.run_safety_checker
- def run_safety_checker(self, image, device, dtype):
- if self.safety_checker is None:
- has_nsfw_concept = None
- else:
- if torch.is_tensor(image):
- feature_extractor_input = self.image_processor.postprocess(image, output_type="pil")
- else:
- feature_extractor_input = self.image_processor.numpy_to_pil(image)
- safety_checker_input = self.feature_extractor(feature_extractor_input, return_tensors="pt").to(device)
- image, has_nsfw_concept = self.safety_checker(
- images=image, clip_input=safety_checker_input.pixel_values.to(dtype)
- )
- return image, has_nsfw_concept
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.decode_latents
- def decode_latents(self, latents):
- deprecation_message = "The decode_latents method is deprecated and will be removed in 1.0.0. Please use VaeImageProcessor.postprocess(...) instead"
- deprecate("decode_latents", "1.0.0", deprecation_message, standard_warn=False)
-
- latents = 1 / self.vae.config.scaling_factor * latents
- image = self.vae.decode(latents, return_dict=False)[0]
- image = (image / 2 + 0.5).clamp(0, 1)
- # we always cast to float32 as this does not cause significant overhead and is compatible with bfloat16
- image = image.cpu().permute(0, 2, 3, 1).float().numpy()
- return image
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_extra_step_kwargs
- def prepare_extra_step_kwargs(self, generator, eta):
- # prepare extra kwargs for the scheduler step, since not all schedulers have the same signature
- # eta (η) is only used with the DDIMScheduler, it will be ignored for other schedulers.
- # eta corresponds to η in DDIM paper: https://arxiv.org/abs/2010.02502
- # and should be between [0, 1]
-
- accepts_eta = "eta" in set(inspect.signature(self.scheduler.step).parameters.keys())
- extra_step_kwargs = {}
- if accepts_eta:
- extra_step_kwargs["eta"] = eta
-
- # check if the scheduler accepts generator
- accepts_generator = "generator" in set(inspect.signature(self.scheduler.step).parameters.keys())
- if accepts_generator:
- extra_step_kwargs["generator"] = generator
- return extra_step_kwargs
-
- def check_inputs(
- self,
- prompt,
- image,
- callback_steps,
- negative_prompt=None,
- prompt_embeds=None,
- negative_prompt_embeds=None,
- controlnet_conditioning_scale=1.0,
- control_guidance_start=0.0,
- control_guidance_end=1.0,
- callback_on_step_end_tensor_inputs=None,
- ):
- if callback_steps is not None and (not isinstance(callback_steps, int) or callback_steps <= 0):
- raise ValueError(
- f"`callback_steps` has to be a positive integer but is {callback_steps} of type"
- f" {type(callback_steps)}."
- )
-
- if callback_on_step_end_tensor_inputs is not None and not all(
- k in self._callback_tensor_inputs for k in callback_on_step_end_tensor_inputs
- ):
- raise ValueError(
- f"`callback_on_step_end_tensor_inputs` has to be in {self._callback_tensor_inputs}, but found {[k for k in callback_on_step_end_tensor_inputs if k not in self._callback_tensor_inputs]}"
- )
-
- if prompt is not None and prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `prompt`: {prompt} and `prompt_embeds`: {prompt_embeds}. Please make sure to"
- " only forward one of the two."
- )
- elif prompt is None and prompt_embeds is None:
- raise ValueError(
- "Provide either `prompt` or `prompt_embeds`. Cannot leave both `prompt` and `prompt_embeds` undefined."
- )
- elif prompt is not None and (not isinstance(prompt, str) and not isinstance(prompt, list)):
- raise ValueError(f"`prompt` has to be of type `str` or `list` but is {type(prompt)}")
-
- if negative_prompt is not None and negative_prompt_embeds is not None:
- raise ValueError(
- f"Cannot forward both `negative_prompt`: {negative_prompt} and `negative_prompt_embeds`:"
- f" {negative_prompt_embeds}. Please make sure to only forward one of the two."
- )
-
- if prompt_embeds is not None and negative_prompt_embeds is not None:
- if prompt_embeds.shape != negative_prompt_embeds.shape:
- raise ValueError(
- "`prompt_embeds` and `negative_prompt_embeds` must have the same shape when passed directly, but"
- f" got: `prompt_embeds` {prompt_embeds.shape} != `negative_prompt_embeds`"
- f" {negative_prompt_embeds.shape}."
- )
-
- # `prompt` needs more sophisticated handling when there are multiple
- # conditionings.
- if isinstance(self.controlnet, MultiControlNetModel):
- if isinstance(prompt, list):
- logger.warning(
- f"You have {len(self.controlnet.nets)} ControlNets and you have passed {len(prompt)}"
- " prompts. The conditionings will be fixed across the prompts."
- )
-
- # Check `image`
- is_compiled = hasattr(F, "scaled_dot_product_attention") and isinstance(
- self.controlnet, torch._dynamo.eval_frame.OptimizedModule
- )
- if (
- isinstance(self.controlnet, ControlNetModel)
- or is_compiled
- and isinstance(self.controlnet._orig_mod, ControlNetModel)
- ):
- self.check_image(image, prompt, prompt_embeds)
- elif (
- isinstance(self.controlnet, MultiControlNetModel)
- or is_compiled
- and isinstance(self.controlnet._orig_mod, MultiControlNetModel)
- ):
- if not isinstance(image, list):
- raise TypeError("For multiple controlnets: `image` must be type `list`")
-
- # When `image` is a nested list:
- # (e.g. [[canny_image_1, pose_image_1], [canny_image_2, pose_image_2]])
- elif any(isinstance(i, list) for i in image):
- raise ValueError("A single batch of multiple conditionings is not supported at the moment.")
- elif len(image) != len(self.controlnet.nets):
- raise ValueError(
- f"For multiple controlnets: `image` must have the same length as the number of controlnets, but got {len(image)} images and {len(self.controlnet.nets)} ControlNets."
- )
-
- for image_ in image:
- self.check_image(image_, prompt, prompt_embeds)
- else:
- assert False
-
- # Check `controlnet_conditioning_scale`
- if (
- isinstance(self.controlnet, ControlNetModel)
- or is_compiled
- and isinstance(self.controlnet._orig_mod, ControlNetModel)
- ):
- if not isinstance(controlnet_conditioning_scale, float):
- raise TypeError("For single controlnet: `controlnet_conditioning_scale` must be type `float`.")
- elif (
- isinstance(self.controlnet, MultiControlNetModel)
- or is_compiled
- and isinstance(self.controlnet._orig_mod, MultiControlNetModel)
- ):
- if isinstance(controlnet_conditioning_scale, list):
- if any(isinstance(i, list) for i in controlnet_conditioning_scale):
- raise ValueError("A single batch of multiple conditionings is not supported at the moment.")
- elif isinstance(controlnet_conditioning_scale, list) and len(controlnet_conditioning_scale) != len(
- self.controlnet.nets
- ):
- raise ValueError(
- "For multiple controlnets: When `controlnet_conditioning_scale` is specified as `list`, it must have"
- " the same length as the number of controlnets"
- )
- else:
- assert False
-
- if not isinstance(control_guidance_start, (tuple, list)):
- control_guidance_start = [control_guidance_start]
-
- if not isinstance(control_guidance_end, (tuple, list)):
- control_guidance_end = [control_guidance_end]
-
- if len(control_guidance_start) != len(control_guidance_end):
- raise ValueError(
- f"`control_guidance_start` has {len(control_guidance_start)} elements, but `control_guidance_end` has {len(control_guidance_end)} elements. Make sure to provide the same number of elements to each list."
- )
-
- if isinstance(self.controlnet, MultiControlNetModel):
- if len(control_guidance_start) != len(self.controlnet.nets):
- raise ValueError(
- f"`control_guidance_start`: {control_guidance_start} has {len(control_guidance_start)} elements but there are {len(self.controlnet.nets)} controlnets available. Make sure to provide {len(self.controlnet.nets)}."
- )
-
- for start, end in zip(control_guidance_start, control_guidance_end):
- if start >= end:
- raise ValueError(
- f"control guidance start: {start} cannot be larger or equal to control guidance end: {end}."
- )
- if start < 0.0:
- raise ValueError(f"control guidance start: {start} can't be smaller than 0.")
- if end > 1.0:
- raise ValueError(f"control guidance end: {end} can't be larger than 1.0.")
-
- def check_image(self, image, prompt, prompt_embeds):
- image_is_pil = isinstance(image, PIL.Image.Image)
- image_is_tensor = isinstance(image, torch.Tensor)
- image_is_np = isinstance(image, np.ndarray)
- image_is_pil_list = isinstance(image, list) and isinstance(image[0], PIL.Image.Image)
- image_is_tensor_list = isinstance(image, list) and isinstance(image[0], torch.Tensor)
- image_is_np_list = isinstance(image, list) and isinstance(image[0], np.ndarray)
-
- if (
- not image_is_pil
- and not image_is_tensor
- and not image_is_np
- and not image_is_pil_list
- and not image_is_tensor_list
- and not image_is_np_list
- ):
- raise TypeError(
- f"image must be passed and be one of PIL image, numpy array, torch tensor, list of PIL images, list of numpy arrays or list of torch tensors, but is {type(image)}"
- )
-
- if image_is_pil:
- image_batch_size = 1
- else:
- image_batch_size = len(image)
-
- if prompt is not None and isinstance(prompt, str):
- prompt_batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- prompt_batch_size = len(prompt)
- elif prompt_embeds is not None:
- prompt_batch_size = prompt_embeds.shape[0]
-
- if image_batch_size != 1 and image_batch_size != prompt_batch_size:
- raise ValueError(
- f"If image batch size is not 1, image batch size must be same as prompt batch size. image batch size: {image_batch_size}, prompt batch size: {prompt_batch_size}"
- )
-
- def prepare_image(
- self,
- image,
- width,
- height,
- batch_size,
- num_images_per_prompt,
- device,
- dtype,
- do_classifier_free_guidance=False,
- guess_mode=False,
- ):
- image = self.control_image_processor.preprocess(image, height=height, width=width).to(dtype=torch.float32)
- image_batch_size = image.shape[0]
-
- if image_batch_size == 1:
- repeat_by = batch_size
- else:
- # image batch size is the same as prompt batch size
- repeat_by = num_images_per_prompt
-
- image = image.repeat_interleave(repeat_by, dim=0)
-
- image = image.to(device=device, dtype=dtype)
-
- if do_classifier_free_guidance and not guess_mode:
- image = torch.cat([image] * 2)
-
- return image
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.prepare_latents
- def prepare_latents(self, batch_size, num_channels_latents, height, width, dtype, device, generator, latents=None):
- shape = (batch_size, num_channels_latents, height // self.vae_scale_factor, width // self.vae_scale_factor)
- if isinstance(generator, list) and len(generator) != batch_size:
- raise ValueError(
- f"You have passed a list of generators of length {len(generator)}, but requested an effective batch"
- f" size of {batch_size}. Make sure the batch size matches the length of the generators."
- )
-
- if latents is None:
- latents = randn_tensor(shape, generator=generator, device=device, dtype=dtype)
- else:
- latents = latents.to(device)
-
- # scale the initial noise by the standard deviation required by the scheduler
- latents = latents * self.scheduler.init_noise_sigma
- return latents
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.enable_freeu
- def enable_freeu(self, s1: float, s2: float, b1: float, b2: float):
- r"""Enables the FreeU mechanism as in https://arxiv.org/abs/2309.11497.
-
- The suffixes after the scaling factors represent the stages where they are being applied.
-
- Please refer to the [official repository](https://github.com/ChenyangSi/FreeU) for combinations of the values
- that are known to work well for different pipelines such as Stable Diffusion v1, v2, and Stable Diffusion XL.
-
- Args:
- s1 (`float`):
- Scaling factor for stage 1 to attenuate the contributions of the skip features. This is done to
- mitigate "oversmoothing effect" in the enhanced denoising process.
- s2 (`float`):
- Scaling factor for stage 2 to attenuate the contributions of the skip features. This is done to
- mitigate "oversmoothing effect" in the enhanced denoising process.
- b1 (`float`): Scaling factor for stage 1 to amplify the contributions of backbone features.
- b2 (`float`): Scaling factor for stage 2 to amplify the contributions of backbone features.
- """
- if not hasattr(self, "unet"):
- raise ValueError("The pipeline must have `unet` for using FreeU.")
- self.unet.enable_freeu(s1=s1, s2=s2, b1=b1, b2=b2)
-
- # Copied from diffusers.pipelines.stable_diffusion.pipeline_stable_diffusion.StableDiffusionPipeline.disable_freeu
- def disable_freeu(self):
- """Disables the FreeU mechanism if enabled."""
- self.unet.disable_freeu()
-
- # Copied from diffusers.pipelines.latent_consistency_models.pipeline_latent_consistency_text2img.LatentConsistencyModelPipeline.get_guidance_scale_embedding
- def get_guidance_scale_embedding(self, w, embedding_dim=512, dtype=torch.float32):
- """
- See https://github.com/google-research/vdm/blob/dc27b98a554f65cdc654b800da5aa1846545d41b/model_vdm.py#L298
-
- Args:
- timesteps (`torch.Tensor`):
- generate embedding vectors at these timesteps
- embedding_dim (`int`, *optional*, defaults to 512):
- dimension of the embeddings to generate
- dtype:
- data type of the generated embeddings
-
- Returns:
- `torch.FloatTensor`: Embedding vectors with shape `(len(timesteps), embedding_dim)`
- """
- assert len(w.shape) == 1
- w = w * 1000.0
-
- half_dim = embedding_dim // 2
- emb = torch.log(torch.tensor(10000.0)) / (half_dim - 1)
- emb = torch.exp(torch.arange(half_dim, dtype=dtype) * -emb)
- emb = w.to(dtype)[:, None] * emb[None, :]
- emb = torch.cat([torch.sin(emb), torch.cos(emb)], dim=1)
- if embedding_dim % 2 == 1: # zero pad
- emb = torch.nn.functional.pad(emb, (0, 1))
- assert emb.shape == (w.shape[0], embedding_dim)
- return emb
-
- @property
- def guidance_scale(self):
- return self._guidance_scale
-
- @property
- def clip_skip(self):
- return self._clip_skip
-
- # here `guidance_scale` is defined analog to the guidance weight `w` of equation (2)
- # of the Imagen paper: https://arxiv.org/pdf/2205.11487.pdf . `guidance_scale = 1`
- # corresponds to doing no classifier free guidance.
- @property
- def do_classifier_free_guidance(self):
- return self._guidance_scale > 1 and self.unet.config.time_cond_proj_dim is None
-
- @property
- def cross_attention_kwargs(self):
- return self._cross_attention_kwargs
-
- @property
- def num_timesteps(self):
- return self._num_timesteps
-
- @torch.no_grad()
- @replace_example_docstring(EXAMPLE_DOC_STRING)
- def __call__(
- self,
- prompt: Union[str, List[str]] = None,
- image: PipelineImageInput = None,
- height: Optional[int] = None,
- width: Optional[int] = None,
- num_inference_steps: int = 50,
- timesteps: List[int] = None,
- guidance_scale: float = 7.5,
- negative_prompt: Optional[Union[str, List[str]]] = None,
- num_images_per_prompt: Optional[int] = 1,
- eta: float = 0.0,
- generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
- latents: Optional[torch.FloatTensor] = None,
- prompt_embeds: Optional[torch.FloatTensor] = None,
- negative_prompt_embeds: Optional[torch.FloatTensor] = None,
- ip_adapter_image: Optional[PipelineImageInput] = None,
- ip_adapter_image_embeds: Optional[List[torch.FloatTensor]] = None,
- output_type: Optional[str] = "pil",
- return_dict: bool = True,
- cross_attention_kwargs: Optional[Dict[str, Any]] = None,
- controlnet_conditioning_scale: Union[float, List[float]] = 1.0,
- controlnet_prompt_embeds: Optional[List[torch.FloatTensor]] = None,
- guess_mode: bool = False,
- control_guidance_start: Union[float, List[float]] = 0.0,
- control_guidance_end: Union[float, List[float]] = 1.0,
- clip_skip: Optional[int] = None,
- callback_on_step_end: Optional[Callable[[int, int, Dict], None]] = None,
- callback_on_step_end_tensor_inputs: List[str] = ["latents"],
- **kwargs,
- ):
- r"""
- The call function to the pipeline for generation.
-
- Args:
- prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts to guide image generation. If not defined, you need to pass `prompt_embeds`.
- image (`torch.FloatTensor`, `PIL.Image.Image`, `np.ndarray`, `List[torch.FloatTensor]`, `List[PIL.Image.Image]`, `List[np.ndarray]`,:
- `List[List[torch.FloatTensor]]`, `List[List[np.ndarray]]` or `List[List[PIL.Image.Image]]`):
- The ControlNet input condition to provide guidance to the `unet` for generation. If the type is
- specified as `torch.FloatTensor`, it is passed to ControlNet as is. `PIL.Image.Image` can also be
- accepted as an image. The dimensions of the output image defaults to `image`'s dimensions. If height
- and/or width are passed, `image` is resized accordingly. If multiple ControlNets are specified in
- `init`, images must be passed as a list such that each element of the list can be correctly batched for
- input to a single ControlNet.
- height (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
- The height in pixels of the generated image.
- width (`int`, *optional*, defaults to `self.unet.config.sample_size * self.vae_scale_factor`):
- The width in pixels of the generated image.
- num_inference_steps (`int`, *optional*, defaults to 50):
- The number of denoising steps. More denoising steps usually lead to a higher quality image at the
- expense of slower inference.
- timesteps (`List[int]`, *optional*):
- Custom timesteps to use for the denoising process with schedulers which support a `timesteps` argument
- in their `set_timesteps` method. If not defined, the default behavior when `num_inference_steps` is
- passed will be used. Must be in descending order.
- guidance_scale (`float`, *optional*, defaults to 7.5):
- A higher guidance scale value encourages the model to generate images closely linked to the text
- `prompt` at the expense of lower image quality. Guidance scale is enabled when `guidance_scale > 1`.
- negative_prompt (`str` or `List[str]`, *optional*):
- The prompt or prompts to guide what to not include in image generation. If not defined, you need to
- pass `negative_prompt_embeds` instead. Ignored when not using guidance (`guidance_scale < 1`).
- num_images_per_prompt (`int`, *optional*, defaults to 1):
- The number of images to generate per prompt.
- eta (`float`, *optional*, defaults to 0.0):
- Corresponds to parameter eta (η) from the [DDIM](https://arxiv.org/abs/2010.02502) paper. Only applies
- to the [`~schedulers.DDIMScheduler`], and is ignored in other schedulers.
- generator (`torch.Generator` or `List[torch.Generator]`, *optional*):
- A [`torch.Generator`](https://pytorch.org/docs/stable/generated/torch.Generator.html) to make
- generation deterministic.
- latents (`torch.FloatTensor`, *optional*):
- Pre-generated noisy latents sampled from a Gaussian distribution, to be used as inputs for image
- generation. Can be used to tweak the same generation with different prompts. If not provided, a latents
- tensor is generated by sampling using the supplied random `generator`.
- prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated text embeddings. Can be used to easily tweak text inputs (prompt weighting). If not
- provided, text embeddings are generated from the `prompt` input argument.
- negative_prompt_embeds (`torch.FloatTensor`, *optional*):
- Pre-generated negative text embeddings. Can be used to easily tweak text inputs (prompt weighting). If
- not provided, `negative_prompt_embeds` are generated from the `negative_prompt` input argument.
- ip_adapter_image: (`PipelineImageInput`, *optional*): Optional image input to work with IP Adapters.
- output_type (`str`, *optional*, defaults to `"pil"`):
- The output format of the generated image. Choose between `PIL.Image` or `np.array`.
- return_dict (`bool`, *optional*, defaults to `True`):
- Whether or not to return a [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] instead of a
- plain tuple.
- callback (`Callable`, *optional*):
- A function that calls every `callback_steps` steps during inference. The function is called with the
- following arguments: `callback(step: int, timestep: int, latents: torch.FloatTensor)`.
- callback_steps (`int`, *optional*, defaults to 1):
- The frequency at which the `callback` function is called. If not specified, the callback is called at
- every step.
- cross_attention_kwargs (`dict`, *optional*):
- A kwargs dictionary that if specified is passed along to the [`AttentionProcessor`] as defined in
- [`self.processor`](https://github.com/huggingface/diffusers/blob/main/src/diffusers/models/attention_processor.py).
- controlnet_conditioning_scale (`float` or `List[float]`, *optional*, defaults to 1.0):
- The outputs of the ControlNet are multiplied by `controlnet_conditioning_scale` before they are added
- to the residual in the original `unet`. If multiple ControlNets are specified in `init`, you can set
- the corresponding scale as a list.
- guess_mode (`bool`, *optional*, defaults to `False`):
- The ControlNet encoder tries to recognize the content of the input image even if you remove all
- prompts. A `guidance_scale` value between 3.0 and 5.0 is recommended.
- control_guidance_start (`float` or `List[float]`, *optional*, defaults to 0.0):
- The percentage of total steps at which the ControlNet starts applying.
- control_guidance_end (`float` or `List[float]`, *optional*, defaults to 1.0):
- The percentage of total steps at which the ControlNet stops applying.
- clip_skip (`int`, *optional*):
- Number of layers to be skipped from CLIP while computing the prompt embeddings. A value of 1 means that
- the output of the pre-final layer will be used for computing the prompt embeddings.
- callback_on_step_end (`Callable`, *optional*):
- A function that calls at the end of each denoising steps during the inference. The function is called
- with the following arguments: `callback_on_step_end(self: DiffusionPipeline, step: int, timestep: int,
- callback_kwargs: Dict)`. `callback_kwargs` will include a list of all tensors as specified by
- `callback_on_step_end_tensor_inputs`.
- callback_on_step_end_tensor_inputs (`List`, *optional*):
- The list of tensor inputs for the `callback_on_step_end` function. The tensors specified in the list
- will be passed as `callback_kwargs` argument. You will only be able to include variables listed in the
- `._callback_tensor_inputs` attribute of your pipeline class.
-
- Examples:
-
- Returns:
- [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] or `tuple`:
- If `return_dict` is `True`, [`~pipelines.stable_diffusion.StableDiffusionPipelineOutput`] is returned,
- otherwise a `tuple` is returned where the first element is a list with the generated images and the
- second element is a list of `bool`s indicating whether the corresponding generated image contains
- "not-safe-for-work" (nsfw) content.
- """
-
- callback = kwargs.pop("callback", None)
- callback_steps = kwargs.pop("callback_steps", None)
-
- if callback is not None:
- deprecate(
- "callback",
- "1.0.0",
- "Passing `callback` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
- )
- if callback_steps is not None:
- deprecate(
- "callback_steps",
- "1.0.0",
- "Passing `callback_steps` as an input argument to `__call__` is deprecated, consider using `callback_on_step_end`",
- )
-
- controlnet = self.controlnet._orig_mod if is_compiled_module(self.controlnet) else self.controlnet
-
- # align format for control guidance
- if not isinstance(control_guidance_start, list) and isinstance(control_guidance_end, list):
- control_guidance_start = len(control_guidance_end) * [control_guidance_start]
- elif not isinstance(control_guidance_end, list) and isinstance(control_guidance_start, list):
- control_guidance_end = len(control_guidance_start) * [control_guidance_end]
- elif not isinstance(control_guidance_start, list) and not isinstance(control_guidance_end, list):
- mult = len(controlnet.nets) if isinstance(controlnet, MultiControlNetModel) else 1
- control_guidance_start, control_guidance_end = (
- mult * [control_guidance_start],
- mult * [control_guidance_end],
- )
-
- # 1. Check inputs. Raise error if not correct
- self.check_inputs(
- prompt,
- image,
- callback_steps,
- negative_prompt,
- prompt_embeds,
- negative_prompt_embeds,
- controlnet_conditioning_scale,
- control_guidance_start,
- control_guidance_end,
- callback_on_step_end_tensor_inputs,
- )
-
- self._guidance_scale = guidance_scale
- self._clip_skip = clip_skip
- self._cross_attention_kwargs = cross_attention_kwargs
-
- # 2. Define call parameters
- if prompt is not None and isinstance(prompt, str):
- batch_size = 1
- elif prompt is not None and isinstance(prompt, list):
- batch_size = len(prompt)
- else:
- batch_size = prompt_embeds.shape[0]
-
- device = self._execution_device
-
- if isinstance(controlnet, MultiControlNetModel) and isinstance(controlnet_conditioning_scale, float):
- controlnet_conditioning_scale = [controlnet_conditioning_scale] * len(controlnet.nets)
-
- global_pool_conditions = (
- controlnet.config.global_pool_conditions
- if isinstance(controlnet, ControlNetModel)
- else controlnet.nets[0].config.global_pool_conditions
- )
- guess_mode = guess_mode or global_pool_conditions
-
- # 3. Encode input prompt
- text_encoder_lora_scale = (
- self.cross_attention_kwargs.get("scale", None) if self.cross_attention_kwargs is not None else None
- )
- prompt_embeds, negative_prompt_embeds = self.encode_prompt(
- prompt,
- device,
- num_images_per_prompt,
- self.do_classifier_free_guidance,
- negative_prompt,
- prompt_embeds=prompt_embeds,
- negative_prompt_embeds=negative_prompt_embeds,
- lora_scale=text_encoder_lora_scale,
- clip_skip=self.clip_skip,
- )
- # For classifier free guidance, we need to do two forward passes.
- # Here we concatenate the unconditional and text embeddings into a single batch
- # to avoid doing two forward passes
- if self.do_classifier_free_guidance:
- prompt_embeds = torch.cat([negative_prompt_embeds, prompt_embeds])
-
- if ip_adapter_image is not None or ip_adapter_image_embeds is not None:
- image_embeds = self.prepare_ip_adapter_image_embeds(
- ip_adapter_image,
- ip_adapter_image_embeds,
- device,
- batch_size * num_images_per_prompt,
- self.do_classifier_free_guidance,
- )
-
- # 4. Prepare image
- if isinstance(controlnet, ControlNetModel):
- image = self.prepare_image(
- image=image,
- width=width,
- height=height,
- batch_size=batch_size * num_images_per_prompt,
- num_images_per_prompt=num_images_per_prompt,
- device=device,
- dtype=controlnet.dtype,
- do_classifier_free_guidance=self.do_classifier_free_guidance,
- guess_mode=guess_mode,
- )
- height, width = image.shape[-2:]
- elif isinstance(controlnet, MultiControlNetModel):
- images = []
-
- for image_ in image:
- image_ = self.prepare_image(
- image=image_,
- width=width,
- height=height,
- batch_size=batch_size * num_images_per_prompt,
- num_images_per_prompt=num_images_per_prompt,
- device=device,
- dtype=controlnet.dtype,
- do_classifier_free_guidance=self.do_classifier_free_guidance,
- guess_mode=guess_mode,
- )
-
- images.append(image_)
-
- image = images
- height, width = image[0].shape[-2:]
- else:
- assert False
-
- # 5. Prepare timesteps
- timesteps, num_inference_steps = retrieve_timesteps(self.scheduler, num_inference_steps, device, timesteps)
- self._num_timesteps = len(timesteps)
-
- # 6. Prepare latent variables
- num_channels_latents = self.unet.config.in_channels
- latents = self.prepare_latents(
- batch_size * num_images_per_prompt,
- num_channels_latents,
- height,
- width,
- prompt_embeds.dtype,
- device,
- generator,
- latents,
- )
-
- # 6.5 Optionally get Guidance Scale Embedding
- timestep_cond = None
- if self.unet.config.time_cond_proj_dim is not None:
- guidance_scale_tensor = torch.tensor(self.guidance_scale - 1).repeat(batch_size * num_images_per_prompt)
- timestep_cond = self.get_guidance_scale_embedding(
- guidance_scale_tensor, embedding_dim=self.unet.config.time_cond_proj_dim
- ).to(device=device, dtype=latents.dtype)
-
- # 7. Prepare extra step kwargs. TODO: Logic should ideally just be moved out of the pipeline
- extra_step_kwargs = self.prepare_extra_step_kwargs(generator, eta)
-
- # 7.1 Add image embeds for IP-Adapter
- added_cond_kwargs = {"image_embeds": image_embeds} if image_embeds is not None else None
-
- # 7.2 Create tensor stating which controlnets to keep
- controlnet_keep = []
- for i in range(len(timesteps)):
- keeps = [
- 1.0 - float(i / len(timesteps) < s or (i + 1) / len(timesteps) > e)
- for s, e in zip(control_guidance_start, control_guidance_end)
- ]
- controlnet_keep.append(keeps[0] if isinstance(controlnet, ControlNetModel) else keeps)
-
- # 8. Denoising loop
- num_warmup_steps = len(timesteps) - num_inference_steps * self.scheduler.order
- is_unet_compiled = is_compiled_module(self.unet)
- is_controlnet_compiled = is_compiled_module(self.controlnet)
- is_torch_higher_equal_2_1 = is_torch_version(">=", "2.1")
- with self.progress_bar(total=num_inference_steps) as progress_bar:
- for i, t in enumerate(timesteps):
- # Relevant thread:
- # https://dev-discuss.pytorch.org/t/cudagraphs-in-pytorch-2-0/1428
- if (is_unet_compiled and is_controlnet_compiled) and is_torch_higher_equal_2_1:
- torch._inductor.cudagraph_mark_step_begin()
- # expand the latents if we are doing classifier free guidance
- latent_model_input = torch.cat([latents] * 2) if self.do_classifier_free_guidance else latents
- latent_model_input = self.scheduler.scale_model_input(latent_model_input, t)
-
- # controlnet(s) inference
- if guess_mode and self.do_classifier_free_guidance:
- # Infer ControlNet only for the conditional batch.
- control_model_input = latents
- control_model_input = self.scheduler.scale_model_input(control_model_input, t)
- controlnet_prompt_embeds = prompt_embeds.chunk(2)[1]
- else:
- control_model_input = latent_model_input
- controlnet_prompt_embeds = prompt_embeds
-
- if isinstance(controlnet_keep[i], list):
- cond_scale = [c * s for c, s in zip(controlnet_conditioning_scale, controlnet_keep[i])]
- else:
- controlnet_cond_scale = controlnet_conditioning_scale
- if isinstance(controlnet_cond_scale, list):
- controlnet_cond_scale = controlnet_cond_scale[0]
- cond_scale = controlnet_cond_scale * controlnet_keep[i]
-
- down_block_res_samples, mid_block_res_sample = self.controlnet(
- control_model_input,
- t,
- encoder_hidden_states=controlnet_prompt_embeds,
- controlnet_cond=image,
- conditioning_scale=cond_scale,
- guess_mode=guess_mode,
- return_dict=False,
- )
-
- if guess_mode and self.do_classifier_free_guidance:
- # Inferred ControlNet only for the conditional batch.
- # To apply the output of ControlNet to both the unconditional and conditional batches,
- # add 0 to the unconditional batch to keep it unchanged.
- down_block_res_samples = [torch.cat([torch.zeros_like(d), d]) for d in down_block_res_samples]
- mid_block_res_sample = torch.cat([torch.zeros_like(mid_block_res_sample), mid_block_res_sample])
-
- # predict the noise residual
- noise_pred = self.unet(
- latent_model_input,
- t,
- encoder_hidden_states=prompt_embeds,
- timestep_cond=timestep_cond,
- cross_attention_kwargs=self.cross_attention_kwargs,
- down_block_additional_residuals=down_block_res_samples,
- mid_block_additional_residual=mid_block_res_sample,
- added_cond_kwargs=added_cond_kwargs,
- return_dict=False,
- )[0]
-
- # perform guidance
- if self.do_classifier_free_guidance:
- noise_pred_uncond, noise_pred_text = noise_pred.chunk(2)
- noise_pred = noise_pred_uncond + self.guidance_scale * (noise_pred_text - noise_pred_uncond)
-
- # compute the previous noisy sample x_t -> x_t-1
- latents = self.scheduler.step(noise_pred, t, latents, **extra_step_kwargs, return_dict=False)[0]
-
- if callback_on_step_end is not None:
- callback_kwargs = {}
- for k in callback_on_step_end_tensor_inputs:
- callback_kwargs[k] = locals()[k]
- callback_outputs = callback_on_step_end(self, i, t, callback_kwargs)
-
- latents = callback_outputs.pop("latents", latents)
- prompt_embeds = callback_outputs.pop("prompt_embeds", prompt_embeds)
- negative_prompt_embeds = callback_outputs.pop("negative_prompt_embeds", negative_prompt_embeds)
-
- # call the callback, if provided
- if i == len(timesteps) - 1 or ((i + 1) > num_warmup_steps and (i + 1) % self.scheduler.order == 0):
- progress_bar.update()
- if callback is not None and i % callback_steps == 0:
- step_idx = i // getattr(self.scheduler, "order", 1)
- callback(step_idx, t, latents)
-
- # If we do sequential model offloading, let's offload unet and controlnet
- # manually for max memory savings
- if hasattr(self, "final_offload_hook") and self.final_offload_hook is not None:
- self.unet.to("cpu")
- self.controlnet.to("cpu")
- torch.cuda.empty_cache()
-
- if not output_type == "latent":
- image = self.vae.decode(latents / self.vae.config.scaling_factor, return_dict=False, generator=generator)[
- 0
- ]
- image, has_nsfw_concept = self.run_safety_checker(image, device, prompt_embeds.dtype)
- else:
- image = latents
- has_nsfw_concept = None
-
- if has_nsfw_concept is None:
- do_denormalize = [True] * image.shape[0]
- else:
- do_denormalize = [not has_nsfw for has_nsfw in has_nsfw_concept]
-
- image = self.image_processor.postprocess(image, output_type=output_type, do_denormalize=do_denormalize)
-
- # Offload all models
- self.maybe_free_model_hooks()
-
- if not return_dict:
- return (image, has_nsfw_concept)
-
- return StableDiffusionPipelineOutput(images=image, nsfw_content_detected=has_nsfw_concept)
diff --git a/foleycrafter/utils/util.py b/foleycrafter/utils/util.py
index a6e1af3..ccfb754 100644
--- a/foleycrafter/utils/util.py
+++ b/foleycrafter/utils/util.py
@@ -28,8 +28,8 @@
from diffusers import ControlNetModel
from diffusers.models import AutoencoderKL
from diffusers.schedulers import DDIMScheduler, PNDMScheduler
-from foleycrafter.models.auffusion_unet import UNet2DConditionModel as af_UNet2DConditionModel
-from foleycrafter.pipelines.pipeline_controlnet import StableDiffusionControlNetPipeline
+from foleycrafter.models.audio_generator.unet import UNet2DConditionModel
+from foleycrafter.pipelines.foleycrafter_pipeline import StableDiffusionControlNetPipeline
def zero_rank_print(s):
@@ -41,7 +41,7 @@ def build_foleycrafter(
pretrained_model_name_or_path: str = "auffusion/auffusion-full-no-adapter",
) -> StableDiffusionControlNetPipeline:
vae = AutoencoderKL.from_pretrained(pretrained_model_name_or_path, subfolder="vae")
- unet = af_UNet2DConditionModel.from_pretrained(pretrained_model_name_or_path, subfolder="unet")
+ unet = UNet2DConditionModel.from_pretrained(pretrained_model_name_or_path, subfolder="unet")
scheduler = PNDMScheduler.from_pretrained(pretrained_model_name_or_path, subfolder="scheduler")
tokenizer = CLIPTokenizer.from_pretrained(pretrained_model_name_or_path, subfolder="tokenizer")
text_encoder = CLIPTextModel.from_pretrained(pretrained_model_name_or_path, subfolder="text_encoder")
diff --git a/inference.py b/inference.py
index 209ab41..2beab69 100644
--- a/inference.py
+++ b/inference.py
@@ -11,10 +11,10 @@
from moviepy.editor import AudioFileClip, VideoFileClip
from transformers import CLIPImageProcessor, CLIPVisionModelWithProjection
+from foleycrafter.models.audio_generator.vocoder import Generator
from foleycrafter.models.onset import torch_utils
from foleycrafter.models.time_detector.model import VideoOnsetNet
-from foleycrafter.pipelines.auffusion_pipeline import Generator, denormalize_spectrogram
-from foleycrafter.utils.util import build_foleycrafter, read_frames_with_moviepy
+from foleycrafter.utils.util import build_foleycrafter, denormalize_spectrogram, read_frames_with_moviepy
vision_transform_list = [
@@ -86,7 +86,10 @@ def build_models(config):
# load semantic adapter
pipe.load_ip_adapter(
- osp.join(config.ckpt, "semantic"), subfolder="", weight_name="semantic_adapter.bin", image_encoder_folder=None
+ osp.join(config.ckpt, "semantic"),
+ subfolder="",
+ weight_name="semantic_adapter.bin",
+ image_encoder_folder=None,
)
ip_adapter_weight = config.semantic_scale
pipe.set_ip_adapter_scale(ip_adapter_weight)