From 78e7293bb157498d23780891cc4ef365a31772b6 Mon Sep 17 00:00:00 2001 From: Shengqi Chen Date: Sun, 14 Jun 2026 13:09:20 +0800 Subject: [PATCH] [Build] Fix CUDA arch build coverage gaps (#45277) Signed-off-by: Shengqi Chen Co-authored-by: Xin Li Co-authored-by: ShawRong Co-authored-by: Change72 --- .buildkite/release-pipeline.yaml | 19 +- .github/workflows/scripts/build.sh | 7 +- CMakeLists.txt | 183 +++++++++--------- cmake/external_projects/qutlass.cmake | 34 ++-- cmake/utils.cmake | 4 +- csrc/libtorch_stable/cuda_vec_utils.cuh | 2 +- .../moe/dsv3_router_gemm_entry.cu | 3 +- .../quantization/fp4/mxfp4_experts_quant.cu | 75 +++++-- .../quantization/fp4/nvfp4_utils.cuh | 8 +- .../w8a8/cutlass/scaled_mm_entry.cu | 12 +- docker/Dockerfile | 8 +- docker/versions.json | 2 +- vllm/_custom_ops.py | 8 + .../layers/fused_moe/experts/cutlass_moe.py | 7 +- 14 files changed, 240 insertions(+), 132 deletions(-) diff --git a/.buildkite/release-pipeline.yaml b/.buildkite/release-pipeline.yaml index b31404bca15..897c9814534 100644 --- a/.buildkite/release-pipeline.yaml +++ b/.buildkite/release-pipeline.yaml @@ -1,12 +1,25 @@ # CUDA architecture lists — following PyTorch RELEASE.md # (https://github.com/pytorch/pytorch/blob/main/RELEASE.md) # SM86 included for broader Ampere coverage; SM89 for marlin fp8 support +# These requested arches are filtered by CMake's CUDA_SUPPORTED_ARCHS before +# per-kernel arch selection. Do not add +PTX here: top-level +PTX is stripped +# during that filtering, so kernels that need PTX must request it locally. env: - CUDA_ARCH_X86: "7.5 8.0 8.6 8.9 9.0 10.0 12.0+PTX" - # aarch64 only architectures: 8.7 for Orin, 11.0 for Thor (since CUDA 13) - CUDA_ARCH_AARCH64: "8.0 8.7 8.9 9.0 10.0 11.0 12.0+PTX" + # for CUDA >=13, sm_100+ targets have family specifiers (see CMakeLists.txt) + # so targets like 10.3 and 12.1 are automatically supported with this list + CUDA_ARCH_X86: "7.5 8.0 8.6 8.9 9.0 10.0 12.0" + # aarch64-only targets: Orin (8.7), Thor (11.0, CUDA 13+) + CUDA_ARCH_AARCH64: "8.0 8.7 8.9 9.0 10.0 11.0 12.0" + + # for CUDA <13, we need to specify all needed targets + # some targets (10.3, 12.1) are skipped to limit the wheel size (< 500MB) + # please use CUDA 13 wheels or compile yourself on these new devices CUDA_ARCH_X86_CU129: "7.5 8.0 8.6 8.9 9.0 10.0 12.0" CUDA_ARCH_AARCH64_CU129: "8.0 8.7 8.9 9.0 10.0 12.0" + + # pre-built mooncake wheels + # the manylinux_2_35 wheel has compatibility issue on Ubuntu 24.04 + # so we use different wheels for the time being MOONCAKE_WHEEL_AARCH64_2_35: "https://vllm-wheels.s3.amazonaws.com/mooncake/mooncake_transfer_engine-0.3.10.post2-0da9dfea3-cp312-cp312-manylinux_2_35_aarch64.whl" MOONCAKE_WHEEL_AARCH64_2_39: "https://vllm-wheels.s3.amazonaws.com/mooncake/mooncake_transfer_engine-0.3.10.post2-0da9dfea3-cp312-cp312-manylinux_2_39_aarch64.whl" MOONCAKE_WHEEL_X86_64: "https://vllm-wheels.s3.amazonaws.com/mooncake/mooncake_transfer_engine-0.3.10.post2-0da9dfea3-cp312-cp312-manylinux_2_35_x86_64.whl" diff --git a/.github/workflows/scripts/build.sh b/.github/workflows/scripts/build.sh index eb3971c42bf..335ec735e62 100644 --- a/.github/workflows/scripts/build.sh +++ b/.github/workflows/scripts/build.sh @@ -9,7 +9,7 @@ PATH=${cuda_home}/bin:$PATH LD_LIBRARY_PATH=${cuda_home}/lib64:$LD_LIBRARY_PATH # Install requirements -if [ "$(echo $2 | cut -d. -f1)" = "12" ]; then +if [ "$(echo "$2" | cut -d. -f1)" = "12" ]; then sed -i 's/^nvidia-cutlass-dsl\[cu13\]>=/nvidia-cutlass-dsl>=/' requirements/cuda.txt fi $python_executable -m pip install -r requirements/build/cuda.txt -r requirements/cuda.txt @@ -17,7 +17,10 @@ $python_executable -m pip install -r requirements/build/cuda.txt -r requirements # Limit the number of parallel jobs to avoid OOM export MAX_JOBS=1 # Make sure release wheels are built for the following architectures -export TORCH_CUDA_ARCH_LIST="7.5 8.0 8.6 8.9 9.0 10.0 12.0+PTX" +# Do not add +PTX here: vLLM filters torch's top-level PTX flag when it +# converts global gencode flags into per-kernel arch lists. If a specific +# kernel needs PTX, add +PTX to that kernel's CMake arch list instead. +export TORCH_CUDA_ARCH_LIST="7.5 8.0 8.6 8.9 9.0 10.0 12.0" bash tools/check_repo.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 49e75688ae2..8405958a419 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -190,6 +190,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA") # the set of architectures we want to compile for and remove the from the # CMAKE_CUDA_FLAGS so that they are not applied globally. # + # `+PTX` in TORCH_CUDA_ARCH_LIST is not preserved here. It is emitted by torch + # as `code=compute_*`, while extract_unique_cuda_archs_ascending() records only + # `arch=compute_*`. If a kernel really needs PTX, add `+PTX` to that kernel's + # component-specific arch list below. + # clear_cuda_arches(CUDA_ARCH_FLAGS) extract_unique_cuda_archs_ascending(CUDA_ARCHS "${CUDA_ARCH_FLAGS}") message(STATUS "CUDA target architectures: ${CUDA_ARCHS}") @@ -365,13 +370,13 @@ if(VLLM_GPU_LANG STREQUAL "CUDA") cuda_archs_loose_intersection(ES_MXFP8_GROUPED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND ES_MXFP8_GROUPED_MM_ARCHS) - set(SRCS + set(ES_MXFP8_GROUPED_MM_SRCS "csrc/libtorch_stable/moe/mxfp8_moe/cutlass_mxfp8_grouped_mm.cu" "csrc/libtorch_stable/moe/mxfp8_moe/mxfp8_experts_quant.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${ES_MXFP8_GROUPED_MM_SRCS}" CUDA_ARCHS "${ES_MXFP8_GROUPED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${ES_MXFP8_GROUPED_MM_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_ES_MXFP8_GROUPED_MM_SM100=1") message(STATUS "Building ES MXFP8 grouped kernels for archs: ${ES_MXFP8_GROUPED_MM_ARCHS}") else() @@ -676,16 +681,16 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # DeepSeek V3 fused A GEMM kernel (requires SM 9.0+, Hopper and later) if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(DSV3_FUSED_A_GEMM_ARCHS "9.0a;10.0f;11.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(DSV3_FUSED_A_GEMM_ARCHS "9.0a;10.0f;11.0f;12.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(DSV3_FUSED_A_GEMM_ARCHS "9.0a;10.0a;10.1a;10.3a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(DSV3_FUSED_A_GEMM_ARCHS "9.0a;10.0a;10.1a;10.3a;12.0a;12.1a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.0 AND DSV3_FUSED_A_GEMM_ARCHS) - set(SRCS "csrc/libtorch_stable/dsv3_fused_a_gemm.cu") + set(DSV3_FUSED_A_GEMM_SRCS "csrc/libtorch_stable/dsv3_fused_a_gemm.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${DSV3_FUSED_A_GEMM_SRCS}" CUDA_ARCHS "${DSV3_FUSED_A_GEMM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${DSV3_FUSED_A_GEMM_SRCS}") message(STATUS "Building dsv3_fused_a_gemm for archs: ${DSV3_FUSED_A_GEMM_ARCHS}") else() message(STATUS "Not building dsv3_fused_a_gemm as no compatible archs found " @@ -695,13 +700,13 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # FP32 router GEMM (H=3072, E=256, M<=32). Requires SM90+ and CUDA >= 12.0. cuda_archs_sm90plus(FP32_ROUTER_GEMM_ARCHS "${CUDA_ARCHS}") if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.0 AND FP32_ROUTER_GEMM_ARCHS) - set(SRCS + set(FP32_ROUTER_GEMM_SRCS "csrc/libtorch_stable/fp32_router_gemm_entry.cu" "csrc/libtorch_stable/fp32_router_gemm.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${FP32_ROUTER_GEMM_SRCS}" CUDA_ARCHS "${FP32_ROUTER_GEMM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${FP32_ROUTER_GEMM_SRCS}") message(STATUS "Building fp32_router_gemm for archs: ${FP32_ROUTER_GEMM_ARCHS}") else() message(STATUS "Not building fp32_router_gemm as no compatible archs found " @@ -711,13 +716,13 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # Only build AllSpark kernels if we are building for at least some compatible archs. cuda_archs_loose_intersection(ALLSPARK_ARCHS "8.0;8.6;8.7;8.9" "${CUDA_ARCHS}") if (ALLSPARK_ARCHS) - set(SRCS + set(ALLSPARK_SRCS "csrc/libtorch_stable/quantization/gptq_allspark/allspark_repack.cu" "csrc/libtorch_stable/quantization/gptq_allspark/allspark_qgemm_w8a16.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${ALLSPARK_SRCS}" CUDA_ARCHS "${ALLSPARK_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${ALLSPARK_SRCS}") message(STATUS "Building AllSpark kernels for archs: ${ALLSPARK_ARCHS}") else() message(STATUS "Not building AllSpark kernels as no compatible archs found" @@ -732,16 +737,16 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # CUDA 12.0 or later cuda_archs_loose_intersection(SCALED_MM_ARCHS "9.0a;" "${CUDA_ARCHS}") if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.0 AND SCALED_MM_ARCHS) - set(SRCS + set(SCALED_MM_SM90_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c3x_sm90.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_sm90_fp8.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_sm90_int8.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_azp_sm90_int8.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_blockwise_sm90_fp8.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${SCALED_MM_SM90_SRCS}" CUDA_ARCHS "${SCALED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SCALED_MM_SM90_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_SCALED_MM_SM90=1") # Let scaled_mm_c2x know it doesn't need to build these arches list(APPEND SCALED_MM_3X_ARCHS "${SCALED_MM_ARCHS}") @@ -767,15 +772,15 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") cuda_archs_loose_intersection(SCALED_MM_ARCHS "12.0a;12.1a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND SCALED_MM_ARCHS) - set(SRCS + set(SCALED_MM_SM120_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c3x_sm120.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_sm120_fp8.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_blockwise_sm120_fp8.cu" ) set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${SCALED_MM_SM120_SRCS}" CUDA_ARCHS "${SCALED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SCALED_MM_SM120_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_SCALED_MM_SM120=1") # Let scaled_mm_c2x know it doesn't need to build these arches list(APPEND SCALED_MM_3X_ARCHS "${SCALED_MM_ARCHS}") @@ -801,15 +806,15 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") cuda_archs_loose_intersection(SCALED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND SCALED_MM_ARCHS) - set(SRCS + set(SCALED_MM_SM100_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c3x_sm100.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_sm100_fp8.cu" "csrc/libtorch_stable/quantization/w8a8/cutlass/c3x/scaled_mm_blockwise_sm100_fp8.cu" ) set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${SCALED_MM_SM100_SRCS}" CUDA_ARCHS "${SCALED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SCALED_MM_SM100_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_SCALED_MM_SM100=1") # Let scaled_mm_c2x know it doesn't need to build these arches list(APPEND SCALED_MM_3X_ARCHS "${SCALED_MM_ARCHS}") @@ -835,11 +840,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # subtract out the archs that are already built for 3x list(REMOVE_ITEM SCALED_MM_2X_ARCHS ${SCALED_MM_3X_ARCHS}) if (SCALED_MM_2X_ARCHS) - set(SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cu") + set(SCALED_MM_C2X_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_c2x.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${SCALED_MM_C2X_SRCS}" CUDA_ARCHS "${SCALED_MM_2X_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${SCALED_MM_C2X_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_SCALED_MM_C2X=1") message(STATUS "Building scaled_mm_c2x for archs: ${SCALED_MM_2X_ARCHS}") else() @@ -861,11 +866,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # if it's possible to compile MoE kernels that use its output. cuda_archs_loose_intersection(SCALED_MM_ARCHS "9.0a" "${CUDA_ARCHS}") if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.3 AND SCALED_MM_ARCHS) - set(SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/grouped_mm_c3x_sm90.cu") + set(CUTLASS_MOE_SM90_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/grouped_mm_c3x_sm90.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${CUTLASS_MOE_SM90_SRCS}" CUDA_ARCHS "${SCALED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${CUTLASS_MOE_SM90_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM90=1") message(STATUS "Building grouped_mm_c3x for archs: ${SCALED_MM_ARCHS}") else() @@ -880,16 +885,16 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(SCALED_MM_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(SCALED_MM_ARCHS "10.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(SCALED_MM_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(SCALED_MM_ARCHS "10.0a;10.3a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND SCALED_MM_ARCHS) - set(SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/grouped_mm_c3x_sm100.cu") + set(CUTLASS_MOE_SM100_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/grouped_mm_c3x_sm100.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${CUTLASS_MOE_SM100_SRCS}" CUDA_ARCHS "${SCALED_MM_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${CUTLASS_MOE_SM100_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM100=1") message(STATUS "Building grouped_mm_c3x for archs: ${SCALED_MM_ARCHS}") else() @@ -910,11 +915,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") cuda_archs_loose_intersection(CUTLASS_MOE_DATA_ARCHS "9.0a;10.0a;10.1a;10.3a;12.0a;12.1a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.3 AND CUTLASS_MOE_DATA_ARCHS) - set(SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/moe_data.cu") + set(CUTLASS_MOE_DATA_SRCS "csrc/libtorch_stable/quantization/w8a8/cutlass/moe/moe_data.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${CUTLASS_MOE_DATA_SRCS}" CUDA_ARCHS "${CUTLASS_MOE_DATA_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${CUTLASS_MOE_DATA_SRCS}") message(STATUS "Building moe_data for archs: ${CUTLASS_MOE_DATA_ARCHS}") else() if (NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.3 AND CUTLASS_MOE_DATA_ARCHS) @@ -931,71 +936,66 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # FP4/NVFP4 kernels (moved from _C to _C_stable_libtorch) # - # The nvfp4_scaled_mm_sm120 kernels for Blackwell SM12x require - # CUDA 12.8 or later + # SM12x FP4 kernels. These share some generic NVFP4 quantization entry + # sources with the SM10x/11x block below; set_gencode_flags_for_srcs appends + # per-source flags, so shared files accumulate both SM12x and SM10x/11x + # gencodes when both families are requested. if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(FP4_ARCHS "12.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(FP4_SM120_ARCHS "12.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(FP4_ARCHS "12.0a;12.1a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(FP4_SM120_ARCHS "12.0a;12.1a" "${CUDA_ARCHS}") endif() - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND FP4_ARCHS) - set(SRCS + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND FP4_SM120_ARCHS) + set(FP4_SM120_SRCS "csrc/libtorch_stable/quantization/fp4/nvfp4_quant_kernels.cu" "csrc/libtorch_stable/quantization/fp4/activation_nvfp4_quant_fusion_kernels.cu" "csrc/libtorch_stable/quantization/fp4/nvfp4_experts_quant.cu" "csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_sm120_kernels.cu" - "csrc/libtorch_stable/quantization/fp4/nvfp4_blockwise_moe_kernel.cu") + "csrc/libtorch_stable/quantization/fp4/nvfp4_blockwise_moe_kernel.cu" + "csrc/libtorch_stable/nvfp4_kv_cache_kernels.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" - CUDA_ARCHS "${FP4_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") - set(NVFP4_KV_SRC "csrc/libtorch_stable/nvfp4_kv_cache_kernels.cu") - set_gencode_flags_for_srcs( - SRCS "${NVFP4_KV_SRC}" - CUDA_ARCHS "${FP4_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${NVFP4_KV_SRC}") + SRCS "${FP4_SM120_SRCS}" + CUDA_ARCHS "${FP4_SM120_ARCHS}") + list(APPEND VLLM_STABLE_EXT_SRC "${FP4_SM120_SRCS}") target_compile_definitions(_C PRIVATE ENABLE_NVFP4_SM120=1) list(APPEND VLLM_GPU_FLAGS "-DENABLE_NVFP4_SM120=1") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM120=1") - message(STATUS "Building NVFP4 for archs: ${FP4_ARCHS}") + message(STATUS "Building SM12x NVFP4 for archs: ${FP4_SM120_ARCHS}") else() - message(STATUS "Not building NVFP4 as no compatible archs were found.") - # clear FP4_ARCHS - set(FP4_ARCHS) + message(STATUS "Not building SM12x NVFP4 as no compatible archs were found.") endif() - # FP4 Archs and flags + # SM10x/11x FP4 kernels. MXFP4 experts quantization is currently compiled + # only in this block; SM12x has separate NVFP4 matmul/MoE kernels above. if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(FP4_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(FP4_SM100_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(FP4_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(FP4_SM100_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") endif() - if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND FP4_ARCHS) - set(SRCS + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND FP4_SM100_ARCHS) + set(FP4_SM100_SRCS "csrc/libtorch_stable/quantization/fp4/nvfp4_quant_kernels.cu" "csrc/libtorch_stable/quantization/fp4/activation_nvfp4_quant_fusion_kernels.cu" "csrc/libtorch_stable/quantization/fp4/nvfp4_experts_quant.cu" "csrc/libtorch_stable/quantization/fp4/nvfp4_scaled_mm_kernels.cu" "csrc/libtorch_stable/quantization/fp4/nvfp4_blockwise_moe_kernel.cu" "csrc/libtorch_stable/quantization/fp4/mxfp4_experts_quant.cu" - "csrc/libtorch_stable/quantization/fp4/mxfp4_blockwise_moe_kernel.cu") + "csrc/libtorch_stable/quantization/fp4/mxfp4_blockwise_moe_kernel.cu" + "csrc/libtorch_stable/nvfp4_kv_cache_kernels.cu") + if(NOT ${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.9) + message(STATUS + "Building mxfp4_experts_quant unsupported stubs because CUDA compiler version is not >= 12.9 (found ${CMAKE_CUDA_COMPILER_VERSION}).") + endif() set_gencode_flags_for_srcs( - SRCS "${SRCS}" - CUDA_ARCHS "${FP4_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") - set(NVFP4_KV_SRC "csrc/libtorch_stable/nvfp4_kv_cache_kernels.cu") - set_gencode_flags_for_srcs( - SRCS "${NVFP4_KV_SRC}" - CUDA_ARCHS "${FP4_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${NVFP4_KV_SRC}") + SRCS "${FP4_SM100_SRCS}" + CUDA_ARCHS "${FP4_SM100_ARCHS}") + list(APPEND VLLM_STABLE_EXT_SRC "${FP4_SM100_SRCS}") target_compile_definitions(_C PRIVATE ENABLE_NVFP4_SM100=1) list(APPEND VLLM_GPU_FLAGS "-DENABLE_NVFP4_SM100=1") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MOE_SM100=1") - message(STATUS "Building NVFP4 for archs: ${FP4_ARCHS}") + message(STATUS "Building SM10x/11x NVFP4/MXFP4 for archs: ${FP4_SM100_ARCHS}") else() - message(STATUS "Not building NVFP4 as no compatible archs were found.") - # clear FP4_ARCHS - set(FP4_ARCHS) + message(STATUS "Not building SM10x/11x NVFP4/MXFP4 as no compatible archs were found.") endif() # @@ -1005,17 +1005,17 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # Only build W4A8 kernels if we are building for something compatible with sm90a cuda_archs_loose_intersection(W4A8_ARCHS "9.0a" "${CUDA_ARCHS}") if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.0 AND W4A8_ARCHS) - set(SRCS + set(W4A8_SRCS "csrc/libtorch_stable/quantization/cutlass_w4a8/w4a8_mm_entry.cu" "csrc/libtorch_stable/quantization/cutlass_w4a8/w4a8_grouped_mm_entry.cu" "csrc/libtorch_stable/quantization/cutlass_w4a8/w4a8_utils.cu" ) set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${W4A8_SRCS}" CUDA_ARCHS "${W4A8_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${W4A8_SRCS}") message(STATUS "Building W4A8 kernels for archs: ${W4A8_ARCHS}") else() @@ -1031,22 +1031,24 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") endif() endif() - # CUTLASS MLA Archs and flags + # CUTLASS MLA Archs and flags. + # Runtime dispatch is gated in + # vllm/v1/attention/backends/mla/cutlass_mla.py. if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(MLA_ARCHS "10.0f;11.0f;12.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(MLA_ARCHS "10.0f;11.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(MLA_ARCHS "10.0a;10.1a;10.3a;12.0a;12.1a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(MLA_ARCHS "10.0a;10.1a;10.3a" "${CUDA_ARCHS}") endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND MLA_ARCHS) - set(SRCS + set(CUTLASS_MLA_SRCS "csrc/libtorch_stable/attention/mla/sm100_cutlass_mla_kernel.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${CUTLASS_MLA_SRCS}" CUDA_ARCHS "${MLA_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${CUTLASS_MLA_SRCS}") list(APPEND VLLM_GPU_FLAGS "-DENABLE_CUTLASS_MLA=1") # Add MLA-specific include directories only to MLA source files - set_source_files_properties(${SRCS} + set_source_files_properties(${CUTLASS_MLA_SRCS} PROPERTIES INCLUDE_DIRECTORIES "${CUTLASS_DIR}/examples/77_blackwell_fmha;${CUTLASS_DIR}/examples/common") message(STATUS "Building CUTLASS MLA for archs: ${MLA_ARCHS}") else() @@ -1058,11 +1060,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") # Hadacore kernels cuda_archs_loose_intersection(HADACORE_ARCHS "8.0+PTX;9.0+PTX" "${CUDA_ARCHS}") if(HADACORE_ARCHS) - set(SRCS "csrc/libtorch_stable/quantization/hadamard/hadacore/hadamard_transform_cuda.cu") + set(HADACORE_SRCS "csrc/libtorch_stable/quantization/hadamard/hadacore/hadamard_transform_cuda.cu") set_gencode_flags_for_srcs( - SRCS "${SRCS}" + SRCS "${HADACORE_SRCS}" CUDA_ARCHS "${HADACORE_ARCHS}") - list(APPEND VLLM_STABLE_EXT_SRC "${SRCS}") + list(APPEND VLLM_STABLE_EXT_SRC "${HADACORE_SRCS}") message(STATUS "Building hadacore") endif() @@ -1070,6 +1072,7 @@ if(VLLM_GPU_LANG STREQUAL "CUDA" OR VLLM_GPU_LANG STREQUAL "HIP") endif() message(STATUS "Enabling C_stable extension.") + list(REMOVE_DUPLICATES VLLM_STABLE_EXT_SRC) define_extension_target( _C_stable_libtorch DESTINATION vllm @@ -1174,7 +1177,11 @@ if(VLLM_GPU_LANG STREQUAL "CUDA") # - sm80 doesn't support fp8 computation # - sm90 and sm100 don't support QMMA.16832.F32.E4M3.E4M3 SAAS instruction # so we only enable fp8 computation for SM89 (e.g. RTX 40x0) and 12.0 (e.g. RTX 50x0) - cuda_archs_loose_intersection(MARLIN_MOE_FP8_ARCHS "8.9;12.0;12.1" "${CUDA_ARCHS}") + if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) + cuda_archs_loose_intersection(MARLIN_MOE_FP8_ARCHS "8.9;12.0f" "${CUDA_ARCHS}") + else() + cuda_archs_loose_intersection(MARLIN_MOE_FP8_ARCHS "8.9;12.0a;12.1a" "${CUDA_ARCHS}") + endif() # moe marlin arches for other files cuda_archs_loose_intersection(MARLIN_MOE_OTHER_ARCHS "7.5;8.0+PTX" "${CUDA_ARCHS}") if (MARLIN_MOE_OTHER_ARCHS) diff --git a/cmake/external_projects/qutlass.cmake b/cmake/external_projects/qutlass.cmake index 273fe754bed..66c001919b0 100644 --- a/cmake/external_projects/qutlass.cmake +++ b/cmake/external_projects/qutlass.cmake @@ -32,21 +32,33 @@ endif() message(STATUS "[QUTLASS] QuTLASS is available at ${qutlass_SOURCE_DIR}") if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(QUTLASS_ARCHS "10.0f;12.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(QUTLASS_SM120_ARCHS "12.0f" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(QUTLASS_SM100_ARCHS "10.0f" "${CUDA_ARCHS}") else() - cuda_archs_loose_intersection(QUTLASS_ARCHS "12.0a;12.1a;10.0a;10.3a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(QUTLASS_SM120_ARCHS "12.0a;12.1a" "${CUDA_ARCHS}") + cuda_archs_loose_intersection(QUTLASS_SM100_ARCHS "10.0a;10.3a" "${CUDA_ARCHS}") +endif() + +# QUTLASS uses TARGET_CUDA_ARCH as a single preprocessor selector for all its +# sources. Do not compile a mixed SM100/SM120 arch list with one selector; prefer +# SM100 when both families are requested because that is the primary deployed +# target for this extension today. +if(QUTLASS_SM100_ARCHS) + set(QUTLASS_ARCHS "${QUTLASS_SM100_ARCHS}") + set(QUTLASS_TARGET_CC 100) + if(QUTLASS_SM120_ARCHS) + message(WARNING + "[QUTLASS] Both SM100 and SM120 archs were requested; selecting SM100 " + "because TARGET_CUDA_ARCH is a single compile-time selector.") + endif() +elseif(QUTLASS_SM120_ARCHS) + set(QUTLASS_ARCHS "${QUTLASS_SM120_ARCHS}") + set(QUTLASS_TARGET_CC 120) +else() + set(QUTLASS_ARCHS) endif() if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 12.8 AND QUTLASS_ARCHS) - - if(QUTLASS_ARCHS MATCHES "10\\.(0a|3a|0f)") - set(QUTLASS_TARGET_CC 100) - elseif(QUTLASS_ARCHS MATCHES "12\\.[01][af]?") - set(QUTLASS_TARGET_CC 120) - else() - message(FATAL_ERROR "[QUTLASS] internal error parsing CUDA_ARCHS='${QUTLASS_ARCHS}'.") - endif() - set(QUTLASS_SOURCES ${qutlass_SOURCE_DIR}/qutlass/csrc/bindings.cpp ${qutlass_SOURCE_DIR}/qutlass/csrc/gemm.cu diff --git a/cmake/utils.cmake b/cmake/utils.cmake index dd2034c1c5e..e3e766541df 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -487,9 +487,9 @@ endfunction() function(cuda_archs_sm90plus OUT_CUDA_ARCHS TGT_CUDA_ARCHS) if(${CMAKE_CUDA_COMPILER_VERSION} VERSION_GREATER_EQUAL 13.0) - cuda_archs_loose_intersection(_archs "9.0a;10.0f;11.0f" "${TGT_CUDA_ARCHS}") + cuda_archs_loose_intersection(_archs "9.0a;10.0f;11.0f;12.0f" "${TGT_CUDA_ARCHS}") else() - cuda_archs_loose_intersection(_archs "9.0a;10.0a;10.1a;10.3a" "${TGT_CUDA_ARCHS}") + cuda_archs_loose_intersection(_archs "9.0a;10.0a;10.1a;10.3a;12.0a;12.1a" "${TGT_CUDA_ARCHS}") endif() set(${OUT_CUDA_ARCHS} ${_archs} PARENT_SCOPE) endfunction() diff --git a/csrc/libtorch_stable/cuda_vec_utils.cuh b/csrc/libtorch_stable/cuda_vec_utils.cuh index efbb09994d2..ec6e60724e6 100644 --- a/csrc/libtorch_stable/cuda_vec_utils.cuh +++ b/csrc/libtorch_stable/cuda_vec_utils.cuh @@ -21,7 +21,7 @@ // together enable 256-bit (v8.u32) PTX load/store instructions. // Use for PTX instruction selection with architecture fallback paths. #if !defined(USE_ROCM) && defined(__CUDA_ARCH__) && __CUDA_ARCH__ >= 1000 && \ - defined(CUDA_VERSION) && CUDA_VERSION >= 12090 + defined(CUDART_VERSION) && CUDART_VERSION >= 12090 #define VLLM_256B_PTX_ENABLED 1 #else #define VLLM_256B_PTX_ENABLED 0 diff --git a/csrc/libtorch_stable/moe/dsv3_router_gemm_entry.cu b/csrc/libtorch_stable/moe/dsv3_router_gemm_entry.cu index 1de1a319e48..53a64fa8c13 100644 --- a/csrc/libtorch_stable/moe/dsv3_router_gemm_entry.cu +++ b/csrc/libtorch_stable/moe/dsv3_router_gemm_entry.cu @@ -144,8 +144,7 @@ void dsv3_router_gemm( "output must be float32 or bf16"); const int sm = getSMVersion(); - STD_TORCH_CHECK(sm >= 90 && sm <= 103, - "required SM_103 >= CUDA ARCH >= SM_90"); + STD_TORCH_CHECK(sm >= 90, "required CUDA ARCH >= SM_90"); const cudaStream_t stream = get_current_cuda_stream(mat_a.get_device_index()); diff --git a/csrc/libtorch_stable/quantization/fp4/mxfp4_experts_quant.cu b/csrc/libtorch_stable/quantization/fp4/mxfp4_experts_quant.cu index 062f6018653..20f024bcef5 100644 --- a/csrc/libtorch_stable/quantization/fp4/mxfp4_experts_quant.cu +++ b/csrc/libtorch_stable/quantization/fp4/mxfp4_experts_quant.cu @@ -27,15 +27,24 @@ #include #include "libtorch_stable/torch_utils.h" #include "libtorch_stable/dispatch_utils.h" +#include "libtorch_stable/cutlass_extensions/common.hpp" #include "../../cuda_vec_utils.cuh" #include "cuda_utils.h" #include "nvfp4_utils.cuh" + +#if defined(CUDART_VERSION) && CUDART_VERSION >= 12090 + #define VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED 1 static_assert(CVT_FP4_ELTS_PER_THREAD == 16, "MXFP4 experts quant requires PACK16 mode (CUDA >= 12.9)"); +#else + #define VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED 0 +#endif #include "libtorch_stable/launch_bounds_utils.h" +#if VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED + namespace vllm { // MXFP4 block size constants @@ -104,7 +113,7 @@ __global__ void __launch_bounds__(512, VLLM_BLOCKS_PER_SM(512)) &input_offset_by_experts[chunk_start + 12])); local_offsets[16] = __ldca(&input_offset_by_experts[chunk_start + 16]); -#pragma unroll + #pragma unroll for (int i = 0; i < 16; i++) { if (rowIdx >= local_offsets[i] && rowIdx < local_offsets[i + 1]) { rowIdx_in_expert = rowIdx - local_offsets[i]; @@ -309,14 +318,14 @@ void mxfp4_quant_impl(void* output, void* output_scale, void* input, } // namespace vllm -/*Quantization entry for mxfp4 experts quantization*/ -#define CHECK_TH_CUDA(x, m) \ - STD_TORCH_CHECK(x.is_cuda(), m, "must be a CUDA tensor") -#define CHECK_CONTIGUOUS(x, m) \ - STD_TORCH_CHECK(x.is_contiguous(), m, "must be contiguous") -#define CHECK_INPUT(x, m) \ - CHECK_TH_CUDA(x, m); \ - CHECK_CONTIGUOUS(x, m); + /*Quantization entry for mxfp4 experts quantization*/ + #define CHECK_TH_CUDA(x, m) \ + STD_TORCH_CHECK(x.is_cuda(), m, "must be a CUDA tensor") + #define CHECK_CONTIGUOUS(x, m) \ + STD_TORCH_CHECK(x.is_contiguous(), m, "must be contiguous") + #define CHECK_INPUT(x, m) \ + CHECK_TH_CUDA(x, m); \ + CHECK_CONTIGUOUS(x, m); constexpr auto HALF = torch::headeronly::ScalarType::Half; constexpr auto BF16 = torch::headeronly::ScalarType::BFloat16; @@ -364,12 +373,28 @@ static void validate_mxfp4_experts_quant_inputs( STD_TORCH_CHECK(output_scale.size(1) * 4 == padded_k); } +#endif // VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED + +static bool mxfp4_experts_quant_sm_supported(int64_t cuda_device_capability) { +#if VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED + return cuda_device_capability >= 100 && cuda_device_capability < 120; +#else + return false; +#endif +} + void mxfp4_experts_quant( torch::stable::Tensor& output, torch::stable::Tensor& output_scale, torch::stable::Tensor const& input, torch::stable::Tensor const& input_offset_by_experts, torch::stable::Tensor const& output_scale_offset_by_experts, int64_t n_experts) { +#if VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED + int32_t sm = get_sm_version_num(); + STD_TORCH_CHECK(mxfp4_experts_quant_sm_supported(sm), + "No compiled MXFP4 experts quant kernel for SM ", sm, + ". Recompile with SM10x/11x FP4 support and CUDA >= 12.9."); + auto m_topk = input.size(0); auto k = input.size(1); @@ -390,6 +415,10 @@ void mxfp4_experts_quant( output_scale_offset_by_experts.data_ptr(), m_topk, k, n_experts, stream); }); +#else + STD_TORCH_CHECK_NOT_IMPLEMENTED(false, + "MXFP4 experts quant requires CUDA >= 12.9."); +#endif } void silu_and_mul_mxfp4_experts_quant( @@ -398,6 +427,12 @@ void silu_and_mul_mxfp4_experts_quant( torch::stable::Tensor const& input_offset_by_experts, torch::stable::Tensor const& output_scale_offset_by_experts, int64_t n_experts) { +#if VLLM_MXFP4_EXPERTS_QUANT_SUPPORTED + int32_t sm = get_sm_version_num(); + STD_TORCH_CHECK(mxfp4_experts_quant_sm_supported(sm), + "No compiled SiLU+Mul MXFP4 experts quant kernel for SM ", sm, + ". Recompile with SM10x/11x FP4 support and CUDA >= 12.9."); + auto m_topk = input.size(0); auto k_times_2 = input.size(1); STD_TORCH_CHECK(k_times_2 % 2 == 0, "input width must be even (gate || up)"); @@ -420,13 +455,29 @@ void silu_and_mul_mxfp4_experts_quant( output_scale_offset_by_experts.data_ptr(), m_topk, k, n_experts, stream); }); +#else + STD_TORCH_CHECK_NOT_IMPLEMENTED( + false, "SiLU+Mul MXFP4 experts quant requires CUDA >= 12.9."); +#endif } -// Registered here (not torch_bindings.cpp) because VLLM_GPU_FLAGS is applied -// only under COMPILE_LANGUAGE:CUDA, so ENABLE_NVFP4_SM100 is invisible to -// .cpp files and cannot gate the registration from there. +bool mxfp4_experts_quant_supported(int64_t cuda_device_capability) { + return mxfp4_experts_quant_sm_supported(cuda_device_capability); +} + +STABLE_TORCH_LIBRARY_FRAGMENT(_C, m) { + m.def("mxfp4_experts_quant_supported(int cuda_device_capability) -> bool"); +} + +// Registered here so the CUDA 12.8 stub and CUDA 12.9+ implementation stay +// tied to the same translation unit. STABLE_TORCH_LIBRARY_IMPL(_C, CUDA, m) { m.impl("mxfp4_experts_quant", TORCH_BOX(&mxfp4_experts_quant)); m.impl("silu_and_mul_mxfp4_experts_quant", TORCH_BOX(&silu_and_mul_mxfp4_experts_quant)); } + +STABLE_TORCH_LIBRARY_IMPL(_C, CompositeExplicitAutograd, m) { + m.impl("mxfp4_experts_quant_supported", + TORCH_BOX(&mxfp4_experts_quant_supported)); +} diff --git a/csrc/libtorch_stable/quantization/fp4/nvfp4_utils.cuh b/csrc/libtorch_stable/quantization/fp4/nvfp4_utils.cuh index 0c04f010888..dd4b061b0bc 100644 --- a/csrc/libtorch_stable/quantization/fp4/nvfp4_utils.cuh +++ b/csrc/libtorch_stable/quantization/fp4/nvfp4_utils.cuh @@ -22,15 +22,15 @@ #include "../../cuda_vec_utils.cuh" -#if defined(NVFP4_ENABLE_ELTS16) && defined(CUDA_VERSION) && \ - CUDA_VERSION >= 12090 +#if defined(NVFP4_ENABLE_ELTS16) && defined(CUDART_VERSION) && \ + CUDART_VERSION >= 12090 #define ELTS_PER_THREAD 16 + #define CVT_FP4_PACK16 1 constexpr int CVT_FP4_ELTS_PER_THREAD = 16; -constexpr bool CVT_FP4_PACK16 = true; #else #define ELTS_PER_THREAD 8 + #define CVT_FP4_PACK16 0 constexpr int CVT_FP4_ELTS_PER_THREAD = 8; -constexpr bool CVT_FP4_PACK16 = false; #endif constexpr int CVT_FP4_SF_VEC_SIZE = 16; diff --git a/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_entry.cu b/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_entry.cu index 0f9873cbf88..8bdb4f56795 100644 --- a/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_entry.cu +++ b/csrc/libtorch_stable/quantization/w8a8/cutlass/scaled_mm_entry.cu @@ -1,3 +1,4 @@ +#include #include #include @@ -174,15 +175,20 @@ bool cutlass_scaled_mm_supports_block_fp8(int64_t cuda_device_capability) { bool cutlass_group_gemm_supported(int64_t cuda_device_capability) { // CUTLASS grouped FP8 kernels need at least CUDA 12.3 and SM90 (Hopper) - // or CUDA 12.8 and SM100 (Blackwell) + // or CUDA 12.8 and SM100 (Blackwell). Only report archs that have an + // actual cutlass_moe_mm dispatch compiled into this file. #if defined CUDA_VERSION - if (cuda_device_capability >= 100) { + #if defined ENABLE_CUTLASS_MOE_SM100 && ENABLE_CUTLASS_MOE_SM100 + if (cuda_device_capability >= 100 && cuda_device_capability < 110) { return CUDA_VERSION >= 12080; } - if (cuda_device_capability >= 90) { + #endif + #if defined ENABLE_CUTLASS_MOE_SM90 && ENABLE_CUTLASS_MOE_SM90 + if (cuda_device_capability >= 90 && cuda_device_capability < 100) { return CUDA_VERSION >= 12030; } + #endif #endif return false; diff --git a/docker/Dockerfile b/docker/Dockerfile index 7a3cc71d339..d7823f32115 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -261,7 +261,10 @@ RUN --mount=type=cache,target=/opt/uv/cache \ # Explicitly set the list to avoid issues with torch 2.2 # See https://github.com/pytorch/pytorch/pull/123243 # From versions.json: .torch.cuda_arch_list -ARG torch_cuda_arch_list='7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0+PTX' +# Do not add +PTX here: vLLM filters torch's top-level PTX flag when it +# converts global gencode flags into per-kernel arch lists. If a specific +# kernel needs PTX, add +PTX to that kernel's CMake arch list instead. +ARG torch_cuda_arch_list='7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0' ENV TORCH_CUDA_ARCH_LIST=${torch_cuda_arch_list} #################### BUILD BASE IMAGE #################### @@ -1010,7 +1013,8 @@ ARG PIP_EXTRA_INDEX_URL UV_EXTRA_INDEX_URL ENV UV_HTTP_TIMEOUT=500 # install kv_connectors if requested -ARG torch_cuda_arch_list='7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0+PTX' +# Do not add +PTX here; see the main TORCH_CUDA_ARCH_LIST comment above. +ARG torch_cuda_arch_list='7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0' ENV TORCH_CUDA_ARCH_LIST=${torch_cuda_arch_list} RUN --mount=type=cache,target=/opt/uv/cache \ --mount=type=bind,source=requirements/kv_connectors.txt,target=/tmp/kv_connectors.txt,ro \ diff --git a/docker/versions.json b/docker/versions.json index 15f77648a9c..3145cfcc53e 100644 --- a/docker/versions.json +++ b/docker/versions.json @@ -35,7 +35,7 @@ "default": "false" }, "TORCH_CUDA_ARCH_LIST": { - "default": "7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0+PTX" + "default": "7.5 8.0 8.6 8.9 9.0 10.0 11.0 12.0" }, "MAX_JOBS": { "default": "2" diff --git a/vllm/_custom_ops.py b/vllm/_custom_ops.py index e3e8677f2ca..38fcca66dc0 100644 --- a/vllm/_custom_ops.py +++ b/vllm/_custom_ops.py @@ -773,6 +773,14 @@ def cutlass_scaled_mm_supports_fp4(cuda_device_capability: int) -> bool: return torch.ops._C.cutlass_scaled_mm_supports_fp4(cuda_device_capability) +def mxfp4_experts_quant_supported(cuda_device_capability: int) -> bool: + try: + return torch.ops._C.mxfp4_experts_quant_supported(cuda_device_capability) + except AttributeError: + # Return False on builds where the CUDA helper is not available. + return False + + def cutlass_scaled_fp4_mm( a: torch.Tensor, b: torch.Tensor, diff --git a/vllm/model_executor/layers/fused_moe/experts/cutlass_moe.py b/vllm/model_executor/layers/fused_moe/experts/cutlass_moe.py index fa91804f35c..68b3249163e 100644 --- a/vllm/model_executor/layers/fused_moe/experts/cutlass_moe.py +++ b/vllm/model_executor/layers/fused_moe/experts/cutlass_moe.py @@ -997,7 +997,12 @@ class CutlassExpertsMxfp4(mk.FusedMoEExpertsModular): @staticmethod def _supports_current_device() -> bool: p = current_platform - return p.is_cuda() and p.is_device_capability_family(100) + capability = p.get_device_capability() + return ( + p.is_cuda() + and capability is not None + and ops.mxfp4_experts_quant_supported(capability.to_int()) + ) @staticmethod def _supports_no_act_and_mul() -> bool: