@tduncan / Nvidia-Optimization-Stack-VLLM Mirror · read-only / commits / f1f0d2fab8
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 14, 05:30 UTC

Revert "[Kernel] Add cuda kernel for gpt_oss activation" (#22948)

Simon Mo committed Aug 14, 2025 at 17:38 UTC f1f0d2fab8a1b1ced68ccf5b7197393cf01e1a02
8 files changed +24 -150
csrc/activation_kernels.cu
-59
@@ -128,45 +128,6 @@ __global__ void act_and_mul_kernel_with_param(
128 }
129 }
130
131 -template <typename T>
132 -__device__ __forceinline__ T swigluoai_and_mul(const T& gate, const T& up,
133 - float alpha, float limit) {
134 - // clamp gate: min=None, max=limit
135 - const float gate_f = (float)gate;
136 - const float clamped_gate = gate_f > limit ? limit : gate_f;
137 -
138 - // clamp up: min=-limit, max=limit
139 - const float up_f = (float)up;
140 - const float clamped_up =
141 - up_f > limit ? limit : (up_f < -limit ? -limit : up_f);
142 -
143 - // glu = gate * sigmoid(gate * alpha)
144 - const float sigmoid_val = 1.0f / (1.0f + expf(-clamped_gate * alpha));
145 - const float glu = clamped_gate * sigmoid_val;
146 -
147 - // (up + 1) * glu
148 - return (T)((clamped_up + 1.0f) * glu);
149 -}
150 -
151 -template <typename scalar_t,
152 - scalar_t (*ACT_FN)(const scalar_t&, const scalar_t&, const float,
153 - const float)>
154 -__global__ void swigluoai_and_mul_kernel(
155 - scalar_t* __restrict__ out, // [..., d]
156 - const scalar_t* __restrict__ input, // [..., 2, d]
157 - const int d, const float alpha, const float limit) {
158 - const int64_t token_idx = blockIdx.x;
159 - // TODO: Vectorize loads and stores.
160 - for (int64_t idx = threadIdx.x; idx < d; idx += blockDim.x) {
161 - // gate = x[..., ::2] (even indices)
162 - const scalar_t gate = VLLM_LDG(&input[token_idx * 2 * d + 2 * idx]);
163 - // up = x[..., 1::2] (odd indices)
164 - const scalar_t up = VLLM_LDG(&input[token_idx * 2 * d + 2 * idx + 1]);
165 -
166 - out[token_idx * d + idx] = ACT_FN(gate, up, alpha, limit);
167 - }
168 -}
169 -
131 } // namespace vllm
132
133 #define LAUNCH_ACTIVATION_GATE_KERNEL_WITH_PARAM(KERNEL, PARAM) \
@@ -184,31 +145,11 @@ __global__ void swigluoai_and_mul_kernel(
145 PARAM); \
146 });
147
187 -#define LAUNCH_SIGLUOAI_AND_MUL(KERNEL, ALPHA, LIMIT) \
188 - int d = input.size(-1) / 2; \
189 - int64_t num_tokens = input.numel() / input.size(-1); \
190 - dim3 grid(num_tokens); \
191 - dim3 block(std::min(d, 1024)); \
192 - const at::cuda::OptionalCUDAGuard device_guard(device_of(input)); \
193 - const cudaStream_t stream = at::cuda::getCurrentCUDAStream(); \
194 - VLLM_DISPATCH_FLOATING_TYPES( \
195 - input.scalar_type(), "clamp_swiglu_kernel_with_params", [&] { \
196 - vllm::swigluoai_and_mul_kernel<scalar_t, KERNEL<scalar_t>> \
197 - <<<grid, block, 0, stream>>>(out.data_ptr<scalar_t>(), \
198 - input.data_ptr<scalar_t>(), d, ALPHA, \
199 - LIMIT); \
200 - });
201 -
148 void fatrelu_and_mul(torch::Tensor& out, // [..., d],
149 torch::Tensor& input, // [..., 2 * d]
150 double threshold) {
151 LAUNCH_ACTIVATION_GATE_KERNEL_WITH_PARAM(vllm::fatrelu_kernel, threshold);
152 }
207 -void swigluoai_and_mul(torch::Tensor& out, // [..., d]
208 - torch::Tensor& input, // [..., 2 * d]
209 - double alpha, double limit) {
210 - LAUNCH_SIGLUOAI_AND_MUL(vllm::swigluoai_and_mul, alpha, limit);
211 -}
153 namespace vllm {
154
155 // Element-wise activation kernel template.
csrc/ops.h
-2
@@ -138,8 +138,6 @@ void gelu_tanh_and_mul(torch::Tensor& out, torch::Tensor& input);
138
139 void fatrelu_and_mul(torch::Tensor& out, torch::Tensor& input,
140 double threshold);
141 -void swigluoai_and_mul(torch::Tensor& out, torch::Tensor& input,
142 - double alpha = 1.702, double limit = 7.0);
141
142 void gelu_new(torch::Tensor& out, torch::Tensor& input);
143
csrc/torch_bindings.cpp
-5
@@ -130,11 +130,6 @@ TORCH_LIBRARY_EXPAND(TORCH_EXTENSION_NAME, ops) {
130 ops.def("fatrelu_and_mul(Tensor! out, Tensor input, float threshold) -> ()");
131 ops.impl("fatrelu_and_mul", torch::kCUDA, &fatrelu_and_mul);
132
133 - ops.def(
134 - "swigluoai_and_mul(Tensor! out, Tensor input, float alpha, float limit) "
135 - "-> ()");
136 - ops.impl("swigluoai_and_mul", torch::kCUDA, &swigluoai_and_mul);
137 -
133 // GELU implementation used in GPT-2.
134 ops.def("gelu_new(Tensor! out, Tensor input) -> ()");
135 ops.impl("gelu_new", torch::kCUDA, &gelu_new);
tests/kernels/core/test_activation.py
+6 -39
@@ -11,7 +11,7 @@ from tests.kernels.utils import opcheck
11 from vllm.model_executor.layers.activation import (FastGELU, FatreluAndMul,
12 GeluAndMul, MulAndSilu,
13 NewGELU, QuickGELU,
14 - SiluAndMul, SwigluOAIAndMul)
14 + SiluAndMul)
15 from vllm.platforms import current_platform
16
17 DTYPES = [torch.half, torch.bfloat16, torch.float]
@@ -25,15 +25,7 @@ CUDA_DEVICES = [
25
26 @pytest.mark.parametrize(
27 "activation",
28 - [
29 - "silu_and_mul",
30 - "mul_and_silu",
31 - "gelu",
32 - "gelu_tanh",
33 - "fatrelu",
34 - "swigluoai_and_mul",
35 - ],
36 -)
28 + ["silu_and_mul", "mul_and_silu", "gelu", "gelu_tanh", "fatrelu"])
29 @pytest.mark.parametrize("num_tokens", NUM_TOKENS)
30 @pytest.mark.parametrize("d", D)
31 @pytest.mark.parametrize("dtype", DTYPES)
@@ -67,43 +59,18 @@ def test_act_and_mul(
59 threshold = random.uniform(0, 1)
60 layer = FatreluAndMul(threshold)
61 fn = torch.ops._C.fatrelu_and_mul
70 - elif activation == "swigluoai_and_mul":
71 - layer = SwigluOAIAndMul()
72 - fn = torch.ops._C.swigluoai_and_mul
62 out = layer(x)
63 ref_out = layer.forward_native(x)
75 - if activation == "swigluoai_and_mul":
76 -
77 - rtol = {
78 - #For fp16, change the relative tolerance from 1e-3 to 2e-3
79 - torch.float16:
80 - 2e-3,
81 - torch.bfloat16:
82 - 2e-2,
83 - torch.float:
84 - 1.3e-6
85 - }
86 -
87 - def _get_rtol(output) -> float:
88 - return rtol[output.dtype]
89 -
90 - torch.testing.assert_close(out,
91 - ref_out,
92 - atol=get_default_atol(out),
93 - rtol=_get_rtol(out))
94 - else:
95 - # The SiluAndMul, MulAndSilu, GELU and FatReLU implementations are
96 - # equivalent to the native PyTorch implementations, so we can do exact
97 - # comparison.
98 - torch.testing.assert_close(out, ref_out, atol=0.0, rtol=0.0)
64 + # The SiluAndMul, MulAndSilu, GELU and FatReLU implementations are
65 + # equivalent to the native PyTorch implementations, so we can do exact
66 + # comparison.
67 + torch.testing.assert_close(out, ref_out, atol=0.0, rtol=0.0)
68
69 d = x.shape[-1] // 2
70 output_shape = (x.shape[:-1] + (d, ))
71 out = torch.empty(output_shape, dtype=x.dtype, device=x.device)
72 if activation == "fatrelu":
73 opcheck(fn, (out, x, threshold))
105 - elif activation == "swigluoai_and_mul":
106 - opcheck(fn, (out, x, layer.alpha, layer.limit))
74 else:
75 opcheck(fn, (out, x))
76
vllm/model_executor/layers/activation.py
+3 -38
@@ -239,35 +239,6 @@ class GeluAndMul(CustomOp):
239 return f'approximate={repr(self.approximate)}'
240
241
242 -@CustomOp.register("swigluoai_and_mul")
243 -class SwigluOAIAndMul(CustomOp):
244 - # https://github.com/huggingface/transformers/blob/v4.55.0/src/transformers/models/gpt_oss/modeling_gpt_oss.py#L106-L110
245 - def __init__(self, alpha: float = 1.702, limit: float = 7.0):
246 - super().__init__()
247 - self.alpha = alpha
248 - self.limit = limit
249 -
250 - def forward_native(self, x: torch.Tensor) -> torch.Tensor:
251 - """PyTorch-native implementation equivalent to forward()."""
252 -
253 - gate, up = x[..., ::2], x[..., 1::2]
254 - gate = gate.clamp(min=None, max=self.limit)
255 - up = up.clamp(min=-self.limit, max=self.limit)
256 - glu = gate * torch.sigmoid(gate * self.alpha)
257 - gated_output = (up + 1) * glu
258 - return gated_output
259 -
260 - def forward_cuda(self, x: torch.Tensor) -> torch.Tensor:
261 - d = x.shape[-1] // 2
262 - output_shape = (x.shape[:-1] + (d, ))
263 - out = torch.empty(output_shape, dtype=x.dtype, device=x.device)
264 - torch.ops._C.swigluoai_and_mul(out, x, self.alpha, self.limit)
265 - return out
266 -
267 - def extra_repr(self) -> str:
268 - return f"alpha={repr(self.alpha)}, limit={repr(self.limit)}"
269 -
270 -
242 @CustomOp.register("gelu_new")
243 class NewGELU(CustomOp):
244
@@ -359,7 +330,6 @@ class ReLUSquaredActivation(CustomOp):
330 return torch.square(F.relu(x))
331
332 def forward_cuda(self, x: torch.Tensor) -> torch.Tensor:
362 - #TODO : implement cuda kenrels
333 return self.forward_native(x)
334
335
@@ -436,14 +406,9 @@ def get_act_fn(act_fn_name: str) -> nn.Module:
406
407
408 _ACTIVATION_AND_MUL_REGISTRY = LazyDict({
439 - "gelu":
440 - lambda: GeluAndMul(),
441 - "silu":
442 - lambda: SiluAndMul(),
443 - "geglu":
444 - lambda: GeluAndMul(),
445 - "swigluoai_and_mul":
446 - lambda *args, **kwargs: SwigluOAIAndMul(*args, **kwargs),
409 + "gelu": lambda: GeluAndMul(),
410 + "silu": lambda: SiluAndMul(),
411 + "geglu": lambda: GeluAndMul(),
412 })
413
414
vllm/model_executor/layers/fused_moe/fused_moe.py
+13 -5
@@ -1633,6 +1633,17 @@ def fused_experts_impl(
1633 block_shape=block_shape,
1634 B_bias=w1_bias)
1635
1636 + # TODO fused kernel
1637 + def swiglu_oai(gate_up):
1638 + alpha = 1.702
1639 + limit = 7.0
1640 + gate, up = gate_up[..., ::2], gate_up[..., 1::2]
1641 + gate = gate.clamp(min=None, max=limit)
1642 + up = up.clamp(min=-limit, max=limit)
1643 + glu = gate * torch.sigmoid(gate * alpha)
1644 + gated_output = (up + 1) * glu
1645 + return gated_output
1646 +
1647 # Activation function with multiplication
1648 if activation == "silu" and is_act_and_mul:
1649 torch.ops._C.silu_and_mul(intermediate_cache2,
@@ -1640,16 +1651,13 @@ def fused_experts_impl(
1651 elif activation == "gelu" and is_act_and_mul:
1652 torch.ops._C.gelu_and_mul(intermediate_cache2,
1653 intermediate_cache1.view(-1, N))
1643 - elif activation == "swigluoai" and is_act_and_mul:
1644 - # alpha = 1.702, limit = 7.0
1645 - torch.ops._C.swigluoai_and_mul(intermediate_cache2,
1646 - intermediate_cache1.view(-1, N))
1654 # Activation function without multiplication
1655 elif activation == "silu":
1656 intermediate_cache2 = F.silu(intermediate_cache1.view(-1, N))
1657 elif activation == "gelu":
1658 intermediate_cache2 = F.gelu(intermediate_cache1.view(-1, N))
1652 -
1659 + elif activation == "swiglu_oai":
1660 + intermediate_cache2 = swiglu_oai(intermediate_cache1.view(-1, N))
1661 else:
1662 raise ValueError(f"Unsupported FusedMoe activation: {activation}, "
1663 f"with is_act_and_mul={is_act_and_mul}.")
vllm/model_executor/layers/quantization/utils/mxfp4_utils.py
+1 -1
@@ -68,7 +68,7 @@ def _can_support_mxfp4(use_grouped_topk: bool = False,
68 return not (use_grouped_topk or topk_group or num_expert_group
69 or expert_map or custom_routing_function
70 or e_score_correction_bias or apply_router_weight_on_input
71 - or scoring_func != "softmax" or activation != "swigluoai"
71 + or scoring_func != "softmax" or activation != "swiglu_oai"
72 or expert_load_view or logical_to_physical_map
73 or logical_replica_count)
74
vllm/model_executor/models/gpt_oss.py
+1 -1
@@ -159,7 +159,7 @@ class MLPBlock(torch.nn.Module):
159 prefix=f"{prefix}.experts",
160 apply_router_weight_on_input=False,
161 has_bias=True,
162 - activation="swigluoai")
162 + activation="swiglu_oai")
163
164 def forward(self, x: torch.Tensor) -> torch.Tensor:
165 t = self.norm(x)