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
215 lines
6.7 KiB
Python
215 lines
6.7 KiB
Python
# Adapted from: https://github.com/vllm-project/vllm/tree/main/vllm/model_executor/layers/mamba/ops/ssd_bmm.py
|
|
|
|
# SPDX-License-Identifier: Apache-2.0
|
|
# SPDX-FileCopyrightText: Copyright contributors to the vLLM project
|
|
|
|
# Copyright (c) 2024, Tri Dao, Albert Gu.
|
|
# Adapted from https://github.com/state-spaces/mamba/blob/v2.2.4/mamba_ssm/ops/triton/ssd_bmm.py
|
|
|
|
# ruff: noqa: E501,SIM102
|
|
|
|
import math
|
|
|
|
import torch
|
|
import triton
|
|
import triton.language as tl
|
|
|
|
|
|
@triton.jit
|
|
def _bmm_chunk_fwd_kernel(
|
|
# Pointers to matrices
|
|
a_ptr,
|
|
b_ptr,
|
|
out_ptr,
|
|
seq_idx_ptr,
|
|
# Matrix dimensions
|
|
seqlen,
|
|
chunk_size,
|
|
K,
|
|
ngroups,
|
|
stride_a_batch,
|
|
stride_a_seqlen,
|
|
stride_a_head,
|
|
stride_ak,
|
|
stride_b_batch,
|
|
stride_b_seqlen,
|
|
stride_b_head,
|
|
stride_bk,
|
|
stride_out_batch,
|
|
stride_out_chunk,
|
|
stride_out_head,
|
|
stride_outm,
|
|
stride_outn,
|
|
stride_seq_idx_batch,
|
|
stride_seq_idx_seqlen,
|
|
# Meta-parameters
|
|
IS_CAUSAL: tl.constexpr,
|
|
dot_dtype: tl.constexpr,
|
|
HAS_SEQ_IDX: tl.constexpr,
|
|
BLOCK_SIZE_M: tl.constexpr = 16,
|
|
BLOCK_SIZE_N: tl.constexpr = 16,
|
|
BLOCK_SIZE_K: tl.constexpr = 16,
|
|
):
|
|
pid_b = tl.program_id(axis=1)
|
|
pid_ch = tl.program_id(axis=2).to(tl.int64)
|
|
pid_c = pid_ch // ngroups
|
|
pid_h = pid_ch - pid_c * ngroups
|
|
num_pid_n = tl.cdiv(chunk_size, BLOCK_SIZE_N)
|
|
pid_m = tl.program_id(axis=0) // num_pid_n
|
|
pid_n = tl.program_id(axis=0) % num_pid_n
|
|
if IS_CAUSAL:
|
|
if pid_n * BLOCK_SIZE_N >= (pid_m + 1) * BLOCK_SIZE_M:
|
|
return
|
|
a_ptr += (
|
|
pid_b * stride_a_batch
|
|
+ pid_c * chunk_size * stride_a_seqlen
|
|
+ pid_h * stride_a_head
|
|
)
|
|
b_ptr += (
|
|
pid_b * stride_b_batch
|
|
+ pid_c * chunk_size * stride_b_seqlen
|
|
+ pid_h * stride_b_head
|
|
)
|
|
if HAS_SEQ_IDX:
|
|
seq_idx_ptr += (
|
|
pid_b * stride_seq_idx_batch + pid_c * chunk_size * stride_seq_idx_seqlen
|
|
)
|
|
|
|
offs_m = pid_m * BLOCK_SIZE_M + tl.arange(0, BLOCK_SIZE_M)
|
|
offs_n = pid_n * BLOCK_SIZE_N + tl.arange(0, BLOCK_SIZE_N)
|
|
offs_k = tl.arange(0, BLOCK_SIZE_K)
|
|
a_ptrs = a_ptr + (offs_m[:, None] * stride_a_seqlen + offs_k[None, :] * stride_ak)
|
|
b_ptrs = b_ptr + (offs_k[:, None] * stride_bk + offs_n[None, :] * stride_b_seqlen)
|
|
chunk_size_limit = min(chunk_size, seqlen - pid_c * chunk_size)
|
|
|
|
acc = tl.zeros((BLOCK_SIZE_M, BLOCK_SIZE_N), dtype=tl.float32)
|
|
for k in range(0, tl.cdiv(K, BLOCK_SIZE_K)):
|
|
a = tl.load(
|
|
a_ptrs,
|
|
mask=(offs_m[:, None] < chunk_size_limit)
|
|
& (offs_k[None, :] < K - k * BLOCK_SIZE_K),
|
|
other=0.0,
|
|
).to(dot_dtype)
|
|
b = tl.load(
|
|
b_ptrs,
|
|
mask=(offs_k[:, None] < K - k * BLOCK_SIZE_K)
|
|
& (offs_n[None, :] < chunk_size_limit),
|
|
other=0.0,
|
|
).to(dot_dtype)
|
|
acc += tl.dot(a, b)
|
|
a_ptrs += BLOCK_SIZE_K * stride_ak
|
|
b_ptrs += BLOCK_SIZE_K * stride_bk
|
|
|
|
offs_m = pid_m * BLOCK_SIZE_M + tl.arange(0, BLOCK_SIZE_M)
|
|
offs_n = pid_n * BLOCK_SIZE_N + tl.arange(0, BLOCK_SIZE_N)
|
|
if HAS_SEQ_IDX:
|
|
chunk_size_limit = min(chunk_size, seqlen - pid_c * chunk_size)
|
|
seq_idx_m = tl.load(
|
|
seq_idx_ptr + offs_m * stride_seq_idx_seqlen,
|
|
mask=offs_m < chunk_size_limit,
|
|
other=-1,
|
|
)
|
|
seq_idx_n = tl.load(
|
|
seq_idx_ptr + offs_n * stride_seq_idx_seqlen,
|
|
mask=offs_n < chunk_size_limit,
|
|
other=-2,
|
|
)
|
|
acc = tl.where(seq_idx_m[:, None] == seq_idx_n[None, :], acc, 0.0)
|
|
out = acc.to(out_ptr.dtype.element_ty)
|
|
|
|
out_ptr += (
|
|
pid_b * stride_out_batch + pid_c * stride_out_chunk + pid_h * stride_out_head
|
|
)
|
|
out_ptrs = out_ptr + (stride_outm * offs_m[:, None] + offs_n[None, :] * stride_outn)
|
|
tl.store(
|
|
out_ptrs,
|
|
out,
|
|
mask=(offs_m[:, None] < chunk_size) & (offs_n[None, :] < chunk_size),
|
|
)
|
|
|
|
|
|
def _bmm_chunk_fwd(a, b, chunk_size, seq_idx=None, causal=False, output_dtype=None):
|
|
"""
|
|
Argument:
|
|
a: (batch, seqlen, k) or (batch, seqlen, ngroups, k)
|
|
b: (batch, seqlen, k) or (batch, seqlen, ngroups, k)
|
|
seq_idx: (batch, seqlen) or None. out[i, j] for seq_idx[i] != seq_idx[j] will be zeroed out.
|
|
causal: if True, then out[i, j] for i > j will be arbitrary, only out[i, j] for i <= j are
|
|
guaranteed to be correct.
|
|
Return:
|
|
out: (batch, nchunks, chunk_size, chunk_size) or (batch, nchunks, ngroups, chunk_size, chunk_size)
|
|
"""
|
|
# Check constraints.
|
|
has_groups = a.dim() == 4
|
|
if not has_groups:
|
|
batch, seqlen, k = a.shape
|
|
else:
|
|
batch, seqlen, ngroups, k = a.shape
|
|
assert b.shape == a.shape
|
|
if seq_idx is not None:
|
|
assert seq_idx.shape == (batch, seqlen)
|
|
if a.stride(-1) != 1 and a.stride(1) != 1:
|
|
a = a.contiguous()
|
|
if b.stride(-1) != 1 and b.stride(1) != 1:
|
|
b = b.contiguous()
|
|
nchunks = math.ceil(seqlen / chunk_size)
|
|
# Allocates output.
|
|
out_dtype = a.dtype if output_dtype is None else output_dtype
|
|
out = torch.empty(
|
|
(
|
|
(batch, nchunks, chunk_size, chunk_size)
|
|
if not has_groups
|
|
else (batch, nchunks, ngroups, chunk_size, chunk_size)
|
|
),
|
|
device=a.device,
|
|
dtype=out_dtype,
|
|
)
|
|
dot_dtype = (
|
|
tl.bfloat16
|
|
if a.dtype == torch.bfloat16 or b.dtype == torch.bfloat16
|
|
else (
|
|
tl.float16
|
|
if a.dtype == torch.float16 or b.dtype == torch.float16
|
|
else tl.float32
|
|
)
|
|
)
|
|
grid = lambda META: (
|
|
triton.cdiv(chunk_size, META["BLOCK_SIZE_M"])
|
|
* triton.cdiv(chunk_size, META["BLOCK_SIZE_N"]),
|
|
batch,
|
|
nchunks if not has_groups else nchunks * ngroups,
|
|
)
|
|
with torch.get_device_module(a.device).device(a.device.index):
|
|
_bmm_chunk_fwd_kernel[grid](
|
|
a,
|
|
b,
|
|
out,
|
|
seq_idx,
|
|
seqlen,
|
|
chunk_size,
|
|
k,
|
|
ngroups if has_groups else 1,
|
|
a.stride(0),
|
|
a.stride(1),
|
|
0 if not has_groups else a.stride(2),
|
|
a.stride(-1),
|
|
b.stride(0),
|
|
b.stride(1),
|
|
0 if not has_groups else b.stride(2),
|
|
b.stride(-1),
|
|
out.stride(0),
|
|
out.stride(1),
|
|
0 if not has_groups else out.stride(2),
|
|
out.stride(-2),
|
|
out.stride(-1),
|
|
*(
|
|
(seq_idx.stride(0), seq_idx.stride(1))
|
|
if seq_idx is not None
|
|
else (0, 0)
|
|
),
|
|
causal,
|
|
dot_dtype,
|
|
HAS_SEQ_IDX=seq_idx is not None,
|
|
)
|
|
return out
|