[feature] implement dcp for deepseek_v2 (#14194)

This commit is contained in:
Augusto Yao
2026-06-25 15:15:04 -07:00
committed by GitHub
parent e4696ed62d
commit ea8f4e9f3f
20 changed files with 1770 additions and 30 deletions
@@ -28,6 +28,10 @@ class ForwardBatchDeepSeekMHAMixin:
prefix_chunk_len: Optional[int] = None
# Start positions of prefix cache for each chunk, (num_prefix_chunks, batch_size)
prefix_chunk_starts: Optional[torch.Tensor] = None
# Start positions of prefix cache for each chunk, (num_prefix_chunks, batch_size), need prefix_chunk_starts_cpu for dcp all gather kv cache
prefix_chunk_starts_cpu: Optional[torch.Tensor] = None
# length of prefix cache for each chunk, (num_prefix_chunks, batch_size)
prefix_chunk_seq_lens_cpu: Optional[torch.Tensor] = None
# Lengths of prefix cache for each chunk, (num_prefix_chunks, batch_size)
prefix_chunk_seq_lens: Optional[torch.Tensor] = None
# Accumulated lengths of prefix cache for each chunk, (num_prefix_chunks, batch_size + 1)
@@ -151,14 +155,19 @@ class ForwardBatchDeepSeekMHAMixin:
self.prefix_chunk_len,
)
)
_, prefix_chunk_seq_lens_cpu = self.get_prefix_chunk_seq_lens(
torch.tensor(self.extend_prefix_lens_cpu),
self.num_prefix_chunks,
self.prefix_chunk_len,
prefix_chunk_starts_cpu, prefix_chunk_seq_lens_cpu = (
self.get_prefix_chunk_seq_lens(
torch.tensor(self.extend_prefix_lens_cpu),
self.num_prefix_chunks,
self.prefix_chunk_len,
)
)
self.prefix_chunk_starts = prefix_chunk_starts_cuda
self.prefix_chunk_seq_lens = prefix_chunk_seq_lens_cuda
# set prefix_chunk_starts_cpu and prefix_chunk_seq_lens_cpu for dcp to gather chunk kv cache with arbitrary lens
self.prefix_chunk_starts_cpu = prefix_chunk_starts_cpu
self.prefix_chunk_seq_lens_cpu = prefix_chunk_seq_lens_cpu
# Metadata for attention backend
self.prefix_chunk_cu_seq_lens = torch.zeros(
self.num_prefix_chunks,
@@ -45,6 +45,7 @@ from sglang.srt.layers.dp_attention import (
set_dp_buffer_len,
set_is_extend_in_batch,
)
from sglang.srt.layers.utils.dcp_utils import DecodeContextParallelMetadata
from sglang.srt.model_executor.forward_batch_deepseek_mha_mixin import (
ForwardBatchDeepSeekMHAMixin,
)
@@ -503,6 +504,9 @@ class ForwardBatch(ForwardBatchDeepSeekMHAMixin):
attn_cp_metadata: Optional[ContextParallelMetadata] = None
# For decode context parallel
attn_dcp_metadata: Optional[DecodeContextParallelMetadata] = None
# Decode context parallel KV write mask.
dcp_kv_mask: Optional[torch.Tensor] = None
@@ -860,7 +864,11 @@ class ForwardBatch(ForwardBatchDeepSeekMHAMixin):
model_runner.lora_manager.prepare_lora_batch(ret)
if getattr(model_runner, "dcp_size", 1) > 1 and ret.out_cache_loc is not None:
if (
getattr(model_runner, "dcp_size", 1) > 1
and ret.out_cache_loc is not None
and is_hip()
):
ret.dcp_kv_mask = (
ret.positions % model_runner.dcp_size == model_runner.dcp_rank
)
@@ -11,7 +11,9 @@ from sglang.srt.configs.model_config import (
is_deepseek_dsa,
is_deepseek_v4,
)
from sglang.srt.distributed.parallel_state import get_world_group
from sglang.srt.distributed.parallel_state import (
get_world_group,
)
from sglang.srt.environ import envs
from sglang.srt.layers.dp_attention import get_attention_tp_size
from sglang.srt.mem_cache.allocator import (
@@ -34,8 +34,16 @@ from sglang.srt.layers.pooler import EmbeddingPoolerOutput
from sglang.srt.model_executor.cuda_graph_buffer_registry import (
build_eager_registry,
)
from sglang.srt.model_executor.forward_batch_deepseek_mha_mixin import (
create_chunked_prefix_cache_kv_indices,
)
from sglang.srt.model_executor.forward_batch_info import ForwardBatch, PPProxyTensors
from sglang.srt.model_executor.forward_context import ForwardContext, forward_context
from sglang.srt.model_executor.forward_context import (
ForwardContext,
forward_context,
get_req_to_token_pool,
get_token_to_kv_pool,
)
from sglang.srt.model_executor.runner.base_runner import BaseRunner
from sglang.srt.model_executor.runner_backend_utils.tc_piecewise_cuda_graph import (
enable_tc_piecewise_cuda_graph,
@@ -256,6 +264,23 @@ class EagerRunner(BaseRunner):
forward_batch = self.load_batch(forward_batch, pp_proxy_tensors)
if forward_batch.needs_forward_metadata_init():
if hasattr(model_runner.model, "prepare_context_parallel_metadata_for_dcp"):
# prepare kv cache buffer for dcp to gather kv cache
forward_batch.attn_dcp_metadata = (
model_runner.model.prepare_context_parallel_metadata_for_dcp(
forward_batch.seq_lens,
forward_batch.extend_prefix_lens,
forward_batch.extend_prefix_lens_cpu,
forward_batch.extend_seq_lens,
forward_batch.req_pool_indices,
get_req_to_token_pool().req_to_token,
forward_batch.seq_lens_sum,
get_token_to_kv_pool().get_key_buffer(0).shape,
model_runner.kv_cache_dtype,
model_runner.device,
create_chunked_prefix_cache_kv_indices,
)
)
if hasattr(model_runner.model, "prepare_forward_batch"):
# Prepare model-specific attention metadata before planning,
# e.g. Moss-VL's prefill cross-attention custom mask.