import collections.abc import math from dataclasses import dataclass from itertools import repeat from typing import Any, Dict import numpy as np import torch import torch.nn as nn import torch.nn.functional as F def _ntuple(n): def parse(x): if isinstance(x, collections.abc.Iterable) and not isinstance(x, str): return tuple(x) return tuple(repeat(x, n)) return parse to_2tuple = _ntuple(2) class AttrDict(dict): def __getattr__(self, item): try: return self[item] except KeyError as error: raise AttributeError(item) from error def __setattr__(self, key, value): self[key] = value @staticmethod def from_data(data: Any) -> Any: if isinstance(data, dict): return AttrDict({k: AttrDict.from_data(v) for k, v in data.items()}) if isinstance(data, list): return [AttrDict.from_data(v) for v in data] return data class PatchEmbed(nn.Module): def __init__(self, input_size: int, patch_size: int, in_channels: int, embed_dim: int, bias: bool = True): super().__init__() self.img_size = to_2tuple(input_size) self.patch_size = to_2tuple(patch_size) self.grid_size = ( self.img_size[0] // self.patch_size[0], self.img_size[1] // self.patch_size[1], ) self.num_patches = self.grid_size[0] * self.grid_size[1] self.proj = nn.Conv2d( in_channels, embed_dim, kernel_size=self.patch_size, stride=self.patch_size, bias=bias, ) def forward(self, hidden_states: torch.Tensor) -> torch.Tensor: hidden_states = self.proj(hidden_states) return hidden_states.flatten(2).transpose(1, 2) class Mlp(nn.Module): def __init__( self, in_features, hidden_features=None, out_features=None, act_layer=nn.GELU, norm_layer=None, bias=True, drop=0.0, ): super().__init__() out_features = out_features or in_features hidden_features = hidden_features or in_features bias = to_2tuple(bias) drop_probs = to_2tuple(drop) self.fc1 = nn.Linear(in_features, hidden_features, bias=bias[0]) self.act = act_layer() self.drop1 = nn.Dropout(drop_probs[0]) self.norm = norm_layer(hidden_features) if norm_layer is not None else nn.Identity() self.fc2 = nn.Linear(hidden_features, out_features, bias=bias[1]) self.drop2 = nn.Dropout(drop_probs[1]) def forward(self, x): x = self.fc1(x) x = self.act(x) x = self.drop1(x) x = self.norm(x) x = self.fc2(x) x = self.drop2(x) return x class MoeMLP(nn.Module): def __init__(self, hidden_size, intermediate_size): super().__init__() self.hidden_size = hidden_size self.intermediate_size = intermediate_size self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size) self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size) self.act_fn = nn.GELU(approximate="tanh") def forward(self, x): return self.down_proj(self.act_fn(self.up_proj(x))) class MoeMLP_DiffMoE(nn.Module): def __init__(self, hidden_size, intermediate_size, pretraining_tp=2): super().__init__() self.hidden_size = hidden_size self.intermediate_size = intermediate_size self.gate_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) self.up_proj = nn.Linear(self.hidden_size, self.intermediate_size, bias=False) self.down_proj = nn.Linear(self.intermediate_size, self.hidden_size, bias=False) self.act_fn = nn.SiLU() self.pretraining_tp = pretraining_tp def forward(self, x): if self.pretraining_tp > 1: split_size = self.intermediate_size // self.pretraining_tp gate_proj_slices = self.gate_proj.weight.split(split_size, dim=0) up_proj_slices = self.up_proj.weight.split(split_size, dim=0) down_proj_slices = self.down_proj.weight.split(split_size, dim=1) gate_proj = torch.cat([F.linear(x, gate_proj_slices[i]) for i in range(self.pretraining_tp)], dim=-1) up_proj = torch.cat([F.linear(x, up_proj_slices[i]) for i in range(self.pretraining_tp)], dim=-1) intermediate_states = (self.act_fn(gate_proj) * up_proj).split(split_size, dim=-1) down_proj = [F.linear(intermediate_states[i], down_proj_slices[i]) for i in range(self.pretraining_tp)] return sum(down_proj) return self.down_proj(self.act_fn(self.gate_proj(x)) * self.up_proj(x)) class Attention(nn.Module): def __init__( self, dim: int, num_heads: int = 8, qkv_bias: bool = False, qk_norm: bool = False, attn_drop: float = 0.0, proj_drop: float = 0.0, head_dim=None, norm_layer: nn.Module = nn.LayerNorm, ): super().__init__() self.num_heads = num_heads if head_dim is None: if dim % num_heads != 0: raise ValueError("dim must be divisible by num_heads") self.head_dim = dim // num_heads else: self.head_dim = head_dim self.scale = self.head_dim**-0.5 self.fused_attn = True self.qkv = nn.Linear(dim, self.head_dim * self.num_heads * 3, bias=qkv_bias) self.q_norm = norm_layer(self.head_dim) if qk_norm else nn.Identity() self.k_norm = norm_layer(self.head_dim) if qk_norm else nn.Identity() self.attn_drop = nn.Dropout(attn_drop) self.proj = nn.Linear(self.head_dim * self.num_heads, dim) self.proj_drop = nn.Dropout(proj_drop) def forward(self, x: torch.Tensor) -> torch.Tensor: batch_size, seq_len, _ = x.shape qkv = self.qkv(x).reshape(batch_size, seq_len, 3, self.num_heads, self.head_dim).permute(2, 0, 3, 1, 4) q, k, v = qkv.unbind(0) q, k = self.q_norm(q), self.k_norm(k) if self.fused_attn: x = F.scaled_dot_product_attention( q, k, v, dropout_p=self.attn_drop.p if self.training else 0.0, ) else: q = q * self.scale attn = (q @ k.transpose(-2, -1)).softmax(dim=-1) attn = self.attn_drop(attn) x = attn @ v x = x.transpose(1, 2).reshape(batch_size, seq_len, -1) x = self.proj(x) return self.proj_drop(x) def modulate(x, shift, scale): return x * (1 + scale.unsqueeze(1)) + shift.unsqueeze(1) class TimestepEmbedder(nn.Module): def __init__(self, hidden_size, frequency_embedding_size=256): super().__init__() self.mlp = nn.Sequential( nn.Linear(frequency_embedding_size, hidden_size, bias=True), nn.SiLU(), nn.Linear(hidden_size, hidden_size, bias=True), ) self.frequency_embedding_size = frequency_embedding_size @staticmethod def timestep_embedding(t, dim, max_period=10000): half = dim // 2 freqs = torch.exp(-math.log(max_period) * torch.arange(start=0, end=half, dtype=torch.float32) / half).to( device=t.device ) args = t[:, None].float() * freqs[None] embedding = torch.cat([torch.cos(args), torch.sin(args)], dim=-1) if dim % 2: embedding = torch.cat([embedding, torch.zeros_like(embedding[:, :1])], dim=-1) return embedding def forward(self, t): t_freq = self.timestep_embedding(t.float(), self.frequency_embedding_size) weight_dtype = self.mlp[0].weight.dtype return self.mlp(t_freq.to(dtype=weight_dtype)) class LabelEmbedder(nn.Module): def __init__(self, num_classes, hidden_size, dropout_prob, return_labels=False): super().__init__() use_cfg_embedding = dropout_prob > 0 self.embedding_table = nn.Embedding(num_classes + int(use_cfg_embedding), hidden_size) self.num_classes = num_classes self.dropout_prob = dropout_prob self.return_labels = return_labels def token_drop(self, labels, force_drop_ids=None): if force_drop_ids is None: drop_ids = torch.rand(labels.shape[0], device=labels.device) < self.dropout_prob else: drop_ids = force_drop_ids == 1 return torch.where(drop_ids, self.num_classes, labels) def forward(self, labels, train, force_drop_ids=None): if (train and self.dropout_prob > 0) or (force_drop_ids is not None): labels = self.token_drop(labels, force_drop_ids) embeddings = self.embedding_table(labels) if self.return_labels: return embeddings, labels return embeddings class FinalLayer(nn.Module): def __init__(self, hidden_size, patch_size, out_channels): super().__init__() self.norm_final = nn.LayerNorm(hidden_size, elementwise_affine=False, eps=1e-6) self.linear = nn.Linear(hidden_size, patch_size * patch_size * out_channels, bias=True) self.adaLN_modulation = nn.Sequential(nn.SiLU(), nn.Linear(hidden_size, 2 * hidden_size, bias=True)) def forward(self, x, c): shift, scale = self.adaLN_modulation(c).chunk(2, dim=1) x = modulate(self.norm_final(x), shift, scale) return self.linear(x) def get_2d_sincos_pos_embed(embed_dim, grid_size, cls_token=False, extra_tokens=0): grid_h = np.arange(grid_size, dtype=np.float32) grid_w = np.arange(grid_size, dtype=np.float32) grid = np.meshgrid(grid_w, grid_h) grid = np.stack(grid, axis=0).reshape([2, 1, grid_size, grid_size]) pos_embed = get_2d_sincos_pos_embed_from_grid(embed_dim, grid) if cls_token and extra_tokens > 0: pos_embed = np.concatenate([np.zeros([extra_tokens, embed_dim]), pos_embed], axis=0) return pos_embed def get_2d_sincos_pos_embed_from_grid(embed_dim, grid): if embed_dim % 2 != 0: raise ValueError("embed_dim must be even") emb_h = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[0]) emb_w = get_1d_sincos_pos_embed_from_grid(embed_dim // 2, grid[1]) return np.concatenate([emb_h, emb_w], axis=1) def get_1d_sincos_pos_embed_from_grid(embed_dim, pos): if embed_dim % 2 != 0: raise ValueError("embed_dim must be even") omega = np.arange(embed_dim // 2, dtype=np.float64) omega /= embed_dim / 2.0 omega = 1.0 / 10000**omega pos = pos.reshape(-1) out = np.einsum("m,d->md", pos, omega) emb_sin = np.sin(out) emb_cos = np.cos(out) return np.concatenate([emb_sin, emb_cos], axis=1)