Selective State Space Models
A continuous linear system, discretised and run over the sequence. Constant state per step rather than a cache that grows with context — and, since Mamba, dynamics that depend on the input.
Standing
PromisingPromising and actively moving. The results are real but narrow — one lab, one model family, or one benchmark suite — and the picture may look different in a year.
Strong results in hybrid stacks. Nobody has yet shipped a frontier model without attention in it.
judged as of 2026-09 · what the labels mean
Theory
Start from a linear time-invariant system mapping a scalar input stream to an output through an -dimensional latent state.
To run it on tokens you discretise with a step size . Zero-order hold gives the matrices the recurrence actually uses.
With , , constant the recurrence is a convolution, computable for the whole sequence in one FFT. That is S4, and it is also its ceiling: a time-invariant system cannot choose what to remember, so it cannot solve selective copying or induction.
Selection
Mamba makes , and functions of the current token. The system stops being time-invariant, the convolution disappears, and what remains is a recurrence that must be scanned.
is the interesting one. Large makes and the state resets to the current input; small makes and the token is ignored. It is a gate in the LSTM sense, arrived at from the discretisation rather than bolted on.
The cost model inverts the transformer’s. Decoding is per token in context length with a fixed-size state, but that state is a lossy summary — exact retrieval from far back is the thing attention buys and this does not. Hybrids that interleave a few attention layers among many SSM layers are the current answer.
Implementation
import torch
from torch import Tensor
def selective_scan(
x: Tensor, # [B, L, D] input
A: Tensor, # [D, N] log-negative, learned
B: Tensor, # [B, L, N] input-dependent
C: Tensor, # [B, L, N] input-dependent
delta: Tensor, # [B, L, D] input-dependent, softplus'd
) -> Tensor:
batch, length, dim = x.shape
state = torch.zeros(batch, dim, A.size(-1), device=x.device)
out = []
for t in range(length):
dt = delta[:, t].unsqueeze(-1) # [B, D, 1]
a_bar = torch.exp(dt * A) # [B, D, N]
b_bar = dt * B[:, t].unsqueeze(1) # [B, 1, N] -> broadcast
state = a_bar * state + b_bar * x[:, t].unsqueeze(-1)
out.append((state @ C[:, t].unsqueeze(-1)).squeeze(-1))
return torch.stack(out, dim=1)is stored as so the eigenvalues stay negative and the system stays stable; then lies in and the state cannot blow up. The above drops the factor for the first-order approximation , which is what Mamba itself uses.