Add files via upload

This commit is contained in:
HM-RunningHub
2024-12-12 21:00:30 +08:00
committed by GitHub
parent 6d24f1f153
commit 5e7a07d8e4
5 changed files with 1106 additions and 0 deletions
+333
View File
@@ -0,0 +1,333 @@
import torch
from typing import List, Union, Optional, Dict, Any, Callable
from diffusers.models.attention_processor import Attention, F
from .lora_controller import enable_lora
def attn_forward(
attn: Attention,
hidden_states: torch.FloatTensor,
encoder_hidden_states: torch.FloatTensor = None,
condition_latents: torch.FloatTensor = None,
attention_mask: Optional[torch.FloatTensor] = None,
image_rotary_emb: Optional[torch.Tensor] = None,
cond_rotary_emb: Optional[torch.Tensor] = None,
model_config: Optional[Dict[str, Any]] = {},
) -> torch.FloatTensor:
batch_size, _, _ = (
hidden_states.shape
if encoder_hidden_states is None
else encoder_hidden_states.shape
)
with enable_lora(
(attn.to_q, attn.to_k, attn.to_v), model_config.get("latent_lora", False)
):
# `sample` projections.
query = attn.to_q(hidden_states)
key = attn.to_k(hidden_states)
value = attn.to_v(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)
if attn.norm_q is not None:
query = attn.norm_q(query)
if attn.norm_k is not None:
key = attn.norm_k(key)
# the attention in FluxSingleTransformerBlock does not use `encoder_hidden_states`
if encoder_hidden_states is not None:
# `context` projections.
encoder_hidden_states_query_proj = attn.add_q_proj(encoder_hidden_states)
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_query_proj = encoder_hidden_states_query_proj.view(
batch_size, -1, attn.heads, head_dim
).transpose(1, 2)
encoder_hidden_states_key_proj = encoder_hidden_states_key_proj.view(
batch_size, -1, attn.heads, head_dim
).transpose(1, 2)
encoder_hidden_states_value_proj = encoder_hidden_states_value_proj.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
)
# attention
query = torch.cat([encoder_hidden_states_query_proj, query], dim=2)
key = torch.cat([encoder_hidden_states_key_proj, key], dim=2)
value = 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 = apply_rotary_emb(query, image_rotary_emb)
key = apply_rotary_emb(key, image_rotary_emb)
if condition_latents is not None:
cond_query = attn.to_q(condition_latents)
cond_key = attn.to_k(condition_latents)
cond_value = attn.to_v(condition_latents)
cond_query = cond_query.view(batch_size, -1, attn.heads, head_dim).transpose(
1, 2
)
cond_key = cond_key.view(batch_size, -1, attn.heads, head_dim).transpose(1, 2)
cond_value = cond_value.view(batch_size, -1, attn.heads, head_dim).transpose(
1, 2
)
if attn.norm_q is not None:
cond_query = attn.norm_q(cond_query)
if attn.norm_k is not None:
cond_key = attn.norm_k(cond_key)
if cond_rotary_emb is not None:
cond_query = apply_rotary_emb(cond_query, cond_rotary_emb)
cond_key = apply_rotary_emb(cond_key, cond_rotary_emb)
if condition_latents is not None:
query = torch.cat([query, cond_query], dim=2)
key = torch.cat([key, cond_key], dim=2)
value = torch.cat([value, cond_value], dim=2)
if not model_config.get("union_cond_attn", True):
# If we don't want to use the union condition attention, we need to mask the attention
# between the hidden states and the condition latents
attention_mask = torch.ones(
query.shape[2], key.shape[2], device=query.device, dtype=torch.bool
)
condition_n = cond_query.shape[2]
attention_mask[-condition_n:, :-condition_n] = False
attention_mask[:-condition_n, -condition_n:] = False
if hasattr(attn, "c_factor"):
attention_mask = torch.zeros(
query.shape[2], key.shape[2], device=query.device, dtype=query.dtype
)
condition_n = cond_query.shape[2]
bias = torch.log(attn.c_factor[0])
attention_mask[-condition_n:, :-condition_n] = bias
attention_mask[:-condition_n, -condition_n:] = bias
hidden_states = F.scaled_dot_product_attention(
query, key, value, dropout_p=0.0, is_causal=False, attn_mask=attention_mask
)
hidden_states = hidden_states.transpose(1, 2).reshape(
batch_size, -1, attn.heads * head_dim
)
hidden_states = hidden_states.to(query.dtype)
if encoder_hidden_states is not None:
if condition_latents is not None:
encoder_hidden_states, hidden_states, condition_latents = (
hidden_states[:, : encoder_hidden_states.shape[1]],
hidden_states[
:, encoder_hidden_states.shape[1] : -condition_latents.shape[1]
],
hidden_states[:, -condition_latents.shape[1] :],
)
else:
encoder_hidden_states, hidden_states = (
hidden_states[:, : encoder_hidden_states.shape[1]],
hidden_states[:, encoder_hidden_states.shape[1] :],
)
with enable_lora((attn.to_out[0],), model_config.get("latent_lora", False)):
# linear proj
hidden_states = attn.to_out[0](hidden_states)
# dropout
hidden_states = attn.to_out[1](hidden_states)
encoder_hidden_states = attn.to_add_out(encoder_hidden_states)
if condition_latents is not None:
condition_latents = attn.to_out[0](condition_latents)
condition_latents = attn.to_out[1](condition_latents)
return (
(hidden_states, encoder_hidden_states, condition_latents)
if condition_latents is not None
else (hidden_states, encoder_hidden_states)
)
elif condition_latents is not None:
# if there are condition_latents, we need to separate the hidden_states and the condition_latents
hidden_states, condition_latents = (
hidden_states[:, : -condition_latents.shape[1]],
hidden_states[:, -condition_latents.shape[1] :],
)
return hidden_states, condition_latents
else:
return hidden_states
def block_forward(
self,
hidden_states: torch.FloatTensor,
encoder_hidden_states: torch.FloatTensor,
condition_latents: torch.FloatTensor,
temb: torch.FloatTensor,
cond_temb: torch.FloatTensor,
cond_rotary_emb=None,
image_rotary_emb=None,
model_config: Optional[Dict[str, Any]] = {},
):
use_cond = condition_latents is not None
with enable_lora((self.norm1.linear,), model_config.get("latent_lora", False)):
norm_hidden_states, gate_msa, shift_mlp, scale_mlp, gate_mlp = self.norm1(
hidden_states, emb=temb
)
norm_encoder_hidden_states, c_gate_msa, c_shift_mlp, c_scale_mlp, c_gate_mlp = (
self.norm1_context(encoder_hidden_states, emb=temb)
)
if use_cond:
(
norm_condition_latents,
cond_gate_msa,
cond_shift_mlp,
cond_scale_mlp,
cond_gate_mlp,
) = self.norm1(condition_latents, emb=cond_temb)
# Attention.
result = attn_forward(
self.attn,
model_config=model_config,
hidden_states=norm_hidden_states,
encoder_hidden_states=norm_encoder_hidden_states,
condition_latents=norm_condition_latents if use_cond else None,
image_rotary_emb=image_rotary_emb,
cond_rotary_emb=cond_rotary_emb if use_cond else None,
)
attn_output, context_attn_output = result[:2]
cond_attn_output = result[2] if use_cond else None
# Process attention outputs for the `hidden_states`.
# 1. hidden_states
attn_output = gate_msa.unsqueeze(1) * attn_output
hidden_states = hidden_states + attn_output
# 2. encoder_hidden_states
context_attn_output = c_gate_msa.unsqueeze(1) * context_attn_output
encoder_hidden_states = encoder_hidden_states + context_attn_output
# 3. condition_latents
if use_cond:
cond_attn_output = cond_gate_msa.unsqueeze(1) * cond_attn_output
condition_latents = condition_latents + cond_attn_output
if model_config.get("add_cond_attn", False):
hidden_states += cond_attn_output
# LayerNorm + MLP.
# 1. hidden_states
norm_hidden_states = self.norm2(hidden_states)
norm_hidden_states = (
norm_hidden_states * (1 + scale_mlp[:, None]) + shift_mlp[:, None]
)
# 2. encoder_hidden_states
norm_encoder_hidden_states = self.norm2_context(encoder_hidden_states)
norm_encoder_hidden_states = (
norm_encoder_hidden_states * (1 + c_scale_mlp[:, None]) + c_shift_mlp[:, None]
)
# 3. condition_latents
if use_cond:
norm_condition_latents = self.norm2(condition_latents)
norm_condition_latents = (
norm_condition_latents * (1 + cond_scale_mlp[:, None])
+ cond_shift_mlp[:, None]
)
# Feed-forward.
with enable_lora((self.ff.net[2],), model_config.get("latent_lora", False)):
# 1. hidden_states
ff_output = self.ff(norm_hidden_states)
ff_output = gate_mlp.unsqueeze(1) * ff_output
# 2. encoder_hidden_states
context_ff_output = self.ff_context(norm_encoder_hidden_states)
context_ff_output = c_gate_mlp.unsqueeze(1) * context_ff_output
# 3. condition_latents
if use_cond:
cond_ff_output = self.ff(norm_condition_latents)
cond_ff_output = cond_gate_mlp.unsqueeze(1) * cond_ff_output
# Process feed-forward outputs.
hidden_states = hidden_states + ff_output
encoder_hidden_states = encoder_hidden_states + context_ff_output
if use_cond:
condition_latents = condition_latents + cond_ff_output
# Clip to avoid overflow.
if encoder_hidden_states.dtype == torch.float16:
encoder_hidden_states = encoder_hidden_states.clip(-65504, 65504)
return encoder_hidden_states, hidden_states, condition_latents if use_cond else None
def single_block_forward(
self,
hidden_states: torch.FloatTensor,
temb: torch.FloatTensor,
image_rotary_emb=None,
condition_latents: torch.FloatTensor = None,
cond_temb: torch.FloatTensor = None,
cond_rotary_emb=None,
model_config: Optional[Dict[str, Any]] = {},
):
using_cond = condition_latents is not None
residual = hidden_states
with enable_lora(
(
self.norm.linear,
self.proj_mlp,
),
model_config.get("latent_lora", False),
):
norm_hidden_states, gate = self.norm(hidden_states, emb=temb)
mlp_hidden_states = self.act_mlp(self.proj_mlp(norm_hidden_states))
if using_cond:
residual_cond = condition_latents
norm_condition_latents, cond_gate = self.norm(condition_latents, emb=cond_temb)
mlp_cond_hidden_states = self.act_mlp(self.proj_mlp(norm_condition_latents))
attn_output = attn_forward(
self.attn,
model_config=model_config,
hidden_states=norm_hidden_states,
image_rotary_emb=image_rotary_emb,
**(
{
"condition_latents": norm_condition_latents,
"cond_rotary_emb": cond_rotary_emb if using_cond else None,
}
if using_cond
else {}
),
)
if using_cond:
attn_output, cond_attn_output = attn_output
with enable_lora((self.proj_out,), model_config.get("latent_lora", False)):
hidden_states = torch.cat([attn_output, mlp_hidden_states], dim=2)
gate = gate.unsqueeze(1)
hidden_states = gate * self.proj_out(hidden_states)
hidden_states = residual + hidden_states
if using_cond:
condition_latents = torch.cat([cond_attn_output, mlp_cond_hidden_states], dim=2)
cond_gate = cond_gate.unsqueeze(1)
condition_latents = cond_gate * self.proj_out(condition_latents)
condition_latents = residual_cond + condition_latents
if hidden_states.dtype == torch.float16:
hidden_states = hidden_states.clip(-65504, 65504)
return hidden_states if not using_cond else (hidden_states, condition_latents)
+128
View File
@@ -0,0 +1,128 @@
import torch
from typing import Optional, Union, List, Tuple
from diffusers.pipelines import FluxPipeline
from PIL import Image, ImageFilter
import numpy as np
import cv2
condition_dict = {
"depth": 0,
"canny": 1,
"subject": 4,
"coloring": 6,
"deblurring": 7,
"fill": 9,
}
class Condition(object):
def __init__(
self,
condition_type: str,
raw_img: Union[Image.Image, torch.Tensor] = None,
condition: Union[Image.Image, torch.Tensor] = None,
mask=None,
) -> None:
self.condition_type = condition_type
assert raw_img is not None or condition is not None
if raw_img is not None:
self.condition = self.get_condition(condition_type, raw_img)
else:
self.condition = condition
# TODO: Add mask support
assert mask is None, "Mask not supported yet"
def get_condition(
self, condition_type: str, raw_img: Union[Image.Image, torch.Tensor]
) -> Union[Image.Image, torch.Tensor]:
"""
Returns the condition image.
"""
if condition_type == "depth":
from transformers import pipeline
import folder_paths
import os
depth_pipe = pipeline(
task="depth-estimation",
# model="LiheYoung/depth-anything-small-hf",
model=os.path.join(folder_paths.models_dir, 'flux', 'OminiControl', 'depth-anything-small-hf'),
device="cuda",
)
source_image = raw_img.convert("RGB")
condition_img = depth_pipe(source_image)["depth"].convert("RGB")
return condition_img
elif condition_type == "canny":
img = np.array(raw_img)
edges = cv2.Canny(img, 100, 200)
edges = Image.fromarray(edges).convert("RGB")
return edges
elif condition_type == "subject":
return raw_img
elif condition_type == "coloring":
return raw_img.convert("L").convert("RGB")
elif condition_type == "deblurring":
condition_image = (
raw_img.convert("RGB")
.filter(ImageFilter.GaussianBlur(10))
.convert("RGB")
)
return condition_image
elif condition_type == "fill":
return raw_img.convert("RGB")
return self.condition
@property
def type_id(self) -> int:
"""
Returns the type id of the condition.
"""
return condition_dict[self.condition_type]
@classmethod
def get_type_id(cls, condition_type: str) -> int:
"""
Returns the type id of the condition.
"""
return condition_dict[condition_type]
def _encode_image(self, pipe: FluxPipeline, cond_img: Image.Image) -> torch.Tensor:
"""
Encodes an image condition into tokens using the pipeline.
"""
cond_img = pipe.image_processor.preprocess(cond_img)
# cond_img = cond_img.to(pipe.device).to(pipe.dtype)
cond_img = cond_img.to('cuda').to(pipe.dtype)
cond_img = pipe.vae.encode(cond_img).latent_dist.sample()
cond_img = (
cond_img - pipe.vae.config.shift_factor
) * pipe.vae.config.scaling_factor
cond_tokens = pipe._pack_latents(cond_img, *cond_img.shape)
cond_ids = pipe._prepare_latent_image_ids(
cond_img.shape[0],
cond_img.shape[2],
cond_img.shape[3],
pipe.device,
pipe.dtype,
)
return cond_tokens, cond_ids
def encode(self, pipe: FluxPipeline) -> Tuple[torch.Tensor, torch.Tensor, int]:
"""
Encodes the condition into tokens, ids and type_id.
"""
if self.condition_type in [
"depth",
"canny",
"subject",
"coloring",
"deblurring",
"fill",
]:
tokens, ids = self._encode_image(pipe, self.condition)
else:
raise NotImplementedError(
f"Condition type {self.condition_type} not implemented"
)
type_id = torch.ones_like(ids[:, :1]) * self.type_id
return tokens, ids, type_id
+300
View File
@@ -0,0 +1,300 @@
import torch
import yaml, os
from diffusers.pipelines import FluxPipeline
from typing import List, Union, Optional, Dict, Any, Callable
from .transformer import tranformer_forward
from .condition import Condition
from diffusers.pipelines.flux.pipeline_flux import (
FluxPipelineOutput,
calculate_shift,
retrieve_timesteps,
np,
)
def prepare_params(
prompt: Union[str, List[str]] = None,
prompt_2: Optional[Union[str, List[str]]] = None,
height: Optional[int] = 512,
width: Optional[int] = 512,
num_inference_steps: int = 28,
timesteps: List[int] = None,
guidance_scale: float = 3.5,
num_images_per_prompt: Optional[int] = 1,
generator: Optional[Union[torch.Generator, List[torch.Generator]]] = None,
latents: Optional[torch.FloatTensor] = None,
prompt_embeds: Optional[torch.FloatTensor] = None,
pooled_prompt_embeds: Optional[torch.FloatTensor] = None,
output_type: Optional[str] = "pil",
return_dict: bool = True,
joint_attention_kwargs: Optional[Dict[str, Any]] = None,
callback_on_step_end: Optional[Callable[[int, int, Dict], None]] = None,
callback_on_step_end_tensor_inputs: List[str] = ["latents"],
max_sequence_length: int = 512,
**kwargs: dict,
):
return (
prompt,
prompt_2,
height,
width,
num_inference_steps,
timesteps,
guidance_scale,
num_images_per_prompt,
generator,
latents,
prompt_embeds,
pooled_prompt_embeds,
output_type,
return_dict,
joint_attention_kwargs,
callback_on_step_end,
callback_on_step_end_tensor_inputs,
max_sequence_length,
)
def seed_everything(seed: int = 42):
torch.backends.cudnn.deterministic = True
torch.manual_seed(seed)
np.random.seed(seed)
@torch.no_grad()
def generate(
pipeline: FluxPipeline,
conditions: List[Condition] = None,
model_config: Optional[Dict[str, Any]] = {},
condition_scale: float = 1.0,
**params: dict,
):
# print(params)
# return
# model_config = model_config or get_config(config_path).get("model", {})
if condition_scale != 1:
for name, module in pipeline.transformer.named_modules():
if not name.endswith(".attn"):
continue
module.c_factor = torch.ones(1, 1) * condition_scale
self = pipeline
(
prompt,
prompt_2,
height,
width,
num_inference_steps,
timesteps,
guidance_scale,
num_images_per_prompt,
generator,
latents,
prompt_embeds,
pooled_prompt_embeds,
output_type,
return_dict,
joint_attention_kwargs,
callback_on_step_end,
callback_on_step_end_tensor_inputs,
max_sequence_length,
) = prepare_params(**params)
height = height or self.default_sample_size * self.vae_scale_factor
width = width or self.default_sample_size * self.vae_scale_factor
# 1. Check inputs. Raise error if not correct
self.check_inputs(
prompt,
prompt_2,
height,
width,
prompt_embeds=prompt_embeds,
pooled_prompt_embeds=pooled_prompt_embeds,
callback_on_step_end_tensor_inputs=callback_on_step_end_tensor_inputs,
max_sequence_length=max_sequence_length,
)
self._guidance_scale = guidance_scale
self._joint_attention_kwargs = joint_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
# print('execution device --->', device)
# device = 'cpu'
lora_scale = (
self.joint_attention_kwargs.get("scale", None)
if self.joint_attention_kwargs is not None
else None
)
(
prompt_embeds,
pooled_prompt_embeds,
text_ids,
) = self.encode_prompt(
prompt=prompt,
prompt_2=prompt_2,
prompt_embeds=prompt_embeds,
pooled_prompt_embeds=pooled_prompt_embeds,
device=device,
num_images_per_prompt=num_images_per_prompt,
max_sequence_length=max_sequence_length,
lora_scale=lora_scale,
)
# print('-----> real prompt embeds:')
# print(prompt_embeds[0])
# print(pooled_prompt_embeds[0])
# print(text_ids)
# 4. Prepare latent variables
num_channels_latents = self.transformer.config.in_channels // 4
latents, latent_image_ids = self.prepare_latents(
batch_size * num_images_per_prompt,
num_channels_latents,
height,
width,
prompt_embeds.dtype,
device,
generator,
latents,
)
# 4.1. Prepare conditions
condition_latents, condition_ids, condition_type_ids = ([] for _ in range(3))
use_condition = conditions is not None or []
if use_condition:
assert len(conditions) <= 1, "Only one condition is supported for now."
pipeline.set_adapters(conditions[0].condition_type)
for condition in conditions:
# tokens, ids, type_id = condition.encode(self)
tokens, ids, type_id = params['encoded_condition']
tokens.to(torch.bfloat16)
ids.to(torch.bfloat16)
type_id.to(torch.bfloat16)
condition_latents.append(tokens) # [batch_size, token_n, token_dim]
condition_ids.append(ids) # [token_n, id_dim(3)]
condition_type_ids.append(type_id) # [token_n, 1]
condition_latents = torch.cat(condition_latents, dim=1)
condition_ids = torch.cat(condition_ids, dim=0)
if condition.condition_type == "subject":
condition_ids[:, 2] += width // 16
condition_type_ids = torch.cat(condition_type_ids, dim=0)
# 5. Prepare timesteps
sigmas = np.linspace(1.0, 1 / num_inference_steps, num_inference_steps)
image_seq_len = latents.shape[1]
mu = calculate_shift(
image_seq_len,
self.scheduler.config.base_image_seq_len,
self.scheduler.config.max_image_seq_len,
self.scheduler.config.base_shift,
self.scheduler.config.max_shift,
)
timesteps, num_inference_steps = retrieve_timesteps(
self.scheduler,
num_inference_steps,
device,
timesteps,
sigmas,
mu=mu,
)
num_warmup_steps = max(
len(timesteps) - num_inference_steps * self.scheduler.order, 0
)
self._num_timesteps = len(timesteps)
# 6. Denoising loop
with self.progress_bar(total=num_inference_steps) as progress_bar:
for i, t in enumerate(timesteps):
if self.interrupt:
continue
# broadcast to batch dimension in a way that's compatible with ONNX/Core ML
timestep = t.expand(latents.shape[0]).to(latents.dtype)
# handle guidance
if self.transformer.config.guidance_embeds:
guidance = torch.tensor([guidance_scale], device=device)
guidance = guidance.expand(latents.shape[0])
else:
guidance = None
noise_pred = tranformer_forward(
self.transformer,
model_config=model_config,
# Inputs of the condition (new feature)
condition_latents=condition_latents if use_condition else None,
condition_ids=condition_ids if use_condition else None,
condition_type_ids=condition_type_ids if use_condition else None,
# Inputs to the original transformer
hidden_states=latents,
# YiYi notes: divide it by 1000 for now because we scale it by 1000 in the transforme rmodel (we should not keep it but I want to keep the inputs same for the model for testing)
timestep=timestep / 1000,
guidance=guidance,
pooled_projections=pooled_prompt_embeds,
encoder_hidden_states=prompt_embeds,
txt_ids=text_ids,
img_ids=latent_image_ids,
joint_attention_kwargs=self.joint_attention_kwargs,
return_dict=False,
)[0]
# compute the previous noisy sample x_t -> x_t-1
latents_dtype = latents.dtype
latents = self.scheduler.step(noise_pred, t, latents, return_dict=False)[0]
if latents.dtype != latents_dtype:
if torch.backends.mps.is_available():
# some platforms (eg. apple mps) misbehave due to a pytorch bug: https://github.com/pytorch/pytorch/pull/99272
latents = latents.to(latents_dtype)
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)
# 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 output_type == "latent":
image = latents
else:
latents = self._unpack_latents(latents, height, width, self.vae_scale_factor)
latents = (
latents / self.vae.config.scaling_factor
) + self.vae.config.shift_factor
image = self.vae.decode(latents, return_dict=False)[0]
image = self.image_processor.postprocess(image, output_type=output_type)
# Offload all models
self.maybe_free_model_hooks()
if condition_scale != 1:
for name, module in pipeline.transformer.named_modules():
if not name.endswith(".attn"):
continue
del module.c_factor
if not return_dict:
return (image,)
return FluxPipelineOutput(images=image)
+75
View File
@@ -0,0 +1,75 @@
from peft.tuners.tuners_utils import BaseTunerLayer
from typing import List, Any, Optional, Type
class enable_lora:
def __init__(self, lora_modules: List[BaseTunerLayer], activated: bool) -> None:
self.activated: bool = activated
if activated:
return
self.lora_modules: List[BaseTunerLayer] = [
each for each in lora_modules if isinstance(each, BaseTunerLayer)
]
self.scales = [
{
active_adapter: lora_module.scaling[active_adapter]
for active_adapter in lora_module.active_adapters
}
for lora_module in self.lora_modules
]
def __enter__(self) -> None:
if self.activated:
return
for lora_module in self.lora_modules:
if not isinstance(lora_module, BaseTunerLayer):
continue
lora_module.scale_layer(0)
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[Any],
) -> None:
if self.activated:
return
for i, lora_module in enumerate(self.lora_modules):
if not isinstance(lora_module, BaseTunerLayer):
continue
for active_adapter in lora_module.active_adapters:
lora_module.scaling[active_adapter] = self.scales[i][active_adapter]
class set_lora_scale:
def __init__(self, lora_modules: List[BaseTunerLayer], scale: float) -> None:
self.lora_modules: List[BaseTunerLayer] = [
each for each in lora_modules if isinstance(each, BaseTunerLayer)
]
self.scales = [
{
active_adapter: lora_module.scaling[active_adapter]
for active_adapter in lora_module.active_adapters
}
for lora_module in self.lora_modules
]
self.scale = scale
def __enter__(self) -> None:
for lora_module in self.lora_modules:
if not isinstance(lora_module, BaseTunerLayer):
continue
lora_module.scale_layer(self.scale)
def __exit__(
self,
exc_type: Optional[Type[BaseException]],
exc_val: Optional[BaseException],
exc_tb: Optional[Any],
) -> None:
for i, lora_module in enumerate(self.lora_modules):
if not isinstance(lora_module, BaseTunerLayer):
continue
for active_adapter in lora_module.active_adapters:
lora_module.scaling[active_adapter] = self.scales[i][active_adapter]
+270
View File
@@ -0,0 +1,270 @@
import torch
from diffusers.pipelines import FluxPipeline
from typing import List, Union, Optional, Dict, Any, Callable
from .block import block_forward, single_block_forward
from .lora_controller import enable_lora
from diffusers.models.transformers.transformer_flux import (
FluxTransformer2DModel,
Transformer2DModelOutput,
USE_PEFT_BACKEND,
is_torch_version,
scale_lora_layers,
unscale_lora_layers,
logger,
)
import numpy as np
def prepare_params(
hidden_states: torch.Tensor,
encoder_hidden_states: torch.Tensor = None,
pooled_projections: torch.Tensor = None,
timestep: torch.LongTensor = None,
img_ids: torch.Tensor = None,
txt_ids: torch.Tensor = None,
guidance: torch.Tensor = None,
joint_attention_kwargs: Optional[Dict[str, Any]] = None,
controlnet_block_samples=None,
controlnet_single_block_samples=None,
return_dict: bool = True,
**kwargs: dict,
):
return (
hidden_states,
encoder_hidden_states,
pooled_projections,
timestep,
img_ids,
txt_ids,
guidance,
joint_attention_kwargs,
controlnet_block_samples,
controlnet_single_block_samples,
return_dict,
)
def tranformer_forward(
transformer: FluxTransformer2DModel,
condition_latents: torch.Tensor,
condition_ids: torch.Tensor,
condition_type_ids: torch.Tensor,
model_config: Optional[Dict[str, Any]] = {},
return_conditional_latents: bool = False,
c_t=0,
**params: dict,
):
self = transformer
use_condition = condition_latents is not None
use_condition_in_single_blocks = model_config.get(
"use_condition_in_single_blocks", True
)
# if return_conditional_latents is True, use_condition and use_condition_in_single_blocks must be True
assert not return_conditional_latents or (
use_condition and use_condition_in_single_blocks
), "`return_conditional_latents` is True, `use_condition` and `use_condition_in_single_blocks` must be True"
(
hidden_states,
encoder_hidden_states,
pooled_projections,
timestep,
img_ids,
txt_ids,
guidance,
joint_attention_kwargs,
controlnet_block_samples,
controlnet_single_block_samples,
return_dict,
) = prepare_params(**params)
if joint_attention_kwargs is not None:
joint_attention_kwargs = joint_attention_kwargs.copy()
lora_scale = joint_attention_kwargs.pop("scale", 1.0)
else:
lora_scale = 1.0
if USE_PEFT_BACKEND:
# weight the lora layers by setting `lora_scale` for each PEFT layer
scale_lora_layers(self, lora_scale)
else:
if (
joint_attention_kwargs is not None
and joint_attention_kwargs.get("scale", None) is not None
):
logger.warning(
"Passing `scale` via `joint_attention_kwargs` when not using the PEFT backend is ineffective."
)
with enable_lora((self.x_embedder,), model_config.get("latent_lora", False)):
hidden_states = self.x_embedder(hidden_states)
condition_latents = self.x_embedder(condition_latents) if use_condition else None
timestep = timestep.to(hidden_states.dtype) * 1000
if guidance is not None:
guidance = guidance.to(hidden_states.dtype) * 1000
else:
guidance = None
temb = (
self.time_text_embed(timestep, pooled_projections)
if guidance is None
else self.time_text_embed(timestep, guidance, pooled_projections)
)
cond_temb = (
self.time_text_embed(torch.ones_like(timestep) * c_t * 1000, pooled_projections)
if guidance is None
else self.time_text_embed(
torch.ones_like(timestep) * c_t * 1000, guidance, pooled_projections
)
)
if hasattr(self, "cond_type_embed") and condition_type_ids is not None:
cond_type_proj = self.time_text_embed.time_proj(condition_type_ids[0])
cond_type_emb = self.cond_type_embed(cond_type_proj.to(dtype=cond_temb.dtype))
cond_temb = cond_temb + cond_type_emb
encoder_hidden_states = self.context_embedder(encoder_hidden_states)
if txt_ids.ndim == 3:
logger.warning(
"Passing `txt_ids` 3d torch.Tensor is deprecated."
"Please remove the batch dimension and pass it as a 2d torch Tensor"
)
txt_ids = txt_ids[0]
if img_ids.ndim == 3:
logger.warning(
"Passing `img_ids` 3d torch.Tensor is deprecated."
"Please remove the batch dimension and pass it as a 2d torch Tensor"
)
img_ids = img_ids[0]
ids = torch.cat((txt_ids, img_ids), dim=0)
image_rotary_emb = self.pos_embed(ids)
if use_condition:
cond_ids = condition_ids
cond_rotary_emb = self.pos_embed(cond_ids)
# hidden_states = torch.cat([hidden_states, condition_latents], dim=1)
for index_block, block in enumerate(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 {}
)
encoder_hidden_states, hidden_states = torch.utils.checkpoint.checkpoint(
create_custom_forward(block),
hidden_states,
encoder_hidden_states,
temb,
image_rotary_emb,
**ckpt_kwargs,
)
else:
encoder_hidden_states, hidden_states, condition_latents = block_forward(
block,
model_config=model_config,
hidden_states=hidden_states,
encoder_hidden_states=encoder_hidden_states,
condition_latents=condition_latents if use_condition else None,
temb=temb,
cond_temb=cond_temb if use_condition else None,
cond_rotary_emb=cond_rotary_emb if use_condition else None,
image_rotary_emb=image_rotary_emb,
)
# controlnet residual
if controlnet_block_samples is not None:
interval_control = len(self.transformer_blocks) / len(
controlnet_block_samples
)
interval_control = int(np.ceil(interval_control))
hidden_states = (
hidden_states
+ controlnet_block_samples[index_block // interval_control]
)
hidden_states = torch.cat([encoder_hidden_states, hidden_states], dim=1)
for index_block, block in enumerate(self.single_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,
temb,
image_rotary_emb,
**ckpt_kwargs,
)
else:
result = single_block_forward(
block,
model_config=model_config,
hidden_states=hidden_states,
temb=temb,
image_rotary_emb=image_rotary_emb,
**(
{
"condition_latents": condition_latents,
"cond_temb": cond_temb,
"cond_rotary_emb": cond_rotary_emb,
}
if use_condition_in_single_blocks and use_condition
else {}
),
)
if use_condition_in_single_blocks and use_condition:
hidden_states, condition_latents = result
else:
hidden_states = result
# controlnet residual
if controlnet_single_block_samples is not None:
interval_control = len(self.single_transformer_blocks) / len(
controlnet_single_block_samples
)
interval_control = int(np.ceil(interval_control))
hidden_states[:, encoder_hidden_states.shape[1] :, ...] = (
hidden_states[:, encoder_hidden_states.shape[1] :, ...]
+ controlnet_single_block_samples[index_block // interval_control]
)
hidden_states = hidden_states[:, encoder_hidden_states.shape[1] :, ...]
hidden_states = self.norm_out(hidden_states, temb)
output = self.proj_out(hidden_states)
if return_conditional_latents:
condition_latents = (
self.norm_out(condition_latents, cond_temb) if use_condition else None
)
condition_output = self.proj_out(condition_latents) if use_condition else None
if USE_PEFT_BACKEND:
# remove `lora_scale` from each PEFT layer
unscale_lora_layers(self, lora_scale)
if not return_dict:
return (
(output,) if not return_conditional_latents else (output, condition_output)
)
return Transformer2DModelOutput(sample=output)