[DeepSeek v3.2] opt Context Parallelism: support fused moe, multi batch and fp8 kvcache (#13959)

This commit is contained in:
Yongfei Xu
2026-01-02 23:49:14 +08:00
committed by GitHub
parent 0eae831797
commit 0d244116d2
14 changed files with 602 additions and 263 deletions
+10 -16
View File
@@ -64,8 +64,8 @@ from sglang.srt.layers.attention.nsa.utils import (
cp_all_gather_rerange_output,
cp_split_and_rebuild_data,
cp_split_and_rebuild_position,
enable_prefill_cp,
is_nsa_enable_prefill_cp,
nsa_use_prefill_cp,
prepare_input_dp_with_cp_dsa,
)
from sglang.srt.layers.attention.tbo_backend import TboAttnBackend
@@ -578,9 +578,7 @@ class MoEGate(nn.Module):
if get_global_server_args().enable_deterministic_inference:
return F.linear(hidden_states, self.weight, None)
if forward_batch is not None and enable_prefill_cp(
forward_batch, self.nsa_enable_prefill_cp
):
if forward_batch is not None and nsa_use_prefill_cp(forward_batch):
logits = F.linear(hidden_states, self.weight, None)
else:
# NOTE: For some unknown reason, router_gemm seems degrade accept length.
@@ -2006,8 +2004,6 @@ class DeepseekV2AttentionMLA(nn.Module):
q_nope_out = q_nope_out.transpose(0, 1)
if enable_prefill_cp(forward_batch, self.nsa_enable_prefill_cp):
positions = cp_split_and_rebuild_position(forward_batch, positions)
if (
self.rotary_emb is not None
and (not self._fuse_rope_for_trtllm_mla(forward_batch))
@@ -2015,7 +2011,7 @@ class DeepseekV2AttentionMLA(nn.Module):
):
q_pe, k_pe = self.rotary_emb(positions, q_pe, k_pe)
if enable_prefill_cp(forward_batch, self.nsa_enable_prefill_cp):
if nsa_use_prefill_cp(forward_batch):
# support allgather+rerrange
k_nope, k_pe = self.rebuild_cp_kv_cache(
latent_cache, forward_batch, k_nope, k_pe
@@ -3181,8 +3177,10 @@ class DeepseekV2Model(nn.Module):
hidden_states = pp_proxy_tensors["hidden_states"]
residual = pp_proxy_tensors["residual"]
if enable_prefill_cp(forward_batch, self.nsa_enable_prefill_cp):
hidden_states = cp_split_and_rebuild_data(forward_batch, hidden_states)
if nsa_use_prefill_cp(forward_batch):
if self.pp_group.is_first_rank:
hidden_states = cp_split_and_rebuild_data(forward_batch, hidden_states)
positions = cp_split_and_rebuild_position(forward_batch, positions)
# llama_4_scaling: for supporting Mistral-Large-3 model
# Compute llama 4 scaling once per forward pass if enabled
@@ -3262,7 +3260,7 @@ class DeepseekV2Model(nn.Module):
else:
hidden_states, _ = self.norm(hidden_states, residual)
if enable_prefill_cp(forward_batch, self.nsa_enable_prefill_cp):
if self.pp_group.is_last_rank and nsa_use_prefill_cp(forward_batch):
# allgather + rerrange
hidden_states = cp_all_gather_rerange_output(
hidden_states,
@@ -3400,13 +3398,9 @@ class DeepseekV2ForCausalLM(nn.Module):
pp_proxy_tensors: Optional[PPProxyTensors] = None,
) -> torch.Tensor:
if self.nsa_enable_prefill_cp:
# TODO current just support prefill batch=1 and len(input_ids) > self.cp_size * 2
# Note: (self.cp_size * 2) To achieve load balancing for seq computation,
# the seq data needs to be divided and recombined at twice the size of cp_size.
cur_cp_seq_len = len(input_ids) // (self.cp_size * 2)
if can_cp_split(cur_cp_seq_len, self.cp_size, self.use_nsa, forward_batch):
if can_cp_split(len(input_ids), self.cp_size, self.use_nsa, forward_batch):
forward_batch.nsa_cp_metadata = prepare_input_dp_with_cp_dsa(
torch.tensor(len(input_ids)),
len(input_ids),
self.cp_rank,
self.cp_size,
forward_batch.seq_lens_cpu.tolist(),