| 299 | return x |
| 300 | |
| 301 | class ConditionalResAttBlock(nn.Module): |
| 302 | def __init__(self, d_model, n_head, window_size=None, drop_path_rate=0.0): |
| 303 | super().__init__() |
| 304 | self.window_size = window_size |
| 305 | |
| 306 | self.self_attn = MultiHeadAttention(d_model, d_model, d_model, d_model, n_head) |
| 307 | self.self_attn_ln = LayerNorm(d_model) |
| 308 | |
| 309 | self.cross_attn = MultiHeadAttention(d_model, d_model, d_model, d_model, n_head) |
| 310 | self.cross_attn_ln = LayerNorm(d_model) |
| 311 | |
| 312 | self.mlp = nn.Sequential(OrderedDict([ |
| 313 | ("c_fc", nn.Linear(d_model, d_model * 4, bias=False)), |
| 314 | ("silu", nn.SiLU(inplace=True)), |
| 315 | ("c_proj", nn.Linear(d_model * 4, d_model, bias=False)) |
| 316 | ])) |
| 317 | self.mlp_ln = LayerNorm(d_model) |
| 318 | |
| 319 | self.drop_path = DropPath(drop_path_rate) if drop_path_rate > 0. else nn.Identity() |
| 320 | |
| 321 | def window_attention(self, x, attn_layer, index): |
| 322 | attn_mask = None |
| 323 | if self.window_size is not None: |
| 324 | l = x.shape[1] |
| 325 | assert l % self.window_size == 0, "Sequence length must be divisible by window size" |
| 326 | if index % 2 == 0: |
| 327 | # Even index: split into windows without shifting. |
| 328 | x = rearrange(x, 'b (p w) c -> (b p) w c', w=self.window_size) |
| 329 | x = attn_layer(x, x, x, need_weights=False, attn_mask=attn_mask)[0] |
| 330 | x = rearrange(x, '(b p) w c -> b (p w) c', p=l // self.window_size) |
| 331 | else: |
| 332 | # Odd index: roll by half a window, then split. |
| 333 | x = torch.roll(x, shifts=self.window_size // 2, dims=1) |
| 334 | x = rearrange(x, 'b (p w) c -> (b p) w c', w=self.window_size) |
| 335 | x = attn_layer(x, x, x, need_weights=False, attn_mask=attn_mask)[0] |
| 336 | x = rearrange(x, '(b p) w c -> b (p w) c', p=l // self.window_size) |
| 337 | x = torch.roll(x, shifts=-self.window_size // 2, dims=1) |
| 338 | else: |
| 339 | x = attn_layer(x, x, x, need_weights=False, attn_mask=attn_mask)[0] |
| 340 | return x |
| 341 | |
| 342 | def forward(self, x, index, condition): |
| 343 | residual = x.type(torch.float32) |
| 344 | x_ln = self.self_attn_ln(x) |
| 345 | x2 = self.window_attention(x_ln, self.self_attn, index) |
| 346 | x = residual + self.drop_path(x2) |
| 347 | |
| 348 | x = rearrange(x, 'b (p n) d -> (b p) n d', p=2) # split back to frame_0 and frame_1 |
| 349 | residual = x.type(torch.float32) |
| 350 | x_ln = self.cross_attn_ln(x) |
| 351 | x2 = self.cross_attn(x_ln, condition, condition, need_weights=False)[0] |
| 352 | x = residual + self.drop_path(x2) |
| 353 | x = rearrange(x, '(b p) n d -> b (p n) d', p=2) # combine frame_0 and frame_1 |
| 354 | |
| 355 | residual = x.type(torch.float32) |
| 356 | x_ln = self.mlp_ln(x) |
| 357 | x2 = self.mlp(x_ln) |
| 358 | x = residual + self.drop_path(x2) |
nothing calls this directly
no outgoing calls
no test coverage detected