Skip to main content

TorchMamba

PyPI CI Python License: MIT

Clean, numerically self-consistent PyTorch reference kernels for Mamba-1 (S6), Mamba-2 (SSD), Mamba-3 SISO, and Mamba-3 MIMO — written directly from the papers, not ported from optimized kernels.

Scope: parity with paper math, not with fast kernels. Every recurrence, mask, and block equation follows the paper (section/equation cited in each module docstring). No Triton/CUDA/TileLang, no causal-conv1d package, no mamba-ssm import. CPU-runnable, autograd-safe. Loop-vs-quadratic-vs-chunkwise-vs-stepwise agreement plus cross-model reductions are proven in fp32/fp64 across 41 tests. Bit-parity with mamba-ssm kernels and paper benchmark numbers (perplexity/throughput) are explicitly out of scope.

If you came for speed, use mamba-ssm. If you came to check what the papers actually say, you are in the right place.

Models

Model Paper Core recurrence Entry points
Mamba-1 (S6) Gu & Dao 2023 h = exp(dt·A)·h + (dt·B)·x (exponential-Euler) selective_scan_loop, selective_scan_matrix, Mamba1Block
Mamba-2 (SSD) Dao & Gu 2024 scalar-decay h = a·h + B·x, chunkwise Listing-1 ssd_recurrent, ssd_quadratic, ssd_chunkwise, ssd_step, Mamba2Block
Mamba-3 SISO Lahoti et al. 2026 3-term trap h = αh + βB₋x₋ + γBx + data-dependent RoPE, no external conv trap_rope_loop, trap_rope_matrix, Mamba3SisoBlock
Mamba-3 MIMO Lahoti et al. 2026 rank-R matmul update on shared (N,P) state mimo_loop, mimo_chunkwise, mimo_as_r2_sisos, Mamba3MimoBlock

Reductions (each proven in tests/test_cross_model.py): M1→M2 at P=1 with dt folded into B; M2→SISO at λ=1, θ=0; SISO→MIMO at R=1 (structural — the R axis is squeezed and the SISO loop runs, not a numerical coincidence).

Requirements

  • Python ≥ 3.12
  • torch>=2.14.0 (CPU suffices; CUDA works too)
  • uv for the commands below (or any PEP 517 installer + pytest)

Install

pip install torchmamba

From source (dev):

git clone https://github.com/nitg3n/torchmamba.git
cd torchmamba
uv sync              # creates .venv, installs torch + package

Quickstart

Block-level — forward equals prefill + stepwise step decode for every model:

import torch
from torchmamba import Mamba2Block

torch.manual_seed(0)
blk = Mamba2Block(d_model=16, n_heads=2, d_head=8, d_state=8, n_groups=1, d_conv=3).eval()
u = torch.randn(2, 17, 16)
with torch.no_grad():
    y = blk(u)                          # (2, 17, 16)
    y_pre, cache = blk.prefill(u[:, :9])
    outs = []
    for t in range(9, 17):
        o, cache = blk.step(u[:, t:t+1], cache)
        outs.append(o)
    assert torch.allclose(torch.cat([y[:, :9], *outs], 1), y, rtol=1e-5, atol=1e-6)

Functional cores — shapes in, shapes out:

from torchmamba import (
    selective_scan_loop,   # M1: x (B,L,D)   -> y (B,L,D),   h (B,D,N)
    ssd_recurrent,          # M2: X (B,L,H,P) -> Y (B,L,H,P), h (B,H,N,P)
    trap_rope_loop,         # M3 SISO: same as M2 + theta (B,L,H,N/2), lam
    mimo_loop,              # M3 MIMO: X (B,L,H,P,R) -> Y (B,L,H,P,R), h (B,H,N,P)
)

y, h = selective_scan_loop(x, dt, A, B, C)
y, h = ssd_recurrent(X, logdecay, B, C)
y, h, dbg = trap_rope_loop(X, logdecay, B, C, theta_dt, lam)
y, h = mimo_loop(Xr, logdecay, Br, Cr, theta_dt, lam)

Subpackage imports work too (torchmamba.mamba1, torchmamba.mamba2, torchmamba.mamba3, torchmamba.core for segsum, discretization, norms, RoPE).

API reference

Blocks — all expose forward(u), prefill(u), step(u_t, cache):

Class Key params (defaults) Cache
Mamba1Block d_model, expand=2, d_state=16, d_conv=4, dt_rank="auto", bias=True Mamba1Cache(conv_state, ssm_state)
Mamba2Block d_model, n_heads, d_head=64, d_state=128, n_groups=1, d_conv=4, bias=True, norm="group", use_normalizer=False, psi=None→SiLU dict {conv_state, ssm_state}
Mamba3SisoBlock d_model, n_heads, d_head=64, d_state=128, n_groups=1, bias=True (no conv, by design) Mamba3SisoCache(angle, ssm, x_prev, b_prev)
Mamba3MimoBlock SISO params + mimo_rank=4 (Mamba3SisoCache, aux); state has no R axis

Behavioral notes (all covered by tests):

  • Core functions take/return (B,L,…) block I/O, except the M1 conv helper which takes channel-first (B,D,L).
  • Oracle size guards raise ValueError above their limits: selective_scan_matrix L≤32, trap_rope_matrix L≤16, ssd_quadratic L≤512.
  • lam=1 takes the exact 2-term code path (no B_prev contribution); theta=None/zeros is the real-only path; MIMO R=1 dispatches to the SISO loop structurally. Unknown norm= raises ValueError.
  • H % G == 0 required wherever groups appear; RoPE needs even N.
  • Numerics (torchmamba.core.policy): fp16/bf16/fp32 compute in fp32, outputs downcast to input dtype; fp64 stays fp64 end-to-end; states never below fp32.

