svjack/MotionClone-Text-to-Video
1
1# Copyright 2023 The HuggingFace Team. All rights reserved.2#3# Licensed under the Apache License, Version 2.0 (the "License");4# you may not use this file except in compliance with the License.5# You may obtain a copy of the License at6#7# http://www.apache.org/licenses/LICENSE-2.08#9# Unless required by applicable law or agreed to in writing, software10# distributed under the License is distributed on an "AS IS" BASIS,11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.12# See the License for the specific language governing permissions and13# limitations under the License.14# 15# Changes were made to this source code by Yuwei Guo.16from dataclasses import dataclass17from typing import Any, Dict, List, Optional, Tuple, Union18 19import torch20from torch import nn21from torch.nn import functional as F22 23from diffusers.configuration_utils import ConfigMixin, register_to_config24from diffusers.utils import BaseOutput, logging25from diffusers.models.embeddings import TimestepEmbedding, Timesteps26from diffusers.models.modeling_utils import ModelMixin27 28 29from .unet_blocks import (30 CrossAttnDownBlock3D,31 DownBlock3D,32 UNetMidBlock3DCrossAttn,33 get_down_block,34)35from einops import repeat, rearrange36from .resnet import InflatedConv3d37 38from diffusers.models.unet_2d_condition import UNet2DConditionModel39 40logger = logging.get_logger(__name__) # pylint: disable=invalid-name41 42 43@dataclass44class SparseControlNetOutput(BaseOutput):45 down_block_res_samples: Tuple[torch.Tensor]46 mid_block_res_sample: torch.Tensor47 48 49class SparseControlNetConditioningEmbedding(nn.Module):50 def __init__(51 self,52 conditioning_embedding_channels: int,53 conditioning_channels: int = 3,54 block_out_channels: Tuple[int] = (16, 32, 96, 256),55 ):56 super().__init__()57 58 self.conv_in = InflatedConv3d(conditioning_channels, block_out_channels[0], kernel_size=3, padding=1)59 60 self.blocks = nn.ModuleList([])61 62 for i in range(len(block_out_channels) - 1):63 channel_in = block_out_channels[i]64 channel_out = block_out_channels[i + 1]65 self.blocks.append(InflatedConv3d(channel_in, channel_in, kernel_size=3, padding=1))66 self.blocks.append(InflatedConv3d(channel_in, channel_out, kernel_size=3, padding=1, stride=2))67 68 self.conv_out = zero_module(69 InflatedConv3d(block_out_channels[-1], conditioning_embedding_channels, kernel_size=3, padding=1)70 )71 72 def forward(self, conditioning):73 embedding = self.conv_in(conditioning)74 embedding = F.silu(embedding)75 76 for block in self.blocks:77 embedding = block(embedding)78 embedding = F.silu(embedding)79 80 embedding = self.conv_out(embedding)81 82 return embedding83 84 85class SparseControlNetModel(ModelMixin, ConfigMixin):86 _supports_gradient_checkpointing = True87 88 @register_to_config89 def __init__(90 self,91 in_channels: int = 4,92 conditioning_channels: int = 3,93 flip_sin_to_cos: bool = True,94 freq_shift: int = 0,95 down_block_types: Tuple[str] = (96 "CrossAttnDownBlock2D",97 "CrossAttnDownBlock2D",98 "CrossAttnDownBlock2D",99 "DownBlock2D",100 ),101 only_cross_attention: Union[bool, Tuple[bool]] = False,102 block_out_channels: Tuple[int] = (320, 640, 1280, 1280),103 layers_per_block: int = 2,104 downsample_padding: int = 1,105 mid_block_scale_factor: float = 1,106 act_fn: str = "silu",107 norm_num_groups: Optional[int] = 32,108 norm_eps: float = 1e-5,109 cross_attention_dim: int = 1280,110 attention_head_dim: Union[int, Tuple[int]] = 8,111 num_attention_heads: Optional[Union[int, Tuple[int]]] = None,112 use_linear_projection: bool = False,113 class_embed_type: Optional[str] = None,114 num_class_embeds: Optional[int] = None,115 upcast_attention: bool = False,116 resnet_time_scale_shift: str = "default",117 projection_class_embeddings_input_dim: Optional[int] = None,118 controlnet_conditioning_channel_order: str = "rgb",119 conditioning_embedding_out_channels: Optional[Tuple[int]] = (16, 32, 96, 256),120 global_pool_conditions: bool = False,121 122 use_motion_module = True,123 motion_module_resolutions = ( 1,2,4,8 ),124 motion_module_mid_block = False,125 motion_module_type = "Vanilla",126 motion_module_kwargs = {127 "num_attention_heads": 8,128 "num_transformer_block": 1,129 "attention_block_types": ["Temporal_Self"],130 "temporal_position_encoding": True,131 "temporal_position_encoding_max_len": 32,132 "temporal_attention_dim_div": 1,133 "causal_temporal_attention": False,134 },135 136 concate_conditioning_mask: bool = True,137 use_simplified_condition_embedding: bool = False,138 139 set_noisy_sample_input_to_zero: bool = False,140 ):141 super().__init__()142 143 # If `num_attention_heads` is not defined (which is the case for most models)144 # it will default to `attention_head_dim`. This looks weird upon first reading it and it is.145 # The reason for this behavior is to correct for incorrectly named variables that were introduced146 # when this library was created. The incorrect naming was only discovered much later in https://github.com/huggingface/diffusers/issues/2011#issuecomment-1547958131147 # Changing `attention_head_dim` to `num_attention_heads` for 40,000+ configurations is too backwards breaking148 # which is why we correct for the naming here.149 num_attention_heads = num_attention_heads or attention_head_dim150 151 # Check inputs152 if len(block_out_channels) != len(down_block_types):153 raise ValueError(154 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}."155 )156 157 if not isinstance(only_cross_attention, bool) and len(only_cross_attention) != len(down_block_types):158 raise ValueError(159 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}."160 )161 162 if not isinstance(num_attention_heads, int) and len(num_attention_heads) != len(down_block_types):163 raise ValueError(164 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}."165 )166 167 # input168 self.set_noisy_sample_input_to_zero = set_noisy_sample_input_to_zero169 170 conv_in_kernel = 3171 conv_in_padding = (conv_in_kernel - 1) // 2172 self.conv_in = InflatedConv3d(173 in_channels, block_out_channels[0], kernel_size=conv_in_kernel, padding=conv_in_padding174 )175 176 if concate_conditioning_mask:177 conditioning_channels = conditioning_channels + 1178 self.concate_conditioning_mask = concate_conditioning_mask179 180 # control net conditioning embedding181 if use_simplified_condition_embedding:182 self.controlnet_cond_embedding = zero_module(183 InflatedConv3d(conditioning_channels, block_out_channels[0], kernel_size=conv_in_kernel, padding=conv_in_padding)184 ).to(torch.float16)185 else:186 self.controlnet_cond_embedding = SparseControlNetConditioningEmbedding(187 conditioning_embedding_channels=block_out_channels[0],188 block_out_channels=conditioning_embedding_out_channels,189 conditioning_channels=conditioning_channels,190 ).to(torch.float16)191 self.use_simplified_condition_embedding = use_simplified_condition_embedding192 193 # time194 time_embed_dim = block_out_channels[0] * 4195 196 self.time_proj = Timesteps(block_out_channels[0], flip_sin_to_cos, freq_shift)197 timestep_input_dim = block_out_channels[0]198 199 self.time_embedding = TimestepEmbedding(200 timestep_input_dim,201 time_embed_dim,202 act_fn=act_fn,203 )204 205 # class embedding206 if class_embed_type is None and num_class_embeds is not None:207 self.class_embedding = nn.Embedding(num_class_embeds, time_embed_dim)208 elif class_embed_type == "timestep":209 self.class_embedding = TimestepEmbedding(timestep_input_dim, time_embed_dim)210 elif class_embed_type == "identity":211 self.class_embedding = nn.Identity(time_embed_dim, time_embed_dim)212 elif class_embed_type == "projection":213 if projection_class_embeddings_input_dim is None:214 raise ValueError(215 "`class_embed_type`: 'projection' requires `projection_class_embeddings_input_dim` be set"216 )217 # The projection `class_embed_type` is the same as the timestep `class_embed_type` except218 # 1. the `class_labels` inputs are not first converted to sinusoidal embeddings219 # 2. it projects from an arbitrary input dimension.220 #221 # Note that `TimestepEmbedding` is quite general, being mainly linear layers and activations.222 # When used for embedding actual timesteps, the timesteps are first converted to sinusoidal embeddings.223 # As a result, `TimestepEmbedding` can be passed arbitrary vectors.224 self.class_embedding = TimestepEmbedding(projection_class_embeddings_input_dim, time_embed_dim)225 else:226 self.class_embedding = None227 228 229 self.down_blocks = nn.ModuleList([])230 self.controlnet_down_blocks = nn.ModuleList([])231 232 if isinstance(only_cross_attention, bool):233 only_cross_attention = [only_cross_attention] * len(down_block_types)234 235 if isinstance(attention_head_dim, int):236 attention_head_dim = (attention_head_dim,) * len(down_block_types)237 238 if isinstance(num_attention_heads, int):239 num_attention_heads = (num_attention_heads,) * len(down_block_types)240 241 # down242 output_channel = block_out_channels[0]243 244 controlnet_block = InflatedConv3d(output_channel, output_channel, kernel_size=1)245 controlnet_block = zero_module(controlnet_block)246 self.controlnet_down_blocks.append(controlnet_block)247 248 for i, down_block_type in enumerate(down_block_types):249 res = 2 ** i250 input_channel = output_channel251 output_channel = block_out_channels[i]252 is_final_block = i == len(block_out_channels) - 1253 254 down_block = get_down_block(255 down_block_type,256 num_layers=layers_per_block,257 in_channels=input_channel,258 out_channels=output_channel,259 temb_channels=time_embed_dim,260 add_downsample=not is_final_block,261 resnet_eps=norm_eps,262 resnet_act_fn=act_fn,263 resnet_groups=norm_num_groups,264 cross_attention_dim=cross_attention_dim,265 attn_num_head_channels=attention_head_dim[i] if attention_head_dim[i] is not None else output_channel,266 downsample_padding=downsample_padding,267 use_linear_projection=use_linear_projection,268 only_cross_attention=only_cross_attention[i],269 upcast_attention=upcast_attention,270 resnet_time_scale_shift=resnet_time_scale_shift,271 272 use_inflated_groupnorm=True,273 274 use_motion_module=use_motion_module and (res in motion_module_resolutions),275 motion_module_type=motion_module_type,276 motion_module_kwargs=motion_module_kwargs,277 )278 self.down_blocks.append(down_block)279 280 for _ in range(layers_per_block):281 controlnet_block = InflatedConv3d(output_channel, output_channel, kernel_size=1)282 controlnet_block = zero_module(controlnet_block)283 self.controlnet_down_blocks.append(controlnet_block)284 285 if not is_final_block:286 controlnet_block = InflatedConv3d(output_channel, output_channel, kernel_size=1)287 controlnet_block = zero_module(controlnet_block)288 self.controlnet_down_blocks.append(controlnet_block)289 290 # mid291 mid_block_channel = block_out_channels[-1]292 293 controlnet_block = InflatedConv3d(mid_block_channel, mid_block_channel, kernel_size=1)294 controlnet_block = zero_module(controlnet_block)295 self.controlnet_mid_block = controlnet_block296 297 self.mid_block = UNetMidBlock3DCrossAttn(298 in_channels=mid_block_channel,299 temb_channels=time_embed_dim,300 resnet_eps=norm_eps,301 resnet_act_fn=act_fn,302 output_scale_factor=mid_block_scale_factor,303 resnet_time_scale_shift=resnet_time_scale_shift,304 cross_attention_dim=cross_attention_dim,305 attn_num_head_channels=num_attention_heads[-1],306 resnet_groups=norm_num_groups,307 use_linear_projection=use_linear_projection,308 upcast_attention=upcast_attention,309 310 use_inflated_groupnorm=True,311 use_motion_module=use_motion_module and motion_module_mid_block,312 motion_module_type=motion_module_type,313 motion_module_kwargs=motion_module_kwargs,314 )315 316 @classmethod317 def from_unet(318 cls,319 unet: UNet2DConditionModel,320 controlnet_conditioning_channel_order: str = "rgb",321 conditioning_embedding_out_channels: Optional[Tuple[int]] = (16, 32, 96, 256),322 load_weights_from_unet: bool = True,323 324 controlnet_additional_kwargs: dict = {},325 ):326 controlnet = cls(327 in_channels=unet.config.in_channels,328 flip_sin_to_cos=unet.config.flip_sin_to_cos,329 freq_shift=unet.config.freq_shift,330 down_block_types=unet.config.down_block_types,331 only_cross_attention=unet.config.only_cross_attention,332 block_out_channels=unet.config.block_out_channels,333 layers_per_block=unet.config.layers_per_block,334 downsample_padding=unet.config.downsample_padding,335 mid_block_scale_factor=unet.config.mid_block_scale_factor,336 act_fn=unet.config.act_fn,337 norm_num_groups=unet.config.norm_num_groups,338 norm_eps=unet.config.norm_eps,339 cross_attention_dim=unet.config.cross_attention_dim,340 attention_head_dim=unet.config.attention_head_dim,341 num_attention_heads=unet.config.num_attention_heads,342 use_linear_projection=unet.config.use_linear_projection,343 class_embed_type=unet.config.class_embed_type,344 num_class_embeds=unet.config.num_class_embeds,345 upcast_attention=unet.config.upcast_attention,346 resnet_time_scale_shift=unet.config.resnet_time_scale_shift,347 projection_class_embeddings_input_dim=unet.config.projection_class_embeddings_input_dim,348 controlnet_conditioning_channel_order=controlnet_conditioning_channel_order,349 conditioning_embedding_out_channels=conditioning_embedding_out_channels,350 351 **controlnet_additional_kwargs,352 )353 354 if load_weights_from_unet:355 m, u = controlnet.conv_in.load_state_dict(cls.image_layer_filter(unet.conv_in.state_dict()), strict=False)356 assert len(u) == 0357 m, u = controlnet.time_proj.load_state_dict(cls.image_layer_filter(unet.time_proj.state_dict()), strict=False)358 assert len(u) == 0359 m, u = controlnet.time_embedding.load_state_dict(cls.image_layer_filter(unet.time_embedding.state_dict()), strict=False)360 assert len(u) == 0361 362 if controlnet.class_embedding:363 m, u = controlnet.class_embedding.load_state_dict(cls.image_layer_filter(unet.class_embedding.state_dict()), strict=False)364 assert len(u) == 0365 m, u = controlnet.down_blocks.load_state_dict(cls.image_layer_filter(unet.down_blocks.state_dict()), strict=False)366 assert len(u) == 0367 m, u = controlnet.mid_block.load_state_dict(cls.image_layer_filter(unet.mid_block.state_dict()), strict=False)368 assert len(u) == 0369 370 return controlnet371 372 @staticmethod373 def image_layer_filter(state_dict):374 new_state_dict = {}375 for name, param in state_dict.items():376 if "motion_modules." in name or "lora" in name: continue377 new_state_dict[name] = param378 return new_state_dict379 380 # Copied from diffusers.models.unet_2d_condition.UNet2DConditionModel.set_attention_slice381 def set_attention_slice(self, slice_size):382 r"""383 Enable sliced attention computation.384 385 When this option is enabled, the attention module splits the input tensor in slices to compute attention in386 several steps. This is useful for saving some memory in exchange for a small decrease in speed.387 388 Args:389 slice_size (`str` or `int` or `list(int)`, *optional*, defaults to `"auto"`):390 When `"auto"`, input to the attention heads is halved, so attention is computed in two steps. If391 `"max"`, maximum amount of memory is saved by running only one slice at a time. If a number is392 provided, uses as many slices as `attention_head_dim // slice_size`. In this case, `attention_head_dim`393 must be a multiple of `slice_size`.394 """395 sliceable_head_dims = []396 397 def fn_recursive_retrieve_sliceable_dims(module: torch.nn.Module):398 if hasattr(module, "set_attention_slice"):399 sliceable_head_dims.append(module.sliceable_head_dim)400 401 for child in module.children():402 fn_recursive_retrieve_sliceable_dims(child)403 404 # retrieve number of attention layers405 for module in self.children():406 fn_recursive_retrieve_sliceable_dims(module)407 408 num_sliceable_layers = len(sliceable_head_dims)409 410 if slice_size == "auto":411 # half the attention head size is usually a good trade-off between412 # speed and memory413 slice_size = [dim // 2 for dim in sliceable_head_dims]414 elif slice_size == "max":415 # make smallest slice possible416 slice_size = num_sliceable_layers * [1]417 418 slice_size = num_sliceable_layers * [slice_size] if not isinstance(slice_size, list) else slice_size419 420 if len(slice_size) != len(sliceable_head_dims):421 raise ValueError(422 f"You have provided {len(slice_size)}, but {self.config} has {len(sliceable_head_dims)} different"423 f" attention layers. Make sure to match `len(slice_size)` to be {len(sliceable_head_dims)}."424 )425 426 for i in range(len(slice_size)):427 size = slice_size[i]428 dim = sliceable_head_dims[i]429 if size is not None and size > dim:430 raise ValueError(f"size {size} has to be smaller or equal to {dim}.")431 432 # Recursively walk through all the children.433 # Any children which exposes the set_attention_slice method434 # gets the message435 def fn_recursive_set_attention_slice(module: torch.nn.Module, slice_size: List[int]):436 if hasattr(module, "set_attention_slice"):437 module.set_attention_slice(slice_size.pop())438 439 for child in module.children():440 fn_recursive_set_attention_slice(child, slice_size)441 442 reversed_slice_size = list(reversed(slice_size))443 for module in self.children():444 fn_recursive_set_attention_slice(module, reversed_slice_size)445 446 def _set_gradient_checkpointing(self, module, value=False):447 if isinstance(module, (CrossAttnDownBlock2D, DownBlock2D)):448 module.gradient_checkpointing = value449 450 def forward(451 self,452 sample: torch.FloatTensor,453 timestep: Union[torch.Tensor, float, int],454 encoder_hidden_states: torch.Tensor,455 456 controlnet_cond: torch.FloatTensor,457 conditioning_mask: Optional[torch.FloatTensor] = None,458 459 conditioning_scale: float = 1.0,460 class_labels: Optional[torch.Tensor] = None,461 attention_mask: Optional[torch.Tensor] = None,462 cross_attention_kwargs: Optional[Dict[str, Any]] = None,463 guess_mode: bool = False,464 return_dict: bool = True,465 ) -> Union[SparseControlNetOutput, Tuple]:466 467 # set input noise to zero468 # if self.set_noisy_sample_input_to_zero:469 # sample = torch.zeros_like(sample).to(sample.device)470 471 # prepare attention_mask472 if attention_mask is not None:473 attention_mask = (1 - attention_mask.to(sample.dtype)) * -10000.0474 attention_mask = attention_mask.unsqueeze(1)475 476 # 1. time477 timesteps = timestep478 if not torch.is_tensor(timesteps):479 # TODO: this requires sync between CPU and GPU. So try to pass timesteps as tensors if you can480 # This would be a good case for the `match` statement (Python 3.10+)481 is_mps = sample.device.type == "mps"482 if isinstance(timestep, float):483 dtype = torch.float32 if is_mps else torch.float64484 else:485 dtype = torch.int32 if is_mps else torch.int64486 timesteps = torch.tensor([timesteps], dtype=dtype, device=sample.device)487 elif len(timesteps.shape) == 0:488 timesteps = timesteps[None].to(sample.device)489 490 timesteps = timesteps.repeat(sample.shape[0] // timesteps.shape[0])491 encoder_hidden_states = encoder_hidden_states.repeat(sample.shape[0] // encoder_hidden_states.shape[0], 1, 1)492 493 # broadcast to batch dimension in a way that's compatible with ONNX/Core ML494 timesteps = timesteps.expand(sample.shape[0])495 496 t_emb = self.time_proj(timesteps)497 498 # timesteps does not contain any weights and will always return f32 tensors499 # but time_embedding might actually be running in fp16. so we need to cast here.500 # there might be better ways to encapsulate this.501 t_emb = t_emb.to(dtype=self.dtype)502 emb = self.time_embedding(t_emb)503 504 if self.class_embedding is not None:505 if class_labels is None:506 raise ValueError("class_labels should be provided when num_class_embeds > 0")507 508 if self.config.class_embed_type == "timestep":509 class_labels = self.time_proj(class_labels)510 511 class_emb = self.class_embedding(class_labels).to(dtype=self.dtype)512 emb = emb + class_emb513 514 # 2. pre-process515 # equal to set input noise to zero516 if self.set_noisy_sample_input_to_zero:517 shape = sample.shape518 sample = self.conv_in.bias.reshape(1,-1,1,1,1).expand(shape[0],-1,shape[2],shape[3],shape[4])519 else:520 sample = self.conv_in(sample)521 522 if self.concate_conditioning_mask:523 controlnet_cond = torch.cat([controlnet_cond, conditioning_mask], dim=1).to(torch.float16)524 # import pdb; pdb.set_trace()525 controlnet_cond = self.controlnet_cond_embedding(controlnet_cond)526 527 sample = sample + controlnet_cond528 529 # 3. down530 down_block_res_samples = (sample,)531 for downsample_block in self.down_blocks:532 if hasattr(downsample_block, "has_cross_attention") and downsample_block.has_cross_attention:533 sample, res_samples = downsample_block(534 hidden_states=sample,535 temb=emb,536 encoder_hidden_states=encoder_hidden_states,537 attention_mask=attention_mask,538 # cross_attention_kwargs=cross_attention_kwargs,539 )540 else: sample, res_samples = downsample_block(hidden_states=sample, temb=emb)541 542 down_block_res_samples += res_samples543 544 # 4. mid545 if self.mid_block is not None:546 sample = self.mid_block(547 sample,548 emb,549 encoder_hidden_states=encoder_hidden_states,550 attention_mask=attention_mask,551 # cross_attention_kwargs=cross_attention_kwargs,552 )553 554 # 5. controlnet blocks555 controlnet_down_block_res_samples = ()556 557 for down_block_res_sample, controlnet_block in zip(down_block_res_samples, self.controlnet_down_blocks):558 down_block_res_sample = controlnet_block(down_block_res_sample)559 controlnet_down_block_res_samples = controlnet_down_block_res_samples + (down_block_res_sample,)560 561 down_block_res_samples = controlnet_down_block_res_samples562 563 mid_block_res_sample = self.controlnet_mid_block(sample)564 565 # 6. scaling566 if guess_mode and not self.config.global_pool_conditions:567 scales = torch.logspace(-1, 0, len(down_block_res_samples) + 1, device=sample.device) # 0.1 to 1.0568 569 scales = scales * conditioning_scale570 down_block_res_samples = [sample * scale for sample, scale in zip(down_block_res_samples, scales)]571 mid_block_res_sample = mid_block_res_sample * scales[-1] # last one572 else:573 down_block_res_samples = [sample * conditioning_scale for sample in down_block_res_samples]574 mid_block_res_sample = mid_block_res_sample * conditioning_scale575 576 if self.config.global_pool_conditions:577 down_block_res_samples = [578 torch.mean(sample, dim=(2, 3), keepdim=True) for sample in down_block_res_samples579 ]580 mid_block_res_sample = torch.mean(mid_block_res_sample, dim=(2, 3), keepdim=True)581 582 if not return_dict:583 return (down_block_res_samples, mid_block_res_sample)584 585 return SparseControlNetOutput(586 down_block_res_samples=down_block_res_samples, mid_block_res_sample=mid_block_res_sample587 )588 589 590def zero_module(module):591 for p in module.parameters():592 nn.init.zeros_(p)593 return module594 