chore: import upstream snapshot with attribution
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
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
This commit is contained in:
@@ -0,0 +1,378 @@
|
||||
import logging
|
||||
import math
|
||||
|
||||
import torch
|
||||
|
||||
from sglang.srt.layers.attention.hybrid_linear_attn_backend import MambaAttnBackendBase
|
||||
from sglang.srt.layers.attention.linear.lightning_attn import (
|
||||
BailingLinearKernel,
|
||||
linear_decode_forward_triton,
|
||||
)
|
||||
from sglang.srt.layers.attention.linear.linear_metadata import (
|
||||
BailingLinearMetadata,
|
||||
)
|
||||
from sglang.srt.layers.attention.linear.seg_la import SegLaMeta, seg_la_fwd
|
||||
from sglang.srt.layers.radix_attention import RadixAttention
|
||||
from sglang.srt.model_executor.forward_batch_info import ForwardBatch
|
||||
from sglang.srt.model_executor.model_runner import ModelRunner
|
||||
from sglang.srt.runtime_context import get_parallel
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LightningAttentionBackend(MambaAttnBackendBase):
|
||||
"""
|
||||
Note about the init:
|
||||
- If no spec decoding
|
||||
- FlashAttentionBackend will be init once when the server starts.
|
||||
- If spec decoding
|
||||
- FlashAttentionBackend will be init once for the target worker
|
||||
- FlashAttentionMultiStepBackend will be once for the draft worker
|
||||
- It will spawn num_steps FlashAttentionBackend for the draft worker
|
||||
|
||||
Note about CUDA Graph:
|
||||
- We only support CUDA Graph for Decode (Normal Decode and Draft Decode) and Target Verify.
|
||||
- We don't support CUDA Graph for Extend and Draft Extend.
|
||||
- When server init, init_cuda_graph_state will be called first and then init_cuda_graph_capture will be called.
|
||||
- For each forward batch, init_replay_cuda_graph will be called first and then replay the graph.
|
||||
"""
|
||||
|
||||
def __init__(self, model_runner: ModelRunner):
|
||||
super().__init__(model_runner)
|
||||
# seg_la processes draft tokens as a chain -- it has no parent-indices
|
||||
# plumbing for tree-shaped drafts, so spec v2 tree verify (topk > 1) would
|
||||
# commit wrong mamba states silently. Fail fast instead of mis-decoding.
|
||||
if self.topk > 1:
|
||||
raise NotImplementedError(
|
||||
"Lightning (seg_la) linear-attention backend does not support "
|
||||
f"speculative decoding with topk > 1 (got topk={self.topk}); "
|
||||
"seg_la verifies a draft tree as a chain. Use "
|
||||
"--speculative-eagle-topk 1."
|
||||
)
|
||||
# lightning attn does not need conv cache, but to keep the interface for mamba cache
|
||||
self.conv_states_shape = (
|
||||
model_runner.req_to_token_pool.mamba_pool.mamba_cache.conv[0].shape
|
||||
)
|
||||
|
||||
assert not (
|
||||
model_runner.sliding_window_size is not None
|
||||
and model_runner.model_config.is_encoder_decoder
|
||||
), "Sliding window and cross attention are not supported together"
|
||||
|
||||
# extra metadata for handling speculative decoding topk > 1, extended draft decode and verify
|
||||
self.max_context_len = model_runner.model_config.context_len
|
||||
self.device = model_runner.device
|
||||
self.decode_cuda_graph_metadata = {}
|
||||
self.kv_cache_dtype = model_runner.kv_cache_dtype
|
||||
self.kv_cache_dtype_str = model_runner.server_args.kv_cache_dtype
|
||||
self.BLOCK = (
|
||||
model_runner.model_config.block
|
||||
if hasattr(model_runner.model_config, "block")
|
||||
else 256
|
||||
)
|
||||
total_num_heads = model_runner.model_config.hf_config.num_attention_heads
|
||||
num_hidden_layers = model_runner.model_config.hf_config.num_hidden_layers
|
||||
self.tp_slope = LightningAttentionBackend._build_slope_tensor(
|
||||
total_num_heads, num_hidden_layers, self.device
|
||||
)
|
||||
self.linear_backend = getattr(
|
||||
model_runner.model_config.hf_config, "linear_backend", "seg_la"
|
||||
)
|
||||
logger.info(
|
||||
f"linear_backend for linear attention in hybrid_linear_backend: {self.linear_backend}"
|
||||
)
|
||||
|
||||
def init_forward_metadata_out_graph(
|
||||
self,
|
||||
forward_batch: ForwardBatch,
|
||||
in_capture: bool = False,
|
||||
):
|
||||
# seq_lens_cpu is unused by the underlying _replay_metadata for
|
||||
# non-target-verify modes; pass it through for compatibility.
|
||||
bs = forward_batch.batch_size
|
||||
metadata = self._replay_metadata(
|
||||
bs,
|
||||
forward_batch.req_pool_indices,
|
||||
forward_batch.forward_mode,
|
||||
forward_batch.spec_info,
|
||||
forward_batch.seq_lens_cpu if not in_capture else None,
|
||||
)
|
||||
self.forward_metadata = BailingLinearMetadata.prepare_decode(
|
||||
metadata.query_start_loc,
|
||||
metadata.mamba_cache_indices,
|
||||
bs,
|
||||
forward_batch.seq_lens,
|
||||
)
|
||||
|
||||
def init_forward_metadata(self, forward_batch: ForwardBatch):
|
||||
metadata = self._forward_metadata(forward_batch)
|
||||
self.forward_metadata = BailingLinearMetadata.prepare_mixed(
|
||||
metadata.query_start_loc,
|
||||
metadata.mamba_cache_indices,
|
||||
forward_batch,
|
||||
)
|
||||
|
||||
@staticmethod
|
||||
def _build_slope_tensor(
|
||||
n_attention_heads: int, num_hidden_layers: int, device="cuda"
|
||||
):
|
||||
def get_slopes(n):
|
||||
def get_slopes_power_of_2(n):
|
||||
start = 2 ** (-(2 ** -(math.log2(n) - 3)))
|
||||
ratio = start
|
||||
return [start * ratio**i for i in range(n)]
|
||||
|
||||
if math.log2(n).is_integer():
|
||||
return get_slopes_power_of_2(n)
|
||||
else:
|
||||
closest_power_of_2 = 2 ** math.floor(math.log2(n))
|
||||
return (
|
||||
get_slopes_power_of_2(closest_power_of_2)
|
||||
+ get_slopes(2 * closest_power_of_2)[0::2][: n - closest_power_of_2]
|
||||
)
|
||||
|
||||
slopes = torch.tensor(
|
||||
get_slopes(n_attention_heads), dtype=torch.float32
|
||||
).reshape(n_attention_heads, 1, 1)
|
||||
|
||||
tp_heads = n_attention_heads // get_parallel().attn_tp_size
|
||||
tp_rank = get_parallel().attn_tp_rank
|
||||
if num_hidden_layers <= 1:
|
||||
slope_rate_list = [slopes * (1 + 1e-5)]
|
||||
else:
|
||||
slope_rate_list = [
|
||||
slopes * (1 - layer_id / (num_hidden_layers - 1) + 1e-5)
|
||||
for layer_id in range(num_hidden_layers)
|
||||
]
|
||||
|
||||
tp_slope = [
|
||||
slope_rate_list[layer_id][tp_rank * tp_heads : (tp_rank + 1) * tp_heads]
|
||||
.contiguous()
|
||||
.to(device)
|
||||
for layer_id in range(num_hidden_layers)
|
||||
]
|
||||
|
||||
return tp_slope
|
||||
|
||||
def _prefill_and_mix_infer(
|
||||
self,
|
||||
q,
|
||||
k,
|
||||
v,
|
||||
kv_cache,
|
||||
state_indices_tensor,
|
||||
forward_batch,
|
||||
layer,
|
||||
metadata,
|
||||
):
|
||||
hidden = []
|
||||
for _prefill_idx in range(metadata.num_prefills):
|
||||
if _prefill_idx >= forward_batch.extend_start_loc.shape[0]:
|
||||
break
|
||||
if _prefill_idx >= state_indices_tensor.shape[0]:
|
||||
break
|
||||
|
||||
_start = forward_batch.extend_start_loc[_prefill_idx]
|
||||
|
||||
if _prefill_idx + 1 < forward_batch.extend_start_loc.shape[0]:
|
||||
_end = forward_batch.extend_start_loc[_prefill_idx + 1]
|
||||
else:
|
||||
if (
|
||||
forward_batch.extend_seq_lens is not None
|
||||
and _prefill_idx < forward_batch.extend_seq_lens.shape[0]
|
||||
and metadata.num_decodes > 0
|
||||
):
|
||||
seq_len = forward_batch.extend_seq_lens[_prefill_idx]
|
||||
_end = _start + seq_len
|
||||
else:
|
||||
_end = q.shape[0]
|
||||
|
||||
slot_id = state_indices_tensor[_prefill_idx]
|
||||
qs = q[_start:_end].transpose(0, 1).contiguous()
|
||||
ks = k[_start:_end].transpose(0, 1).contiguous()
|
||||
vs = v[_start:_end].transpose(0, 1).contiguous()
|
||||
slice_layer_cache = kv_cache[slot_id, ...]
|
||||
out_slice = BailingLinearKernel.jit_linear_forward_prefix(
|
||||
qs,
|
||||
ks,
|
||||
vs,
|
||||
slice_layer_cache,
|
||||
self.tp_slope[layer.layer_id],
|
||||
self.BLOCK,
|
||||
layer_idx=layer.layer_id,
|
||||
)
|
||||
hidden.append(out_slice.contiguous())
|
||||
if metadata.num_decodes > 0:
|
||||
hidden.append(
|
||||
self._decode_infer(
|
||||
q, k, v, kv_cache, state_indices_tensor, metadata, layer
|
||||
)
|
||||
)
|
||||
|
||||
if not hidden:
|
||||
return torch.empty((0, q.size(-1)), device=q.device, dtype=q.dtype)
|
||||
|
||||
hidden = torch.concat(hidden, dim=0).contiguous()
|
||||
return hidden
|
||||
|
||||
def _decode_infer(self, q, k, v, kv_cache, state_indices_tensor, metadata, layer):
|
||||
num_prefill_tokens = metadata.num_prefill_tokens
|
||||
num_prefills = metadata.num_prefills
|
||||
q = q[num_prefill_tokens:].unsqueeze(2).contiguous()
|
||||
k = k[num_prefill_tokens:].unsqueeze(2).contiguous()
|
||||
v = v[num_prefill_tokens:].unsqueeze(2).contiguous()
|
||||
slot_id = state_indices_tensor[num_prefills:]
|
||||
|
||||
assert slot_id.shape[0] == q.shape[0], (
|
||||
f"slot_id length {slot_id.shape[0]} does not match decode batch size {q.shape[0]}. "
|
||||
"This indicates a bug in the upstream logic that should be investigated."
|
||||
)
|
||||
hidden = linear_decode_forward_triton(
|
||||
q, k, v, kv_cache, self.tp_slope[layer.layer_id], slot_id, 32
|
||||
)
|
||||
return hidden
|
||||
|
||||
def _linear_attention_entry(
|
||||
self,
|
||||
q,
|
||||
k,
|
||||
v,
|
||||
kv_cache,
|
||||
state_indices_tensor,
|
||||
metadata,
|
||||
layer,
|
||||
mask=None,
|
||||
temp_cache=None,
|
||||
intermediate_state_indices=None,
|
||||
):
|
||||
q_offsets = metadata.query_start_loc
|
||||
|
||||
seg_meta = SegLaMeta(
|
||||
batch_size=metadata.batch_size,
|
||||
q_offsets=metadata.query_start_loc,
|
||||
s_offsets=state_indices_tensor,
|
||||
q_lengths=q_offsets.diff(),
|
||||
s_scales=metadata.has_initial_states,
|
||||
max_q_length=None,
|
||||
mask=mask,
|
||||
)
|
||||
hidden = seg_la_fwd(
|
||||
q=q,
|
||||
k=k,
|
||||
v=v,
|
||||
s=kv_cache,
|
||||
decay_scales=self.tp_slope[layer.layer_id],
|
||||
meta=seg_meta,
|
||||
caches=temp_cache,
|
||||
cache_indices=intermediate_state_indices,
|
||||
decouple=True,
|
||||
)
|
||||
return hidden
|
||||
|
||||
def forward_extend(
|
||||
self,
|
||||
q: torch.Tensor,
|
||||
k: torch.Tensor,
|
||||
v: torch.Tensor,
|
||||
layer: RadixAttention,
|
||||
forward_batch: ForwardBatch,
|
||||
save_kv_cache=True,
|
||||
**kwargs,
|
||||
):
|
||||
layer_id = layer.layer_id if layer else kwargs["layer_id"]
|
||||
|
||||
metadata = self.forward_metadata
|
||||
|
||||
if self.kv_cache_dtype_str != "auto" and layer.k_scale is not None:
|
||||
q = q.to(self.kv_cache_dtype)
|
||||
|
||||
cache_indices = self.forward_metadata.mamba_cache_indices
|
||||
mamba_cache_params = self.req_to_token_pool.mamba2_layer_cache(layer_id)
|
||||
ssm_states = mamba_cache_params.temporal
|
||||
if self.linear_backend == "minimax":
|
||||
o = self._prefill_and_mix_infer(
|
||||
q.contiguous().view(-1, layer.tp_q_head_num, layer.head_dim),
|
||||
k,
|
||||
v,
|
||||
ssm_states,
|
||||
cache_indices,
|
||||
forward_batch,
|
||||
layer,
|
||||
metadata,
|
||||
)
|
||||
elif self.linear_backend == "seg_la":
|
||||
intermediate_state_indices = (
|
||||
torch.arange(
|
||||
cache_indices.shape[0],
|
||||
dtype=torch.int32,
|
||||
device=cache_indices.device,
|
||||
)
|
||||
if forward_batch.forward_mode.is_target_verify()
|
||||
else None
|
||||
)
|
||||
o = self._linear_attention_entry(
|
||||
q,
|
||||
k,
|
||||
v,
|
||||
ssm_states,
|
||||
cache_indices,
|
||||
metadata,
|
||||
layer,
|
||||
temp_cache=(
|
||||
mamba_cache_params.intermediate_ssm
|
||||
if forward_batch.forward_mode.is_target_verify()
|
||||
else None
|
||||
),
|
||||
intermediate_state_indices=intermediate_state_indices,
|
||||
)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"linear backend: {self.linear_backend} is not support for now"
|
||||
)
|
||||
|
||||
if (
|
||||
not forward_batch.forward_mode.is_target_verify()
|
||||
and forward_batch.mamba_track_mask is not None
|
||||
):
|
||||
# save mamba cache for extra buffer
|
||||
mamba_track_mask = forward_batch.mamba_track_mask
|
||||
mamba_track_indices = forward_batch.mamba_track_indices
|
||||
dst_masked = mamba_track_indices[mamba_track_mask]
|
||||
src_masked = metadata.mamba_cache_indices[mamba_track_mask]
|
||||
ssm_states[dst_masked] = ssm_states[src_masked]
|
||||
|
||||
return o.view(-1, layer.tp_q_head_num * layer.v_head_dim)
|
||||
|
||||
def forward_decode(
|
||||
self,
|
||||
q: torch.Tensor,
|
||||
k: torch.Tensor,
|
||||
v: torch.Tensor,
|
||||
layer: RadixAttention,
|
||||
forward_batch: ForwardBatch,
|
||||
save_kv_cache=True,
|
||||
**kwargs,
|
||||
) -> torch.Tensor:
|
||||
layer_id = layer.layer_id if layer else kwargs["layer_id"]
|
||||
|
||||
# Use precomputed metadata across all layers
|
||||
metadata = self.forward_metadata
|
||||
|
||||
if self.kv_cache_dtype_str != "auto":
|
||||
q = q.to(self.kv_cache_dtype)
|
||||
|
||||
# Do linear attention
|
||||
cache_indices = self.forward_metadata.mamba_cache_indices
|
||||
mamba_cache_params = self.req_to_token_pool.mamba2_layer_cache(layer_id)
|
||||
ssm_states = mamba_cache_params.temporal
|
||||
if self.linear_backend == "minimax":
|
||||
o = self._decode_infer(q, k, v, ssm_states, cache_indices, metadata, layer)
|
||||
elif self.linear_backend == "seg_la":
|
||||
o = self._linear_attention_entry(
|
||||
q, k, v, ssm_states, cache_indices, metadata, layer
|
||||
)
|
||||
else:
|
||||
raise ValueError(
|
||||
f"linear backend: {self.linear_backend} is not support for now"
|
||||
)
|
||||
return o.view(-1, layer.tp_q_head_num * layer.v_head_dim)
|
||||
Reference in New Issue
Block a user