ggml-cuda: add chunked SSD matmul for Mamba-2 prefill acceleration - #22675
Conversation
|
@ORippler and @gaugarg-nv for review. |
|
The failure in CI / ubuntu-24-webgpu (pull_request) is unrelated to my change. |
gaugarg-nv
left a comment
There was a problem hiding this comment.
I think for the perf data, you can keep the ISL constant to something like 16384, but change the ubatch and batch size from 32 till 8192. Something like-
llama-bench -m <model> -fa 1 -p 16384 -b 8192 -ub 32,64,128,256,512,1024,2048,4096,8192 -r 3
Sure, below is the perf table for Nemotron 9b nano model
Command used on PC with RTX 6000 Blackwell - |
|
I found some more optimization opportunities in CUDA kernel working on it and will update here soon. For now, converting to draft in the meantime. |
|
My latest optimization improved performance, although the baseline appears to have shifted. The updated performance relative to baseline is shown below. ubatch sweep - RTX 5090
llama-bench.exe -m <nvidia_NVIDIA-Nemotron-Nano-9B-v2-Q4_K_M.gguf> -ngl 99 -fa 1 -p 16384 -b 8192 -ub 32,64,128,256,512,1024,2048,4096,8192 -r 3 |
|
ubatch sweep - DGX Spark
llama-bench.exe -m <nvidia_NVIDIA-Nemotron-Nano-9B-v2-Q4_K_M.gguf> -ngl 99 -fa 1 -p 16384 -b 8192 -ub 32,64,128,256,512,1024,2048,4096,8192 -r 3 |
ORippler
left a comment
There was a problem hiding this comment.
Did we run any studies on TF32 vs. BF16 vs. F16 w.r.t numerical precision and speed?
At first glance, the changes required in test-backend-ops to get the new implementation to pass correctness are a bit concerning. Please elaborate on those seemingly magic bounds.
I compared FP16 and BF16 for precision and BF16 shows significantly higher error than FP16.
Also, I have now cleaned up |
| ggml_cuda_pool_alloc<float> dt_sp_buf(ctx.pool(), n_tok * n_head * n_seq); | ||
| ggml_cuda_pool_alloc<float> cs_buf(ctx.pool(), n_tok * n_head * n_seq); | ||
| ggml_cuda_pool_alloc<float> CB_buf(ctx.pool(), chunk_size * chunk_size * n_group * n_seq); | ||
| ggml_cuda_pool_alloc<matmul_t> X_dt_buf(ctx.pool(), chunk_size * head_dim * n_head * n_seq); | ||
| ggml_cuda_pool_alloc<matmul_t> B_w_buf(ctx.pool(), d_state * chunk_size * n_head * n_seq); | ||
| ggml_cuda_pool_alloc<float> C_s_buf(ctx.pool(), d_state * chunk_size * n_head * n_seq); |
There was a problem hiding this comment.
Do you have data on how much VRAM does this scratch space take for different ubatch sizes?
There was a problem hiding this comment.
Below is the VRAM table for Nemotron Nano 4B, 9B, and Nemotron 3 Super models
| ub | 4B (n_head=96) | 9B (n_head=128) | 120B (n_head=128) | path |
|---|---|---|---|---|
| 256 | 35.9 MB | 47.2 MB | 46.2 MB | SSD |
| 512 | 36.1 MB | 47.5 MB | 46.5 MB | SSD |
| 1024 | 36.5 MB | 48.0 MB | 47.0 MB | SSD |
| 2048 | 37.2 MB | 49.0 MB | 48.0 MB | SSD |
| 4096 | 38.8 MB | 51.0 MB | 50.0 MB | SSD |
| 8192 | 41.8 MB | 55.0 MB | 54.0 MB | SSD |
Note: The scratch is per-layer but pool-allocated, so the peak VRAM footprint is one layer's worth at a time.
|
The PR looks good overall to me. Please rebase and update the PR description (which seems to be stale now). @JohannesGaessler @am17an Can you please take a look as well? |
PR #24561 improves numerical stability by using log-space differences instead of dividing very small exponentials, which helps eliminate NaNs and underflow. It also ensures stability in tests by initializing g in the range [-20, -1e-4], so that 0 < exp(g) < 1. Without this constraint, positive g would give exp(g) > 1, causing the recurrent state to grow exponentially and potentially overflow. For this Mamba-2 SSD PR, this change does not really apply since it already uses a stable formulation: decay = exp(A * (cs_out - cs_in)), with A < 0. This keeps values in the range and avoids overflow or 0/0 issues. So, the implementation is already numerically stable. The minor remaining error (~2e-7) comes from FP16 quantization rather than instability and using log-space tricks is unlikely to reduce it further. Higher precision would be the more effective option, though the gap is already very small (~2e-7) and does not have a meaningful impact based on perplexity and KL divergence. |
…proves memory coalescing in ssm_ssd_prepare_dt_kernel, and boosts efficiency by merging B_weighted and C_scaled; also addresses prior review comments.
8e71a37 to
3c6938c
Compare
|
Perf sweep on latest changes Nemotron-Nano-9B-v2
pp16384 tok/s (base=scan, branch=SSD at ub>128) tested on RTX 6000 Pro MaxQ. |
|
The failing CI jobs appear to be pre-existing on master and are not caused by this PR. The jobs The job This PR modifies only the CUDA code path and does not affect Vulkan, HIP, WebGPU, OpenVINO, or the LLVM toolchain build configuration. |
…gml-org#22675) * ggml-cuda: add chunked SSD matmul for Mamba-2 prefill acceleration * cuda: added SSD CICD fixes for CUDA / HIP / MUSA / MSVC. * ggml-cuda: review comments fixed. * ggml-cuda: Fuse M matrix materialization into pre_matmul kernel and enabled test. * ggml-cuda: test updates and fixes * ggml-cuda: test updates to remove hardcoding of tensor initialise data limits. * ggml-cuda: ssd minor review comment fixed. * ggml-cuda: ssd minor CICD fixed. * CUDA SSD: Fixes correctness by promoting s0_stride_seq to int64_t, improves memory coalescing in ssm_ssd_prepare_dt_kernel, and boosts efficiency by merging B_weighted and C_scaled; also addresses prior review comments. * cuda: fix sdata read-write race in prepare_dt fallback scan loop
…gml-org#22675) * ggml-cuda: add chunked SSD matmul for Mamba-2 prefill acceleration * cuda: added SSD CICD fixes for CUDA / HIP / MUSA / MSVC. * ggml-cuda: review comments fixed. * ggml-cuda: Fuse M matrix materialization into pre_matmul kernel and enabled test. * ggml-cuda: test updates and fixes * ggml-cuda: test updates to remove hardcoding of tensor initialise data limits. * ggml-cuda: ssd minor review comment fixed. * ggml-cuda: ssd minor CICD fixed. * CUDA SSD: Fixes correctness by promoting s0_stride_seq to int64_t, improves memory coalescing in ssm_ssd_prepare_dt_kernel, and boosts efficiency by merging B_weighted and C_scaled; also addresses prior review comments. * cuda: fix sdata read-write race in prepare_dt fallback scan loop
…gml-org#22675) * ggml-cuda: add chunked SSD matmul for Mamba-2 prefill acceleration * cuda: added SSD CICD fixes for CUDA / HIP / MUSA / MSVC. * ggml-cuda: review comments fixed. * ggml-cuda: Fuse M matrix materialization into pre_matmul kernel and enabled test. * ggml-cuda: test updates and fixes * ggml-cuda: test updates to remove hardcoding of tensor initialise data limits. * ggml-cuda: ssd minor review comment fixed. * ggml-cuda: ssd minor CICD fixed. * CUDA SSD: Fixes correctness by promoting s0_stride_seq to int64_t, improves memory coalescing in ssm_ssd_prepare_dt_kernel, and boosts efficiency by merging B_weighted and C_scaled; also addresses prior review comments. * cuda: fix sdata read-write race in prepare_dt fallback scan loop
…gml-org#22675) * ggml-cuda: add chunked SSD matmul for Mamba-2 prefill acceleration * cuda: added SSD CICD fixes for CUDA / HIP / MUSA / MSVC. * ggml-cuda: review comments fixed. * ggml-cuda: Fuse M matrix materialization into pre_matmul kernel and enabled test. * ggml-cuda: test updates and fixes * ggml-cuda: test updates to remove hardcoding of tensor initialise data limits. * ggml-cuda: ssd minor review comment fixed. * ggml-cuda: ssd minor CICD fixed. * CUDA SSD: Fixes correctness by promoting s0_stride_seq to int64_t, improves memory coalescing in ssm_ssd_prepare_dt_kernel, and boosts efficiency by merging B_weighted and C_scaled; also addresses prior review comments. * cuda: fix sdata read-write race in prepare_dt fallback scan loop
Overview
Adding SSD (State Space Duality) matmul path to the CUDA SSM scan for Mamba-2 prefill acceleration. For sequences >64 tokens, replaces the sequential O(T*N) scan with chunked parallel matmuls using cuBLAS batched GEMMs and a fused MMA tensor-core kernel that computes the causal decay mask on-the-fly in shared memory.
-- mamba2-2.7B: +15-18% PP (pp128–pp32768)
-- Nemotron-Nano-4B (hybrid): +11-16% PP
-- Nemotron-Nano-9B (hybrid): +12-16% PP
-- Nemotron-Super-120B-A12B (MoE): +3-8% PP
-- TG unchanged (scan kernel still used for n_tokens ≤ 64). Perplexity verified identical on all models.
Additional information
Only
ggml/src/ggml-cuda/ssm-scan.cuis modified. The existing sequential scan kernel is untouched and used as fallback for short sequences, non-NVIDIA GPUs, and pre-Turing architectures.Requirements