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

364 lines
13 KiB
Python

# SPDX-License-Identifier: Apache-2.0
# SPDX-FileCopyrightText: Copyright contributors to the SGLang project
from __future__ import annotations
import logging
from typing import Any, Iterable, List, Optional, Tuple
import torch
from sglang.srt.layers.logits_processor import LogitsProcessorOutput
from sglang.srt.layers.quantization.base_config import QuantizationConfig
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
from sglang.srt.model_executor.forward_context import (
get_req_to_token_pool,
get_token_to_kv_pool,
)
from sglang.srt.models.registry import import_model_classes
from sglang.srt.runtime_context import get_parallel
from sglang.srt.utils import is_npu
_is_npu = is_npu()
if _is_npu:
import mindspore as ms
import numpy as np
import torch_npu
from mindspore import Tensor, mint, mutable
logger = logging.getLogger(__name__)
def _get_arch_from_config(config):
mindspore_models = import_model_classes("sgl_mindspore.models")
architectures = getattr(config, "architectures", [])
if isinstance(architectures, str):
architectures = [architectures]
if not architectures:
raise ValueError("No model architectures are specified")
for arch in architectures:
if arch in mindspore_models:
return mindspore_models[arch]
raise ValueError(f"Unsupported arch {architectures}")
def tensor_torch2ms(x: torch.Tensor):
if x is None or not isinstance(x, torch.Tensor):
return x
# torch tensor -> dlpack -> mindspore tensor
pt_dlpack = torch.utils.dlpack.to_dlpack(x)
ms_tensor = ms.utils.dlpack.from_dlpack(pt_dlpack)
return ms_tensor
def tensor_ms2torch(x: ms.Tensor):
if x is None or not isinstance(x, ms.Tensor):
return x
# ms tensor -> dlpack -> torch tensor
ms_dlpack = ms.utils.dlpack.to_dlpack(x)
torch_tensor = torch.utils.dlpack.from_dlpack(ms_dlpack)
torch_npu.npu.synchronize()
return torch_tensor
# Adapt from: https://gitee.com/mindspore/vllm-mindspore/blob/master/vllm_mindspore/model_executor/models/attention_mask.py
class LowerTriangularMask:
r"""
Provide Infer model attention mask.
Args:
dtype (ms dtype): The compute type of Infer model.
max_model_len (int): The max model length of Infer model.
"""
def __init__(self, dtype, max_model_len, decode_mask_coeff=-10000.0):
self.dtype = dtype
self.max_model_len = max_model_len
self.cached_mask_len = 8 * 1024
self.decode_mask_coeff = decode_mask_coeff
prefill_mask_coeff = 1.0 if self.dtype == ms.bfloat16 else -10000.0
self.prefill_mask = Tensor(
np.triu(np.ones(shape=(128, 128), dtype=np.float16), k=1)
* prefill_mask_coeff,
dtype=self.dtype,
)
self.hard_mask = mint.zeros((1, 1), dtype=dtype)
self.decode_mask = (
Tensor(
np.triu(
np.ones(
shape=(self.cached_mask_len, self.cached_mask_len),
dtype=np.int8,
),
k=1,
),
dtype=self.dtype,
)
* self.decode_mask_coeff
)
def create_mask(self, query_lens_np, seq_lens_np):
"""
when query_lens_np = [3], seq_lens_np = [6], decode_mask_coeff = 1
init attention mask
0 0 0 0 0 0
0 0 0 0 0 0
0 0 0 0 0 0
"""
max_seq_len = seq_lens_np.max().item()
total_q_len = query_lens_np.sum().item()
attention_mask = mint.zeros((total_q_len, max_seq_len), dtype=self.dtype)
req_num = query_lens_np.shape[0]
current_row = 0
for i in range(req_num):
q_len = query_lens_np[i].item()
current_row += q_len
# skip row when q_len <= 1, to decrease execute time
if q_len <= 1:
continue
seq_len = seq_lens_np[i].item()
context_len = seq_len - q_len
"""
set the right half to 1
0 0 0 1 1 1
0 0 0 1 1 1
0 0 0 1 1 1
"""
attention_mask[current_row - q_len : current_row, context_len:] = (
self.decode_mask_coeff
)
"""
set the lower triangle of the right half to 0
0 0 0 0 1 1
0 0 0 0 0 1
0 0 0 0 0 0
"""
right_tensor = attention_mask[
current_row - q_len : current_row, context_len:seq_len
]
# use masked_fill_ to inplace modify attention_mask
right_tensor.masked_fill_(right_tensor.tril() == self.decode_mask_coeff, 0)
return attention_mask
def gen_attention_mask(
self,
is_prefill: bool,
position_ids: ms.Tensor,
query_lens_np: np.ndarray,
seq_lens_np: np.ndarray,
):
max_query_len = query_lens_np.max()
max_seq_len = seq_lens_np.max()
if is_prefill:
attention_mask = self.prefill_mask
elif max_query_len > 1:
if max_seq_len <= self.cached_mask_len:
attention_mask = mint.index_select(self.decode_mask, 0, position_ids)
else:
attention_mask = self.create_mask(query_lens_np, seq_lens_np)
else:
attention_mask = self.hard_mask
return attention_mask
class MindSporeForCausalLM(torch.nn.Module):
def __init__(
self,
config: Any,
quant_config: Optional[QuantizationConfig] = None,
prefix: str = "",
) -> None:
super().__init__()
self.config = config
ms.set_context(graph_kernel_flags="--disable_pass=gather_pre_rms_norm_fusion")
ms.set_kernel_launch_capture(False)
logger.info(
"MindSporeForCausalLM tp size %d tp rank %d",
get_parallel().tp_size,
get_parallel().tp_rank,
)
if get_parallel().tp_size not in (1, 2, 4, 8):
# MatMulAllReduce only support tp size in (1, 2, 4, 8)
ms.set_context(graph_kernel_flags="--disable_pass=MatMulAllReduce")
arch = self.get_arch(self.config)
self.model = arch(config=config, quant_config=quant_config)
self.causal_mask = LowerTriangularMask(
self.config.param_dtype, self.config.max_position_embeddings
)
self.key_cache = []
self.value_cache = []
@property
def hot_token_id(self):
if hasattr(self.model, "hot_token_id"):
return tensor_ms2torch(self.model.hot_token_id)
return None
def get_arch(self, config):
return _get_arch_from_config(config)
@property
def use_mla(self):
return self.config.architectures[0] in ("DeepseekV3ForCausalLM")
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
self.model.load_weights(weights)
for _, cell in self.model.cells_and_names():
quant_method = getattr(cell, "quant_method", None)
if quant_method is not None:
quant_method.process_weights_after_loading(cell)
def get_kvcache(self, forward_batch: ForwardBatch):
def prepare_cache(cache_list, is_key_cache):
for i in range(self.config.num_hidden_layers):
if is_key_cache:
cache = get_token_to_kv_pool().get_key_buffer(i)
else:
cache = get_token_to_kv_pool().get_value_buffer(i)
cache_ms = tensor_torch2ms(cache)
if self.use_mla and cache_ms.ndim == 3:
cache_ms = mint.unsqueeze(cache_ms, 2)
cache_list.append(cache_ms)
if self.use_mla:
if not self.key_cache:
prepare_cache(self.key_cache, is_key_cache=True)
return mutable(self.key_cache)
if self.key_cache and self.value_cache:
return mutable(self.key_cache), mutable(self.value_cache)
prepare_cache(self.key_cache, is_key_cache=True)
prepare_cache(self.value_cache, is_key_cache=False)
return mutable(self.key_cache), mutable(self.value_cache)
def _is_prefill(self, forward_batch: ForwardBatch):
# Different processing for the mindspore attention operator
# Without any prefix cache => Use FlashAttentionScore
# With cache => Use PagedAttention, no matter the query length is 1 or not
is_prefill = (
forward_batch.forward_mode.is_extend()
and not forward_batch.forward_mode.is_draft_extend_v2()
and not forward_batch.forward_mode.is_target_verify()
)
if forward_batch.extend_prefix_lens is not None:
is_prefill = (
is_prefill and forward_batch.extend_prefix_lens.sum().item() == 0
)
return is_prefill
def prepare_inputs(self, input_ids, positions, forward_batch):
if self.use_mla:
key_cache = self.get_kvcache(forward_batch)
else:
key_cache, value_cache = self.get_kvcache(forward_batch)
is_prefill = self._is_prefill(forward_batch)
batch_valid_length = forward_batch.seq_lens.cpu().numpy()
if forward_batch.forward_mode.is_target_verify():
batch_valid_length += forward_batch.spec_info.num_tokens_per_req
if forward_batch.extend_seq_lens is not None:
q_seq_lens = forward_batch.extend_seq_lens.cpu().numpy()
else:
q_seq_lens = np.ones([forward_batch.batch_size], dtype=np.int32)
if forward_batch.forward_mode.is_target_verify():
q_seq_lens = q_seq_lens * forward_batch.spec_info.num_tokens_per_req
page_size = get_token_to_kv_pool().page_size
block_tables = tensor_torch2ms(
(
get_req_to_token_pool().req_to_token[
forward_batch.req_pool_indices, : batch_valid_length.max()
][:, ::page_size]
// page_size
)
).to(ms.int32)
model_inputs = {}
model_inputs["input_ids"] = tensor_torch2ms(input_ids).to(ms.int32)
model_inputs["batch_valid_length"] = ms.Tensor(
batch_valid_length, dtype=ms.int32
)
model_inputs["position_ids"] = tensor_torch2ms(positions)
model_inputs["q_seq_lens"] = ms.Tensor(q_seq_lens, dtype=ms.int32)
model_inputs["attention_mask"] = self.causal_mask.gen_attention_mask(
is_prefill, model_inputs["position_ids"], q_seq_lens, batch_valid_length
).contiguous()
model_inputs["out_cache_loc"] = tensor_torch2ms(forward_batch.out_cache_loc).to(
ms.int32
)
model_inputs["is_prefill"] = is_prefill
model_inputs["key_cache"] = key_cache
if not self.use_mla:
model_inputs["value_cache"] = value_cache
model_inputs["block_tables"] = block_tables
# for speculative decode
model_inputs["forward_mode"] = forward_batch.forward_mode
return model_inputs
def forward(
self,
input_ids: torch.Tensor,
positions: torch.Tensor,
forward_batch: ForwardBatch,
) -> ms.Tensor:
# prepare base inputs
model_inputs = self.prepare_inputs(input_ids, positions, forward_batch)
# prepare model inputs
model_inputs = self.model.prepare_inputs(forward_batch, model_inputs)
# Used by speculative decoding (EAGLE)
if self.model.capture_aux_hidden_states:
logits, hidden_states = self.model(**model_inputs)
else:
logits = self.model(**model_inputs)
hidden_states = None
logits_result = LogitsProcessorOutput(
next_token_logits=tensor_ms2torch(logits),
hidden_states=tensor_ms2torch(hidden_states),
)
return logits_result
@classmethod
def get_model_config_for_expert_location(cls, config):
try:
arch_cls = _get_arch_from_config(config)
method = getattr(arch_cls, "get_model_config_for_expert_location", None)
if method is None:
return None
return method(config)
except Exception:
return None
# The following methods are used for speculative decoding
def get_embed_and_head(self):
embed, head = self.model.get_embed_and_head()
return tensor_ms2torch(embed), tensor_ms2torch(head)
def set_embed_and_head(self, embed, head):
self.model.set_embed_and_head(tensor_torch2ms(embed), tensor_torch2ms(head))
def get_embed(self):
return tensor_ms2torch(self.model.get_embed())
def set_embed(self, embed):
self.model.set_embed(tensor_torch2ms(embed))
def set_eagle3_layers_to_capture(self, layer_ids: Optional[List[int]] = None):
self.model.set_eagle3_layers_to_capture(layer_ids)
EntryClass = [MindSporeForCausalLM]