BiliSakura commited on
Commit
774dec2
·
verified ·
1 Parent(s): 3b98545

Update all files for EO-VAE

Browse files
Files changed (1) hide show
  1. _eo_vae/layers.py +93 -0
_eo_vae/layers.py ADDED
@@ -0,0 +1,93 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Apache-2.0 - Based on Flux2 / diffusers
2
+ # ResnetBlock, AttnBlock, Downsample, Upsample
3
+
4
+ import torch
5
+ import torch.nn as nn
6
+ from torch import Tensor
7
+
8
+
9
+ def swish(x: Tensor) -> Tensor:
10
+ return x * torch.sigmoid(x)
11
+
12
+
13
+ class Downsample(nn.Module):
14
+ def __init__(self, in_channels: int):
15
+ super().__init__()
16
+ self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=2, padding=0)
17
+
18
+ def forward(self, x: Tensor) -> Tensor:
19
+ x = nn.functional.pad(x, (0, 1, 0, 1), mode="constant", value=0)
20
+ return self.conv(x)
21
+
22
+
23
+ class Upsample(nn.Module):
24
+ def __init__(self, in_channels: int):
25
+ super().__init__()
26
+ self.conv = nn.Conv2d(in_channels, in_channels, kernel_size=3, stride=1, padding=1)
27
+
28
+ def forward(self, x: Tensor) -> Tensor:
29
+ x = nn.functional.interpolate(x, scale_factor=2.0, mode="nearest")
30
+ return self.conv(x)
31
+
32
+
33
+ class ResnetBlock(nn.Module):
34
+ def __init__(self, in_channels: int, out_channels: int, cond_dim: int = None):
35
+ super().__init__()
36
+ self.in_channels = in_channels
37
+ self.out_channels = out_channels if out_channels is not None else in_channels
38
+ self.cond_dim = cond_dim
39
+
40
+ self.norm1 = nn.GroupNorm(32, in_channels, eps=1e-6, affine=True)
41
+ self.conv1 = nn.Conv2d(in_channels, self.out_channels, 3, stride=1, padding=1)
42
+
43
+ if self.cond_dim is not None:
44
+ self.emb_proj = nn.Linear(cond_dim, self.out_channels * 2)
45
+ nn.init.zeros_(self.emb_proj.bias)
46
+ self.emb_proj.weight.data.zero_()
47
+ self.emb_proj.bias.data[: self.out_channels] = 1.0
48
+
49
+ self.norm2 = nn.GroupNorm(32, self.out_channels, eps=1e-6, affine=True)
50
+ self.conv2 = nn.Conv2d(self.out_channels, self.out_channels, 3, stride=1, padding=1)
51
+ self.nin_shortcut = (
52
+ nn.Conv2d(in_channels, self.out_channels, 1, stride=1, padding=0)
53
+ if in_channels != self.out_channels
54
+ else nn.Identity()
55
+ )
56
+
57
+ def forward(self, x: Tensor, emb: Tensor = None) -> Tensor:
58
+ h = self.norm1(x)
59
+ h = swish(h)
60
+ h = self.conv1(h)
61
+
62
+ if self.cond_dim is not None and emb is not None:
63
+ style = self.emb_proj(emb).unsqueeze(-1).unsqueeze(-1)
64
+ scale, shift = style.chunk(2, dim=1)
65
+ h = self.norm2(h)
66
+ h = h * scale + shift
67
+ else:
68
+ h = self.norm2(h)
69
+
70
+ h = swish(h)
71
+ h = self.conv2(h)
72
+ return h + self.nin_shortcut(x)
73
+
74
+
75
+ class AttnBlock(nn.Module):
76
+ def __init__(self, in_channels: int):
77
+ super().__init__()
78
+ self.norm = nn.GroupNorm(32, in_channels, eps=1e-6, affine=True)
79
+ self.q = nn.Conv2d(in_channels, in_channels, 1)
80
+ self.k = nn.Conv2d(in_channels, in_channels, 1)
81
+ self.v = nn.Conv2d(in_channels, in_channels, 1)
82
+ self.proj_out = nn.Conv2d(in_channels, in_channels, 1)
83
+
84
+ def forward(self, x: Tensor) -> Tensor:
85
+ h_ = self.norm(x)
86
+ q, k, v = self.q(h_), self.k(h_), self.v(h_)
87
+ b, c, h, w = q.shape
88
+ q = q.flatten(2).transpose(1, 2).unsqueeze(1) # b 1 (hw) c
89
+ k = k.flatten(2).transpose(1, 2).unsqueeze(1)
90
+ v = v.flatten(2).transpose(1, 2).unsqueeze(1)
91
+ h_ = torch.nn.functional.scaled_dot_product_attention(q, k, v)
92
+ h_ = h_.squeeze(1).transpose(1, 2).view(b, c, h, w)
93
+ return x + self.proj_out(h_)