run pass llm cp
(cherry picked from commit 1d85394563d96cf22d5d84f15c0e9043582419e4)
This commit is contained in:
@@ -966,12 +966,14 @@ def handle_language_model_only(server_args: Any):
|
|||||||
):
|
):
|
||||||
if flag:
|
if flag:
|
||||||
raise ValueError(f"--language-model-only cannot be combined with {name}")
|
raise ValueError(f"--language-model-only cannot be combined with {name}")
|
||||||
if cfg.disaggregation_mode != "null":
|
hf_config = model_config_of(server_args).hf_config
|
||||||
|
# V4.1 text-only workers use the standard PD KV transfer path.
|
||||||
|
if cfg.disaggregation_mode != "null" and hf_config.model_type != "deepseek_v41":
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"--language-model-only is incompatible with --disaggregation-mode "
|
"--language-model-only is incompatible with --disaggregation-mode "
|
||||||
"prefill/decode"
|
"prefill/decode"
|
||||||
)
|
)
|
||||||
architectures = model_config_of(server_args).hf_config.architectures
|
architectures = hf_config.architectures
|
||||||
if not any(
|
if not any(
|
||||||
a in server_args.LANGUAGE_MODEL_ONLY_ARCHITECTURES for a in architectures
|
a in server_args.LANGUAGE_MODEL_ONLY_ARCHITECTURES for a in architectures
|
||||||
):
|
):
|
||||||
|
|||||||
@@ -934,9 +934,16 @@ class CommonKVManager(BaseKVManager):
|
|||||||
"enable DSpark with the same block size and target/draft KV "
|
"enable DSpark with the same block size and target/draft KV "
|
||||||
"layout. Upgrade both servers together."
|
"layout. Upgrade both servers together."
|
||||||
)
|
)
|
||||||
if info.attn_tp_size != self.attn_tp_size:
|
same_tp_with_prefill_cp = (
|
||||||
|
info.attn_cp_size > 1
|
||||||
|
and (self.is_mla_backend or self.is_hybrid_mla_backend)
|
||||||
|
and self.attn_cp_size == 1
|
||||||
|
and info.attn_tp_size * info.attn_cp_size == self.attn_tp_size
|
||||||
|
)
|
||||||
|
if info.attn_tp_size != self.attn_tp_size and not same_tp_with_prefill_cp:
|
||||||
raise RuntimeError(
|
raise RuntimeError(
|
||||||
"DeepSeek-V4.1 DSpark PD requires the same TP size on both servers"
|
"DeepSeek-V4.1 DSpark PD requires the same TP size on both "
|
||||||
|
"servers (including prefill CP ranks for MLA)"
|
||||||
)
|
)
|
||||||
|
|
||||||
if self.dcp_size > 1:
|
if self.dcp_size > 1:
|
||||||
|
|||||||
@@ -155,6 +155,10 @@ def free_kv_row_segments(
|
|||||||
|
|
||||||
def maybe_cache_unfinished_req(req: Req, tree_cache: BasePrefixCache, **kwargs):
|
def maybe_cache_unfinished_req(req: Req, tree_cache: BasePrefixCache, **kwargs):
|
||||||
if getattr(req, "skip_radix_cache_insert", False):
|
if getattr(req, "skip_radix_cache_insert", False):
|
||||||
|
kv_indices = tree_cache.req_to_token_pool.req_to_token[
|
||||||
|
req.kv.req_pool_idx, : len(req.get_fill_ids())
|
||||||
|
]
|
||||||
|
req.prefix_indices = kv_indices.to(dtype=torch.int64, copy=True)
|
||||||
return
|
return
|
||||||
|
|
||||||
tree_cache.cache_unfinished_req(req, **kwargs)
|
tree_cache.cache_unfinished_req(req, **kwargs)
|
||||||
|
|||||||
@@ -385,14 +385,22 @@ class EagerRunner(BaseRunner):
|
|||||||
"""
|
"""
|
||||||
model = self.model_runner.model
|
model = self.model_runner.model
|
||||||
|
|
||||||
|
input_ids = forward_batch.input_ids
|
||||||
input_embeds = kwargs.get("input_embeds")
|
input_embeds = kwargs.get("input_embeds")
|
||||||
|
# Multimodal spans must be embedded in global token order, before CP
|
||||||
|
# slicing. The model may also normalize image hash IDs for its router.
|
||||||
|
prepare_inputs = getattr(model, "prepare_language_model_inputs", None)
|
||||||
|
if prepare_inputs is not None:
|
||||||
|
input_ids, input_embeds = prepare_inputs(
|
||||||
|
input_ids, forward_batch, input_embeds
|
||||||
|
)
|
||||||
if input_embeds is None:
|
if input_embeds is None:
|
||||||
input_embeds = model.get_input_embeddings()(forward_batch.input_ids)
|
input_embeds = model.get_input_embeddings()(input_ids)
|
||||||
with cp_shard_model_inputs(
|
with cp_shard_model_inputs(
|
||||||
input_embeds,
|
input_embeds,
|
||||||
forward_batch.positions,
|
forward_batch.positions,
|
||||||
forward_batch,
|
forward_batch,
|
||||||
forward_batch.input_ids,
|
input_ids,
|
||||||
) as (sharded_input_embeds, sharded_positions, model_input_ids):
|
) as (sharded_input_embeds, sharded_positions, model_input_ids):
|
||||||
model_kwargs = {"input_embeds": sharded_input_embeds}
|
model_kwargs = {"input_embeds": sharded_input_embeds}
|
||||||
if (pp_proxy_tensors := kwargs.get("pp_proxy_tensors")) is not None:
|
if (pp_proxy_tensors := kwargs.get("pp_proxy_tensors")) is not None:
|
||||||
@@ -437,7 +445,7 @@ class EagerRunner(BaseRunner):
|
|||||||
if aux_hidden_states is None:
|
if aux_hidden_states is None:
|
||||||
logits_kwargs["hidden_states_before_norm"] = hidden_states_before_norm
|
logits_kwargs["hidden_states_before_norm"] = hidden_states_before_norm
|
||||||
return model.logits_processor(
|
return model.logits_processor(
|
||||||
forward_batch.input_ids,
|
input_ids,
|
||||||
hidden_states,
|
hidden_states,
|
||||||
model.lm_head,
|
model.lm_head,
|
||||||
forward_batch,
|
forward_batch,
|
||||||
|
|||||||
@@ -2650,7 +2650,8 @@ class DeepseekV4DecoderLayer(nn.Module):
|
|||||||
is_nextn=is_nextn,
|
is_nextn=is_nextn,
|
||||||
is_deepseek_v4=True,
|
is_deepseek_v4=True,
|
||||||
vl_correction_bias=config.model_type == "deepseek_v41"
|
vl_correction_bias=config.model_type == "deepseek_v41"
|
||||||
and config.vision_n_layers > 0,
|
and config.vision_n_layers > 0
|
||||||
|
and not getattr(config, "language_model_only", False),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
self.input_layernorm = RMSNorm(config.hidden_size, eps=config.rms_norm_eps)
|
||||||
@@ -3872,6 +3873,14 @@ class DeepseekV4DecoderLayer(nn.Module):
|
|||||||
finally:
|
finally:
|
||||||
forward_batch.num_token_non_padded = saved_num_token_non_padded
|
forward_batch.num_token_non_padded = saved_num_token_non_padded
|
||||||
if _use_cp and get_moe_a2a_backend().is_none():
|
if _use_cp and get_moe_a2a_backend().is_none():
|
||||||
|
if self.config.model_type == "deepseek_v41":
|
||||||
|
parallel = get_parallel()
|
||||||
|
hidden_states = parallel.tp_group.all_reduce(hidden_states)
|
||||||
|
parallel = get_parallel()
|
||||||
|
hidden_states = hidden_states.tensor_split(parallel.attn_cp_size)[
|
||||||
|
parallel.attn_cp_rank
|
||||||
|
].contiguous()
|
||||||
|
else:
|
||||||
hidden_states = dsa_cp_reduce_scatter_hidden_states(hidden_states)
|
hidden_states = dsa_cp_reduce_scatter_hidden_states(hidden_states)
|
||||||
elif _use_tp_moe_gather:
|
elif _use_tp_moe_gather:
|
||||||
hidden_states, global_hidden_states = (
|
hidden_states, global_hidden_states = (
|
||||||
@@ -4871,7 +4880,7 @@ class DeepseekV4ForCausalLM(nn.Module):
|
|||||||
or not get_moe_a2a_backend().is_none()
|
or not get_moe_a2a_backend().is_none()
|
||||||
):
|
):
|
||||||
raise ValueError(
|
raise ValueError(
|
||||||
"V4.1 vision currently supports TP/EP/DP without CP, PP or MoE A2A"
|
"V4.1 vision supports TP/EP/DP and prefill CP without PP or MoE A2A"
|
||||||
)
|
)
|
||||||
|
|
||||||
args = SimpleNamespace(**vars(config), dim=config.hidden_size)
|
args = SimpleNamespace(**vars(config), dim=config.hidden_size)
|
||||||
@@ -5078,16 +5087,19 @@ class DeepseekV4ForCausalLM(nn.Module):
|
|||||||
0 if is_shared_experts_fusion_disabled() else self.config.n_shared_experts
|
0 if is_shared_experts_fusion_disabled() else self.config.n_shared_experts
|
||||||
)
|
)
|
||||||
|
|
||||||
def forward(
|
def prepare_language_model_inputs(
|
||||||
self,
|
self,
|
||||||
input_ids: torch.Tensor,
|
input_ids: torch.Tensor,
|
||||||
positions: torch.Tensor,
|
|
||||||
forward_batch: ForwardBatch,
|
forward_batch: ForwardBatch,
|
||||||
input_embeds: Optional[torch.Tensor] = None,
|
input_embeds: Optional[torch.Tensor] = None,
|
||||||
pp_proxy_tensors: Optional[PPProxyTensors] = None,
|
) -> Tuple[torch.Tensor, Optional[torch.Tensor]]:
|
||||||
) -> torch.Tensor:
|
"""Prepare full-sequence image embeddings and model IDs before CP splits.
|
||||||
|
|
||||||
|
Scheduler hash IDs stay intact for multimodal cache keys; the language
|
||||||
|
model uses image_token_id for Engram masking and visual MoE routing.
|
||||||
|
"""
|
||||||
if (
|
if (
|
||||||
self.vision is not None
|
getattr(self, "vision", None) is not None
|
||||||
and not forward_batch.forward_mode.is_decode()
|
and not forward_batch.forward_mode.is_decode()
|
||||||
and not forward_batch.forward_mode.is_target_verify()
|
and not forward_batch.forward_mode.is_target_verify()
|
||||||
and forward_batch.mm_inputs is not None
|
and forward_batch.mm_inputs is not None
|
||||||
@@ -5096,7 +5108,7 @@ class DeepseekV4ForCausalLM(nn.Module):
|
|||||||
if input_embeds is not None:
|
if input_embeds is not None:
|
||||||
raise ValueError("Cannot combine input_embeds and image inputs")
|
raise ValueError("Cannot combine input_embeds and image inputs")
|
||||||
input_embeds = self._prepare_mm_embeddings(input_ids, forward_batch)
|
input_embeds = self._prepare_mm_embeddings(input_ids, forward_batch)
|
||||||
if self.vision is not None and not (
|
if getattr(self, "vision", None) is not None and not (
|
||||||
forward_batch.forward_mode.is_decode_or_idle()
|
forward_batch.forward_mode.is_decode_or_idle()
|
||||||
or forward_batch.forward_mode.is_target_verify()
|
or forward_batch.forward_mode.is_target_verify()
|
||||||
):
|
):
|
||||||
@@ -5106,6 +5118,19 @@ class DeepseekV4ForCausalLM(nn.Module):
|
|||||||
input_ids >= MM_PAD_SHIFT_VALUE, self.config.image_token_id
|
input_ids >= MM_PAD_SHIFT_VALUE, self.config.image_token_id
|
||||||
)
|
)
|
||||||
|
|
||||||
|
return input_ids, input_embeds
|
||||||
|
|
||||||
|
def forward(
|
||||||
|
self,
|
||||||
|
input_ids: torch.Tensor,
|
||||||
|
positions: torch.Tensor,
|
||||||
|
forward_batch: ForwardBatch,
|
||||||
|
input_embeds: Optional[torch.Tensor] = None,
|
||||||
|
pp_proxy_tensors: Optional[PPProxyTensors] = None,
|
||||||
|
) -> torch.Tensor:
|
||||||
|
input_ids, input_embeds = self.prepare_language_model_inputs(
|
||||||
|
input_ids, forward_batch, input_embeds
|
||||||
|
)
|
||||||
with get_attn_tp_context().maybe_input_scattered(forward_batch):
|
with get_attn_tp_context().maybe_input_scattered(forward_batch):
|
||||||
hidden_states = self.model.forward(
|
hidden_states = self.model.forward(
|
||||||
input_ids, positions, forward_batch, input_embeds, pp_proxy_tensors
|
input_ids, positions, forward_batch, input_embeds, pp_proxy_tensors
|
||||||
|
|||||||
@@ -331,6 +331,7 @@ class ServerArgs:
|
|||||||
# ===== END TO BE REFACTORED ====
|
# ===== END TO BE REFACTORED ====
|
||||||
|
|
||||||
LANGUAGE_MODEL_ONLY_ARCHITECTURES = (
|
LANGUAGE_MODEL_ONLY_ARCHITECTURES = (
|
||||||
|
"DeepseekV4ForCausalLM",
|
||||||
"MuseGlimmerForConditionalGeneration",
|
"MuseGlimmerForConditionalGeneration",
|
||||||
"Cosmos3ForConditionalGeneration",
|
"Cosmos3ForConditionalGeneration",
|
||||||
"Cosmos3EdgeForConditionalGeneration",
|
"Cosmos3EdgeForConditionalGeneration",
|
||||||
|
|||||||
Reference in New Issue
Block a user