| import torch |
| import torch.nn as nn |
|
|
|
|
| class HybridStateSpaceMemory(nn.Module): |
| """ |
| Lightweight legacy VideoSSM hybrid block: |
| depthwise temporal conv over per-spatial token trajectories. |
| """ |
|
|
| def __init__(self, dim: int, kernel_size: int = 3, expand: int = 2): |
| super().__init__() |
| self.dim = int(dim) |
| self.kernel_size = int(kernel_size) |
| hidden = int(dim) * max(int(expand), 1) |
| pad = self.kernel_size - 1 |
| self.in_proj = nn.Linear(self.dim, hidden) |
| self.dw = nn.Conv1d(hidden, hidden, kernel_size=self.kernel_size, groups=hidden, padding=pad) |
| self.out_proj = nn.Linear(hidden, self.dim) |
| self.gate = nn.Parameter(torch.zeros(1)) |
|
|
| def forward(self, x: torch.Tensor, f: int, h: int, w: int, **_kwargs): |
| |
| if x is None or x.ndim != 3: |
| return x |
| b, n, d = x.shape |
| f = int(f) |
| hw = int(h) * int(w) |
| if d != self.dim or f <= 1 or n != f * hw: |
| return x |
| x4 = x.reshape(b, f, hw, d).permute(0, 2, 1, 3).reshape(b * hw, f, d) |
| y = self.in_proj(x4) |
| y = y.transpose(1, 2) |
| y = self.dw(y)[..., :f] |
| y = y.transpose(1, 2) |
| y = self.out_proj(y) |
| y = y.reshape(b, hw, f, d).permute(0, 2, 1, 3).reshape(b, n, d) |
| return x + torch.tanh(self.gate) * y |
|
|
|
|