[CI/Build][Docker] Bump nvidia-cutlass-dsl to 4.6.0 and drop packaging workarounds (#47442)

Signed-off-by: Artem Perevedentsev <aperevedents@nvidia.com> Signed-off-by: Matthew Bonanni <mbonanni@redhat.com> Co-authored-by: Matthew Bonanni <mbonanni@redhat.com>

Artem Perevedentsev committed Jul 16, 2026 at 16:51 UTC 7cd1d57b749fc9a0e5bad1bf8874992ed443e54b
7 files changed +8 -120
cmake/external_projects/vllm_flash_attn.cmake
+1 -1
@@ -39,7 +39,7 @@ else()
39 FetchContent_Declare(
40 vllm-flash-attn
41 GIT_REPOSITORY https://github.com/vllm-project/flash-attention.git
42 - GIT_TAG bb9a72e7dde0dc614ffc663e052cd6a19ce73a42
42 + GIT_TAG caaa4eb59845388a20b1f435ecaafb4bd9517ad8
43 GIT_PROGRESS TRUE
44 # Don't share the vllm-flash-attn build between build types
45 BINARY_DIR ${CMAKE_BINARY_DIR}/vllm-flash-attn
docker/Dockerfile
-35
@@ -248,10 +248,6 @@ COPY requirements/common.txt requirements/common.txt
248 COPY requirements/cuda.txt requirements/cuda.txt
249 COPY use_existing_torch.py use_existing_torch.py
250 COPY pyproject.toml pyproject.toml
251 -# nvidia-cutlass-dsl[cu13] installs -libs-base and -libs-cu13 wheels that
252 -# share paths with different content. uv can extract them in either order,
253 -# leaving base files that break CUDA 13 CuTe DSL JIT.
254 -# TODO(mmangkad): Remove this after NVIDIA/cutlass#3259 is fixed.
251 RUN --mount=type=cache,target=/opt/uv/cache \
252 if [ "$(echo $CUDA_VERSION | cut -d. -f1)" = "12" ]; then \
253 sed -i 's/^nvidia-cutlass-dsl\[cu13\]/nvidia-cutlass-dsl/' requirements/cuda.txt; \
@@ -268,13 +264,6 @@ RUN --mount=type=cache,target=/opt/uv/cache \
264 else \
265 uv pip install --python /opt/venv/bin/python3 -r requirements/cuda.txt \
266 --extra-index-url ${PYTORCH_CUDA_INDEX_BASE_URL}/cu$(echo $CUDA_VERSION | cut -d. -f1,2 | tr -d '.'); \
271 - fi \
272 - && if [ "$(echo $CUDA_VERSION | cut -d. -f1)" = "13" ]; then \
273 - CUTLASS_DSL_VERSION=$(uv pip show --python /opt/venv/bin/python3 nvidia-cutlass-dsl 2>/dev/null | awk '/^Version:/{print $2}') && \
274 - if [ -n "$CUTLASS_DSL_VERSION" ]; then \
275 - uv pip install --python /opt/venv/bin/python3 --force-reinstall --no-deps \
276 - "nvidia-cutlass-dsl-libs-cu13==${CUTLASS_DSL_VERSION}"; \
277 - fi; \
267 fi
268
269 # Track PyTorch lib versions used during build and match in downstream instances.
@@ -792,10 +781,6 @@ ENV VLLM_ENABLE_CUDA_COMPATIBILITY=0
781 ARG PYTORCH_CUDA_INDEX_BASE_URL
782 COPY requirements/common.txt /tmp/common.txt
783 COPY requirements/cuda.txt /tmp/requirements-cuda.txt
795 -# nvidia-cutlass-dsl[cu13] installs -libs-base and -libs-cu13 wheels that
796 -# share paths with different content. uv can extract them in either order,
797 -# leaving base files that break CUDA 13 CuTe DSL JIT.
798 -# TODO(mmangkad): Remove this after NVIDIA/cutlass#3259 is fixed.
784 RUN --mount=type=cache,target=/opt/uv/cache \
785 if [ "$(echo $CUDA_VERSION | cut -d. -f1)" = "12" ]; then \
786 sed -i 's/^nvidia-cutlass-dsl\[cu13\]/nvidia-cutlass-dsl/' /tmp/requirements-cuda.txt; \
@@ -803,13 +788,6 @@ RUN --mount=type=cache,target=/opt/uv/cache \
788 fi && \
789 uv pip install --system -r /tmp/requirements-cuda.txt \
790 --extra-index-url ${PYTORCH_CUDA_INDEX_BASE_URL}/cu$(echo $CUDA_VERSION | cut -d. -f1,2 | tr -d '.') && \
806 - if [ "$(echo $CUDA_VERSION | cut -d. -f1)" = "13" ]; then \
807 - CUTLASS_DSL_VERSION=$(uv pip show --system nvidia-cutlass-dsl 2>/dev/null | awk '/^Version:/{print $2}') && \
808 - if [ -n "$CUTLASS_DSL_VERSION" ]; then \
809 - uv pip install --system --force-reinstall --no-deps \
810 - "nvidia-cutlass-dsl-libs-cu13==${CUTLASS_DSL_VERSION}"; \
811 - fi; \
812 - fi && \
791 rm /tmp/requirements-cuda.txt /tmp/common.txt
792
793 # Install FlashInfer JIT cache (requires CUDA-version-specific index URL)
@@ -908,19 +886,6 @@ RUN --mount=type=bind,from=build,src=/tmp/ep_kernels_workspace/dist,target=/vllm
886 uv pip install --system ep_kernels/dist/*.whl --verbose \
887 --extra-index-url ${PYTORCH_CUDA_INDEX_BASE_URL}/cu$(echo $CUDA_VERSION | cut -d. -f1,2 | tr -d '.')
888
911 -# nvidia-cutlass-dsl[cu13] installs -libs-base and -libs-cu13 wheels that
912 -# share paths with different content. Force -libs-cu13 last after runtime
913 -# dependency installs so uv cannot leave base files behind.
914 -# TODO(mmangkad): Remove this after NVIDIA/cutlass#3259 is fixed.
915 -RUN --mount=type=cache,target=/opt/uv/cache \
916 - if [ "$(echo $CUDA_VERSION | cut -d. -f1)" = "13" ]; then \
917 - CUTLASS_DSL_VERSION=$(uv pip show --system nvidia-cutlass-dsl 2>/dev/null | awk '/^Version:/{print $2}') && \
918 - if [ -n "$CUTLASS_DSL_VERSION" ]; then \
919 - uv pip install --system --force-reinstall --no-deps \
920 - "nvidia-cutlass-dsl-libs-cu13==${CUTLASS_DSL_VERSION}"; \
921 - fi; \
922 - fi
923 -
889 # CUDA image changed from /usr/local/nvidia to /usr/local/cuda in 12.8 but will
890 # return to /usr/local/nvidia in 13.0 to allow container providers to mount drivers
891 # consistently from the host (see https://github.com/vllm-project/vllm/issues/18859).
requirements/cuda.txt
+2 -2
@@ -16,7 +16,7 @@ PyNvVideoCodec==2.0.4
16 --extra-index-url https://flashinfer.ai/whl/
17 flashinfer-python==0.6.14
18 flashinfer-cubin==0.6.14
19 -apache-tvm-ffi==0.1.9
19 +apache-tvm-ffi==0.1.10
20 tilelang==0.1.9
21 nvidia-cudnn-frontend>=1.19.1
22 # Required for LLM_NVTX_SCOPES_FOR_PROFILING=1
@@ -25,7 +25,7 @@ nvtx==0.2.15
25 fastsafetensors >= 0.3.2
26
27 # QuACK and Cutlass DSL for FA4 (cute-DSL implementation)
28 -nvidia-cutlass-dsl[cu13]==4.5.2
28 +nvidia-cutlass-dsl[cu13]==4.6.0
29 quack-kernels>=0.4.0 # Required for tml-fa4
30
31 # Tokenspeed_MLA for faster mla with spec decode
requirements/test/cuda.txt
+1 -1
@@ -43,7 +43,7 @@ anyio==4.14.1
43 # sse-starlette
44 # starlette
45 # watchfiles
46 -apache-tvm-ffi==0.1.9
46 +apache-tvm-ffi==0.1.10
47 # via
48 # -c requirements/cuda.txt
49 # xgrammar
tests/entrypoints/pooling/scoring/test_cross_encoder_online_vision.py
+1
@@ -47,6 +47,7 @@ BACKEND_TOL: dict[str, float] = {
47 # TRITON_ATTN: gfx942/ROCm 7.2 drifts ~0.008 abs on text-vs-text (~7.9% rel).
48 BACKEND_ABS_TOL: dict[str, float] = {
49 "default": 0.0,
50 + "auto": 0.007,
51 "ROCM_AITER_FA": 0.005,
52 "TRITON_ATTN": 0.009,
53 "FLEX_ATTENTION": 0.006,
vllm/model_executor/layers/mamba/gdn/qwen_gdn_linear_attn.py
+2 -80
@@ -2,7 +2,6 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 """Inference-only Qwen3-Next/Qwen3.5 model."""
4
5 -import functools
5 from typing import Literal
6
7 import torch
@@ -83,70 +82,6 @@ if GDN_AITER_TRITON_AVAILABLE:
82 logger = init_logger(__name__)
83
84
86 -# TODO(arpera): remove ``_is_libs_cu13_install_intact`` and its caller in
87 -# ``_resolve_gdn_prefill_backend`` once the upstream packaging bug is
88 -# fixed and the broken wheels are yanked / superseded on PyPI:
89 -# https://github.com/NVIDIA/cutlass/issues/3170
90 -# https://github.com/NVIDIA/cutlass/issues/3259
91 -@functools.cache
92 -def _is_libs_cu13_install_intact() -> bool:
93 - """Return True if every file installed by ``nvidia-cutlass-dsl-libs-cu13``
94 - matches the SHA-256 declared in its wheel ``RECORD``.
95 -
96 - ``nvidia-cutlass-dsl-libs-base`` and ``nvidia-cutlass-dsl-libs-cu13``
97 - both ship into the shared ``nvidia_cutlass_dsl/`` namespace and
98 - write many of the same on-disk paths (the runtime ``.so``, the MLIR
99 - Python bindings, cuTe-DSL Python sources, ...) with different
100 - content. Whichever wheel extracts last wins; with a parallel
101 - installer (e.g. ``uv``) the order is racy and the resulting venv
102 - can end up with a mix of files from both variants. The
103 - ``-libs-base`` variant fails MLIR legalization when JIT-compiling
104 - the FlashInfer Blackwell GDN prefill kernel, and any other
105 - cuTe-DSL-based kernel can break too if on-disk files diverge from
106 - what ``-libs-cu13``'s wheel expects. Tracked upstream at:
107 -
108 - * https://github.com/NVIDIA/cutlass/issues/3170
109 - * https://github.com/NVIDIA/cutlass/issues/3259
110 -
111 - This helper re-hashes every file the ``-libs-cu13`` wheel claims to
112 - own and compares against its declared SHA-256. Returns False on any
113 - error (uninstalled, missing RECORD, missing file, hash mismatch).
114 - Result is cached per-process.
115 - """
116 - import hashlib
117 - import importlib.metadata
118 -
119 - import pybase64 as base64
120 -
121 - try:
122 - dist = importlib.metadata.distribution("nvidia-cutlass-dsl-libs-cu13")
123 - except importlib.metadata.PackageNotFoundError:
124 - return False
125 -
126 - files = dist.files
127 - if not files:
128 - return False
129 -
130 - for pkg_path in files:
131 - file_hash = pkg_path.hash
132 - # Skip RECORD rows without a hash (RECORD itself, generated
133 - # ``.pyc`` files, ...) and any non-SHA-256 hash modes.
134 - if file_hash is None or not file_hash.value:
135 - continue
136 - if file_hash.mode != "sha256":
137 - continue
138 - try:
139 - with open(pkg_path.locate(), "rb") as f:
140 - digest = hashlib.sha256(f.read()).digest()
141 - except OSError:
142 - return False
143 - actual = base64.urlsafe_b64encode(digest).decode().rstrip("=")
144 - if actual != file_hash.value:
145 - return False
146 -
147 - return True
148 -
149 -
85 def _resolve_gdn_prefill_backend(
86 vllm_config: VllmConfig,
87 ) -> tuple[str, Literal["triton", "flashinfer", "cutedsl"]]:
@@ -157,9 +92,7 @@ def _resolve_gdn_prefill_backend(
92 * ``platform == cuda``;
93 * one of the following:
94 - Hopper (SM90) — no further constraints;
160 - - Blackwell (SM10.x) with ``head_k_dim == 128``, ``cuda_runtime >= 13``,
161 - and an intact ``nvidia-cutlass-dsl-libs-cu13`` install on disk
162 - (see :func:`_is_libs_cu13_install_intact`).
95 + - Blackwell (SM10.x) with ``head_k_dim == 128``, ``cuda_runtime >= 13``.
96
97 In-tree CuteDSL GDN prefill kernel is chosen when:
98 * "cutedsl" is requested; (opt-in only)
@@ -190,19 +123,8 @@ def _resolve_gdn_prefill_backend(
123 and head_k_dim == 128
124 and current_platform.get_cuda_runtime_major() >= 13
125 ):
193 - supports_flashinfer = _is_libs_cu13_install_intact()
126 + supports_flashinfer = True
127 supports_cutedsl = True
195 - if not supports_flashinfer:
196 - logger.warning_once(
197 - "FlashInfer Blackwell GDN requires an intact nvidia-cutlass-dsl"
198 - "-libs-cu13 install, but some on-disk files do not match the "
199 - "SHA-256 declared in its RECORD (install-order race in "
200 - "nvidia-cutlass-dsl packaging -- see "
201 - "https://github.com/NVIDIA/cutlass/issues/3170 and "
202 - "https://github.com/NVIDIA/cutlass/issues/3259). Falling back "
203 - "to Triton/FLA. Repair with: pip install --force-reinstall "
204 - "--no-deps nvidia-cutlass-dsl-libs-cu13"
205 - )
128
129 if backend in ["flashinfer", "auto"] and supports_flashinfer:
130 return backend, "flashinfer"
vllm/vllm_flash_attn/flash_attn_interface.py
+1 -1
@@ -388,7 +388,7 @@ def flash_attn_varlen_func(
388
389 from vllm.vllm_flash_attn.cute.interface import _flash_attn_fwd
390
391 - out, softmax_lse = _flash_attn_fwd(
391 + out, softmax_lse, _, _ = _flash_attn_fwd(
392 q,
393 k,
394 v,