| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| from contextlib import nullcontext |
| import os |
| from typing import Optional |
|
|
| from diffusers import ConfigMixin, ModelMixin |
| from diffusers.configuration_utils import register_to_config |
| from diffusers.models.attention import Attention, FeedForward |
| from diffusers.models.embeddings import SinusoidalPositionalEmbedding, TimestepEmbedding, Timesteps |
| import torch |
| from torch import nn |
| import torch.nn.functional as F |
|
|
|
|
| def _is_spark_sm121() -> bool: |
| if not torch.cuda.is_available(): |
| return False |
|
|
| major, minor = torch.cuda.get_device_capability() |
| return (major, minor) == (12, 1) |
|
|
|
|
| def _should_force_math_sdpa() -> bool: |
| override = os.environ.get("GR00T_DIT_SDPA_MODE") |
| if override == "math": |
| return True |
| if override == "default": |
| return False |
|
|
| return _is_spark_sm121() |
|
|
|
|
| def _sdpa_context(): |
| |
| |
| if not _should_force_math_sdpa(): |
| return nullcontext() |
|
|
| return torch.backends.cuda.sdp_kernel( |
| enable_flash=False, |
| enable_math=True, |
| enable_mem_efficient=False, |
| enable_cudnn=False, |
| ) |
|
|
|
|
| class TimestepEncoder(nn.Module): |
| def __init__(self, embedding_dim, compute_dtype=torch.float32): |
| super().__init__() |
| self.time_proj = Timesteps(num_channels=256, flip_sin_to_cos=True, downscale_freq_shift=1) |
| self.timestep_embedder = TimestepEmbedding(in_channels=256, time_embed_dim=embedding_dim) |
|
|
| def forward(self, timesteps): |
| dtype = next(self.parameters()).dtype |
| timesteps_proj = self.time_proj(timesteps).to(dtype) |
| timesteps_emb = self.timestep_embedder(timesteps_proj) |
| return timesteps_emb |
|
|
|
|
| class AdaLayerNorm(nn.Module): |
| def __init__( |
| self, |
| embedding_dim: int, |
| norm_elementwise_affine: bool = False, |
| norm_eps: float = 1e-5, |
| chunk_dim: int = 0, |
| ): |
| super().__init__() |
| self.chunk_dim = chunk_dim |
| output_dim = embedding_dim * 2 |
| self.silu = nn.SiLU() |
| self.linear = nn.Linear(embedding_dim, output_dim) |
| self.norm = nn.LayerNorm(output_dim // 2, norm_eps, norm_elementwise_affine) |
|
|
| def forward( |
| self, |
| x: torch.Tensor, |
| temb: Optional[torch.Tensor] = None, |
| ) -> torch.Tensor: |
| temb = self.linear(self.silu(temb)) |
| scale, shift = temb.chunk(2, dim=1) |
| x = self.norm(x) * (1 + scale[:, None]) + shift[:, None] |
| return x |
|
|
|
|
| class BasicTransformerBlock(nn.Module): |
| 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", |
| attention_bias: bool = False, |
| upcast_attention: bool = False, |
| norm_elementwise_affine: bool = True, |
| norm_type: str = "layer_norm", |
| norm_eps: float = 1e-5, |
| final_dropout: bool = False, |
| attention_type: str = "default", |
| positional_embeddings: Optional[str] = None, |
| num_positional_embeddings: Optional[int] = None, |
| ff_inner_dim: Optional[int] = None, |
| ff_bias: bool = True, |
| attention_out_bias: bool = True, |
| ): |
| super().__init__() |
| self.dim = dim |
| self.num_attention_heads = num_attention_heads |
| self.attention_head_dim = attention_head_dim |
| self.dropout = dropout |
| self.cross_attention_dim = cross_attention_dim |
| self.activation_fn = activation_fn |
| self.attention_bias = attention_bias |
| self.norm_elementwise_affine = norm_elementwise_affine |
| self.positional_embeddings = positional_embeddings |
| self.num_positional_embeddings = num_positional_embeddings |
| self.norm_type = 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 |
|
|
| |
| |
| if norm_type == "ada_norm": |
| self.norm1 = AdaLayerNorm(dim) |
| 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, |
| upcast_attention=upcast_attention, |
| out_bias=attention_out_bias, |
| ) |
|
|
| |
| 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, |
| ) |
| if final_dropout: |
| self.final_dropout = nn.Dropout(dropout) |
| else: |
| self.final_dropout = None |
|
|
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| attention_mask: Optional[torch.Tensor] = None, |
| encoder_hidden_states: Optional[torch.Tensor] = None, |
| encoder_attention_mask: Optional[torch.Tensor] = None, |
| temb: Optional[torch.LongTensor] = None, |
| ) -> torch.Tensor: |
| |
| if self.norm_type == "ada_norm": |
| norm_hidden_states = self.norm1(hidden_states, temb) |
| else: |
| norm_hidden_states = self.norm1(hidden_states) |
|
|
| if self.pos_embed is not None: |
| norm_hidden_states = self.pos_embed(norm_hidden_states) |
|
|
| with _sdpa_context(): |
| attn_output = self.attn1( |
| norm_hidden_states, |
| encoder_hidden_states=encoder_hidden_states, |
| attention_mask=( |
| encoder_attention_mask if encoder_hidden_states is not None else attention_mask |
| ), |
| ) |
| if self.final_dropout: |
| attn_output = self.final_dropout(attn_output) |
|
|
| hidden_states = attn_output + hidden_states |
| if hidden_states.ndim == 4: |
| hidden_states = hidden_states.squeeze(1) |
|
|
| |
| norm_hidden_states = self.norm3(hidden_states) |
| ff_output = self.ff(norm_hidden_states) |
|
|
| hidden_states = ff_output + hidden_states |
| if hidden_states.ndim == 4: |
| hidden_states = hidden_states.squeeze(1) |
| return hidden_states |
|
|
|
|
| class DiT(ModelMixin, ConfigMixin): |
| _supports_gradient_checkpointing = True |
|
|
| @register_to_config |
| def __init__( |
| self, |
| num_attention_heads: int = 8, |
| attention_head_dim: int = 64, |
| output_dim: int = 26, |
| num_layers: int = 12, |
| dropout: float = 0.1, |
| attention_bias: bool = True, |
| activation_fn: str = "gelu-approximate", |
| num_embeds_ada_norm: Optional[int] = 1000, |
| upcast_attention: bool = False, |
| norm_type: str = "ada_norm", |
| norm_elementwise_affine: bool = False, |
| norm_eps: float = 1e-5, |
| max_num_positional_embeddings: int = 512, |
| compute_dtype=torch.float32, |
| final_dropout: bool = True, |
| positional_embeddings: Optional[str] = "sinusoidal", |
| interleave_self_attention=False, |
| cross_attention_dim: Optional[int] = None, |
| ): |
| super().__init__() |
|
|
| self.attention_head_dim = attention_head_dim |
| self.inner_dim = self.config.num_attention_heads * self.config.attention_head_dim |
| self.gradient_checkpointing = False |
|
|
| |
| self.timestep_encoder = TimestepEncoder( |
| embedding_dim=self.inner_dim, compute_dtype=self.compute_dtype |
| ) |
|
|
| all_blocks = [] |
| for idx in range(self.config.num_layers): |
| use_self_attn = idx % 2 == 1 and interleave_self_attention |
| curr_cross_attention_dim = cross_attention_dim if not use_self_attn else None |
|
|
| all_blocks += [ |
| BasicTransformerBlock( |
| self.inner_dim, |
| self.config.num_attention_heads, |
| self.config.attention_head_dim, |
| dropout=self.config.dropout, |
| activation_fn=self.config.activation_fn, |
| attention_bias=self.config.attention_bias, |
| upcast_attention=self.config.upcast_attention, |
| norm_type=norm_type, |
| norm_elementwise_affine=self.config.norm_elementwise_affine, |
| norm_eps=self.config.norm_eps, |
| positional_embeddings=positional_embeddings, |
| num_positional_embeddings=self.config.max_num_positional_embeddings, |
| final_dropout=final_dropout, |
| cross_attention_dim=curr_cross_attention_dim, |
| ) |
| ] |
| self.transformer_blocks = nn.ModuleList(all_blocks) |
|
|
| |
| self.norm_out = nn.LayerNorm(self.inner_dim, elementwise_affine=False, eps=1e-6) |
| self.proj_out_1 = nn.Linear(self.inner_dim, 2 * self.inner_dim) |
| self.proj_out_2 = nn.Linear(self.inner_dim, self.output_dim) |
| print( |
| "Total number of DiT parameters: ", |
| sum(p.numel() for p in self.parameters() if p.requires_grad), |
| ) |
|
|
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| encoder_hidden_states: torch.Tensor, |
| timestep: Optional[torch.LongTensor] = None, |
| encoder_attention_mask: Optional[torch.Tensor] = None, |
| return_all_hidden_states: bool = False, |
| ): |
| |
| temb = self.timestep_encoder(timestep) |
|
|
| |
| hidden_states = hidden_states.contiguous() |
| encoder_hidden_states = encoder_hidden_states.contiguous() |
|
|
| all_hidden_states = [hidden_states] |
|
|
| |
| for idx, block in enumerate(self.transformer_blocks): |
| if idx % 2 == 1 and self.config.interleave_self_attention: |
| hidden_states = block( |
| hidden_states, |
| attention_mask=None, |
| encoder_hidden_states=None, |
| encoder_attention_mask=None, |
| temb=temb, |
| ) |
| else: |
| hidden_states = block( |
| hidden_states, |
| attention_mask=None, |
| encoder_hidden_states=encoder_hidden_states, |
| encoder_attention_mask=None, |
| temb=temb, |
| ) |
| all_hidden_states.append(hidden_states) |
|
|
| |
| conditioning = temb |
| 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] |
| if return_all_hidden_states: |
| return self.proj_out_2(hidden_states), all_hidden_states |
| else: |
| return self.proj_out_2(hidden_states) |
|
|
|
|
| class AlternateVLDiT(DiT): |
| """ |
| Alternate Vision-Language DiT that separates image and non-image tokens |
| during cross-attention processing. |
| """ |
|
|
| def __init__(self, *args, attend_text_every_n_blocks: int = 2, **kwargs): |
| super().__init__(*args, **kwargs) |
| self.attend_text_every_n_blocks = attend_text_every_n_blocks |
|
|
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| encoder_hidden_states: torch.Tensor, |
| timestep: Optional[torch.LongTensor] = None, |
| encoder_attention_mask: Optional[torch.Tensor] = None, |
| return_all_hidden_states: bool = False, |
| image_mask: Optional[torch.Tensor] = None, |
| backbone_attention_mask: Optional[torch.Tensor] = None, |
| ): |
| assert image_mask is not None, "Image mask is required" |
|
|
| |
| temb = self.timestep_encoder(timestep) |
|
|
| |
| hidden_states = hidden_states.contiguous() |
| encoder_hidden_states = encoder_hidden_states.contiguous() |
|
|
| |
| |
| |
|
|
| image_attention_mask = image_mask & backbone_attention_mask |
| non_image_attention_mask = (~image_mask) & backbone_attention_mask |
|
|
| all_hidden_states = [hidden_states] |
| assert self.config.interleave_self_attention, "Interleave self attention must be enabled" |
|
|
| |
| for idx, block in enumerate(self.transformer_blocks): |
| if idx % 2 == 1: |
| |
| hidden_states = block( |
| hidden_states, |
| attention_mask=None, |
| encoder_hidden_states=None, |
| encoder_attention_mask=None, |
| temb=temb, |
| ) |
| else: |
| |
| if idx % (2 * self.attend_text_every_n_blocks) == 0: |
| |
| curr_encoder_attention_mask = non_image_attention_mask |
| else: |
| |
| curr_encoder_attention_mask = image_attention_mask |
|
|
| hidden_states = block( |
| hidden_states, |
| attention_mask=None, |
| encoder_hidden_states=encoder_hidden_states, |
| encoder_attention_mask=curr_encoder_attention_mask, |
| temb=temb, |
| ) |
| all_hidden_states.append(hidden_states) |
|
|
| |
| conditioning = temb |
| 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] |
| if return_all_hidden_states: |
| return self.proj_out_2(hidden_states), all_hidden_states |
| else: |
| return self.proj_out_2(hidden_states) |
|
|
|
|
| class SelfAttentionTransformer(ModelMixin, ConfigMixin): |
| _supports_gradient_checkpointing = True |
|
|
| @register_to_config |
| def __init__( |
| self, |
| num_attention_heads: int = 8, |
| attention_head_dim: int = 64, |
| output_dim: int = 26, |
| num_layers: int = 12, |
| dropout: float = 0.1, |
| attention_bias: bool = True, |
| activation_fn: str = "gelu-approximate", |
| num_embeds_ada_norm: Optional[int] = 1000, |
| upcast_attention: bool = False, |
| max_num_positional_embeddings: int = 512, |
| compute_dtype=torch.float32, |
| final_dropout: bool = True, |
| positional_embeddings: Optional[str] = "sinusoidal", |
| interleave_self_attention=False, |
| ): |
| super().__init__() |
|
|
| self.attention_head_dim = attention_head_dim |
| self.inner_dim = self.config.num_attention_heads * self.config.attention_head_dim |
| self.gradient_checkpointing = False |
|
|
| self.transformer_blocks = nn.ModuleList( |
| [ |
| BasicTransformerBlock( |
| self.inner_dim, |
| self.config.num_attention_heads, |
| self.config.attention_head_dim, |
| dropout=self.config.dropout, |
| activation_fn=self.config.activation_fn, |
| attention_bias=self.config.attention_bias, |
| upcast_attention=self.config.upcast_attention, |
| positional_embeddings=positional_embeddings, |
| num_positional_embeddings=self.config.max_num_positional_embeddings, |
| final_dropout=final_dropout, |
| ) |
| for _ in range(self.config.num_layers) |
| ] |
| ) |
| print( |
| "Total number of SelfAttentionTransformer parameters: ", |
| sum(p.numel() for p in self.parameters() if p.requires_grad), |
| ) |
|
|
| def forward( |
| self, |
| hidden_states: torch.Tensor, |
| return_all_hidden_states: bool = False, |
| ): |
| |
| hidden_states = hidden_states.contiguous() |
| all_hidden_states = [hidden_states] |
|
|
| |
| for idx, block in enumerate(self.transformer_blocks): |
| hidden_states = block(hidden_states) |
| all_hidden_states.append(hidden_states) |
|
|
| if return_all_hidden_states: |
| return hidden_states, all_hidden_states |
| else: |
| return hidden_states |
|
|