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

282 lines
10 KiB
Python

# Copyright 2023-2026 SGLang Team
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ==============================================================================
import triton
import triton.language as tl
@triton.jit
def sgl_build_tree_kernel_efficient_triton(
parent_list_ptr,
selected_index_ptr,
verified_seq_len_ptr,
seq_len_prefix_sum_ptr,
tree_mask_ptr,
positions_ptr,
retrieve_index_ptr,
retrieve_next_token_ptr,
retrieve_next_sibling_ptr,
topk: tl.constexpr,
depth: tl.constexpr,
draft_token_num: tl.constexpr,
tree_mask_mode: tl.constexpr,
batch_size: tl.constexpr,
parent_list_stride: tl.constexpr,
selected_index_stride: tl.constexpr,
):
"""
Triton kernel for building EAGLE tree structure.
Each program handles one batch item (batch_idx).
"""
batch_idx = tl.program_id(0)
# Calculate seq_tree_idx
seq_len = tl.load(verified_seq_len_ptr + batch_idx)
seq_len_prefix_sum = tl.load(seq_len_prefix_sum_ptr + batch_idx)
# Cast initial value to match the dtype of loaded tensors to avoid type inconsistency
seq_tree_idx = (
tl.cast(draft_token_num * draft_token_num * batch_idx, seq_len.dtype)
+ seq_len_prefix_sum * draft_token_num
)
positions_offset = batch_idx * draft_token_num
tl.store(positions_ptr + positions_offset, seq_len)
retrieve_index_offset = batch_idx * draft_token_num
# Build retrieval index structure (reverse loop from draft_token_num-1 to 1)
for i in range(draft_token_num - 1, 0, -1):
current_token_idx = retrieve_index_offset + i
tl.store(
retrieve_index_ptr + batch_idx * draft_token_num + i,
current_token_idx,
)
parent_tb_idx = (
tl.load(selected_index_ptr + batch_idx * selected_index_stride + (i - 1))
// topk
)
parent_position = 0
found = 0
if parent_tb_idx == 0:
found = 1
else:
parent_token_idx = tl.load(
parent_list_ptr + batch_idx * parent_list_stride + parent_tb_idx
)
# Find parent position
for pp in range(draft_token_num - 1):
if found == 0:
sel_idx = tl.load(
selected_index_ptr + batch_idx * selected_index_stride + pp
)
if sel_idx == parent_token_idx:
parent_position = pp + 1
found = 1
if found == 1:
# Update next token links
next_tok_addr = (
retrieve_next_token_ptr + batch_idx * draft_token_num + parent_position
)
next_tok = tl.load(next_tok_addr)
if next_tok == -1:
tl.store(next_tok_addr, i)
else:
tl.store(next_tok_addr, i)
tl.store(
retrieve_next_sibling_ptr + batch_idx * draft_token_num + i,
next_tok,
)
tl.store(retrieve_index_ptr + batch_idx * draft_token_num, retrieve_index_offset)
# Process all draft token indices for tree mask
for draft_tokenx in range(draft_token_num):
if tree_mask_mode == 0: # FULL_MASK
token_tree_idx = (
seq_tree_idx + (seq_len + draft_token_num) * draft_tokenx + seq_len + 1
)
else:
token_tree_idx = (
draft_token_num * draft_token_num * batch_idx
+ draft_token_num * draft_tokenx
+ 1
)
tl.store(tree_mask_ptr + token_tree_idx - 1, 1)
for i in range(draft_token_num - 1):
tl.store(tree_mask_ptr + token_tree_idx + i, 0)
if draft_tokenx > 0:
# Build tree path for draft_tokenx > 0
cur_position = draft_tokenx - 1
position = 0
should_continue = 1
for _ in range(depth):
if should_continue:
position += 1
tl.store(tree_mask_ptr + token_tree_idx + cur_position, 1)
parent_tb_idx = (
tl.load(
selected_index_ptr
+ batch_idx * selected_index_stride
+ cur_position
)
// topk
)
if parent_tb_idx == 0:
should_continue = 0
else:
parent_token_idx = tl.load(
parent_list_ptr
+ batch_idx * parent_list_stride
+ parent_tb_idx
)
# Find cur_position for next iteration
found = 0
for cp in range(draft_token_num - 1):
if found == 0:
if (
tl.load(
selected_index_ptr
+ batch_idx * selected_index_stride
+ cp
)
== parent_token_idx
):
cur_position = cp
found = 1
if found == 0:
should_continue = 0
tl.store(
positions_ptr + batch_idx * draft_token_num + draft_tokenx,
position + seq_len,
)
@triton.jit
def verify_tree_greedy_kernel_triton(
predicts_ptr,
accept_index_ptr,
accept_token_num_ptr,
candidates_ptr,
retrieve_index_ptr,
retrieve_next_token_ptr,
retrieve_next_sibling_ptr,
target_predict_ptr,
batch_size: tl.constexpr,
num_speculative_tokens: tl.constexpr,
num_draft_tokens: tl.constexpr,
):
"""
Triton kernel for verifying EAGLE tree in greedy mode.
Each program handles one batch item.
"""
bx = tl.program_id(0)
# Initialize
last_accept_retrieve_idx = tl.load(retrieve_index_ptr + bx * num_draft_tokens)
tl.store(accept_index_ptr + bx * num_speculative_tokens, last_accept_retrieve_idx)
# Cast to match dtype of loaded tensors to avoid type inconsistency
num_accept_tokens = tl.cast(0, last_accept_retrieve_idx.dtype)
cur_index = tl.cast(0, last_accept_retrieve_idx.dtype)
# Tree traversal loop
should_continue = 1
for j in range(1, num_speculative_tokens):
if should_continue: # Early exit guard
cur_index = tl.load(
retrieve_next_token_ptr + bx * num_draft_tokens + cur_index
)
# Load target token once per level (before sibling search)
# last_accept_retrieve_idx is constant during sibling traversal
target_row = last_accept_retrieve_idx // num_draft_tokens
target_col = last_accept_retrieve_idx % num_draft_tokens
target_token = tl.load(
target_predict_ptr + target_row * num_draft_tokens + target_col
)
# Traverse siblings
found_match = 0
for _ in range(num_draft_tokens): # Max iterations = num_draft_tokens
if found_match == 0: # Early exit guard
# Check if we've reached end of sibling list
is_valid = cur_index != -1
# Use masked loads with safe address (0 when invalid)
safe_cur_index = (
cur_index * is_valid
) # 0 if invalid, cur_index if valid
safe_index = bx * num_draft_tokens + safe_cur_index
# Load draft token info (loads from index 0 when invalid, but we won't use it)
draft_index = tl.load(retrieve_index_ptr + safe_index)
draft_token = tl.load(candidates_ptr + safe_index)
# Check for token match (only valid when is_valid is True)
token_match = is_valid & (draft_token == target_token)
# Accept token using predicated stores (only write if matched)
tl.store(
predicts_ptr + last_accept_retrieve_idx,
target_token,
mask=token_match,
)
next_num_accept_tokens = num_accept_tokens + 1
tl.store(
accept_index_ptr
+ bx * num_speculative_tokens
+ next_num_accept_tokens,
draft_index,
mask=token_match,
)
num_accept_tokens = num_accept_tokens + token_match
last_accept_retrieve_idx = (
token_match * draft_index
+ (~token_match) * last_accept_retrieve_idx
)
found_match = token_match * 1 + (~is_valid) * (-1)
# Masked load: only load next sibling when no match (hardware predication)
# When matched: returns cur_index (other); when not matched: loads sibling
cur_index = tl.load(
retrieve_next_sibling_ptr + safe_index,
mask=~token_match
& is_valid, # Only load when valid and NOT matched
other=cur_index, # Keep cur_index when matched or invalid
)
if found_match != 1:
should_continue = 0
# Store final results
tl.store(accept_token_num_ptr + bx, num_accept_tokens)
target_row = last_accept_retrieve_idx // num_draft_tokens
target_col = last_accept_retrieve_idx % num_draft_tokens
final_target = tl.load(
target_predict_ptr + target_row * num_draft_tokens + target_col
)
tl.store(predicts_ptr + last_accept_retrieve_idx, final_target)