Enable DFLASH support for additional model backends (#22358)
Co-authored-by: David Wang <21328423+dcw02@users.noreply.github.com>
This commit is contained in:
co-authored by
David Wang
parent
28ef6de091
commit
c3833ba929
@@ -2355,6 +2355,18 @@ class DeepseekV2ForCausalLM(nn.Module, DeepseekV2WeightLoaderMixin):
|
||||
# of the (i-1)th layer as aux hidden state
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
|
||||
self.capture_aux_hidden_states = True
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
|
||||
class DeepseekV3ForCausalLM(DeepseekV2ForCausalLM):
|
||||
pass
|
||||
|
||||
@@ -1175,6 +1175,9 @@ class GptOssForCausalLM(nn.Module):
|
||||
def get_embed_and_head(self):
|
||||
return self.model.embed_tokens.weight, self.lm_head.weight
|
||||
|
||||
def get_input_embeddings(self) -> nn.Embedding:
|
||||
return self.model.embed_tokens
|
||||
|
||||
def set_embed_and_head(self, embed, head):
|
||||
del self.model.embed_tokens.weight
|
||||
del self.lm_head.weight
|
||||
@@ -1197,6 +1200,18 @@ class GptOssForCausalLM(nn.Module):
|
||||
# of the (i-1)th layer as aux hidden state
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
|
||||
self.capture_aux_hidden_states = True
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
@classmethod
|
||||
def get_model_config_for_expert_location(cls, config):
|
||||
return ModelConfigForExpertLocation(
|
||||
|
||||
@@ -849,6 +849,30 @@ class KimiK25ForConditionalGeneration(nn.Module):
|
||||
|
||||
self.language_model.set_eagle3_layers_to_capture(layer_ids)
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]) -> None:
|
||||
"""Set the layers to capture for DFLASH draft model training."""
|
||||
if not hasattr(self.language_model, "set_dflash_layers_to_capture"):
|
||||
raise AttributeError(
|
||||
"language_model does not support DFLASH layer capture."
|
||||
)
|
||||
|
||||
self.language_model.set_dflash_layers_to_capture(layer_ids)
|
||||
|
||||
def get_input_embeddings(self):
|
||||
if not hasattr(self.language_model, "get_input_embeddings"):
|
||||
raise AttributeError(
|
||||
"language_model does not support get_input_embeddings()."
|
||||
)
|
||||
|
||||
return self.language_model.get_input_embeddings()
|
||||
|
||||
@property
|
||||
def lm_head(self):
|
||||
if not hasattr(self.language_model, "lm_head"):
|
||||
raise AttributeError("language_model does not expose lm_head.")
|
||||
|
||||
return self.language_model.lm_head
|
||||
|
||||
def get_embed_and_head(self) -> Tuple[torch.Tensor, torch.Tensor]:
|
||||
"""Get embedding and LM head weights for speculative decoding."""
|
||||
if not hasattr(self.language_model, "get_embed_and_head"):
|
||||
|
||||
@@ -686,5 +686,19 @@ class Qwen3ForCausalLM(nn.Module):
|
||||
else:
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
|
||||
self.capture_aux_hidden_states = True
|
||||
# SGLang captures "before layer i". To capture the hidden state after target
|
||||
# layer `k` (HF-style), we capture before layer `k + 1`.
|
||||
self.model.layers_to_capture = [val + 1 for val in layer_ids]
|
||||
|
||||
|
||||
EntryClass = Qwen3ForCausalLM
|
||||
|
||||
@@ -574,8 +574,15 @@ class Qwen3_5LinearDecoderLayer(nn.Module):
|
||||
):
|
||||
forward_batch = kwargs.get("forward_batch", None)
|
||||
|
||||
hidden_states, residual = self.layer_communicator.prepare_attn(
|
||||
hidden_states, residual, forward_batch
|
||||
hidden_states, residual = (
|
||||
self.layer_communicator.prepare_attn_and_capture_last_layer_outputs(
|
||||
hidden_states,
|
||||
residual,
|
||||
forward_batch,
|
||||
captured_last_layer_outputs=kwargs.get(
|
||||
"captured_last_layer_outputs", None
|
||||
),
|
||||
)
|
||||
)
|
||||
|
||||
if not forward_batch.forward_mode.is_idle():
|
||||
@@ -825,10 +832,16 @@ class Qwen3_5AttentionDecoderLayer(nn.Module):
|
||||
hidden_states: torch.Tensor,
|
||||
residual: Optional[torch.Tensor],
|
||||
forward_batch: ForwardBatch,
|
||||
captured_last_layer_outputs: Optional[list[torch.Tensor]] = None,
|
||||
**kwargs,
|
||||
):
|
||||
hidden_states, residual = self.layer_communicator.prepare_attn(
|
||||
hidden_states, residual, forward_batch
|
||||
hidden_states, residual = (
|
||||
self.layer_communicator.prepare_attn_and_capture_last_layer_outputs(
|
||||
hidden_states,
|
||||
residual,
|
||||
forward_batch,
|
||||
captured_last_layer_outputs=captured_last_layer_outputs,
|
||||
)
|
||||
)
|
||||
|
||||
if not forward_batch.forward_mode.is_idle():
|
||||
@@ -945,9 +958,16 @@ class Qwen3_5ForCausalLM(nn.Module):
|
||||
else:
|
||||
self.norm = PPMissingLayer()
|
||||
|
||||
self.layers_to_capture = []
|
||||
|
||||
def get_input_embeddings(self):
|
||||
return self.embed_tokens
|
||||
|
||||
def set_dflash_layers_to_capture(self, layers_to_capture: list[int]):
|
||||
self.layers_to_capture = layers_to_capture
|
||||
for layer_id in self.layers_to_capture:
|
||||
setattr(self.layers[layer_id], "_is_layer_to_capture", True)
|
||||
|
||||
@property
|
||||
def start_layer(self) -> int:
|
||||
return self._start_layer
|
||||
@@ -978,6 +998,7 @@ class Qwen3_5ForCausalLM(nn.Module):
|
||||
hidden_states = pp_proxy_tensors["hidden_states"]
|
||||
residual = pp_proxy_tensors["residual"]
|
||||
|
||||
aux_hidden_states = []
|
||||
# Pass through decoder layers
|
||||
for layer_idx in range(self.start_layer, self.end_layer):
|
||||
layer = self.layers[layer_idx]
|
||||
@@ -989,6 +1010,11 @@ class Qwen3_5ForCausalLM(nn.Module):
|
||||
hidden_states=hidden_states,
|
||||
residual=residual,
|
||||
forward_batch=forward_batch,
|
||||
captured_last_layer_outputs=(
|
||||
aux_hidden_states
|
||||
if getattr(layer, "_is_layer_to_capture", False)
|
||||
else None
|
||||
),
|
||||
)
|
||||
|
||||
# Process deepstack embeddings if provided
|
||||
@@ -1018,7 +1044,10 @@ class Qwen3_5ForCausalLM(nn.Module):
|
||||
else:
|
||||
hidden_states, _ = self.norm(hidden_states, residual)
|
||||
|
||||
return hidden_states
|
||||
if len(aux_hidden_states) == 0:
|
||||
return hidden_states
|
||||
|
||||
return hidden_states, aux_hidden_states
|
||||
|
||||
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
|
||||
stacked_params_mapping = [
|
||||
|
||||
@@ -924,6 +924,11 @@ class Qwen3MoeModel(Qwen2MoeModel):
|
||||
alt_stream=alt_stream,
|
||||
)
|
||||
|
||||
def set_dflash_layers_to_capture(self, layers_to_capture: List[int]):
|
||||
self.layers_to_capture = layers_to_capture
|
||||
for layer_id in self.layers_to_capture:
|
||||
setattr(self.layers[layer_id], "_is_layer_to_capture", True)
|
||||
|
||||
|
||||
class Qwen3MoeForCausalLM(nn.Module):
|
||||
fall_back_to_pt_during_load = False
|
||||
@@ -1079,6 +1084,18 @@ class Qwen3MoeForCausalLM(nn.Module):
|
||||
else:
|
||||
self.model.set_eagle3_layers_to_capture([val + 1 for val in layer_ids])
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
|
||||
self.capture_aux_hidden_states = True
|
||||
self.model.set_dflash_layers_to_capture([val + 1 for val in layer_ids])
|
||||
|
||||
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
|
||||
stacked_params_mapping = [
|
||||
# (param_name, shard_name, shard_id)
|
||||
|
||||
@@ -813,6 +813,11 @@ class Qwen3NextModel(nn.Module):
|
||||
for layer_id in self.layers_to_capture:
|
||||
setattr(self.layers[layer_id], "_is_layer_to_capture", True)
|
||||
|
||||
def set_dflash_layers_to_capture(self, layers_to_capture: list[int]):
|
||||
self.layers_to_capture = layers_to_capture
|
||||
for layer_id in self.layers_to_capture:
|
||||
setattr(self.layers[layer_id], "_is_layer_to_capture", True)
|
||||
|
||||
def forward(
|
||||
self,
|
||||
input_ids: torch.Tensor,
|
||||
@@ -947,6 +952,9 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
def get_embed_and_head(self):
|
||||
return self.model.embed_tokens.weight, self.lm_head.weight
|
||||
|
||||
def get_input_embeddings(self) -> nn.Embedding:
|
||||
return self.model.embed_tokens
|
||||
|
||||
def set_embed_and_head(self, embed, head):
|
||||
del self.model.embed_tokens.weight
|
||||
del self.lm_head.weight
|
||||
@@ -1127,5 +1135,17 @@ class Qwen3NextForCausalLM(nn.Module):
|
||||
else:
|
||||
self.model.set_eagle3_layers_to_capture([val + 1 for val in layer_ids])
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: list[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
|
||||
self.capture_aux_hidden_states = True
|
||||
self.model.set_dflash_layers_to_capture([val + 1 for val in layer_ids])
|
||||
|
||||
|
||||
EntryClass = Qwen3NextForCausalLM
|
||||
|
||||
@@ -1122,6 +1122,7 @@ class Qwen3VLForConditionalGeneration(nn.Module):
|
||||
|
||||
self.logits_processor = LogitsProcessor(self.config)
|
||||
self.pooler = Pooler(pooling_type=PoolingType.LAST, normalize=True)
|
||||
self.capture_aux_hidden_states = False
|
||||
# like {8:0, 16:1, 24:2}, which stands for the captured deepstack features on
|
||||
# 8, 16, 24 layer will be merged to 0, 1, 2 layer of decoder output hidden_states
|
||||
|
||||
@@ -1267,6 +1268,16 @@ class Qwen3VLForConditionalGeneration(nn.Module):
|
||||
else:
|
||||
return hidden_states
|
||||
|
||||
def set_dflash_layers_to_capture(self, layer_ids: List[int]):
|
||||
if not self.pp_group.is_last_rank:
|
||||
return
|
||||
if layer_ids is None:
|
||||
raise ValueError(
|
||||
"DFLASH requires explicit layer_ids for aux hidden capture."
|
||||
)
|
||||
self.capture_aux_hidden_states = True
|
||||
self.model.set_dflash_layers_to_capture([val + 1 for val in layer_ids])
|
||||
|
||||
def load_weights(self, weights: Iterable[Tuple[str, torch.Tensor]]):
|
||||
stacked_params_mapping = [
|
||||
# (param_name, shard_name, shard_id)
|
||||
|
||||
Reference in New Issue
Block a user