Skip to content
Back to skills

State Space Models Mamba

ASecurity

Use when building state space models like Mamba and S4.

  • 2 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 10, 2026
ai-agentspythongogit

Security analysis

A100/100

Scanned September 10, 2026

npx -y skills add LoopyLuci/Skills --skill state-space-models-mamba --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of State Space Models Mamba?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for State Space Models Mamba
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/loopyluci-state-space-models-mamba/badge)](https://www.skillsdirectory.com/skills/loopyluci-state-space-models-mamba)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: state-space-models-mamba
description: "Use when building state space models like Mamba and S4."
version: 1.0.0
author: Hermes Agent
license: MIT
metadata:
  hermes:
    tags: [ssm, state-space, mamba, s4, sequence-models, pytorch]
    related_skills: [transformer-architectures, attention-mechanisms-deep, custom-neural-architecture-design, neural-network-fundamentals]
---

# State Space Models — Mamba, S4, and Beyond

Designing and implementing state space model (SSM) architectures for sequence modeling — structured state spaces (S4), Mamba (S6), and their variants as alternatives to transformers for efficient long-range dependency modeling.

## When to Use

- Processing long sequences (10K+ tokens) where self-attention's O(n²) cost is prohibitive
- Tasks requiring linear or near-linear scaling with sequence length
- Continuous-time signals (audio, sensor data, physical simulations)
- Building efficient alternatives to transformers for edge/latency-sensitive deployment
- Researching new sequence model architectures

## SSM Fundamentals

### Continuous State Space Model

```python
# A continuous SSM maps input u(t) to output y(t) via hidden state x(t):
# x'(t) = A @ x(t) + B @ u(t)
# y(t)  = C @ x(t) + D @ u(t)
# A: state transition (N x N), B: input projection (N x 1), C: output projection (1 x N)
```

### Discretization (for digital computation)

```python
import torch
import torch.nn as nn
import torch.nn.functional as F

def discretize(A, B, delta):
    """Discretize continuous SSM parameters using zero-order hold.
    A_bar = exp(delta * A)
    B_bar = (exp(delta * A) - I) @ inv(A) @ B ≈ delta * B  (first-order approx)
    """
    A_bar = torch.matrix_exp(delta.unsqueeze(-1) * A)
    B_bar = delta.unsqueeze(-1) * B  # First-order approximation
    return A_bar, B_bar
```

## S4 (Structured State Space)

The Structured State Space (S4) uses HiPPO initialization for long-range memory:

```python
class S4Block(nn.Module):
    """S4 layer: structured state space with HiPPO initialization.
    Handles long-range dependencies (up to 16K tokens)."""
    
    def __init__(self, d_model, d_state=64, l_max=4096):
        super().__init__()
        self.d_model = d_model
        self.d_state = d_state
        
        # HiPPO-LegS matrix: captures long-range memory structure
        self._init_hippo()
        
        # Parametrized input/output projections
        self.B = nn.Parameter(torch.randn(d_model, d_state) / d_state**0.5)
        self.C = nn.Parameter(torch.randn(d_model, d_state) / d_state**0.5)
        self.D = nn.Parameter(torch.ones(d_model))
        self.delta = nn.Parameter(torch.log(torch.rand(d_model)))  # log-delta
        
        # Output projection
        self.out_proj = nn.Linear(d_model, d_model)
        self.act = nn.GELU()
    
    def _init_hippo(self):
        """Initialize A matrix with HiPPO-LegS (Structured State Space)."""
        N = self.d_state
        # HiPPO matrix: A[n,k] = -0.5 if n>k, 0.5 if n<k, -[0.5 if n==k]
        A = torch.zeros(N, N)
        for n in range(N):
            for k in range(N):
                if n > k:
                    A[n, k] = 1.0
                elif n == k:
                    A[n, k] = 0.5
        A = -A  # Normalized low-rank structure
        # Normal plus low-rank decomposition
        self.A_normal = nn.Parameter(torch.diag(torch.linspace(0.5, N+0.5, N)))
        self.A_low_rank = nn.Parameter(A - torch.diag(torch.diag(A)))
    
    def forward(self, u):
        """
        u: (batch, seq_len, d_model)
        Returns: (batch, seq_len, d_model)
        """
        batch, seq_len, _ = u.shape
        
        # Global convolution mode (parallel during training)
        # Uses FFT convolution for O(L log L) instead of O(L²) recurrence
        A = self.A_normal + self.A_low_rank  # Reconstruct A
        delta = F.softplus(self.delta)  # Ensure positive
        
        # Discretize
        A_bar, B_bar = discretize(A, self.B, delta)
        
        # Compute SSM kernel (convolutional representation)
        kernel = self._compute_kernel(A_bar, B_bar, seq_len)
        
        # Global convolution via FFT
        y = self._fft_convolution(u, kernel)
        
        # Residual connection + gating
        y = self.act(self.out_proj(y))
        return y + u  # Skip connection
    
    def _compute_kernel(self, A_bar, B_bar, L):
        """K = (C B, C A B, C A² B, ..., C A^L-1 B)"""
        kernel = torch.zeros(L, self.d_model, device=A_bar.device)
        power = torch.eye(self.d_state, device=A_bar.device)
        for t in range(L):
            kernel[t] = (self.C @ power @ B_bar).sum(-1)
            power = A_bar @ power
        return kernel
    
    def _fft_convolution(self, u, kernel):
        """Convolution via FFT: O(L log L)."""
        u_fft = torch.fft.fft(u.transpose(1, 2), n=2*u.shape[1])
        k_fft = torch.fft.fft(kernel.unsqueeze(0).transpose(1, 2), n=2*u.shape[1])
        y = torch.fft.ifft(u_fft * k_fft, n=2*u.shape[1]).real
        return y[:, :, :u.shape[1]].transpose(1, 2)
```

## Mamba (S6 — Selective State Space)

Mamba improves S4 with input-dependent (selective) state transitions:

```python
class MambaBlock(nn.Module):
    """Mamba: Selective state space model with input-dependent dynamics.
    O(n) inference, parallel training, matches transformer quality."""
    
    def __init__(self, d_model, d_state=16, expand_factor=2, d_conv=4):
        super().__init__()
        self.d_model = d_model
        self.d_inner = d_model * expand_factor
        self.d_state = d_state
        
        # Input projection
        self.in_proj = nn.Linear(d_model, self.d_inner * 2, bias=False)
        
        # Convolution + activation before SSM
        self.conv1d = nn.Conv1d(
            in_channels=self.d_inner,
            out_channels=self.d_inner,
            kernel_size=d_conv,
            padding=d_conv - 1,
            groups=self.d_inner,  # Depthwise
            bias=False
        )
        
        # Selective parameters (input-dependent)
        # These make Mamba "selective" — filtering based on content
        self.x_proj = nn.Linear(self.d_inner, d_state * 3, bias=False)  # delta, B, C
        self.dt_proj = nn.Linear(d_state, self.d_inner, bias=True)
        
        # Output projection
        self.out_proj = nn.Linear(self.d_inner, d_model, bias=False)
        
        # Initialize A as log-uniform
        A_log = torch.log(torch.arange(1, d_state + 1, dtype=torch.float32))
        self.A_log = nn.Parameter(A_log)
        self.D = nn.Parameter(torch.ones(self.d_inner))
    
    def forward(self, x):
        """
        x: (batch, seq_len, d_model)
        """
        batch, seq_len, _ = x.shape
        
        # Input projection + activation
        x_and_res = self.in_proj(x)
        x, res = x_and_r.chunk(2, dim=-1)
        x = F.silu(x)
        
        # 1D convolution (depthwise)
        x_conv = x.transpose(1, 2)  # (batch, d_inner, seq_len)
        x_conv = self.conv1d(x_conv)[:, :, :seq_len]
        x = F.silu(x_conv.transpose(1, 2))
        
        # Selective SSM parameters (input-dependent!)
        # This is the key innovation: A, B, C, delta depend on input
        delta_BC = self.x_proj(x)  # (batch, seq_len, d_state*3)
        delta, B, C = delta_BC.split([self.d_state, self.d_state, self.d_state], dim=-1)
        
        delta = F.softplus(self.dt_proj(delta))  # (batch, seq_len, d_inner)
        
        # Selective SSM (recurrent scan)
        y = self._selective_scan(x, delta, B, C)
        
        # Gated residual
        y = y * res
        return self.out_proj(y)
    
    def _selective_scan(self, u, delta, B, C):
        """
        Selective scan: O(n) sequential during inference.
        For training, uses parallel associative scan.
        """
        batch, seq_len, d_inner = u.shape
        d_state = B.shape[-1]
        
        # A from log-uniform init (negative ensures stability)
        A = -torch.exp(self.A_log.float())  # (d_state,)
        
        # Discretize with selective delta
        delta_A = torch.exp(delta.unsqueeze(-1) * A)  # (batch, seq_len, d_inner, d_state)
        delta_B = delta.unsqueeze(-1) * B.unsqueeze(2)  # (batch, seq_len, d_inner, d_state)
        
        # Recurrent scan
        h = torch.zeros(batch, d_inner, d_state, device=u.device)
        outputs = []
        for t in range(seq_len):
            h = delta_A[:, t] * h + delta_B[:, t] * u[:, t].unsqueeze(-1)
            y_t = (h @ C[:, t].unsqueeze(-1)).squeeze(-1)
            outputs.append(y_t + self.D * u[:, t])
        
        return torch.stack(outputs, dim=1)
    
    def step(self, x, state=None):
        """Inference mode: single step with state caching. O(1) per step."""
        # Same as forward but processes one token at a time
        # Caches state between steps for efficient autoregressive generation
        pass
```

## Mamba Architecture

```python
class MambaLanguageModel(nn.Module):
    """Full Mamba architecture for language modeling.
    Stacks Mamba blocks with RMSNorm instead of LayerNorm."""
    
    def __init__(self, vocab_size=32000, d_model=2560, n_layers=32, 
                 d_state=16, expand_factor=2):
        super().__init__()
        
        self.embedding = nn.Embedding(vocab_size, d_model)
        
        self.layers = nn.ModuleList([
            nn.ModuleDict({
                'norm': RMSNorm(d_model),
                'mamba': MambaBlock(d_model, d_state, expand_factor)
            })
            for _ in range(n_layers)
        ])
        
        self.final_norm = RMSNorm(d_model)
        self.lm_head = nn.Linear(d_model, vocab_size, bias=False)
        
        # Tie embeddings
        self.lm_head.weight = self.embedding.weight
    
    def forward(self, input_ids):
        x = self.embedding(input_ids)
        
        for layer in self.layers:
            x = x + layer['mamba'](layer['norm'](x))
        
        x = self.final_norm(x)
        return self.lm_head(x)
    
    def generate(self, input_ids, max_new_tokens=100):
        """Autoregressive generation with cached state."""
        for _ in range(max_new_tokens):
            logits = self(input_ids[:, -1:])
            next_token = logits[:, -1, :].argmax(dim=-1, keepdim=True)
            input_ids = torch.cat([input_ids, next_token], dim=-1)
        return input_ids


class RMSNorm(nn.Module):
    """Root Mean Square Layer Normalization."""
    def __init__(self, dim, eps=1e-6):
        super().__init__()
        self.weight = nn.Parameter(torch.ones(dim))
        self.eps = eps
    
    def forward(self, x):
        rms = x.pow(2).mean(-1, keepdim=True).sqrt()
        return x / (rms + self.eps) * self.weight
```

## SSM Variants

| Model | State Transition | Selection | Key Innovation |
|-------|-----------------|-----------|----------------|
| S4 (2021) | HiPPO + DPLR | No | Structured initialization for long-range memory |
| S4D (2022) | Diagonal | No | Simplified diagonal parameterization |
| DSS (2022) | Diagonal | No | Explicit diagonalization |
| S5 (2022) | Multi-input Multi-output | No | Parallel scan, MIMO generalization |
| Mega (2022) | Simplified EMA | Yes | Exponential moving average + attention |
| Mamba (S6, 2023) | Selective | Yes | Input-dependent state transitions + hardware-efficient scan |
| Jamba (2024) | Hybrid Mamba-Attention | Yes | Interleaved Mamba + attention layers + MoE |

## SSM vs Transformer

| Aspect | Transformer | SSM (Mamba) |
|--------|-------------|-------------|
| Complexity | O(n²) | O(n) |
| Long-range (16K+) | Prohibitive cost | Efficient |
| Autoregressive generation | O(n²) KV-cache | O(1) state |
| Hardware efficiency | Attention compute-bound | Scan memory-bound |
| In-context learning | Strong | Weaker |
| Quality (equiparameter) | Slightly better | Competitive |
| Training stability | Well-studied | More sensitive |

## Hardware-Efficient Scan (for Training)

```python
# Mamba's training efficiency comes from the parallel associative scan
# (not sequential like inference). Key insight:
# The recurrence is a linear operation (no nonlinearities),
# so it can be parallelized with scan/prefix-sum algorithms.

def associate_scan(u, delta_A, delta_B):
    """Parallel associative scan using work-efficient algorithm.
    Complexity: O(L log L) parallel steps instead of O(L) sequential."""
    # Step 1: Up-sweep (bottom-up)
    for stride in [1, 2, 4, 8, ...]:
        for i in range(0, L, stride*2):
            u[i+stride] = delta_A[i+stride] * u[i+stride] + delta_B[i+stride] * u[i]
    
    # Step 2: Down-sweep (top-down)
    ...
```

## Common Pitfalls

1. **Numerical stability** — SSMs can amplify numerical errors over long sequences; double-check discretization
2. **Initialization sensitivity** — Mamba is more sensitive to init than transformers; use provided init recipes
3. **Hardware utilization** — SSMs are memory-bound, not compute-bound; optimize for memory bandwidth
4. **Attention-free blind spot** — pure SSMs can struggle at tasks needing content-based retrieval; hybrid Mamba-Attention helps
5. **Autoregressive mode mismatch** — training uses parallel scan, inference uses recurrent; ensure state equivalence
6. **Normalization choice** — RMSNorm works better than LayerNorm for SSMs

## Verification Checklist

- [ ] Recurrence numerically stable for sequence length up to max expected
- [ ] Parallel scan forward matches sequential forward (numerical tolerance 1e-5)
- [ ] Inference state caching works correctly across multiple steps
- [ ] Gradient flows through discretization (check grad on delta parameter)
- [ ] Training loss matches reference implementation on small task
- [ ] Memory efficient: peak memory < O(n²) baseline for long sequences
- [ ] Throughput measured: tokens/second vs equivalent transformer

## See Also

- transformer-architectures — the alternative to SSMs
- attention-mechanisms-deep — attention that SSMs can replace
- custom-neural-architecture-design — architecture design patterns

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…