MagicQuillV2 / src /layers_cache.py
LiuZichen's picture
update
f460ce6
import inspect
import math
from typing import Callable, List, Optional, Tuple, Union, Any, Dict
from einops import rearrange
import torch
from torch import nn
import torch.nn.functional as F
from torch import Tensor
from diffusers.models.attention_processor import Attention
TXTLEN = 128
KONTEXT = False
class LoRALinearLayer(nn.Module):
def __init__(
self,
in_features: int,
out_features: int,
rank: int = 4,
network_alpha: Optional[float] = None,
device: Optional[Union[torch.device, str]] = None,
dtype: Optional[torch.dtype] = None,
cond_widths: Optional[List[int]] = None,
cond_heights: Optional[List[int]] = None,
lora_index: int = 0,
n_loras: int = 1,
):
super().__init__()
self.down = nn.Linear(in_features, rank, bias=False, device=device, dtype=dtype)
self.up = nn.Linear(rank, out_features, bias=False, device=device, dtype=dtype)
self.network_alpha = network_alpha
self.rank = rank
self.out_features = out_features
self.in_features = in_features
nn.init.normal_(self.down.weight, std=1 / rank)
nn.init.zeros_(self.up.weight)
self.cond_heights = cond_heights if cond_heights is not None else [512]
self.cond_widths = cond_widths if cond_widths is not None else [512]
self.lora_index = lora_index
self.n_loras = n_loras
def forward(self, hidden_states: torch.Tensor) -> torch.Tensor:
orig_dtype = hidden_states.dtype
dtype = self.down.weight.dtype
batch_size = hidden_states.shape[0]
cond_sizes = [(w // 8 * h // 8 * 16 // 64) for w, h in zip(self.cond_widths, self.cond_heights)]
total_cond_size = sum(cond_sizes)
block_size = hidden_states.shape[1] - total_cond_size
offset = sum(cond_sizes[:self.lora_index])
current_cond_size = cond_sizes[self.lora_index]
shape = (batch_size, hidden_states.shape[1], 3072)
mask = torch.ones(shape, device=hidden_states.device, dtype=dtype)
mask[:, :block_size + offset, :] = 0
mask[:, block_size + offset + current_cond_size:, :] = 0
hidden_states = mask * hidden_states
down_hidden_states = self.down(hidden_states.to(dtype))
up_hidden_states = self.up(down_hidden_states)
if self.network_alpha is not None:
up_hidden_states *= self.network_alpha / self.rank
return up_hidden_states.to(orig_dtype)
class MultiSingleStreamBlockLoraProcessor(nn.Module):
def __init__(self, dim: int, ranks: List[int], lora_weights: List[float], network_alphas: List[float], device=None, dtype=None, cond_widths: Optional[List[int]] = None, cond_heights: Optional[List[int]] = None, n_loras=1):
super().__init__()
self.n_loras = n_loras
self.cond_widths = cond_widths if cond_widths is not None else [512]
self.cond_heights = cond_heights if cond_heights is not None else [512]
self.q_loras = nn.ModuleList([
LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras)
for i in range(n_loras)
])
self.k_loras = nn.ModuleList([
LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras)
for i in range(n_loras)
])
self.v_loras = nn.ModuleList([
LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras)
for i in range(n_loras)
])
self.lora_weights = lora_weights
self.bank_attn = None
self.bank_kv: List[torch.Tensor] = []
def __call__(self,
attn: Attention,
hidden_states: torch.Tensor,
encoder_hidden_states: Optional[torch.Tensor] = None,
attention_mask: Optional[torch.Tensor] = None,
image_rotary_emb: Optional[torch.Tensor] = None,
use_cond = False
) -> Union[torch.Tensor, Tuple[torch.Tensor, torch.Tensor]]:
batch_size, _, _ = hidden_states.shape if encoder_hidden_states is None else encoder_hidden_states.shape
scaled_seq_len = hidden_states.shape[1]
cond_sizes = [(w // 8 * h // 8 * 16 // 64) for w, h in zip(self.cond_widths, self.cond_heights)]
total_cond_size = sum(cond_sizes)
block_size = scaled_seq_len - total_cond_size
scaled_cond_sizes = cond_sizes
scaled_block_size = block_size
global TXTLEN
global KONTEXT
if KONTEXT:
img_start, img_end = TXTLEN, (TXTLEN + block_size) // 2
else:
img_start, img_end = TXTLEN, block_size
cond_start, cond_end = block_size, scaled_seq_len
cache = len(self.bank_kv) == 0
if cache:
query = attn.to_q(hidden_states)
key = attn.to_k(hidden_states)
value = attn.to_v(hidden_states)
for i in range(self.n_loras):
query = query + self.lora_weights[i] * self.q_loras[i](hidden_states)
key = key + self.lora_weights[i] * self.k_loras[i](hidden_states)
value = value + self.lora_weights[i] * self.v_loras[i](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)
self.bank_kv.extend([key[:, :, scaled_block_size:, :], value[:, :, scaled_block_size:, :]])
if attn.norm_q is not None: query = attn.norm_q(query)
if attn.norm_k is not None: key = attn.norm_k(key)
if image_rotary_emb is not None:
from diffusers.models.embeddings import apply_rotary_emb
query, key = apply_rotary_emb(query, image_rotary_emb), apply_rotary_emb(key, image_rotary_emb)
mask = torch.ones((scaled_seq_len, scaled_seq_len), device=hidden_states.device)
mask[ :scaled_block_size, :] = 0
current_offset = 0
for i in range(self.n_loras):
start, end = scaled_block_size + current_offset, scaled_block_size + current_offset + scaled_cond_sizes[i]
mask[start:end, start:end] = 0
current_offset += scaled_cond_sizes[i]
mask *= -1e20
c_factor = getattr(self, "c_factor", None)
if c_factor is not None:
# print(f"Using c_factor: {c_factor}")
current_offset = 0
for i in range(self.n_loras):
bias = torch.log(c_factor[i])
cond_i_start, cond_i_end = cond_start + current_offset, cond_start + current_offset + scaled_cond_sizes[i]
mask[img_start:img_end, cond_i_start:cond_i_end] = bias
current_offset += scaled_cond_sizes[i]
# c_factor_kontext = getattr(self, "c_factor_kontext", None)
# if c_factor_kontext is not None:
# bias = torch.log(c_factor_kontext)
# kontext_start, kontext_end = img_end, block_size
# mask[img_start:img_end, kontext_start:kontext_end] = bias
# mask[kontext_start:kontext_end, img_start:img_end] = bias
# mask[kontext_start:kontext_end, kontext_end:] = -1e20
hidden_states = F.scaled_dot_product_attention(query, key, value, dropout_p=0.0, is_causal=False, attn_mask=mask.to(query.dtype))
self.bank_attn = hidden_states[:, :, scaled_block_size:, :]
else:
query, key, value = attn.to_q(hidden_states), attn.to_k(hidden_states), attn.to_v(hidden_states)
inner_dim = query.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)
key = torch.cat([key[:, :, :scaled_block_size, :], self.bank_kv[0]], dim=-2)
value = torch.cat([value[:, :, :scaled_block_size, :], self.bank_kv[1]], dim=-2)
if attn.norm_q is not None: query = attn.norm_q(query)
if attn.norm_k is not None: key = attn.norm_k(key)
if image_rotary_emb is not None:
from diffusers.models.embeddings import apply_rotary_emb
query, key = apply_rotary_emb(query, image_rotary_emb), apply_rotary_emb(key, image_rotary_emb)
query = query[:, :, :scaled_block_size, :]
attn_mask = None
c_factor = getattr(self, "c_factor", None)
if c_factor is not None:
# print(f"Using c_factor: {c_factor}")
attn_mask = torch.zeros((query.shape[2], key.shape[2]), device=query.device, dtype=query.dtype)
current_offset = 0
for i in range(self.n_loras):
bias = torch.log(c_factor[i])
cond_i_start, cond_i_end = cond_start + current_offset, cond_start + current_offset + scaled_cond_sizes[i]
attn_mask[img_start:img_end, cond_i_start:cond_i_end] = bias
current_offset += scaled_cond_sizes[i]
# c_factor_kontext = getattr(self, "c_factor_kontext", None)
# if c_factor_kontext is not None:
# if attn_mask is None:
# attn_mask = torch.zeros((query.shape[2], key.shape[2]), device=query.device, dtype=query.dtype)
# bias = torch.log(c_factor_kontext)
# kontext_start, kontext_end = img_end, block_size
# attn_mask[img_start:img_end, kontext_start:kontext_end] = bias
# attn_mask[kontext_start:kontext_end, img_start:img_end] = bias
# attn_mask[kontext_start:kontext_end, kontext_end:] = -1e20
hidden_states = F.scaled_dot_product_attention(query, key, value, dropout_p=0.0, is_causal=False, attn_mask=attn_mask)
if self.bank_attn is not None: hidden_states = torch.cat([hidden_states, self.bank_attn], dim=-2)
hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
hidden_states = hidden_states.to(query.dtype)
cond_hidden_states = hidden_states[:, block_size:,:]
hidden_states = hidden_states[:, : block_size,:]
return (hidden_states, cond_hidden_states) if use_cond else hidden_states
class MultiDoubleStreamBlockLoraProcessor(nn.Module):
def __init__(self, dim: int, ranks: List[int], lora_weights: List[float], network_alphas: List[float], device=None, dtype=None, cond_widths: Optional[List[int]] = None, cond_heights: Optional[List[int]] = None, n_loras=1):
super().__init__()
self.n_loras = n_loras
self.cond_widths = cond_widths if cond_widths is not None else [512]
self.cond_heights = cond_heights if cond_heights is not None else [512]
self.q_loras = nn.ModuleList([LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras) for i in range(n_loras)])
self.k_loras = nn.ModuleList([LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras) for i in range(n_loras)])
self.v_loras = nn.ModuleList([LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras) for i in range(n_loras)])
self.proj_loras = nn.ModuleList([LoRALinearLayer(dim, dim, ranks[i], network_alphas[i], device=device, dtype=dtype, cond_widths=self.cond_widths, cond_heights=self.cond_heights, lora_index=i, n_loras=n_loras) for i in range(n_loras)])
self.lora_weights = lora_weights
self.bank_attn = None
self.bank_kv: List[torch.Tensor] = []
def __call__(self,
attn: Attention,
hidden_states: torch.Tensor,
encoder_hidden_states: Optional[torch.Tensor] = None,
attention_mask: Optional[torch.Tensor] = None,
image_rotary_emb: Optional[torch.Tensor] = None,
use_cond=False,
) -> Union[Tuple[torch.Tensor, torch.Tensor], Tuple[torch.Tensor, torch.Tensor, torch.Tensor]]:
global TXTLEN
global KONTEXT
TXTLEN = encoder_hidden_states.shape[1] if encoder_hidden_states is not None else 128
batch_size, _, _ = hidden_states.shape
cond_sizes = [(w // 8 * h // 8 * 16 // 64) for w, h in zip(self.cond_widths, self.cond_heights)]
block_size = hidden_states.shape[1] - sum(cond_sizes)
scaled_seq_len = encoder_hidden_states.shape[1] + hidden_states.shape[1]
scaled_cond_sizes = cond_sizes
scaled_block_size = scaled_seq_len - sum(scaled_cond_sizes)
if KONTEXT:
img_start, img_end = TXTLEN, (TXTLEN + block_size) // 2
else:
img_start, img_end = TXTLEN, block_size
cond_start, cond_end = scaled_block_size, scaled_seq_len
inner_dim, head_dim = 3072, 3072 // attn.heads
encoder_hidden_states_query_proj = attn.add_q_proj(encoder_hidden_states).view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
encoder_hidden_states_key_proj = attn.add_k_proj(encoder_hidden_states).view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
encoder_hidden_states_value_proj = attn.add_v_proj(encoder_hidden_states).view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
if attn.norm_added_q is not None: encoder_hidden_states_query_proj = attn.norm_added_q(encoder_hidden_states_query_proj)
if attn.norm_added_k is not None: encoder_hidden_states_key_proj = attn.norm_added_k(encoder_hidden_states_key_proj)
cache = len(self.bank_kv) == 0
if cache:
query, key, value = attn.to_q(hidden_states), attn.to_k(hidden_states), attn.to_v(hidden_states)
for i in range(self.n_loras):
query, key, value = query + self.lora_weights[i] * self.q_loras[i](hidden_states), key + self.lora_weights[i] * self.k_loras[i](hidden_states), value + self.lora_weights[i] * self.v_loras[i](hidden_states)
query, key, value = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2), key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2), value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
self.bank_kv.extend([key[:, :, block_size:, :], value[:, :, block_size:, :]])
if attn.norm_q is not None: query = attn.norm_q(query)
if attn.norm_k is not None: key = attn.norm_k(key)
query, key, value = torch.cat([encoder_hidden_states_query_proj, query], dim=2), torch.cat([encoder_hidden_states_key_proj, key], dim=2), torch.cat([encoder_hidden_states_value_proj, value], dim=2)
if image_rotary_emb is not None:
from diffusers.models.embeddings import apply_rotary_emb
query, key = apply_rotary_emb(query, image_rotary_emb), apply_rotary_emb(key, image_rotary_emb)
mask = torch.ones((scaled_seq_len, scaled_seq_len), device=hidden_states.device)
mask[:scaled_block_size, :] = 0
current_offset = 0
for i in range(self.n_loras):
start, end = scaled_block_size + current_offset, scaled_block_size + current_offset + scaled_cond_sizes[i]
mask[start:end, start:end] = 0
current_offset += scaled_cond_sizes[i]
mask *= -1e20
c_factor = getattr(self, "c_factor", None)
if c_factor is not None:
# print(f"Using c_factor: {c_factor}")
current_offset = 0
for i in range(self.n_loras):
bias = torch.log(c_factor[i])
cond_i_start, cond_i_end = cond_start + current_offset, cond_start + current_offset + scaled_cond_sizes[i]
mask[img_start:img_end, cond_i_start:cond_i_end] = bias
current_offset += scaled_cond_sizes[i]
# c_factor_kontext = getattr(self, "c_factor_kontext", None)
# if c_factor_kontext is not None:
# bias = torch.log(c_factor_kontext)
# kontext_start, kontext_end = img_end, block_size
# mask[img_start:img_end, kontext_start:kontext_end] = bias
# mask[kontext_start:kontext_end, img_start:img_end] = bias
# mask[kontext_start:kontext_end, kontext_end:] = -1e20
hidden_states = F.scaled_dot_product_attention(query, key, value, dropout_p=0.0, is_causal=False, attn_mask=mask.to(query.dtype))
self.bank_attn = hidden_states[:, :, scaled_block_size:, :]
else:
query, key, value = attn.to_q(hidden_states), attn.to_k(hidden_states), attn.to_v(hidden_states)
query, key, value = query.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2), key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2), value.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
key, value = torch.cat([key[:, :, :block_size, :], self.bank_kv[0]], dim=-2), torch.cat([value[:, :, :block_size, :], self.bank_kv[1]], dim=-2)
if attn.norm_q is not None: query = attn.norm_q(query)
if attn.norm_k is not None: key = attn.norm_k(key)
query, key, value = torch.cat([encoder_hidden_states_query_proj, query], dim=2), torch.cat([encoder_hidden_states_key_proj, key], dim=2), torch.cat([encoder_hidden_states_value_proj, value], dim=2)
if image_rotary_emb is not None:
from diffusers.models.embeddings import apply_rotary_emb
query, key = apply_rotary_emb(query, image_rotary_emb), apply_rotary_emb(key, image_rotary_emb)
query = query[:, :, :scaled_block_size, :]
attn_mask = None
c_factor = getattr(self, "c_factor", None)
if c_factor is not None:
# print(f"Using c_factor: {c_factor}")
attn_mask = torch.zeros((query.shape[2], key.shape[2]), device=query.device, dtype=query.dtype)
current_offset = 0
for i in range(self.n_loras):
bias = torch.log(c_factor[i])
cond_i_start, cond_i_end = cond_start + current_offset, cond_start + current_offset + scaled_cond_sizes[i]
attn_mask[img_start:img_end, cond_i_start:cond_i_end] = bias
current_offset += scaled_cond_sizes[i]
# c_factor_kontext = getattr(self, "c_factor_kontext", None)
# if c_factor_kontext is not None:
# if attn_mask is None:
# attn_mask = torch.zeros((query.shape[2], key.shape[2]), device=query.device, dtype=query.dtype)
# bias = torch.log(c_factor_kontext)
# kontext_start, kontext_end = img_end, block_size
# attn_mask[img_start:img_end, kontext_start:kontext_end] = bias
# attn_mask[kontext_start:kontext_end, img_start:img_end] = bias
# attn_mask[kontext_start:kontext_end, kontext_end:] = -1e20
hidden_states = F.scaled_dot_product_attention(query, key, value, dropout_p=0.0, is_causal=False, attn_mask=attn_mask)
if self.bank_attn is not None: hidden_states = torch.cat([hidden_states, self.bank_attn], dim=-2)
hidden_states = hidden_states.transpose(1, 2).reshape(batch_size, -1, attn.heads * head_dim)
hidden_states = hidden_states.to(query.dtype)
encoder_hidden_states, hidden_states = hidden_states[:, :encoder_hidden_states.shape[1]], hidden_states[:, encoder_hidden_states.shape[1]:]
hidden_states = attn.to_out[0](hidden_states)
for i in range(self.n_loras):
hidden_states = hidden_states + self.lora_weights[i] * self.proj_loras[i](hidden_states)
hidden_states = attn.to_out[1](hidden_states)
encoder_hidden_states = attn.to_add_out(encoder_hidden_states)
cond_hidden_states = hidden_states[:, block_size:,:]
hidden_states = hidden_states[:, :block_size,:]
return (hidden_states, encoder_hidden_states, cond_hidden_states) if use_cond else (encoder_hidden_states, hidden_states)