Commit 85bc559
authored
Add nvfp4 attention support for vLLM serving (#1898)
### What does this PR do?
Type of change: New feature
This PR adds an NVFP4+sparse attention serving path for vLLM and
consolidates it with the existing checkpoint-driven sparse-attention
integration.
#### NVFP4 attention
- Applies dynamic block-16 NVFP4 fake quantization to Q/K/P/V.
- Quantizes K before the KV-cache write. V remains pristine until a
complete 16-token group can be finalized once; an incomplete tail is QDQ
on read.
- Adds paged/chunked prefill support and a dedicated split-K decode
kernel. Decode uses a fixed 32-split, 128-key-tile schedule because
split-local P quantization is part of the numerical contract.
#### vLLM integration
- Provides one consolidated worker module:
- `SparseAttnWorker` for checkpoint-driven sparse attention.
- `QuantSparseAttnWorker` for fixed NVFP4 Q/K/P/V plus optional
checkpoint sparsity.
- Supports the native vLLM FlashAttention and FlashInfer backends. The
worker replaces only the selected implementation and delegates inactive
launches back to that backend.
- Preserves FlashInfer NHD/HND cache layouts and separates mixed
decode/prefill launches so each phase uses the correct kernel contract.
- Restores checkpoint-driven N:M sparse-softmax and skip-softmax
metadata. N:M remains a prefill transform; calibrated skip-softmax
decode uses the shared paged kernel.
- Validates the complete attention plan before modifying the model and
reports unsupported configurations without leaving a partially converted
model.
Supported configurations are regular decoder self-attention with vLLM >=
0.15.0, FlashInfer or FlashAttention, fp16/bf16 model and KV cache,
equal Q/K/V head dimensions divisible by 16, and DCP 1. The README
documents unsupported features and CUDA-graph constraints.
### Usage
Let vLLM select the backend for the model and platform. For example,
Nemotron-H on Blackwell selects FlashInfer automatically.
```bash
cd examples/vllm_serve
python vllm_serve_sparse_attn.py <MODEL_PATH> -tp 8 \
--no-enable-prefix-caching \
--worker-cls sparse_attn_worker.QuantSparseAttnWorker
```
If `<MODEL_PATH>/config.json` contains `sparse_attention_config`, the
same worker also applies its N:M or skip-softmax settings. Otherwise, it
runs NVFP4 attention only.
### Testing
Focused attention kernels:
```bash
PYTEST_VERSION=1 PYTHONPATH=$PWD python -m pytest -q \
tests/gpu/torch/kernels/common/attention/test_triton_fa_p_qdq.py \
tests/gpu/torch/kernels/common/attention/test_decode_attention.py \
tests/gpu/torch/kernels/common/attention/test_triton_fa_paged.py
```
- B200 NVFP4 run before final test deduplication: 47 passed.
- Current RTX A6000 run: 23 passed, 21 skipped. The skips require native
E4M3 support (compute capability >= 8.9).
Focused vLLM worker and adapter tests:
```bash
PYTHONPATH=$PWD python -m pytest -q \
tests/gpu_vllm/torch/sparsity/attention_sparsity/test_sparse_attn_worker.py \
tests/gpu_vllm/torch/sparsity/attention_sparsity/test_quant_sparse_attn_worker.py
```
Result: 43 passed.
CPU import and launch-contract tests:
```bash
PYTHONPATH=$PWD python -m pytest -q \
tests/unit/torch/kernels/common/attention/test_triton_fa.py
```
Result: 9 passed.
GitHub Linux, Windows, multi-version, code-quality, documentation, and
required unit checks pass.
### Before your PR is "*Ready for review*"
Make sure you read and follow [Contributor
guidelines](https://github.com/NVIDIA/Model-Optimizer/blob/main/CONTRIBUTING.md)
and your commits are signed (`git commit -s -S`).
Make sure you read and follow the [Security Best
Practices](https://github.com/NVIDIA/Model-Optimizer/blob/main/SECURITY.md#security-coding-practices-for-contributors)
(e.g. avoiding hardcoded `trust_remote_code=True`, `torch.load(...,
weights_only=False)`, `pickle`, etc.).
- Is this change backward compatible?: ✅ — both serving policies are
opt-in; sparse-only remains the launcher default.
- If you copied code from any other sources or added a new PIP
dependency, did you follow guidance in `CONTRIBUTING.md`: N/A — no
copied code or new dependency.
- Did you write any new necessary tests?: ✅
- Did you update
[Changelog](https://github.com/NVIDIA/Model-Optimizer/blob/main/CHANGELOG.rst)?:
N/A — the example README documents this opt-in serving path; no stable
public API changed.
- Did you get Claude approval on this PR?: N/A
### Additional Information
The fixed attention recipe intentionally does not expose the integration
branch's environment-variable matrix. Backend selection is automatic
unless an explicit vLLM backend override is needed.
<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit
* **New Features**
* Added quant+sparse vLLM serving worker support and clarified compact
NVFP4 attention worker behavior.
* Introduced paged split-K decode and NVFP4 QDQ, including on-write
V-cache quantization and new decode attention API.
* Expanded vLLM runtime installation to support NVFP4 quantization and
sparse attention with FlashInfer metadata compatibility.
* **Bug Fixes**
* Improved NVFP4 degenerate/underflow scale handling to reliably zero
out blocks.
* Strengthened validation for paged-cache and NVFP4 quantization
contracts.
* **Documentation**
* Updated the vLLM sparse-attention example docs with tested versions
and explicit limitations.
* **Tests**
* Expanded GPU correctness and integration coverage for split-K decode,
NVFP4 QDQ, vLLM workers, and runtime installation paths.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->
---------
Signed-off-by: Kai Xu <kaix@nvidia.com>1 parent 95ee9c4 commit 85bc559
22 files changed
Lines changed: 4577 additions & 712 deletions
File tree
- examples/vllm_serve
- modelopt/torch
- kernels
- common/attention
- quantization
- attention
- common
- sparsity/attention
- quantization/plugins
- sparsity/attention_sparsity/plugins
- tests
- gpu_vllm/torch
- quantization
- sparsity/attention_sparsity
- gpu/torch
- kernels/common/attention
- quantization
- unit/torch/kernels/common/attention
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
| 8 | + | |
8 | 9 | | |
9 | 10 | | |
10 | 11 | | |
| |||
101 | 102 | | |
102 | 103 | | |
103 | 104 | | |
104 | | - | |
| 105 | + | |
105 | 106 | | |
106 | | - | |
| 107 | + | |
107 | 108 | | |
108 | 109 | | |
109 | 110 | | |
| |||
114 | 115 | | |
115 | 116 | | |
116 | 117 | | |
117 | | - | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
118 | 131 | | |
119 | 132 | | |
120 | 133 | | |
121 | 134 | | |
122 | | - | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
123 | 162 | | |
124 | 163 | | |
125 | 164 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
16 | | - | |
17 | | - | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
24 | | - | |
25 | | - | |
26 | | - | |
27 | | - | |
28 | | - | |
29 | | - | |
30 | | - | |
31 | | - | |
32 | | - | |
33 | | - | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
38 | | - | |
39 | | - | |
40 | | - | |
41 | | - | |
42 | | - | |
43 | | - | |
44 | | - | |
45 | | - | |
46 | | - | |
| 16 | + | |
47 | 17 | | |
48 | 18 | | |
49 | 19 | | |
50 | | - | |
51 | | - | |
52 | | - | |
53 | | - | |
54 | | - | |
55 | | - | |
56 | | - | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
57 | 23 | | |
58 | 24 | | |
| 25 | + | |
59 | 26 | | |
60 | | - | |
61 | | - | |
| 27 | + | |
62 | 28 | | |
63 | | - | |
64 | | - | |
65 | | - | |
66 | | - | |
67 | | - | |
68 | | - | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
69 | 55 | | |
70 | 56 | | |
71 | | - | |
72 | | - | |
73 | | - | |
| 57 | + | |
| 58 | + | |
74 | 59 | | |
75 | | - | |
76 | | - | |
77 | | - | |
78 | | - | |
79 | | - | |
80 | | - | |
81 | | - | |
82 | 60 | | |
83 | | - | |
84 | | - | |
85 | | - | |
86 | | - | |
87 | 61 | | |
88 | | - | |
89 | | - | |
90 | | - | |
91 | | - | |
92 | | - | |
93 | | - | |
94 | | - | |
95 | | - | |
96 | | - | |
97 | | - | |
98 | | - | |
99 | | - | |
100 | | - | |
101 | | - | |
| 62 | + | |
| 63 | + | |
102 | 64 | | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
103 | 70 | | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | 71 | | |
| 72 | + | |
| 73 | + | |
108 | 74 | | |
109 | | - | |
110 | | - | |
| 75 | + | |
| 76 | + | |
111 | 77 | | |
112 | | - | |
113 | | - | |
114 | | - | |
| 78 | + | |
115 | 79 | | |
116 | 80 | | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
117 | 92 | | |
118 | | - | |
| 93 | + | |
119 | 94 | | |
120 | | - | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
| 18 | + | |
| 19 | + | |
20 | 20 | | |
21 | | - | |
| 21 | + | |
22 | 22 | | |
23 | 23 | | |
24 | | - | |
25 | | - | |
| 24 | + | |
| 25 | + | |
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
| |||
0 commit comments