Math notes

One paragraph per model — the load-bearing facts, with paper pointers:

  • M1. Continuous SSM → exponential-Euler discretization α=exp(dt·A), B_disc=dt·B (M1 text claims ZOH; the shipped implementation is EE, and M3 §3.1 derives it — EE is the ground truth here, ZOH a documented alternative guarded by a test so the default can never silently flip). Input-dependent (Δ,B,C) make it LTV: scan-only, no convolution view (M1 §3.2 Alg. 2).
  • M2. Scalar-identity A=aI splits decay from content: M = L∘(CBᵀ) (M2 §5.1), quadratic dual Y=(L∘QKᵀ)V with Q↔C, K↔B, V↔X (M2 §5.1 Eq. 16), chunkwise intra-quadratic plus B→A→C factored inter-chunk carry (M2 §6 Listing 1: O(TN²) FLOPs, matmul-bound). Heads follow MVA/GVA (M2 §7.2); (Δ,B,C) project from the block input in parallel, so tensor parallel needs one all-reduce (M2 §8.1).
  • M3 SISO. Exponential-trapezoidal 3-term recurrence with data-dependent λ (M3 Prop. 1 Eqs. 5–6); the parallel mask is L = 1SS @ band — a matrix product, not Hadamard (M3 Eq. 7). Complex state enters via the RoPE trick: accumulated data-dependent pairwise rotations on B,C (M3 Props. 2–4 Eqs. 8–11; vanilla RoPE is data-independent). BCNorm+bias replace the external short convolution, which is removed (M3 §3.4, Table 5a: adding conv back does not help).
  • MIMO. Rank-R expansion turns the B·xᵀ outer product into a matmul on a shared (N,P) state, lifting decode intensity from Θ(1) to Θ(R) at fixed state size (M3 §3.3 Table 2). Training is R² SISO calls (M3 Eqs. 12–14); chunked C_MIMO=C_SISO/R cuts it to R×; per-head x/y/z expand by a learned vector (DP+PR, not DPR) with MLP shrink for param-match (M3 App. C).

Repository layout

torchmamba/
├── README.md
├── LICENSE
├── pyproject.toml
├── uv.lock
├── src/torchmamba/
│   ├── __init__.py           # top-level re-exports (18 symbols)
│   ├── core/                 # policy, discretize, segsum, conv, norms, rope
│   ├── mamba1/               # scan loop/matrix + block
│   ├── mamba2/               # recurrent/quadratic/chunkwise/step + block
│   └── mamba3/               # siso_core/block, mimo_core/block
└── tests/                    # 41 tests: primitives, 4 models, reductions,
    ├── parity/               # forward == prefill + stepwise decode
    └── test_*.py

Verification

uv run pytest -q
# 41 passed

Per-model forward-vs-decode maxima live in tests/parity/test_forward_prefill_step.py (seeded, B=2, L=17, prefix=9): 1.490e-08 / 5.066e-07 / 7.749e-07 / 7.153e-07, all < 1e-5.

Tolerances: fp64 rtol=1e-10, atol=1e-12; fp32 rtol=1e-5, atol=1e-6 (the M2 long-sequence fp32 path documents 2e-5/5e-6 for exp/cumsum rounding). The suite includes fp64 gradchecks per core, oracle-vs-loop-vs-chunkwise-vs-step agreement, cross-model reductions, and the ZOH-vs-EE differ-guard.

Non-goals

  • No fused/fast kernels, no varlen cu_seqlens API, no distributed sharding.
  • No mamba-ssm weight compatibility or kernel bit-parity harness.
  • No training runs or paper Table 3–7 reproduction.

References

  • Mamba-1: Gu & Dao, Mamba: Linear-Time Sequence Modeling with Selective State Spaces, arXiv:2312.00752.
  • Mamba-2: Dao & Gu, Transformers are SSMs, arXiv:2405.21060.
  • Mamba-3: Lahoti et al., Mamba-3: Improved Sequence Modeling using State Space Principles, arXiv:2603.15569.
  • Fast implementation (not a dependency): state-spaces/mamba (+ causal-conv1d).

License

MIT — see LICENSE.

Metadata

Release files for torchmamba 0.1.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for torchmamba 0.1.2
File Size Uploaded
torchmamba-0.1.2.tar.gz 21.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for torchmamba 0.1.2
File Interpreter ABI Platform
torchmamba-0.1.2-py3-none-any.whl Python 3 none any Details

Total release size: 53.7 kB

Release files / torchmamba-0.1.2.tar.gz

Download URL torchmamba-0.1.2.tar.gz
Size 21.7 kB
Tags Source
SHA-256 checksum
How to use checksums
ed86f0d11caf8511cc97d0258cbf7ad394850cefd24683cde19a3f2f0582e1ff
BLAKE2b-256 checksum
How to use checksums
45dc19742febd2e0cafb551c206799491badb085969d1639a1c132bbe76446e5
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release files / torchmamba-0.1.2-py3-none-any.whl

Download URL torchmamba-0.1.2-py3-none-any.whl
Size 32.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
4580747a9dedc079eda7da8b693261b4d1ed1b794e9180fac44f27c336dcf1ba
BLAKE2b-256 checksum
How to use checksums
80be7892c7561846ed955b353966f398e5a143c7657c15b1a463a2a08b56223f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.12.3

Release history Release notifications | RSS feed

This release

0.1.2 This release

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page