mirror of
https://github.com/NVIDIA/Model-Optimizer.git
synced 2026-11-12 02:06:41 +08:00
remove DetachedEagleGPT model and handle all offline mode in the _DynamicEagleGPTModel (#321)
Signed-off-by: Ye Yu <yeyu@nvidia.com> Signed-off-by: Kinjal Patel <kinjalpravin@nvidia.com> Signed-off-by: Asha Anoosheh <aanoosheh@nvidia.com> Signed-off-by: realAsma <akuriparambi@nvidia.com> Signed-off-by: Chenjie Luo <chenjiel@nvidia.com> Signed-off-by: Riyad Islam <rislam@nvidia.com> Signed-off-by: Yue <yueshen@nvidia.com> Signed-off-by: h-guo18 <67671475+h-guo18@users.noreply.github.com> Signed-off-by: Chenjie Luo <108829653+cjluo-nv@users.noreply.github.com> Signed-off-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com> Signed-off-by: omrialmog <oalmog@nvidia.com> Signed-off-by: Jennifer Chen <jennifchen@nvidia.com> Co-authored-by: kinjalpatel27 <31936134+kinjalpatel27@users.noreply.github.com> Co-authored-by: Asha Anoosheh <aanoosheh@nvidia.com> Co-authored-by: realAsma <86726418+realAsma@users.noreply.github.com> Co-authored-by: Chenjie Luo <108829653+cjluo-nv@users.noreply.github.com> Co-authored-by: Riyad Islam <rislam@nvidia.com> Co-authored-by: yueshen2016 <39203804+yueshen2016@users.noreply.github.com> Co-authored-by: h-guo18 <67671475+h-guo18@users.noreply.github.com> Co-authored-by: Chenjie Luo <chenjie@omniml.ai> Co-authored-by: Keval Morabia <28916987+kevalmorabia97@users.noreply.github.com> Co-authored-by: omrialmog <oalmog@nvidia.com> Co-authored-by: Jenny Chen <jennifchen@nvidia.com>
This commit is contained in:
co-authored by
kinjalpatel27
Asha Anoosheh
realAsma
Chenjie Luo
Riyad Islam
yueshen2016
h-guo18
Chenjie Luo
Keval Morabia
omrialmog
Jenny Chen
parent
b895dc5c7c
commit
00a7e6079f
@@ -24,7 +24,6 @@ from modelopt.torch.opt.mode import ConvertReturnType, MetadataDict
|
||||
from ..config import EagleConfig
|
||||
|
||||
EagleDMRegistry = _DMRegistryCls(prefix="Eagle") # global instance for the registry
|
||||
OfflineEagleDMRegistry = _DMRegistryCls(prefix="DetachedEagle") # global instance for the registry
|
||||
|
||||
|
||||
def convert_to_eagle_model(model: nn.Module, config: EagleConfig) -> ConvertReturnType:
|
||||
@@ -32,16 +31,14 @@ def convert_to_eagle_model(model: nn.Module, config: EagleConfig) -> ConvertRetu
|
||||
# initialize the true module if necessary
|
||||
model = model.init_modellike() if isinstance(model, ModelLikeModule) else model
|
||||
|
||||
registry = OfflineEagleDMRegistry if config.eagle_offline else EagleDMRegistry
|
||||
|
||||
original_cls = type(model)
|
||||
if original_cls not in registry:
|
||||
for cls in registry._registry:
|
||||
if original_cls not in EagleDMRegistry:
|
||||
for cls in EagleDMRegistry._registry:
|
||||
if issubclass(original_cls, cls):
|
||||
registry.register({original_cls: "base_model_class"})(registry[cls])
|
||||
EagleDMRegistry.register({original_cls: "base_model_class"})(EagleDMRegistry[cls])
|
||||
break
|
||||
|
||||
eagle_model = registry.convert(model)
|
||||
eagle_model = EagleDMRegistry.convert(model)
|
||||
eagle_model.modify(
|
||||
eagle_offline=config.eagle_offline,
|
||||
eagle_hidden_state_distillation=config.eagle_hidden_state_distillation,
|
||||
|
||||
@@ -52,7 +52,7 @@ from megatron.core.transformer.utils import sharded_state_dict_default
|
||||
from megatron.core.utils import make_tp_sharded_tensor_for_checkpoint
|
||||
from packaging.version import Version
|
||||
|
||||
from ..eagle.conversion import EagleDMRegistry, OfflineEagleDMRegistry
|
||||
from ..eagle.conversion import EagleDMRegistry
|
||||
from ..eagle.eagle_model import EagleModel
|
||||
from ..utils import (
|
||||
AcceptanceRateValidation,
|
||||
@@ -745,6 +745,10 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
eagle_architecture_config=eagle_architecture_config,
|
||||
)
|
||||
|
||||
# sequence_parallel is not used in offline eagle
|
||||
if self.eagle_offline:
|
||||
self.config.sequence_parallel = False
|
||||
|
||||
self.eagle_config = dict_to_config(
|
||||
eagle_architecture_config,
|
||||
self.config.use_cpu_initialization,
|
||||
@@ -760,6 +764,7 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
|
||||
# Use default aux_hidden_state layers if use_aux_hidden_state is True
|
||||
# but no layer id is given
|
||||
# layer ids are not used in offline eagle, but we need to set this to have correct fc_input_size_multiplier
|
||||
if (
|
||||
self.eagle_config.use_aux_hidden_state
|
||||
and len(self.eagle_config.eagle_aux_hidden_state_layer_ids) == 0
|
||||
@@ -810,6 +815,8 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
self.eagle_config.eagle_aux_hidden_state_layer_ids
|
||||
)
|
||||
eagle_config.use_mtp_layernorm = self.eagle_config.use_mtp_layernorm
|
||||
eagle_config.draft_vocab_size = self.eagle_config.draft_vocab_size
|
||||
eagle_config.has_lm_head = self.eagle_config.has_lm_head
|
||||
self.eagle_module = EagleModule(
|
||||
eagle_config,
|
||||
self.rotary_pos_emb,
|
||||
@@ -837,24 +844,25 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
self.kld = logits_kld_loss
|
||||
|
||||
def _get_eagle_input_hidden_states(self, hidden_states: torch.Tensor, apply_fc: bool = True):
|
||||
"""When _aux_hidden_states is not empty, then this is EAGLE-3.
|
||||
"""When _aux_hidden_states is not empty for online, then this is EAGLE-3.
|
||||
|
||||
Args:
|
||||
hidden_states: last hidden_states
|
||||
apply_fc: whether to apply EAGLE3 fc
|
||||
"""
|
||||
if len(self._aux_hidden_states) == 0:
|
||||
return hidden_states
|
||||
if not self.eagle_offline:
|
||||
if len(self._aux_hidden_states) == 0:
|
||||
return hidden_states
|
||||
|
||||
# [s / TP, b, len(self._aux_hidden_states) * h]
|
||||
aux_hidden_states = torch.cat(self._aux_hidden_states, dim=-1)
|
||||
self._aux_hidden_states.clear()
|
||||
# [s / TP, b, len(self._aux_hidden_states) * h]
|
||||
hidden_states = torch.cat(self._aux_hidden_states, dim=-1)
|
||||
self._aux_hidden_states.clear()
|
||||
|
||||
if apply_fc:
|
||||
# [s / TP, b, 3h] -> [s / TP, b, h]
|
||||
return self.eagle_module.fc(aux_hidden_states)[0]
|
||||
return self.eagle_module.fc(hidden_states)[0]
|
||||
else:
|
||||
return aux_hidden_states
|
||||
return hidden_states
|
||||
|
||||
def _get_eagle_module_inputs(
|
||||
self,
|
||||
@@ -1183,34 +1191,51 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
return_eagle_inputs: bool = False,
|
||||
**kwargs,
|
||||
) -> torch.Tensor:
|
||||
if input_ids is not None and (position_ids is None or attention_mask is None):
|
||||
if position_ids is None or attention_mask is None:
|
||||
attention_mask, position_ids = get_default_attention_mask_and_position_ids(input_ids)
|
||||
|
||||
# When return_eagle_inputs is True, return decoder_input_for_eagle.
|
||||
# When LLM, decoder_input_for_eagle is just the text embeddings. However, when VLM
|
||||
# decoder_input_for_eagle will also contain projected image/video embeddings.
|
||||
hidden_states, decoder_input_for_eagle = self._base_model_forward(
|
||||
input_ids,
|
||||
position_ids,
|
||||
attention_mask,
|
||||
decoder_input,
|
||||
inference_params,
|
||||
packed_seq_params,
|
||||
extra_block_kwargs,
|
||||
return_eagle_inputs=return_eagle_inputs,
|
||||
)
|
||||
if self.eagle_offline:
|
||||
# aux_hidden_states and hidden_states are provided for offline eagle
|
||||
# _base_model_forward is skipped
|
||||
if return_eagle_inputs:
|
||||
raise ValueError("return_eagle_inputs is unsupported in EAGLE offline mode.")
|
||||
aux_hidden_states = kwargs.get("aux_hidden_states")
|
||||
hidden_states = kwargs.get("hidden_states")
|
||||
if aux_hidden_states is None or hidden_states is None:
|
||||
raise ValueError(
|
||||
"EAGLE offline mode requires kwargs: aux_hidden_states=[s,b,k*h], "
|
||||
"hidden_states=[s,b,h]."
|
||||
)
|
||||
else:
|
||||
# When return_eagle_inputs is True, return decoder_input_for_eagle.
|
||||
# For LLM, decoder_input_for_eagle is just the text embeddings. However, for VLM
|
||||
# decoder_input_for_eagle will also contain projected image/video embeddings.
|
||||
hidden_states, decoder_input_for_eagle = self._base_model_forward(
|
||||
input_ids,
|
||||
position_ids,
|
||||
attention_mask,
|
||||
decoder_input,
|
||||
inference_params,
|
||||
packed_seq_params,
|
||||
extra_block_kwargs,
|
||||
return_eagle_inputs=return_eagle_inputs,
|
||||
)
|
||||
|
||||
# Typically, this is only the case when PP > 1.
|
||||
if not self.post_process:
|
||||
return hidden_states
|
||||
# Typically, this is only the case when PP > 1.
|
||||
if not self.post_process:
|
||||
return hidden_states
|
||||
|
||||
output_weight = None
|
||||
if self.share_embeddings_and_output_weights:
|
||||
output_weight = self.shared_embedding_or_output_weight()
|
||||
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
||||
|
||||
if self.eagle_offline:
|
||||
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(
|
||||
aux_hidden_states, apply_fc=self.eagle_config.use_aux_hidden_state
|
||||
)
|
||||
# If EAGLE-3, aux_hidden_states are gathered by the forward_hook
|
||||
if return_eagle_inputs:
|
||||
elif return_eagle_inputs:
|
||||
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(
|
||||
hidden_states, apply_fc=False
|
||||
)
|
||||
@@ -1232,7 +1257,7 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
hidden_states, apply_fc=True
|
||||
)
|
||||
|
||||
# Either inference or calibration mode, we want to make sure all weights have been exercised.
|
||||
# In calibration mode, we want to make sure all weights have been exercised.
|
||||
# This makes sure all quantized weights have amax calibrated
|
||||
if inference_params is None or self.calibration_mode:
|
||||
eagle_inputs_0 = self._get_eagle_module_inputs(
|
||||
@@ -1254,6 +1279,17 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
# all eagle weights have been exercised for quantization calibration purpose.
|
||||
if labels is None:
|
||||
return logits_sbh.transpose(0, 1).contiguous()
|
||||
elif labels.shape[1] == input_ids.shape[1] - 1:
|
||||
# For offline training, labels may be 1 token shorter than input_ids.
|
||||
# We will just pad a 0 to the labels to make the seq_len the same as
|
||||
# input_ids. This will introduce a small error in training if logit_distillation
|
||||
# is False, and testing accuracy is wrong for the last token.
|
||||
right_token_pad = torch.zeros(
|
||||
(labels.shape[0], 1),
|
||||
dtype=labels.dtype,
|
||||
device=labels.device,
|
||||
)
|
||||
labels = torch.cat((labels, right_token_pad), dim=-1)
|
||||
|
||||
# If eagle_freeze_base_model is set to True,
|
||||
# the base model is frozen .
|
||||
@@ -1305,7 +1341,7 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
packed_seq_params=packed_seq_params,
|
||||
**(extra_block_kwargs or {}),
|
||||
)
|
||||
eagle_logits_1 = eagle_logits_2x[labels.shape[1] :, :, :]
|
||||
eagle_logits_1 = eagle_logits_2x[-labels.shape[1] :, :, :]
|
||||
|
||||
loss_1 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_1)
|
||||
# [b, s - 2]
|
||||
@@ -1713,408 +1749,6 @@ class _DynamicEagleGPTModel(EagleModel):
|
||||
return base_token, draft_tokens
|
||||
|
||||
|
||||
@OfflineEagleDMRegistry.register({GPTModel: "megatron.core.models.gpt.GPTModel"})
|
||||
class _DetachedEagleGPTModel(_DynamicEagleGPTModel):
|
||||
"""A wrapper for detached Eagle module."""
|
||||
|
||||
def modify(
|
||||
self,
|
||||
eagle_offline,
|
||||
eagle_hidden_state_distillation,
|
||||
eagle_self_logit_distillation,
|
||||
eagle_freeze_base_model,
|
||||
eagle_report_acc,
|
||||
eagle_reuse_base_decoder,
|
||||
eagle_loss_decay_factor,
|
||||
eagle_architecture_config,
|
||||
):
|
||||
super(_DynamicEagleGPTModel, self).modify(
|
||||
eagle_offline=eagle_offline,
|
||||
eagle_hidden_state_distillation=eagle_hidden_state_distillation,
|
||||
eagle_self_logit_distillation=eagle_self_logit_distillation,
|
||||
eagle_freeze_base_model=eagle_freeze_base_model,
|
||||
eagle_report_acc=eagle_report_acc,
|
||||
eagle_reuse_base_decoder=eagle_reuse_base_decoder,
|
||||
eagle_loss_decay_factor=eagle_loss_decay_factor,
|
||||
eagle_architecture_config=eagle_architecture_config,
|
||||
)
|
||||
|
||||
# Freeze all parameters
|
||||
if self.eagle_freeze_base_model:
|
||||
for name, param in self.named_parameters():
|
||||
param.requires_grad = False
|
||||
|
||||
self.eagle_config = dict_to_config(
|
||||
eagle_architecture_config,
|
||||
self.config.use_cpu_initialization,
|
||||
self.config.fp16,
|
||||
self.config.bf16,
|
||||
)
|
||||
|
||||
assert not eagle_reuse_base_decoder, (
|
||||
"_DetachedEagleGPTModel does not have a base model so eagle_reuse_base_decoder must be False!"
|
||||
)
|
||||
|
||||
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
||||
assert eagle_self_logit_distillation, (
|
||||
"Only logit distillation is supported when draft_vocab_size != vocab_size!"
|
||||
)
|
||||
|
||||
# Use default aux_hidden_state layers if use_aux_hidden_state is True
|
||||
# but no layer id is given
|
||||
# layer ids are not used in detached eagle, but we need to set this to have correct fc_input_size_multiplier
|
||||
if (
|
||||
self.eagle_config.use_aux_hidden_state
|
||||
and len(self.eagle_config.eagle_aux_hidden_state_layer_ids) == 0
|
||||
):
|
||||
self._set_default_aux_hidden_state_layers()
|
||||
|
||||
# Only the last PP stage has the additional projection and decoder layer.
|
||||
# This is to simplify the export.
|
||||
if self.post_process:
|
||||
rotary_pos_emb = RotaryEmbedding(
|
||||
kv_channels=self.eagle_config.kv_channels,
|
||||
rotary_percent=self.eagle_config.rotary_percent,
|
||||
rotary_interleaved=False,
|
||||
seq_len_interpolation_factor=None,
|
||||
rotary_base=self.eagle_config.rotary_base,
|
||||
rope_scaling=self.eagle_config.rope_scaling,
|
||||
rope_scaling_factor=self.eagle_config.rope_scaling_factor,
|
||||
use_cpu_initialization=self.eagle_config.use_cpu_initialization,
|
||||
)
|
||||
|
||||
self.eagle_module = EagleModule(
|
||||
self.eagle_config,
|
||||
rotary_pos_emb,
|
||||
bias=False,
|
||||
)
|
||||
|
||||
# Eagle loss functions
|
||||
self.kld = logits_kld_loss
|
||||
|
||||
def _get_eagle_input_hidden_states(self, hidden_states: torch.Tensor, apply_fc: bool = True):
|
||||
if apply_fc:
|
||||
# [s / TP, b, 3h] -> [s / TP, b, h]
|
||||
return self.eagle_module.fc(hidden_states)[0]
|
||||
else:
|
||||
return hidden_states
|
||||
|
||||
def _get_detached_eagle_module_inputs(
|
||||
self,
|
||||
input_ids: torch.Tensor,
|
||||
hidden_states: torch.Tensor,
|
||||
attention_mask: torch.Tensor,
|
||||
position_ids: torch.Tensor,
|
||||
features: torch.Tensor | None = None,
|
||||
):
|
||||
"""Getting EAGLE module inputs."""
|
||||
b = hidden_states.shape[1]
|
||||
h = hidden_states.shape[2]
|
||||
|
||||
# [b, 1]
|
||||
id_padding = torch.zeros((b, 1), dtype=input_ids.dtype, device=input_ids.device)
|
||||
padded_input_ids = torch.cat((input_ids[:, 1:], id_padding), dim=-1)
|
||||
|
||||
rotary_pos_emb = self.eagle_module.rotary_pos_emb(padded_input_ids.shape[-1])
|
||||
|
||||
attn_mask = attention_mask.clone().detach()
|
||||
attn_mask[:, :, :-1, :-1] = attention_mask[:, :, 1:, 1:]
|
||||
attn_mask[:, :, -1, :] = True
|
||||
attn_mask[:, :, :, -1] = True
|
||||
|
||||
eagle_inputs = {}
|
||||
|
||||
assert self.eagle_config.parallel_draft_step == 1, (
|
||||
"Detached Eagle module does not support parallel draft yet!"
|
||||
)
|
||||
if features is None:
|
||||
eagle_inputs["input_ids"] = padded_input_ids
|
||||
eagle_inputs["hidden_states"] = hidden_states
|
||||
eagle_inputs["attention_mask"] = attn_mask
|
||||
eagle_inputs["position_ids"] = position_ids
|
||||
eagle_inputs["rotary_pos_emb"] = rotary_pos_emb
|
||||
elif features.shape[0] == hidden_states.shape[0]:
|
||||
eagle_inputs["input_ids"] = torch.cat(
|
||||
(padded_input_ids, padded_input_ids),
|
||||
dim=-1,
|
||||
)
|
||||
eagle_inputs["hidden_states"] = torch.cat(
|
||||
(
|
||||
hidden_states,
|
||||
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
||||
features[:-1, :, :],
|
||||
),
|
||||
dim=0,
|
||||
)
|
||||
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 2)
|
||||
eagle_inputs["position_ids"] = torch.cat((position_ids, position_ids), dim=-1)
|
||||
|
||||
if rotary_pos_emb is not None:
|
||||
eagle_inputs["rotary_pos_emb"] = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=0)
|
||||
else:
|
||||
# [TODO] (yeyu): there will be problem here with MLA
|
||||
eagle_inputs["rotary_pos_emb"] = None
|
||||
elif features.shape[0] == hidden_states.shape[0] * 2:
|
||||
eagle_inputs["input_ids"] = torch.cat(
|
||||
(padded_input_ids, padded_input_ids, padded_input_ids),
|
||||
dim=-1,
|
||||
)
|
||||
eagle_inputs["hidden_states"] = torch.cat(
|
||||
(
|
||||
hidden_states,
|
||||
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
||||
features[:-1, :, :],
|
||||
),
|
||||
dim=0,
|
||||
)
|
||||
|
||||
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 3)
|
||||
eagle_inputs["position_ids"] = torch.cat(
|
||||
(position_ids, position_ids, position_ids), dim=-1
|
||||
)
|
||||
|
||||
if rotary_pos_emb is not None:
|
||||
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
||||
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
||||
dim=0,
|
||||
)
|
||||
else:
|
||||
# [TODO] (yeyu): there will be problem here with MLA
|
||||
eagle_inputs["rotary_pos_emb"] = None
|
||||
else:
|
||||
eagle_inputs["input_ids"] = torch.cat(
|
||||
(padded_input_ids, padded_input_ids, padded_input_ids, padded_input_ids),
|
||||
dim=-1,
|
||||
)
|
||||
eagle_inputs["hidden_states"] = torch.cat(
|
||||
(
|
||||
hidden_states,
|
||||
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
||||
features[:-1, :, :],
|
||||
),
|
||||
dim=0,
|
||||
)
|
||||
|
||||
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 4)
|
||||
eagle_inputs["position_ids"] = torch.cat(
|
||||
(position_ids, position_ids, position_ids, position_ids), dim=-1
|
||||
)
|
||||
|
||||
if rotary_pos_emb is not None:
|
||||
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
||||
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
||||
dim=0,
|
||||
)
|
||||
else:
|
||||
# [TODO] (yeyu): there will be problem here with MLA
|
||||
eagle_inputs["rotary_pos_emb"] = None
|
||||
|
||||
eagle_inputs["embedding"] = self.embedding(
|
||||
input_ids=eagle_inputs["input_ids"],
|
||||
position_ids=eagle_inputs["position_ids"],
|
||||
)
|
||||
|
||||
return eagle_inputs
|
||||
|
||||
def forward(
|
||||
self,
|
||||
input_ids: torch.Tensor = None,
|
||||
position_ids: torch.Tensor = None,
|
||||
attention_mask: torch.Tensor = None,
|
||||
decoder_input: torch.Tensor = None,
|
||||
labels: torch.Tensor = None,
|
||||
inference_params: InferenceParams = None,
|
||||
packed_seq_params: PackedSeqParams = None,
|
||||
extra_block_kwargs: dict | None = None,
|
||||
return_eagle_inputs: bool = False, # Not used in Detached Eagle
|
||||
**kwargs,
|
||||
) -> torch.Tensor:
|
||||
assert "aux_hidden_states" in kwargs, (
|
||||
"aux_hidden_states is required as input to _DetachedEagleGPTModel"
|
||||
)
|
||||
assert "hidden_states" in kwargs, (
|
||||
"hidden_states is required as input to _DetachedEagleGPTModel"
|
||||
)
|
||||
aux_hidden_states = kwargs.get("aux_hidden_states")
|
||||
hidden_states = kwargs.get("hidden_states")
|
||||
|
||||
# Note: labels is 1 token shorter than logits in detached mode
|
||||
|
||||
if position_ids is None or attention_mask is None:
|
||||
attention_mask, position_ids = get_default_attention_mask_and_position_ids(input_ids)
|
||||
|
||||
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(aux_hidden_states)
|
||||
output_weight = None
|
||||
if self.share_embeddings_and_output_weights:
|
||||
output_weight = self.shared_embedding_or_output_weight()
|
||||
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
||||
|
||||
eagle_inputs_0 = self._get_detached_eagle_module_inputs(
|
||||
input_ids=input_ids,
|
||||
hidden_states=eagle_module_input_hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_ids=position_ids,
|
||||
)
|
||||
|
||||
_, eagle_logits_0, eagle_hidden_states_0_pre_norm = self._eagle_forward(
|
||||
eagle_inputs_0,
|
||||
None,
|
||||
inference_params=inference_params,
|
||||
packed_seq_params=packed_seq_params,
|
||||
**(extra_block_kwargs or {}),
|
||||
)
|
||||
|
||||
loss = torch.zeros(input_ids.shape).to(input_ids.device)
|
||||
|
||||
loss_0 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_0)
|
||||
loss[:, 1:] += self.eagle_loss_decay_factor * loss_0
|
||||
|
||||
if self.eagle_report_acc and not self.training:
|
||||
acc = []
|
||||
with torch.no_grad():
|
||||
gathered_logits = gather_from_tensor_model_parallel_region(
|
||||
eagle_logits_0[:-2, :, :]
|
||||
)
|
||||
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
||||
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
||||
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
||||
top1_p = torch.eq(labels[:, 1:], eagle_top1).sum() / eagle_top1.numel()
|
||||
acc.append(top1_p)
|
||||
|
||||
if get_tensor_model_parallel_rank() == 0:
|
||||
print(
|
||||
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 1st Top-1: {acc}",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
# Second round of EAGLE loss
|
||||
eagle_inputs_1 = self._get_detached_eagle_module_inputs(
|
||||
input_ids=input_ids,
|
||||
hidden_states=eagle_module_input_hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_ids=position_ids,
|
||||
features=eagle_hidden_states_0_pre_norm,
|
||||
)
|
||||
|
||||
_, eagle_logits_2x, eagle_hidden_states_2x_pre_norm = self._eagle_forward(
|
||||
eagle_inputs_1,
|
||||
None,
|
||||
inference_params=inference_params,
|
||||
packed_seq_params=packed_seq_params,
|
||||
**(extra_block_kwargs or {}),
|
||||
)
|
||||
eagle_logits_1 = eagle_logits_2x[logits_sbh.shape[0] :, :, :]
|
||||
|
||||
loss_1 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_1)
|
||||
# [b, s - 2]
|
||||
loss_1 = loss_1[:, 1:]
|
||||
loss[:, 2:] += self.eagle_loss_decay_factor**2 * loss_1
|
||||
|
||||
if self.eagle_report_acc and not self.training:
|
||||
acc = []
|
||||
with torch.no_grad():
|
||||
gathered_logits = gather_from_tensor_model_parallel_region(
|
||||
eagle_logits_1[1:-2, :, :]
|
||||
)
|
||||
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
||||
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
||||
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
||||
top1_p = torch.eq(labels[:, 2:], eagle_top1).sum() / eagle_top1.numel()
|
||||
acc.append(top1_p)
|
||||
|
||||
if get_tensor_model_parallel_rank() == 0:
|
||||
print(
|
||||
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 2nd Top-1: {acc}",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
# Third EAGLE loss
|
||||
eagle_inputs_2 = self._get_detached_eagle_module_inputs(
|
||||
input_ids=input_ids,
|
||||
hidden_states=eagle_module_input_hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_ids=position_ids,
|
||||
features=eagle_hidden_states_2x_pre_norm,
|
||||
)
|
||||
|
||||
_, eagle_logits_3x, eagle_hidden_states_3x_pre_norm = self._eagle_forward(
|
||||
eagle_inputs_2,
|
||||
None,
|
||||
inference_params=inference_params,
|
||||
packed_seq_params=packed_seq_params,
|
||||
**(extra_block_kwargs or {}),
|
||||
)
|
||||
|
||||
eagle_logits_2 = eagle_logits_3x[-logits_sbh.shape[0] :, :, :]
|
||||
|
||||
loss_2 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_2)
|
||||
# [b, s - 3]
|
||||
loss_2 = loss_2[:, 2:]
|
||||
loss[:, 3:] += self.eagle_loss_decay_factor**3 * loss_2
|
||||
|
||||
if self.eagle_report_acc and not self.training:
|
||||
acc = []
|
||||
with torch.no_grad():
|
||||
gathered_logits = gather_from_tensor_model_parallel_region(
|
||||
eagle_logits_2[2:-2, :, :]
|
||||
)
|
||||
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
||||
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
||||
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
||||
top1_p = torch.eq(labels[:, 3:], eagle_top1).sum() / eagle_top1.numel()
|
||||
acc.append(top1_p)
|
||||
|
||||
if get_tensor_model_parallel_rank() == 0:
|
||||
print(
|
||||
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 3rd Top-1: {acc}",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
# Forth EAGLE loss
|
||||
eagle_inputs_3 = self._get_detached_eagle_module_inputs(
|
||||
input_ids=input_ids,
|
||||
hidden_states=eagle_module_input_hidden_states,
|
||||
attention_mask=attention_mask,
|
||||
position_ids=position_ids,
|
||||
features=eagle_hidden_states_3x_pre_norm,
|
||||
)
|
||||
|
||||
_, eagle_logits_4x, eagle_hidden_states_4x_pre_norm = self._eagle_forward(
|
||||
eagle_inputs_3,
|
||||
None,
|
||||
inference_params=inference_params,
|
||||
packed_seq_params=packed_seq_params,
|
||||
**(extra_block_kwargs or {}),
|
||||
)
|
||||
|
||||
eagle_logits_3 = eagle_logits_4x[-logits_sbh.shape[0] :, :, :]
|
||||
|
||||
loss_3 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_3)
|
||||
# [b, s - 4]
|
||||
loss_3 = loss_3[:, 3:]
|
||||
loss[:, 4:] += self.eagle_loss_decay_factor**4 * loss_3
|
||||
|
||||
if self.eagle_report_acc and not self.training:
|
||||
acc = []
|
||||
with torch.no_grad():
|
||||
gathered_logits = gather_from_tensor_model_parallel_region(
|
||||
eagle_logits_3[3:-2, :, :]
|
||||
)
|
||||
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
||||
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
||||
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
||||
top1_p = torch.eq(labels[:, 4:], eagle_top1).sum() / eagle_top1.numel()
|
||||
acc.append(top1_p)
|
||||
|
||||
if get_tensor_model_parallel_rank() == 0:
|
||||
print(
|
||||
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 4th Top-1: {acc}",
|
||||
flush=True,
|
||||
)
|
||||
|
||||
return loss
|
||||
|
||||
|
||||
class MegatronARValidation(AcceptanceRateValidation):
|
||||
"""This is the subclass for megatron model AR validation."""
|
||||
|
||||
|
||||
@@ -46,7 +46,7 @@ from transformers.models.llama.modeling_llama import (
|
||||
from transformers.trainer_pt_utils import LabelSmoother
|
||||
from transformers.utils import ModelOutput
|
||||
|
||||
from ..eagle.conversion import EagleDMRegistry, OfflineEagleDMRegistry
|
||||
from ..eagle.conversion import EagleDMRegistry
|
||||
from ..eagle.eagle_model import EagleModel
|
||||
from ..eagle.utils import RMSNorm, expand_mask, make_causal_mask
|
||||
from ..medusa.conversion import MedusaDMRegistry
|
||||
@@ -1141,13 +1141,6 @@ class HFEagleModel(EagleModel):
|
||||
return base_token, draft_tokens
|
||||
|
||||
|
||||
@OfflineEagleDMRegistry.register({PreTrainedModel: "hf.PreTrainedModel"})
|
||||
class DetachedHFEagleModel(HFEagleModel):
|
||||
"""A wrapper for detached Eagle module."""
|
||||
|
||||
# TODO: Implement DetachedHFEagleModel class for offline eagle.
|
||||
|
||||
|
||||
class HFARValidation(AcceptanceRateValidation):
|
||||
"""This is the subclass for HF model AR validation."""
|
||||
|
||||
|
||||
Reference in New Issue
Block a user