dplotnikov's picture
Upload StrataBERT diagnostic checkpoint
2c6267a verified
Raw
History Blame Contribute Delete
1.97 kB
"""Fallback padding-safe recurrent SSM scan.
This is not a fast Mamba kernel. It is a deterministic reference path for
correctness tests, mask semantics, and future kernel equivalence checks.
"""
from __future__ import annotations
import torch
from torch import nn
class MaskedScanSSM(nn.Module):
def __init__(self, hidden_size: int, state_size: int):
super().__init__()
self.hidden_size = hidden_size
self.state_size = state_size
self.in_proj = nn.Linear(hidden_size, state_size)
self.state_proj = nn.Linear(state_size, state_size, bias=False)
self.out_proj = nn.Linear(state_size, hidden_size)
self.gate = nn.Linear(hidden_size, hidden_size)
def forward(
self,
hidden_states: torch.Tensor,
attention_mask: torch.Tensor,
segment_ids: torch.Tensor | None = None,
reset_on_pad: bool = True,
reset_on_segment: bool = True,
) -> torch.Tensor:
batch, length, _ = hidden_states.shape
state = hidden_states.new_zeros(batch, self.state_size)
outputs = []
projected = self.in_proj(hidden_states)
for idx in range(length):
valid = attention_mask[:, idx].unsqueeze(-1)
if reset_on_segment and segment_ids is not None and idx > 0:
same_segment = (segment_ids[:, idx] == segment_ids[:, idx - 1]).unsqueeze(-1)
state = torch.where(same_segment, state, torch.zeros_like(state))
if reset_on_pad:
state = torch.where(valid, state, torch.zeros_like(state))
proposed = torch.tanh(projected[:, idx] + self.state_proj(state))
state = torch.where(valid, proposed, torch.zeros_like(state) if reset_on_pad else state)
out = self.out_proj(state) * torch.sigmoid(self.gate(hidden_states[:, idx]))
outputs.append(torch.where(valid, out, torch.zeros_like(out)))
return torch.stack(outputs, dim=1)