ProMoE-diffusers / ProMoE-B-256 /transformer /modeling_promoe_common.py
BiliSakura's picture
Upload folder using huggingface_hub
24196fc verified
Raw
History Blame Contribute Delete
10.8 kB
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)