[Bugfix][CPU] Fix DeepSeek V4.1 import without Triton (#57654)

Signed-off-by: Jiang Wu <245355730+JiangLLM@users.noreply.github.com> Co-authored-by: Jiang Wu <245355730+JiangLLM@users.noreply.github.com>

Jiang Wu committed Sep 18, 2026 at 22:46 UTC 6af44e2887e3dbfb1c59807d1315af88f232df11
3 files changed +8 -8
tests/test_triton_utils.py
+3 -1
@@ -97,7 +97,8 @@ def test_triton_placeholder_language():
97 lang = TritonLanguagePlaceholder()
98 assert isinstance(lang, types.ModuleType)
99 assert lang.__name__ == "triton.language"
100 - assert lang.constexpr is None
100 + assert lang.constexpr(2**31 - 1) == 2**31 - 1
101 + assert lang.constexpr(1.5) == 1.5
102 assert lang.dtype is None
103 assert lang.int64 is None
104 assert lang.int32 is None
@@ -143,3 +144,4 @@ def test_no_triton_fallback():
144 assert triton.__class__.__name__ == "TritonPlaceholder"
145 assert triton.language.__class__.__name__ == "TritonLanguagePlaceholder"
146 assert tl.__class__.__name__ == "TritonLanguagePlaceholder"
147 + assert tl.constexpr(2**31 - 1) == 2**31 - 1
vllm/triton_utils/importing.py
+1 -1
@@ -124,7 +124,7 @@ class TritonPlaceholder(types.ModuleType):
124 class TritonLanguagePlaceholder(types.ModuleType):
125 def __init__(self):
126 super().__init__("triton.language")
127 - self.constexpr = None
127 + self.constexpr = lambda value: value
128 self.dtype = None
129 self.int64 = None
130 self.int32 = None
vllm/v1/worker/gpu/sample/gumbel.py
+4 -6
@@ -2,22 +2,20 @@
2 # SPDX-FileCopyrightText: Copyright contributors to the vLLM project
3 import torch
4
5 -from vllm.triton_utils import HAS_TRITON, tl, triton
5 +from vllm.triton_utils import tl, triton
6
7 # Smallest positive value produced by Triton's fp32 `tl.rand`. Used by the
8 # retained Philox helper for rejection sampling.
9 #
10 # Triton requires globals accessed from `@triton.jit` functions to be wrapped
11 -# in `tl.constexpr(...)`. We can only do that when Triton is actually
12 -# available — on the CPU worker path `tl` is a placeholder whose `constexpr`
13 -# attribute is `None`, and `tl.constexpr(...)` would crash at import time.
14 -_TL_RAND_MIN = tl.constexpr(4.6566127342e-10) if HAS_TRITON else 4.6566127342e-10
11 +# in `tl.constexpr(...)`.
12 +_TL_RAND_MIN = tl.constexpr(4.6566127342e-10)
13
14 # Offset salt keeping the draft's Gumbel noise disjoint from the target's.
15 # Verification is a probability-ratio test, not a Gumbel coupling, so a proposal
16 # and the residual it is resampled from must not share a noise vector.
17 # Positions are int64 and never approach 2**30, so the streams cannot collide.
20 -_DRAFT_NOISE_SALT = tl.constexpr(1 << 30) if HAS_TRITON else (1 << 30)
18 +_DRAFT_NOISE_SALT = tl.constexpr(1 << 30)
19
20
21 @triton.jit