MCPcopy Create free account
hub / github.com/DSL-Lab/StreamSplat / ConditionalResAttBlock

Class ConditionalResAttBlock

model/transformer_utils.py:301–360  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

299 return x
300
301class 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)

Callers

nothing calls this directly

Calls

no outgoing calls

Tested by

no test coverage detected