| 4 | |
| 5 | |
| 6 | class TemporalResnetBlock(torch.nn.Module): |
| 7 | def __init__(self, in_channels, out_channels, temb_channels=None, groups=32, eps=1e-5): |
| 8 | super().__init__() |
| 9 | self.norm1 = torch.nn.GroupNorm(num_groups=groups, num_channels=in_channels, eps=eps, affine=True) |
| 10 | self.conv1 = torch.nn.Conv3d(in_channels, out_channels, kernel_size=(3, 1, 1), stride=(1, 1, 1), padding=(1, 0, 0)) |
| 11 | if temb_channels is not None: |
| 12 | self.time_emb_proj = torch.nn.Linear(temb_channels, out_channels) |
| 13 | self.norm2 = torch.nn.GroupNorm(num_groups=groups, num_channels=out_channels, eps=eps, affine=True) |
| 14 | self.conv2 = torch.nn.Conv3d(out_channels, out_channels, kernel_size=(3, 1, 1), stride=(1, 1, 1), padding=(1, 0, 0)) |
| 15 | self.nonlinearity = torch.nn.SiLU() |
| 16 | self.conv_shortcut = None |
| 17 | if in_channels != out_channels: |
| 18 | self.conv_shortcut = torch.nn.Conv3d(in_channels, out_channels, kernel_size=1, stride=1, padding=0, bias=True) |
| 19 | |
| 20 | def forward(self, hidden_states, time_emb, text_emb, res_stack, **kwargs): |
| 21 | x = rearrange(hidden_states, "f c h w -> 1 c f h w") |
| 22 | x = self.norm1(x) |
| 23 | x = self.nonlinearity(x) |
| 24 | x = self.conv1(x) |
| 25 | if time_emb is not None: |
| 26 | emb = self.nonlinearity(time_emb) |
| 27 | emb = self.time_emb_proj(emb) |
| 28 | emb = repeat(emb, "b c -> b c f 1 1", f=hidden_states.shape[0]) |
| 29 | x = x + emb |
| 30 | x = self.norm2(x) |
| 31 | x = self.nonlinearity(x) |
| 32 | x = self.conv2(x) |
| 33 | if self.conv_shortcut is not None: |
| 34 | hidden_states = self.conv_shortcut(hidden_states) |
| 35 | x = rearrange(x[0], "c f h w -> f c h w") |
| 36 | hidden_states = hidden_states + x |
| 37 | return hidden_states, time_emb, text_emb, res_stack |
| 38 | |
| 39 | |
| 40 | def get_timestep_embedding( |