Instructions to use BiliSakura/ProMoE-diffusers with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- Diffusers
How to use BiliSakura/ProMoE-diffusers with Diffusers:
pip install -U diffusers transformers accelerate
import torch from diffusers import DiffusionPipeline # switch to "mps" for apple devices pipe = DiffusionPipeline.from_pretrained("BiliSakura/ProMoE-diffusers", dtype=torch.bfloat16, device_map="cuda") prompt = "Astronaut in a jungle, cold color palette, muted colors, detailed, 8k" image = pipe(prompt).images[0] - Notebooks
- Google Colab
- Kaggle
| 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 | |
| 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 | |
| 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) | |