@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / 4fa7ce46f3
Fork 0

A high-throughput and memory-efficient inference and serving engine for LLMs

Mirrored from https://github.com/tduncan-lum/Nvidia-Optimization-Stack---VLLM.git

Synced Nov 11, 12:30 UTC

[Feature] Add SM103 (Blackwell Ultra) Support to vLLM (#30484)

Signed-off-by: LopezCastroRoberto <robertol.c510@gmail.com> Signed-off-by: Roberto L. Castro <38211239+LopezCastroRoberto@users.noreply.github.com> Co-authored-by: youkaichao <youkaichao@gmail.com>

Roberto L. Castro committed Dec 13, 2025 at 04:34 UTC 4fa7ce46f31cbd97b4651694caf9991cc395a259
21 files changed +53 -33
tests/compile/distributed/test_fusions_e2e.py
+1 -1
@@ -20,7 +20,7 @@ from vllm.utils.torch_utils import is_torch_equal_or_newer
20
21 from ...utils import flat_product, multi_gpu_test
22
23 -is_blackwell = lambda: current_platform.is_device_capability(100)
23 +is_blackwell = lambda: current_platform.is_device_capability_family(100)
24 """Are we running on Blackwell, a lot of tests depend on it"""
25
26
tests/kernels/attention/test_cutlass_mla_decode.py
+2 -2
@@ -32,8 +32,8 @@ def cal_diff(
32
33
34 CUTLASS_MLA_UNSUPPORTED_REASON = (
35 - "Cutlass MLA Requires compute capability of 10 or above."
36 - if not current_platform.is_device_capability(100)
35 + "Cutlass MLA Requires compute capability of 100 or above."
36 + if not current_platform.is_device_capability_family(100)
37 else "Cutlass MLA is supported"
38 )
39
tests/kernels/attention/test_flashinfer_trtllm_attention.py
+2 -2
@@ -11,7 +11,7 @@ from tests.kernels.quantization.nvfp4_utils import (
11 from vllm.platforms import current_platform
12 from vllm.utils.math_utils import round_up
13
14 -if not current_platform.is_device_capability(100):
14 +if not current_platform.is_device_capability_family(100):
15 pytest.skip(
16 "This TRTLLM kernel requires NVIDIA Blackwell.", allow_module_level=True
17 )
@@ -443,7 +443,7 @@ def test_flashinfer_trtllm_prefill_with_baseline(
443 output_trtllm = output_trtllm.reshape(-1, query.shape[1], query.shape[2])
444
445 if q_quant_dtype == FP8_DTYPE and o_quant_dtype == FP4_DTYPE:
446 - rtol, atol = 1e-1, 2e-1
446 + rtol, atol = 3e-1, 4e-1
447 elif q_quant_dtype == FP8_DTYPE and o_quant_dtype == FP8_DTYPE:
448 rtol, atol = 4e-2, 6e-2
449 elif q_quant_dtype == FP8_DTYPE and o_quant_dtype == dtype:
tests/kernels/moe/test_ocp_mx_moe.py
+2 -2
@@ -17,7 +17,7 @@ QUARK_MXFP4_AVAILABLE = find_spec("quark") is not None and version.parse(
17 ) >= version.parse("0.8.99")
18
19 TRTLLM_GEN_MXFP4_AVAILABLE = (
20 - current_platform.is_cuda() and current_platform.is_device_capability(100)
20 + current_platform.is_cuda() and current_platform.is_device_capability_family(100)
21 )
22
23 HOPPER_MXFP4_BF16_AVAILABLE = (
@@ -799,7 +799,7 @@ def test_flashinfer_cutlass_mxfp4_fused_moe(
799 @pytest.mark.skipif(
800 not (
801 current_platform.is_cuda()
802 - and current_platform.is_device_capability(100)
802 + and current_platform.is_device_capability_family(100)
803 and has_flashinfer()
804 ),
805 reason="NVIDIA GPU sm100 and flashinfer are required for this test",
tests/quantization/test_blackwell_moe.py
+2 -2
@@ -10,9 +10,9 @@ import pytest
10 from tests.utils import RemoteOpenAIServer
11 from vllm.platforms import current_platform
12
13 -if not current_platform.is_device_capability(100):
13 +if not current_platform.is_device_capability_family(100):
14 pytest.skip(
15 - "This test only runs on Blackwell GPUs (SM100).", allow_module_level=True
15 + "This test only runs on Blackwell GPUs (SM10x).", allow_module_level=True
16 )
17
18
vllm/model_executor/layers/batch_invariant.py
+1 -1
@@ -936,7 +936,7 @@ def enable_batch_invariant_mode():
936 # Batch invariant matmuls are no longer needed after cublas overrides
937 if not is_torch_equal_or_newer("2.10.0.dev"):
938 if (
939 - current_platform.is_device_capability(100)
939 + current_platform.is_device_capability_family(100)
940 or current_platform.is_device_capability(80)
941 or current_platform.is_device_capability(89)
942 ):
vllm/model_executor/layers/fused_moe/batched_deep_gemm_moe.py
+4 -1
@@ -287,7 +287,10 @@ class BatchedDeepGemmExperts(mk.FusedMoEPermuteExpertsUnpermute):
287 """
288 DeepGemm supports packed ue8m0 activation scales format in devices == sm100
289 """
290 - return is_deep_gemm_e8m0_used() and current_platform.is_device_capability(100)
290 + return (
291 + is_deep_gemm_e8m0_used()
292 + and current_platform.is_device_capability_family(100)
293 + )
294
295 def finalize_weight_and_reduce_impl(self) -> mk.TopKWeightAndReduce:
296 # Let PrepareAndFinalize::finalize() decide the impl.
vllm/model_executor/layers/quantization/fp8.py
+3 -3
@@ -137,7 +137,7 @@ def get_fp8_moe_backend(
137 if (
138 current_platform.is_cuda()
139 and (
140 - current_platform.is_device_capability(100)
140 + current_platform.is_device_capability_family(100)
141 or current_platform.is_device_capability(90)
142 )
143 and envs.VLLM_USE_FLASHINFER_MOE_FP8
@@ -148,7 +148,7 @@ def get_fp8_moe_backend(
148 logger.info_once("Using FlashInfer FP8 MoE TRTLLM backend for SM100")
149 return Fp8MoeBackend.FLASHINFER_TRTLLM
150 else:
151 - if block_quant and current_platform.is_device_capability(100):
151 + if block_quant and current_platform.is_device_capability_family(100):
152 raise ValueError(
153 "FlashInfer FP8 MoE throughput backend does not "
154 "support block quantization. Please use "
@@ -193,7 +193,7 @@ def get_fp8_moe_backend(
193 # CUTLASS BlockScaled GroupedGemm on SM100 with block-quantized weights
194 if (
195 current_platform.is_cuda()
196 - and current_platform.is_device_capability(100)
196 + and current_platform.is_device_capability_family(100)
197 and block_quant
198 ):
199 logger.info_once(
vllm/model_executor/layers/quantization/mxfp4.py
+4 -4
@@ -118,19 +118,19 @@ def get_mxfp4_backend(with_lora_support: bool) -> Mxfp4Backend:
118 logger.info_once("Using FlashInfer MXFP4 BF16 backend for SM90")
119 return Mxfp4Backend.SM90_FI_MXFP4_BF16
120 elif (
121 - current_platform.is_device_capability(100)
121 + current_platform.is_device_capability_family(100)
122 and has_flashinfer()
123 and envs.VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8_CUTLASS
124 ):
125 logger.info_once("Using FlashInfer MXFP4 MXFP8 CUTLASS backend for SM100")
126 return Mxfp4Backend.SM100_FI_MXFP4_MXFP8_CUTLASS
127 elif (
128 - current_platform.is_device_capability(100)
128 + current_platform.is_device_capability_family(100)
129 and has_flashinfer()
130 and envs.VLLM_USE_FLASHINFER_MOE_MXFP4_MXFP8
131 ):
132 return Mxfp4Backend.SM100_FI_MXFP4_MXFP8_TRTLLM
133 - elif current_platform.is_device_capability(100) and has_flashinfer():
133 + elif current_platform.is_device_capability_family(100) and has_flashinfer():
134 logger.info_once(
135 "Using FlashInfer MXFP4 BF16 backend for SM100, "
136 "For faster performance on SM100, consider setting "
@@ -139,7 +139,7 @@ def get_mxfp4_backend(with_lora_support: bool) -> Mxfp4Backend:
139 )
140 return Mxfp4Backend.SM100_FI_MXFP4_BF16
141 elif (
142 - current_platform.is_device_capability(100)
142 + current_platform.is_device_capability_family(100)
143 or current_platform.is_device_capability(90)
144 ) and not has_flashinfer():
145 logger.warning_once(
vllm/model_executor/layers/quantization/utils/flashinfer_fp4_moe.py
+1 -1
@@ -50,7 +50,7 @@ def is_flashinfer_fp4_cutedsl_moe_available() -> bool:
50 envs.VLLM_USE_FLASHINFER_MOE_FP4
51 and has_flashinfer_cutedsl_grouped_gemm_nt_masked()
52 and current_platform.is_cuda()
53 - and current_platform.is_device_capability(100)
53 + and current_platform.is_device_capability_family(100)
54 )
55
56
vllm/model_executor/layers/quantization/utils/flashinfer_utils.py
+1 -1
@@ -290,7 +290,7 @@ def get_flashinfer_moe_backend() -> FlashinferMoeBackend:
290 if flashinfer_moe_backend in backend_map:
291 if (
292 flashinfer_moe_backend == "latency"
293 - and not current_platform.has_device_capability(100)
293 + and not current_platform.is_device_capability_family(100)
294 ):
295 logger.info_once(
296 "Flashinfer TRTLLM MOE backend is only supported on "
vllm/model_executor/layers/quantization/utils/fp8_utils.py
+1 -1
@@ -247,7 +247,7 @@ class W8A8BlockFp8LinearOp:
247 self.act_quant_group_shape = act_quant_group_shape
248 self.is_deep_gemm_supported = is_deep_gemm_supported()
249 self.is_hopper = current_platform.is_device_capability(90)
250 - self.is_blackwell = current_platform.is_device_capability(100)
250 + self.is_blackwell = current_platform.is_device_capability_family(100)
251 self.use_deep_gemm_e8m0 = is_deep_gemm_e8m0_used()
252
253 # Get the correct blockscale mul and input quant operations.
vllm/model_executor/layers/quantization/utils/mxfp4_utils.py
+1 -1
@@ -63,7 +63,7 @@ def _swizzle_mxfp4(quant_tensor, scale, num_warps):
63 "split_k": 1,
64 }
65 opt_flags.update_opt_flags_constraints(constraints)
66 - elif current_platform.is_device_capability(100):
66 + elif current_platform.is_device_capability_family(100):
67 constraints = {
68 "is_persistent": True,
69 "epilogue_subtile": 1,
vllm/model_executor/models/config.py
+1 -1
@@ -363,7 +363,7 @@ class HybridAttentionMambaModelConfig(VerifyAndUpdateConfig):
363 else:
364 kernel_block_alignment_size = 16
365 if (
366 - current_platform.is_device_capability(100)
366 + current_platform.is_device_capability_family(100)
367 and model_config.get_head_size() == 256
368 and (
369 attention_config.backend is None
vllm/platforms/cuda.py
+1 -1
@@ -182,7 +182,7 @@ class CudaPlatformBase(Platform):
182
183 if vllm_config.attention_config.backend is None:
184 # Default case
185 - if cls.is_device_capability(100) and not use_sparse:
185 + if cls.is_device_capability_family(100) and not use_sparse:
186 # Blackwell => Force CutlassMLA (unless sparse, i.e. DSv3.2).
187 use_cutlass_mla = True
188 # Set the backend in AttentionConfig so it's used during
vllm/platforms/interface.py
+15
@@ -301,6 +301,21 @@ class Platform:
301
302 return current_capability.to_int() == capability
303
304 + @classmethod
305 + def is_device_capability_family(
306 + cls,
307 + capability: int,
308 + device_id: int = 0,
309 + ) -> bool:
310 + """
311 + Returns True if the device capability is any <major>.x.
312 + Mirrors CUDA 13 'family' architecture semantics (e.g. 10.x, 11.x, 12.x).
313 + """
314 + current_capability = cls.get_device_capability(device_id=device_id)
315 + if current_capability is None:
316 + return False
317 + return (current_capability.to_int() // 10) == (capability // 10)
318 +
319 @classmethod
320 def get_device_name(cls, device_id: int = 0) -> str:
321 """Get the name of a device."""
vllm/utils/deep_gemm.py
+2 -2
@@ -38,7 +38,7 @@ class DeepGemmQuantScaleFMT(Enum):
38 return DeepGemmQuantScaleFMT.FLOAT32
39 return (
40 DeepGemmQuantScaleFMT.UE8M0
41 - if current_platform.is_device_capability(100)
41 + if current_platform.is_device_capability_family(100)
42 else DeepGemmQuantScaleFMT.FLOAT32_CEIL_UE8M0
43 )
44
@@ -50,7 +50,7 @@ def is_deep_gemm_supported() -> bool:
50 """
51 is_supported_arch = current_platform.is_cuda() and (
52 current_platform.is_device_capability(90)
53 - or current_platform.is_device_capability(100)
53 + or current_platform.is_device_capability_family(100)
54 )
55 return envs.VLLM_USE_DEEP_GEMM and has_deep_gemm() and is_supported_arch
56
vllm/utils/flashinfer.py
+3 -1
@@ -264,7 +264,9 @@ def supports_trtllm_attention() -> bool:
264 return False
265
266 # Requires SM100 and NVIDIA artifactory to be accessible to download cubins
267 - return current_platform.is_device_capability(100) and has_nvidia_artifactory()
267 + return (
268 + current_platform.is_device_capability_family(100) and has_nvidia_artifactory()
269 + )
270
271
272 def force_use_trtllm_attention() -> bool | None:
vllm/v1/attention/backends/flashinfer.py
+1 -1
@@ -564,7 +564,7 @@ class FlashInferMetadataBuilder(AttentionMetadataBuilder[FlashInferMetadata]):
564 )
565 self.paged_kv_last_page_len_np = self.paged_kv_last_page_len_cpu.numpy()
566
567 - if self.head_dim == 256 and current_platform.is_device_capability(100):
567 + if self.head_dim == 256 and current_platform.is_device_capability_family(100):
568 # https://github.com/flashinfer-ai/flashinfer/issues/1993 reports that
569 # head size 256 and block size 16 is not supported on blackwell.
570 assert kv_cache_spec.block_size != 16, (
vllm/v1/attention/backends/mla/common.py
+3 -3
@@ -446,7 +446,7 @@ def use_flashinfer_prefill() -> bool:
446 and flashinfer_available
447 and not vllm_config.attention_config.use_cudnn_prefill
448 and not vllm_config.attention_config.use_trtllm_ragged_deepseek_prefill
449 - and current_platform.is_device_capability(100)
449 + and current_platform.is_device_capability_family(100)
450 )
451
452
@@ -457,7 +457,7 @@ def use_cudnn_prefill() -> bool:
457 return (
458 flashinfer_available
459 and vllm_config.attention_config.use_cudnn_prefill
460 - and current_platform.is_device_capability(100)
460 + and current_platform.is_device_capability_family(100)
461 and has_nvidia_artifactory()
462 )
463
@@ -470,7 +470,7 @@ def use_trtllm_ragged_deepseek_prefill() -> bool:
470 return (
471 flashinfer_available
472 and vllm_config.attention_config.use_trtllm_ragged_deepseek_prefill
473 - and current_platform.is_device_capability(100)
473 + and current_platform.is_device_capability_family(100)
474 )
475
476
vllm/v1/attention/backends/mla/flashmla_sparse.py
+2 -2
@@ -420,7 +420,7 @@ class FlashMLASparseMetadataBuilder(AttentionMetadataBuilder[FlashMLASparseMetad
420 max_num_sm_parts = int(
421 max((sm_count // 2) / h_k // (cdiv(h_q // h_k, 2 * 64) * s_q), 1)
422 )
423 - if current_platform.is_device_capability(100):
423 + if current_platform.is_device_capability_family(100):
424 max_num_sm_parts *= 2
425 self.tile_scheduler_metadata_buffer = torch.empty(
426 # TileSchedulerMetaDataSize = 8
@@ -719,7 +719,7 @@ class FlashMLASparseImpl(MLACommonBaseImpl[FlashMLASparseMetadata]):
719 self.softmax_scale = scale
720 assert indexer is not None
721 self.topk_indices_buffer = indexer.topk_indices_buffer
722 - self.padding = 128 if current_platform.is_device_capability(100) else 64
722 + self.padding = 128 if current_platform.is_device_capability_family(100) else 64
723
724 if kv_cache_dtype == "fp8_ds_mla":
725 # Reserve workspace during initialization