Files
wehub-resource-sync 94057c3d3e
PR Test (NPU) / check-changes (push) Has been cancelled
PR Test (NPU) / pr-gate (push) Has been cancelled
PR Test (NPU) / set-image-config (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-1-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (0) (push) Has been cancelled
PR Test (NPU) / stage-b-test-2-npu-a2 (1) (push) Has been cancelled
PR Test (NPU) / stage-b-test-4-npu-a3 (push) Has been cancelled
PR Test (NPU) / stage-b-test-16-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-1-npu-a3 (push) Has been cancelled
PR Test (NPU) / multimodal-gen-test-2-npu-a3 (push) Has been cancelled
PR Test (Arm64) / pr-gate (push) Has been cancelled
PR Test (Arm64) / check-changes (push) Has been cancelled
PR Test (Arm64) / build-test (push) Has been cancelled
PR Test (sgl-router) / gate (push) Has been cancelled
PR Test (sgl-router) / tier-1 — lint (push) Has been cancelled
PR Test (sgl-router) / tier-2 — build + test (push) Has been cancelled
PR Test (sgl-router) / tier-3 — docker (placeholder) (push) Has been cancelled
PR Test (sgl-router) / tier-3 — k8s integration (push) Has been cancelled
PR Test (sgl-router) / tier-3 — e2e (push) Has been cancelled
PR Test (sgl-router) / finish (push) Has been cancelled
PR Test (NPU) / single-node-poc (map[name:qwen3_6_27b_w8a8_1p_in64k_out1k_50ms runner:linux-aarch64-a3-2 test_case:test/registered/ascend/performance/qwen3_6_27b/test_npu_qwen3_6_27b_w8a8_1p_in64k_out1k_50ms.py test_type:perf]) (push) Has been cancelled
PR Test (NPU) / pr-test-npu-finish (push) Has been cancelled
PR Test (Xeon) / pr-gate (push) Has been cancelled
PR Test (Xeon) / check-changes (push) Has been cancelled
PR Test (Xeon) / build-test (, xeon-gnr, base-b-test-cpu) (push) Has been cancelled
PR Test (XPU) / check-changes (push) Has been cancelled
PR Test (XPU) / pr-gate (push) Has been cancelled
PR Test (XPU) / stage-a-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / wait-for-stage-a (push) Has been cancelled
PR Test (XPU) / stage-b-test-1-gpu-xpu (push) Has been cancelled
PR Test (XPU) / finish (push) Has been cancelled
CI Model Inventory / build-inventory (push) Has been cancelled
Lint / lint (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Compilation Check (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Manual Policy (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark - Request Processing (push) Has been cancelled
PR Benchmark (SMG Components) / Benchmark Summary (push) Has been cancelled
PR Test (SMG) / build-wheel (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on windows (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (x86_64 - auto) (push) Has been cancelled
PR Test (SMG) / python-unit-tests (push) Has been cancelled
PR Test (SMG) / unit-tests (push) Has been cancelled
PR Test (SMG) / benchmarks (push) Has been cancelled
PR Test (SMG) / chat-completions (push) Has been cancelled
PR Test (SMG) / chat-completions-4gpu (push) Has been cancelled
PR Test (SMG) / e2e (push) Has been cancelled
PR Test (SMG) / docker-build-test (push) Has been cancelled
PR Test (SMG) / k8s-integration (push) Has been cancelled
PR Test (SMG) / finish (push) Has been cancelled
PR Test (SMG) / summarize-benchmarks (push) Has been cancelled
Release SGLang Model Gateway Docker Image / publish (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on macos (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - auto) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (aarch64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / build on linux (x86_64 - musllinux_1_1) (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Build SDist (push) Has been cancelled
Release SGLang Model Gateway to PyPI / Upload to PyPI (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (aarch64, 12.9, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu129-matrix (x86_64, 12.9, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu129 (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (aarch64, 13.0, 3.10, arm-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / build-cu130-matrix (x86_64, 13.0, 3.10, x64-kernel-build-node) (push) Has been cancelled
Release SGLang Kernels / release-cu130 (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 700) (push) Has been cancelled
Release SGLang Kernels / build-rocm-matrix (3.10, 720) (push) Has been cancelled
Release SGLang Kernels / release-rocm700 (push) Has been cancelled
Release SGLang Kernels / release-rocm720 (push) Has been cancelled
Release SGLang Kernels / build-musa43 (43, 3.10) (push) Has been cancelled
Release SGLang Kernels / release-musa43 (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:38:16 +08:00

171 lines
4.9 KiB
Python

"""Fused per-head Gemma-RMSNorm + partial NeoX RoPE for MiniMax-M3 attention.
In-place over a fused QKV tensor: normalizes + rotates one or more groups of
heads (each group = a contiguous head run sharing one norm weight, all getting
RoPE), leaving every other head (V, index-V) untouched. Consumes the model's
own ``cos_sin_cache`` (fp32) so the rotation matches sglang's RotaryEmbedding
exactly.
Two entry points:
* :func:`minimax_qknorm_rope` -- the original main-attention call
``(q | k | v ...)``: Q heads then K heads, both normed + roped.
* :func:`minimax_qknorm_rope_grouped` -- a multi-group launch (up to 4 groups),
used to fold the main Q/K *and* the sparse-index Q/K of one fused
qkv+index-qkv GEMM output into a single kernel launch (mirroring the
multi-branch single-launch design of ``fused_store_kv_index.cuh``).
"""
from __future__ import annotations
from typing import TYPE_CHECKING, List, Sequence, Tuple
import torch
from sglang.jit_kernel.utils import (
cache_once,
is_arch_support_pdl,
load_jit,
make_cpp_args,
)
from sglang.srt.utils.custom_op import register_custom_op
if TYPE_CHECKING:
from tvm_ffi.module import Module
_MAX_GROUPS = 4
@cache_once
def _jit_module(pos_dtype, head_dim, rope_dim) -> Module:
args = make_cpp_args(pos_dtype, head_dim, rope_dim, is_arch_support_pdl())
return load_jit(
"fused_gemma_qknorm_rope",
*args,
cuda_files=["minimax/fused_gemma_qknorm_rope.cuh"],
cuda_wrappers=[("fused_gemma_qknorm_rope", f"fused_gemma_qknorm_rope<{args}>")],
)
@register_custom_op(mutates_args=["qkv"])
def _fused_gemma_qknorm_rope(
qkv: torch.Tensor,
w0: torch.Tensor,
w1: torch.Tensor,
w2: torch.Tensor,
w3: torch.Tensor,
cos_sin_cache: torch.Tensor,
positions: torch.Tensor,
off0: int,
cnt0: int,
off1: int,
cnt1: int,
off2: int,
cnt2: int,
off3: int,
cnt3: int,
num_groups: int,
eps: float,
) -> None:
# Wrap the tvm-ffi kernel as a custom op so torch.compile / piecewise CUDA
# graph can trace past the otherwise-opaque FFI call. The launch is
# graph-capturable (host-side constant offsets/counts), so it stays inside
# the captured region.
module = _jit_module(positions.dtype, 128, 64)
module.fused_gemma_qknorm_rope(
qkv,
w0,
w1,
w2,
w3,
cos_sin_cache,
positions,
off0,
cnt0,
off1,
cnt1,
off2,
cnt2,
off3,
cnt3,
num_groups,
eps,
)
def minimax_qknorm_rope_grouped(
qkv: torch.Tensor,
groups: Sequence[Tuple[torch.Tensor, int, int]],
cos_sin_cache: torch.Tensor,
positions: torch.Tensor,
eps: float,
) -> torch.Tensor:
"""Fused GemmaRMSNorm + partial NeoX RoPE over ``groups``, in place on ``qkv``.
``qkv`` is ``[T, total_heads * head_dim]`` (head_dim == 128). Each group is
``(weight, head_offset, head_count)``: ``head_count`` consecutive heads
starting at ``head_offset`` (in head units) are normed with ``weight``
(a ``[head_dim]`` bf16 tensor, the *raw* Gemma weight -- the kernel applies
``1 + weight``) and rotated. Heads outside every group are untouched.
Up to 4 groups are supported in one launch. The offsets/counts are
host-side constants, so the launch is CUDA-graph capturable.
"""
groups = [(w, off, cnt) for (w, off, cnt) in groups if cnt > 0]
num_groups = len(groups)
assert (
1 <= num_groups <= _MAX_GROUPS
), f"need 1..{_MAX_GROUPS} groups, got {num_groups}"
weights: List[torch.Tensor] = [g[0] for g in groups]
offsets: List[int] = [int(g[1]) for g in groups]
counts: List[int] = [int(g[2]) for g in groups]
# Pad weight slots up to 4 with a dummy (group 0's weight); the kernel never
# reads padded slots because num_groups bounds the in-kernel group scan.
while len(weights) < _MAX_GROUPS:
weights.append(weights[0])
offsets.append(0)
counts.append(0)
_fused_gemma_qknorm_rope(
qkv,
weights[0],
weights[1],
weights[2],
weights[3],
cos_sin_cache,
positions,
offsets[0],
counts[0],
offsets[1],
counts[1],
offsets[2],
counts[2],
offsets[3],
counts[3],
num_groups,
eps,
)
return qkv
def minimax_qknorm_rope(
qkv: torch.Tensor,
q_weight: torch.Tensor,
k_weight: torch.Tensor,
cos_sin_cache: torch.Tensor,
positions: torch.Tensor,
nq: int,
nk: int,
nv: int, # deprecated / ignored: V heads are simply left untouched
eps: float,
) -> torch.Tensor:
"""Main-attention layout ``[q (nq) | k (nk) | v ...]``: norm + rope Q then K."""
return minimax_qknorm_rope_grouped(
qkv,
[(q_weight, 0, nq), (k_weight, nq, nk)],
cos_sin_cache,
positions,
eps,
)