Download src/model/layers.py from joelinator/dflow-novo-model: direct link, hf CLI and curl.
- Browser
- Download file 3.26 kB
-
https://huggingface.co/joelinator/dflow-novo-model/resolve/main/src/model/layers.py
- Command line
-
hf download hf://joelinator/dflow-novo-model/src/model/layers.py
-
curl -L -o layers.py https://huggingface.co/joelinator/dflow-novo-model/resolve/main/src/model/layers.py
3.26 kB
| import math | |
| import torch | |
| import torch.nn as nn | |
| import torch.nn.functional as F | |
| class SinusoidalEmbedding(nn.Module): | |
| def __init__(self, embedding_dim, device="cpu"): | |
| super().__init__() | |
| half_dim = embedding_dim // 2 | |
| freqs = math.log(10_000) / (half_dim - 1) | |
| freqs = torch.exp(torch.arange(half_dim, device=device) * -freqs) | |
| self.register_buffer("freqs", freqs) | |
| def forward(self, x): | |
| embeddings = self.freqs.reshape((1,) * len(x.shape) + self.freqs.shape) | |
| embeddings = x.unsqueeze(-1) * embeddings | |
| return torch.cat((embeddings.cos(), embeddings.sin()), dim=-1) | |
| class MzArrayEncoder(nn.Module): | |
| def __init__(self, lambda_min=1e-3, lambda_max=1e4, emb_dim=128, device="cpu"): | |
| super().__init__() | |
| half_dim = emb_dim // 2 | |
| freqs = math.log(lambda_max / lambda_min) / (half_dim - 1) | |
| freqs = torch.exp(torch.arange(half_dim, device=device) * -freqs) | |
| freqs = freqs * 2 * torch.pi / lambda_min | |
| self.register_buffer("freqs", freqs) | |
| def forward(self, m): | |
| embeddings = self.freqs.reshape((1,) * len(m.shape) + self.freqs.shape) | |
| embeddings = m.unsqueeze(-1) * embeddings | |
| return torch.cat((embeddings.cos(), -embeddings.sin()), dim=-1) | |
| class AdaNLayers(nn.Module): | |
| def __init__(self, emb_dim=128, n=1): | |
| super().__init__() | |
| self.norm = nn.LayerNorm(emb_dim, elementwise_affine=False) | |
| self.mlp = nn.Sequential(nn.SiLU(), nn.Linear(emb_dim, emb_dim * n * 2)) | |
| self.n = n | |
| def forward(self, conditioner): | |
| x = self.mlp(conditioner) | |
| return x.chunk(2 * self.n, dim=-1) | |
| def modulate(x: torch.Tensor, shift: torch.Tensor, scale: torch.Tensor) -> torch.Tensor: | |
| """Modulate normalized features with scale and shift: x * (1 + scale) + shift.""" | |
| return x * (1.0 + scale.unsqueeze(1)) + shift.unsqueeze(1) | |
| class AdaLNZero(nn.Module): | |
| """ | |
| Adaptive Layer Normalization with Zero-Initialization for Diffusion Transformers (DiT). | |
| Predicts (scale, shift, gate) modulation parameters for transformer sublayers. | |
| Initializes the projection to zeros so blocks start as identity functions. | |
| """ | |
| def __init__(self, emb_dim: int = 512, num_params: int = 9): | |
| super().__init__() | |
| self.mlp = nn.Sequential( | |
| nn.SiLU(), | |
| nn.Linear(emb_dim, num_params * emb_dim), | |
| ) | |
| # AdaLN-Zero: zero out the final linear layer | |
| nn.init.zeros_(self.mlp[1].weight) | |
| nn.init.zeros_(self.mlp[1].bias) | |
| self.num_params = num_params | |
| def forward(self, conditioner: torch.Tensor) -> tuple[torch.Tensor, ...]: | |
| return self.mlp(conditioner).chunk(self.num_params, dim=-1) | |
| class SwiGLU(nn.Module): | |
| def __init__(self, d_model: int, d_ff: int, dropout: float = 0.0): | |
| super().__init__() | |
| self.w_gate_up = nn.Linear(d_model, 2 * d_ff, bias=False) | |
| self.w_down = nn.Linear(d_ff, d_model, bias=False) | |
| self.dropout = nn.Dropout(dropout) if dropout > 0.0 else nn.Identity() | |
| def forward(self, x: torch.Tensor) -> torch.Tensor: | |
| gate, up = self.w_gate_up(x).chunk(2, dim=-1) | |
| return self.dropout(self.w_down(F.silu(gate) * up)) | |
| SwiGLUFFN = SwiGLU | |