nvidia-modelopt 0.35.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modelopt/__init__.py +20 -0
- modelopt/deploy/__init__.py +16 -0
- modelopt/deploy/llm/__init__.py +30 -0
- modelopt/deploy/llm/generate.py +345 -0
- modelopt/onnx/__init__.py +34 -0
- modelopt/onnx/autocast/__init__.py +19 -0
- modelopt/onnx/autocast/__main__.py +187 -0
- modelopt/onnx/autocast/convert.py +202 -0
- modelopt/onnx/autocast/graphsanitizer.py +422 -0
- modelopt/onnx/autocast/logging_config.py +78 -0
- modelopt/onnx/autocast/nodeclassifier.py +416 -0
- modelopt/onnx/autocast/precisionconverter.py +1032 -0
- modelopt/onnx/autocast/referencerunner.py +159 -0
- modelopt/onnx/autocast/utils.py +117 -0
- modelopt/onnx/llm_export_utils/__init__.py +16 -0
- modelopt/onnx/llm_export_utils/export_utils.py +162 -0
- modelopt/onnx/llm_export_utils/quantization_utils.py +122 -0
- modelopt/onnx/llm_export_utils/surgeon_utils.py +120 -0
- modelopt/onnx/logging_config.py +77 -0
- modelopt/onnx/op_types.py +300 -0
- modelopt/onnx/quantization/__init__.py +20 -0
- modelopt/onnx/quantization/__main__.py +291 -0
- modelopt/onnx/quantization/calib_utils.py +178 -0
- modelopt/onnx/quantization/extensions.py +35 -0
- modelopt/onnx/quantization/fp8.py +375 -0
- modelopt/onnx/quantization/graph_utils.py +1479 -0
- modelopt/onnx/quantization/gs_patching.py +112 -0
- modelopt/onnx/quantization/int4.py +1347 -0
- modelopt/onnx/quantization/int8.py +283 -0
- modelopt/onnx/quantization/operators.py +121 -0
- modelopt/onnx/quantization/ort_patching.py +1766 -0
- modelopt/onnx/quantization/ort_utils.py +346 -0
- modelopt/onnx/quantization/partitioning.py +439 -0
- modelopt/onnx/quantization/qdq_utils.py +1349 -0
- modelopt/onnx/quantization/quant_utils.py +283 -0
- modelopt/onnx/quantization/quantize.py +528 -0
- modelopt/onnx/quantization/src/modelopt_round_and_pack_ext.cpp +127 -0
- modelopt/onnx/trt_utils.py +424 -0
- modelopt/onnx/utils.py +753 -0
- modelopt/torch/__init__.py +41 -0
- modelopt/torch/_deploy/__init__.py +23 -0
- modelopt/torch/_deploy/_runtime/__init__.py +29 -0
- modelopt/torch/_deploy/_runtime/common.py +72 -0
- modelopt/torch/_deploy/_runtime/ort_client.py +193 -0
- modelopt/torch/_deploy/_runtime/registry.py +83 -0
- modelopt/torch/_deploy/_runtime/runtime_client.py +154 -0
- modelopt/torch/_deploy/_runtime/tensorrt/constants.py +108 -0
- modelopt/torch/_deploy/_runtime/tensorrt/engine_builder.py +324 -0
- modelopt/torch/_deploy/_runtime/tensorrt/hw_param_config.py +51 -0
- modelopt/torch/_deploy/_runtime/tensorrt/layerwise_profiling.py +178 -0
- modelopt/torch/_deploy/_runtime/tensorrt/parse_trtexec_log.py +151 -0
- modelopt/torch/_deploy/_runtime/tensorrt/tensorrt_utils.py +200 -0
- modelopt/torch/_deploy/_runtime/trt_client.py +219 -0
- modelopt/torch/_deploy/compilation.py +142 -0
- modelopt/torch/_deploy/device_model.py +157 -0
- modelopt/torch/_deploy/profiling.py +193 -0
- modelopt/torch/_deploy/utils/__init__.py +18 -0
- modelopt/torch/_deploy/utils/onnx_optimizer.py +120 -0
- modelopt/torch/_deploy/utils/onnx_utils.py +58 -0
- modelopt/torch/_deploy/utils/torch_onnx.py +593 -0
- modelopt/torch/distill/__init__.py +28 -0
- modelopt/torch/distill/config.py +130 -0
- modelopt/torch/distill/distillation.py +84 -0
- modelopt/torch/distill/distillation_model.py +318 -0
- modelopt/torch/distill/loss_balancers.py +140 -0
- modelopt/torch/distill/losses.py +275 -0
- modelopt/torch/distill/mode.py +223 -0
- modelopt/torch/distill/plugins/__init__.py +24 -0
- modelopt/torch/distill/plugins/huggingface.py +110 -0
- modelopt/torch/distill/plugins/megatron.py +476 -0
- modelopt/torch/distill/registry.py +23 -0
- modelopt/torch/export/__init__.py +24 -0
- modelopt/torch/export/convert_hf_config.py +117 -0
- modelopt/torch/export/distribute.py +300 -0
- modelopt/torch/export/hf_config_map.py +84 -0
- modelopt/torch/export/layer_utils.py +1893 -0
- modelopt/torch/export/mcore_config_map.py +25 -0
- modelopt/torch/export/model_config.py +623 -0
- modelopt/torch/export/model_config_export.py +552 -0
- modelopt/torch/export/model_config_utils.py +392 -0
- modelopt/torch/export/model_utils.py +71 -0
- modelopt/torch/export/plugins/__init__.py +21 -0
- modelopt/torch/export/plugins/mcore_common.py +67 -0
- modelopt/torch/export/plugins/mcore_custom.py +530 -0
- modelopt/torch/export/plugins/mcore_deepseek.py +143 -0
- modelopt/torch/export/plugins/mcore_gptoss.py +71 -0
- modelopt/torch/export/plugins/mcore_llama.py +164 -0
- modelopt/torch/export/plugins/mcore_nemotron.py +90 -0
- modelopt/torch/export/plugins/mcore_qwen.py +99 -0
- modelopt/torch/export/plugins/megatron_importer.py +647 -0
- modelopt/torch/export/postprocess.py +847 -0
- modelopt/torch/export/quant_utils.py +1069 -0
- modelopt/torch/export/tensorrt_llm_type.py +42 -0
- modelopt/torch/export/tensorrt_llm_utils.py +405 -0
- modelopt/torch/export/transformer_engine.py +94 -0
- modelopt/torch/export/unified_export_hf.py +537 -0
- modelopt/torch/export/unified_export_megatron.py +1164 -0
- modelopt/torch/nas/__init__.py +27 -0
- modelopt/torch/nas/algorithms.py +856 -0
- modelopt/torch/nas/autonas.py +808 -0
- modelopt/torch/nas/conversion.py +119 -0
- modelopt/torch/nas/hparams/__init__.py +19 -0
- modelopt/torch/nas/hparams/concat.py +319 -0
- modelopt/torch/nas/hparams/container.py +48 -0
- modelopt/torch/nas/modules/__init__.py +21 -0
- modelopt/torch/nas/modules/container.py +99 -0
- modelopt/torch/nas/modules/conv.py +254 -0
- modelopt/torch/nas/modules/linear.py +76 -0
- modelopt/torch/nas/modules/norm.py +193 -0
- modelopt/torch/nas/modules/utils.py +61 -0
- modelopt/torch/nas/patch.py +261 -0
- modelopt/torch/nas/plugins/__init__.py +29 -0
- modelopt/torch/nas/plugins/megatron.py +1497 -0
- modelopt/torch/nas/plugins/torch.py +71 -0
- modelopt/torch/nas/plugins/transformer_engine.py +42 -0
- modelopt/torch/nas/plugins/transformers.py +210 -0
- modelopt/torch/nas/registry.py +23 -0
- modelopt/torch/nas/search_space.py +260 -0
- modelopt/torch/nas/traced_hp.py +149 -0
- modelopt/torch/nas/utils.py +408 -0
- modelopt/torch/opt/__init__.py +41 -0
- modelopt/torch/opt/_hooks.py +98 -0
- modelopt/torch/opt/config.py +383 -0
- modelopt/torch/opt/conversion.py +620 -0
- modelopt/torch/opt/dynamic.py +1367 -0
- modelopt/torch/opt/hparam.py +275 -0
- modelopt/torch/opt/mode.py +353 -0
- modelopt/torch/opt/plugins/__init__.py +38 -0
- modelopt/torch/opt/plugins/diffusers.py +40 -0
- modelopt/torch/opt/plugins/huggingface.py +162 -0
- modelopt/torch/opt/plugins/mcore_dist_checkpointing.py +211 -0
- modelopt/torch/opt/plugins/megatron.py +142 -0
- modelopt/torch/opt/plugins/peft.py +108 -0
- modelopt/torch/opt/plugins/transformers.py +160 -0
- modelopt/torch/opt/searcher.py +363 -0
- modelopt/torch/opt/utils.py +125 -0
- modelopt/torch/prune/__init__.py +26 -0
- modelopt/torch/prune/fastnas.py +376 -0
- modelopt/torch/prune/gradnas.py +349 -0
- modelopt/torch/prune/plugins/__init__.py +24 -0
- modelopt/torch/prune/plugins/mcore_minitron.py +263 -0
- modelopt/torch/prune/plugins/transformers.py +41 -0
- modelopt/torch/prune/pruning.py +211 -0
- modelopt/torch/quantization/__init__.py +26 -0
- modelopt/torch/quantization/algorithms.py +671 -0
- modelopt/torch/quantization/backends/__init__.py +20 -0
- modelopt/torch/quantization/backends/fp8_per_tensor_gemm.py +204 -0
- modelopt/torch/quantization/backends/gemm_registry.py +156 -0
- modelopt/torch/quantization/backends/nvfp4_gemm.py +201 -0
- modelopt/torch/quantization/backends/utils.py +28 -0
- modelopt/torch/quantization/calib/__init__.py +25 -0
- modelopt/torch/quantization/calib/bias.py +172 -0
- modelopt/torch/quantization/calib/calibrator.py +63 -0
- modelopt/torch/quantization/calib/histogram.py +434 -0
- modelopt/torch/quantization/calib/max.py +110 -0
- modelopt/torch/quantization/compress.py +227 -0
- modelopt/torch/quantization/config.py +1180 -0
- modelopt/torch/quantization/conversion.py +389 -0
- modelopt/torch/quantization/export_onnx.py +639 -0
- modelopt/torch/quantization/extensions.py +89 -0
- modelopt/torch/quantization/mode.py +428 -0
- modelopt/torch/quantization/model_calib.py +949 -0
- modelopt/torch/quantization/model_quant.py +477 -0
- modelopt/torch/quantization/nn/__init__.py +26 -0
- modelopt/torch/quantization/nn/functional.py +109 -0
- modelopt/torch/quantization/nn/modules/__init__.py +16 -0
- modelopt/torch/quantization/nn/modules/quant_activations.py +22 -0
- modelopt/torch/quantization/nn/modules/quant_batchnorm.py +24 -0
- modelopt/torch/quantization/nn/modules/quant_conv.py +123 -0
- modelopt/torch/quantization/nn/modules/quant_instancenorm.py +39 -0
- modelopt/torch/quantization/nn/modules/quant_linear.py +258 -0
- modelopt/torch/quantization/nn/modules/quant_module.py +211 -0
- modelopt/torch/quantization/nn/modules/quant_pooling.py +99 -0
- modelopt/torch/quantization/nn/modules/quant_rnn.py +527 -0
- modelopt/torch/quantization/nn/modules/tensor_quantizer.py +1293 -0
- modelopt/torch/quantization/plugins/__init__.py +73 -0
- modelopt/torch/quantization/plugins/accelerate.py +214 -0
- modelopt/torch/quantization/plugins/apex.py +52 -0
- modelopt/torch/quantization/plugins/attention.py +312 -0
- modelopt/torch/quantization/plugins/custom.py +192 -0
- modelopt/torch/quantization/plugins/diffusers.py +237 -0
- modelopt/torch/quantization/plugins/fairscale.py +45 -0
- modelopt/torch/quantization/plugins/huggingface.py +736 -0
- modelopt/torch/quantization/plugins/megatron.py +462 -0
- modelopt/torch/quantization/plugins/peft.py +148 -0
- modelopt/torch/quantization/plugins/transformer_engine.py +60 -0
- modelopt/torch/quantization/plugins/transformers.py +52 -0
- modelopt/torch/quantization/plugins/transformers_trainer.py +426 -0
- modelopt/torch/quantization/plugins/trl.py +27 -0
- modelopt/torch/quantization/plugins/vllm.py +199 -0
- modelopt/torch/quantization/qtensor/__init__.py +24 -0
- modelopt/torch/quantization/qtensor/base_qtensor.py +370 -0
- modelopt/torch/quantization/qtensor/fp8_tensor.py +151 -0
- modelopt/torch/quantization/qtensor/int4_tensor.py +130 -0
- modelopt/torch/quantization/qtensor/int8_tensor.py +124 -0
- modelopt/torch/quantization/qtensor/mxfp4_tensor.py +144 -0
- modelopt/torch/quantization/qtensor/nf4_tensor.py +199 -0
- modelopt/torch/quantization/qtensor/nvfp4_tensor.py +295 -0
- modelopt/torch/quantization/src/tensor_quant.cpp +77 -0
- modelopt/torch/quantization/src/tensor_quant.h +69 -0
- modelopt/torch/quantization/src/tensor_quant_fp8.cpp +48 -0
- modelopt/torch/quantization/src/tensor_quant_gpu.cu +361 -0
- modelopt/torch/quantization/src/tensor_quant_gpu_fp8.cu +122 -0
- modelopt/torch/quantization/src/tensor_quant_mx.cu +411 -0
- modelopt/torch/quantization/src/tensor_quant_mx.h +247 -0
- modelopt/torch/quantization/tensor_quant.py +816 -0
- modelopt/torch/quantization/triton/__init__.py +36 -0
- modelopt/torch/quantization/triton/fp4_kernel.py +303 -0
- modelopt/torch/quantization/utils.py +443 -0
- modelopt/torch/sparsity/__init__.py +19 -0
- modelopt/torch/sparsity/config.py +51 -0
- modelopt/torch/sparsity/magnitude.py +148 -0
- modelopt/torch/sparsity/mode.py +203 -0
- modelopt/torch/sparsity/module.py +87 -0
- modelopt/torch/sparsity/plugins/__init__.py +27 -0
- modelopt/torch/sparsity/plugins/megatron.py +93 -0
- modelopt/torch/sparsity/searcher.py +84 -0
- modelopt/torch/sparsity/sparsegpt.py +276 -0
- modelopt/torch/sparsity/sparsification.py +123 -0
- modelopt/torch/speculative/__init__.py +20 -0
- modelopt/torch/speculative/config.py +100 -0
- modelopt/torch/speculative/eagle/__init__.py +20 -0
- modelopt/torch/speculative/eagle/conversion.py +67 -0
- modelopt/torch/speculative/eagle/default_config.py +50 -0
- modelopt/torch/speculative/eagle/eagle_model.py +51 -0
- modelopt/torch/speculative/eagle/utils.py +91 -0
- modelopt/torch/speculative/medusa/__init__.py +19 -0
- modelopt/torch/speculative/medusa/conversion.py +59 -0
- modelopt/torch/speculative/medusa/medusa_model.py +32 -0
- modelopt/torch/speculative/mode.py +86 -0
- modelopt/torch/speculative/plugins/__init__.py +33 -0
- modelopt/torch/speculative/plugins/megatron_eagle.py +2119 -0
- modelopt/torch/speculative/plugins/megatron_medusa.py +312 -0
- modelopt/torch/speculative/plugins/transformers.py +1138 -0
- modelopt/torch/speculative/speculative_decoding.py +59 -0
- modelopt/torch/speculative/utils.py +364 -0
- modelopt/torch/trace/__init__.py +25 -0
- modelopt/torch/trace/analyzer.py +1368 -0
- modelopt/torch/trace/modules/__init__.py +19 -0
- modelopt/torch/trace/modules/concat.py +384 -0
- modelopt/torch/trace/modules/nn.py +153 -0
- modelopt/torch/trace/plugins/__init__.py +34 -0
- modelopt/torch/trace/plugins/megatron.py +36 -0
- modelopt/torch/trace/plugins/transformers.py +58 -0
- modelopt/torch/trace/symbols.py +545 -0
- modelopt/torch/trace/tracer.py +331 -0
- modelopt/torch/utils/__init__.py +28 -0
- modelopt/torch/utils/_pytree.py +133 -0
- modelopt/torch/utils/cpp_extension.py +91 -0
- modelopt/torch/utils/dataset_utils.py +484 -0
- modelopt/torch/utils/distributed.py +311 -0
- modelopt/torch/utils/graph.py +123 -0
- modelopt/torch/utils/image_processor.py +112 -0
- modelopt/torch/utils/import_utils.py +35 -0
- modelopt/torch/utils/list.py +54 -0
- modelopt/torch/utils/logging.py +127 -0
- modelopt/torch/utils/memory_monitor.py +146 -0
- modelopt/torch/utils/network.py +658 -0
- modelopt/torch/utils/perf.py +174 -0
- modelopt/torch/utils/plugins/__init__.py +27 -0
- modelopt/torch/utils/plugins/megatron_generate.py +299 -0
- modelopt/torch/utils/plugins/megatron_mmlu.py +152 -0
- modelopt/torch/utils/plugins/megatron_preprocess_data.py +200 -0
- modelopt/torch/utils/random.py +163 -0
- modelopt/torch/utils/speech_dataset_utils.py +134 -0
- modelopt/torch/utils/tensor.py +87 -0
- modelopt/torch/utils/vlm_dataset_utils.py +110 -0
- nvidia_modelopt-0.35.0.dist-info/METADATA +171 -0
- nvidia_modelopt-0.35.0.dist-info/RECORD +272 -0
- nvidia_modelopt-0.35.0.dist-info/WHEEL +5 -0
- nvidia_modelopt-0.35.0.dist-info/licenses/LICENSE +14 -0
- nvidia_modelopt-0.35.0.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,2119 @@
|
|
|
1
|
+
# SPDX-FileCopyrightText: Copyright (c) 2024 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
|
|
2
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
#
|
|
4
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
5
|
+
# you may not use this file except in compliance with the License.
|
|
6
|
+
# You may obtain a copy of the License at
|
|
7
|
+
#
|
|
8
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
9
|
+
#
|
|
10
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
11
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
12
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
13
|
+
# See the License for the specific language governing permissions and
|
|
14
|
+
# limitations under the License.
|
|
15
|
+
|
|
16
|
+
"""Plugin to add EAGLE support for Megatron-Core GPT model."""
|
|
17
|
+
|
|
18
|
+
import copy
|
|
19
|
+
import warnings
|
|
20
|
+
from collections import deque
|
|
21
|
+
|
|
22
|
+
import megatron.core
|
|
23
|
+
import torch
|
|
24
|
+
import torch.nn.functional as F
|
|
25
|
+
from megatron.core import InferenceParams, tensor_parallel
|
|
26
|
+
from megatron.core.dist_checkpointing.mapping import ShardedStateDict
|
|
27
|
+
from megatron.core.dist_checkpointing.utils import replace_prefix_for_sharding
|
|
28
|
+
from megatron.core.extensions.transformer_engine import TENorm
|
|
29
|
+
from megatron.core.models.common.embeddings.language_model_embedding import LanguageModelEmbedding
|
|
30
|
+
from megatron.core.models.common.embeddings.rotary_pos_embedding import RotaryEmbedding
|
|
31
|
+
from megatron.core.models.gpt import GPTModel
|
|
32
|
+
from megatron.core.packed_seq_params import PackedSeqParams
|
|
33
|
+
from megatron.core.parallel_state import (
|
|
34
|
+
get_data_parallel_rank,
|
|
35
|
+
get_expert_tensor_parallel_world_size,
|
|
36
|
+
get_pipeline_model_parallel_world_size,
|
|
37
|
+
get_tensor_model_parallel_rank,
|
|
38
|
+
get_tensor_model_parallel_world_size,
|
|
39
|
+
)
|
|
40
|
+
from megatron.core.tensor_parallel.mappings import (
|
|
41
|
+
gather_from_sequence_parallel_region,
|
|
42
|
+
gather_from_tensor_model_parallel_region,
|
|
43
|
+
scatter_to_sequence_parallel_region,
|
|
44
|
+
)
|
|
45
|
+
from megatron.core.transformer.attention import SelfAttention
|
|
46
|
+
from megatron.core.transformer.identity_op import IdentityOp
|
|
47
|
+
from megatron.core.transformer.module import MegatronModule
|
|
48
|
+
from megatron.core.transformer.transformer_block import TransformerBlock
|
|
49
|
+
from megatron.core.transformer.transformer_config import TransformerConfig
|
|
50
|
+
from megatron.core.transformer.transformer_layer import TransformerLayer
|
|
51
|
+
from megatron.core.transformer.utils import sharded_state_dict_default
|
|
52
|
+
from megatron.core.utils import make_tp_sharded_tensor_for_checkpoint
|
|
53
|
+
from packaging.version import Version
|
|
54
|
+
|
|
55
|
+
from ..eagle.conversion import EagleDMRegistry, OfflineEagleDMRegistry
|
|
56
|
+
from ..eagle.eagle_model import EagleModel
|
|
57
|
+
from ..utils import (
|
|
58
|
+
AcceptanceRateValidation,
|
|
59
|
+
Tree,
|
|
60
|
+
TreeNode,
|
|
61
|
+
get_default_attention_mask_and_position_ids,
|
|
62
|
+
)
|
|
63
|
+
|
|
64
|
+
try:
|
|
65
|
+
from megatron.core.post_training.modelopt.gpt.model_specs import get_gpt_modelopt_spec
|
|
66
|
+
from megatron.core.post_training.modelopt.layers import Linear
|
|
67
|
+
except ImportError:
|
|
68
|
+
warnings.warn("Fail to import megatron.core.post_training! EAGLE feature will be disable!")
|
|
69
|
+
|
|
70
|
+
|
|
71
|
+
def dict_to_config(
|
|
72
|
+
architecture_config,
|
|
73
|
+
use_cpu_initialization=None,
|
|
74
|
+
fp16=False,
|
|
75
|
+
bf16=True,
|
|
76
|
+
sequence_parallel=False,
|
|
77
|
+
):
|
|
78
|
+
"""Helper function to convert a dictionary to TransformerConfig."""
|
|
79
|
+
config = TransformerConfig(
|
|
80
|
+
normalization="RMSNorm",
|
|
81
|
+
activation_func=F.silu,
|
|
82
|
+
gated_linear_unit=True,
|
|
83
|
+
hidden_dropout=0.0,
|
|
84
|
+
attention_softmax_in_fp32=False,
|
|
85
|
+
tensor_model_parallel_size=get_tensor_model_parallel_world_size(),
|
|
86
|
+
pipeline_model_parallel_size=get_pipeline_model_parallel_world_size(),
|
|
87
|
+
expert_tensor_parallel_size=get_expert_tensor_parallel_world_size(),
|
|
88
|
+
sequence_parallel=sequence_parallel,
|
|
89
|
+
use_cpu_initialization=use_cpu_initialization,
|
|
90
|
+
fp16=fp16,
|
|
91
|
+
bf16=bf16,
|
|
92
|
+
params_dtype=getattr(torch, architecture_config["torch_dtype"]),
|
|
93
|
+
pipeline_dtype=None,
|
|
94
|
+
num_layers=architecture_config.get("num_hidden_layers"),
|
|
95
|
+
hidden_size=architecture_config.get("hidden_size"),
|
|
96
|
+
ffn_hidden_size=architecture_config.get("intermediate_size"),
|
|
97
|
+
num_attention_heads=architecture_config.get("num_attention_heads"),
|
|
98
|
+
kv_channels=architecture_config.get(
|
|
99
|
+
"head_dim",
|
|
100
|
+
architecture_config.get("hidden_size")
|
|
101
|
+
// architecture_config.get("num_attention_heads"),
|
|
102
|
+
),
|
|
103
|
+
num_query_groups=architecture_config.get("num_key_value_heads"),
|
|
104
|
+
init_method_std=architecture_config.get("initializer_range"),
|
|
105
|
+
layernorm_epsilon=architecture_config.get("rms_norm_eps"),
|
|
106
|
+
add_bias_linear=architecture_config.get("mlp_bias"),
|
|
107
|
+
attention_dropout=architecture_config.get("attention_dropout"),
|
|
108
|
+
)
|
|
109
|
+
|
|
110
|
+
config.transformer_layer_spec = None
|
|
111
|
+
config.seq_length = 8192
|
|
112
|
+
config.gradient_accumulation_fusion = False
|
|
113
|
+
config.vocab_size = architecture_config.get("vocab_size")
|
|
114
|
+
config.max_sequence_length = architecture_config.get("max_position_embeddings")
|
|
115
|
+
config.position_embedding_type = architecture_config.get("position_embedding_type")
|
|
116
|
+
config.rotary_percent = 1.0
|
|
117
|
+
config.rotary_base = architecture_config.get("rope_theta")
|
|
118
|
+
config.rope_scaling = "rope_scaling" in architecture_config
|
|
119
|
+
config.rope_scaling_factor = (
|
|
120
|
+
architecture_config.get("rope_scaling").get("factor")
|
|
121
|
+
if "rope_scaling" in architecture_config
|
|
122
|
+
else None
|
|
123
|
+
)
|
|
124
|
+
|
|
125
|
+
config.draft_vocab_size = architecture_config.get("draft_vocab_size")
|
|
126
|
+
config.use_input_layernorm_in_first_layer = architecture_config.get(
|
|
127
|
+
"use_input_layernorm_in_first_layer"
|
|
128
|
+
)
|
|
129
|
+
config.use_last_layernorm = architecture_config.get("use_last_layernorm")
|
|
130
|
+
config.use_aux_hidden_state = architecture_config.get("use_aux_hidden_state")
|
|
131
|
+
config.eagle_aux_hidden_state_layer_ids = architecture_config.get(
|
|
132
|
+
"eagle_aux_hidden_state_layer_ids"
|
|
133
|
+
)
|
|
134
|
+
config.use_mtp_layernorm = architecture_config.get("use_mtp_layernorm")
|
|
135
|
+
config.parallel_draft_step = architecture_config.get("parallel_draft_step")
|
|
136
|
+
config.has_lm_head = architecture_config.get("has_lm_head")
|
|
137
|
+
|
|
138
|
+
return config
|
|
139
|
+
|
|
140
|
+
|
|
141
|
+
def mcore_version_higher_than(target_version: str):
|
|
142
|
+
"""Check if megatron-core is least this version."""
|
|
143
|
+
return Version(megatron.core.__version__) > Version(target_version)
|
|
144
|
+
|
|
145
|
+
|
|
146
|
+
def logits_kld_loss(logits, gt_logits, mapping=None):
|
|
147
|
+
"""KL Divergence loss using ground truth logits."""
|
|
148
|
+
gathered_logits = gather_from_tensor_model_parallel_region(logits)
|
|
149
|
+
gathered_gt_logits = gather_from_tensor_model_parallel_region(gt_logits)
|
|
150
|
+
if mapping is not None:
|
|
151
|
+
reverse_mapping = torch.arange(len(mapping)).to(mapping.device) + mapping
|
|
152
|
+
gathered_gt_logits = gathered_gt_logits[:, :, reverse_mapping]
|
|
153
|
+
loss = torch.nn.Softmax(dim=2)(gathered_gt_logits) * torch.nn.LogSoftmax(dim=2)(gathered_logits)
|
|
154
|
+
loss = -torch.sum(loss, 2)
|
|
155
|
+
return loss.transpose(0, 1)
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
def right_padding(input_ids: torch.Tensor, hidden_states: torch.Tensor = None):
|
|
159
|
+
"""Pad zeros to the right so that the padded_input_ids is a multiple of tp."""
|
|
160
|
+
tp = get_tensor_model_parallel_world_size()
|
|
161
|
+
seq_len = input_ids.shape[-1]
|
|
162
|
+
right_padding_len = 0 if seq_len % tp == 0 else (tp - seq_len % tp)
|
|
163
|
+
|
|
164
|
+
if right_padding_len > 0:
|
|
165
|
+
right_token_pad = torch.zeros(
|
|
166
|
+
(input_ids.shape[0], right_padding_len),
|
|
167
|
+
dtype=input_ids.dtype,
|
|
168
|
+
device=input_ids.device,
|
|
169
|
+
)
|
|
170
|
+
padded_input_ids = torch.cat((input_ids, right_token_pad), dim=-1)
|
|
171
|
+
if hidden_states is not None:
|
|
172
|
+
# If sequence_parallel is used, the input hidden_states is already gathered
|
|
173
|
+
padding_zeros = torch.zeros(
|
|
174
|
+
(right_padding_len, hidden_states.shape[1], hidden_states.shape[2]),
|
|
175
|
+
dtype=hidden_states.dtype,
|
|
176
|
+
device=hidden_states.device,
|
|
177
|
+
)
|
|
178
|
+
padded_hidden_states = torch.cat((hidden_states, padding_zeros), dim=0)
|
|
179
|
+
else:
|
|
180
|
+
padded_input_ids = input_ids
|
|
181
|
+
padded_hidden_states = hidden_states
|
|
182
|
+
|
|
183
|
+
if hidden_states is not None:
|
|
184
|
+
return padded_input_ids, seq_len, padded_hidden_states
|
|
185
|
+
else:
|
|
186
|
+
return padded_input_ids, seq_len
|
|
187
|
+
|
|
188
|
+
|
|
189
|
+
def set_multi_step_attention_mask(attn_mask, step):
|
|
190
|
+
"""Given an original attention_mask, construct a multi-step attention_mask.
|
|
191
|
+
|
|
192
|
+
i0 i1 i2 i3 i4 i5 i6 i7 (base input_ids)
|
|
193
|
+
=======================
|
|
194
|
+
h0 h1 h2 h3 h4 h5 h6 h7 (base hidden_states)
|
|
195
|
+
l0 l1 l2 l3 l4 l5 l6 l7 (base labels)
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
(1st) | i1 i2 i3 i4 i5 i6 i7 -- |
|
|
199
|
+
(out) | h0 h1 h2 h3 h4 h5 h6 h7 |
|
|
200
|
+
=========================================
|
|
201
|
+
f1 l1 | i1 h0 | x |
|
|
202
|
+
f2 l2 | i2 h1 | x x |
|
|
203
|
+
f3 l3 | i3 h2 | x x x |
|
|
204
|
+
f4 l4 | i4 h3 | x x x x |
|
|
205
|
+
f5 l5 | i5 h4 | x x x x x |
|
|
206
|
+
f6 l6 | i6 h5 | x x x x x x |
|
|
207
|
+
f7 l7 | i7 h6 | x x x x x x x |
|
|
208
|
+
-- -- | -- h7 | o o o o o o o o |
|
|
209
|
+
=========================================
|
|
210
|
+
|
|
211
|
+
|
|
212
|
+
(2nd) | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- |
|
|
213
|
+
(out) | h0 h1 h2 h3 h4 h5 h6 h7 | -- F1 F2 F3 F4 F5 F6 F7 |
|
|
214
|
+
===================================================================
|
|
215
|
+
F1 l1 | i1 h0 | x | |
|
|
216
|
+
F2 l2 | i2 h1 | x x | |
|
|
217
|
+
F3 l3 | i3 h2 | x x x | |
|
|
218
|
+
F4 l4 | i4 h3 | x x x x | |
|
|
219
|
+
F5 l5 | i5 h4 | x x x x x | |
|
|
220
|
+
F6 l6 | i6 h5 | x x x x x x | |
|
|
221
|
+
F7 l7 | i7 h6 | x x x x x x x | |
|
|
222
|
+
-- -- | -- h7 | o o o o o o o o | |
|
|
223
|
+
===================================================================
|
|
224
|
+
-- -- | i1 -- | | |
|
|
225
|
+
G2 l2 | i2 F1 | x o | x |
|
|
226
|
+
G3 l3 | i3 F2 | x x o | x |
|
|
227
|
+
G4 l4 | i4 F3 | x x x o | x |
|
|
228
|
+
G5 l5 | i5 F4 | x x x x o | x |
|
|
229
|
+
G6 l6 | i6 F5 | x x x x x o | x |
|
|
230
|
+
G7 l7 | i7 F6 | x x x x x x o | x |
|
|
231
|
+
-- -- | -- F7 | | |
|
|
232
|
+
===================================================================
|
|
233
|
+
|
|
234
|
+
|
|
235
|
+
(3rd) | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- |
|
|
236
|
+
(out) | h0 h1 h2 h3 h4 h5 h6 h7 | -- F1 F2 F3 F4 F5 F6 F7 | -- -- G2 G3 G4 G5 G6 G7 |
|
|
237
|
+
=============================================================================================
|
|
238
|
+
F1 l1 | i1 h0 | x | | |
|
|
239
|
+
F2 l2 | i2 h1 | x x | | |
|
|
240
|
+
F3 l3 | i3 h2 | x x x | | |
|
|
241
|
+
F4 l4 | i4 h3 | x x x x | | |
|
|
242
|
+
F5 l5 | i5 h4 | x x x x x | | |
|
|
243
|
+
F6 l6 | i6 h5 | x x x x x x | | |
|
|
244
|
+
F7 l7 | i7 h6 | x x x x x x x | | |
|
|
245
|
+
-- -- | -- h7 | o o o o o o o o | | |
|
|
246
|
+
=============================================================================================
|
|
247
|
+
-- -- | i1 -- | | | |
|
|
248
|
+
G2 l2 | i2 F1 | x o | x | |
|
|
249
|
+
G3 l3 | i3 F2 | x x o | x | |
|
|
250
|
+
G4 l4 | i4 F3 | x x x o | x | |
|
|
251
|
+
G5 l5 | i5 F4 | x x x x o | x | |
|
|
252
|
+
G6 l6 | i6 F5 | x x x x x o | x | |
|
|
253
|
+
G7 l7 | i7 F6 | x x x x x x o | x | |
|
|
254
|
+
-- -- | -- F7 | | | |
|
|
255
|
+
=============================================================================================
|
|
256
|
+
-- -- | i1 -- | | | |
|
|
257
|
+
-- -- | i2 -- | | | |
|
|
258
|
+
H3 l3 | i3 G2 | x o o | x o | x |
|
|
259
|
+
H4 l4 | i4 G3 | x x o o | x o | x |
|
|
260
|
+
H5 l5 | i5 G4 | x x x o o | x o | x |
|
|
261
|
+
H6 l6 | i6 G5 | x x x x o o | x o | x |
|
|
262
|
+
H7 l7 | i7 G6 | x x x x x o o | x o | x |
|
|
263
|
+
-- -- | -- G7 | | | |
|
|
264
|
+
=============================================================================================
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
(4th) | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- | i1 i2 i3 i4 i5 i6 i7 -- |
|
|
268
|
+
(out) | h0 h1 h2 h3 h4 h5 h6 h7 | -- F1 F2 F3 F4 F5 F6 F7 | -- -- G2 G3 G4 G5 G6 G7 | -- -- -- H3 H4 H5 H6 H7 |
|
|
269
|
+
=======================================================================================================================
|
|
270
|
+
F1 l1 | i1 h0 | x | | | |
|
|
271
|
+
F2 l2 | i2 h1 | x x | | | |
|
|
272
|
+
F3 l3 | i3 h2 | x x x | | | |
|
|
273
|
+
F4 l4 | i4 h3 | x x x x | | | |
|
|
274
|
+
F5 l5 | i5 h4 | x x x x x | | | |
|
|
275
|
+
F6 l6 | i6 h5 | x x x x x x | | | |
|
|
276
|
+
F7 l7 | i7 h6 | x x x x x x x | | | |
|
|
277
|
+
-- -- | -- h7 | o o o o o o o o | | | |
|
|
278
|
+
=======================================================================================================================
|
|
279
|
+
-- -- | i1 -- | | | | |
|
|
280
|
+
G2 l2 | i2 F1 | x o | x | | |
|
|
281
|
+
G3 l3 | i3 F2 | x x o | x | | |
|
|
282
|
+
G4 l4 | i4 F3 | x x x o | x | | |
|
|
283
|
+
G5 l5 | i5 F4 | x x x x o | x | | |
|
|
284
|
+
G6 l6 | i6 F5 | x x x x x o | x | | |
|
|
285
|
+
G7 l7 | i7 F6 | x x x x x x o | x | | |
|
|
286
|
+
-- -- | -- F7 | | | | |
|
|
287
|
+
=======================================================================================================================
|
|
288
|
+
-- -- | i1 -- | | | | |
|
|
289
|
+
-- -- | i2 -- | | | | |
|
|
290
|
+
H3 l3 | i3 G2 | x o o | x o | x | |
|
|
291
|
+
H4 l4 | i4 G3 | x x o o | x o | x | |
|
|
292
|
+
H5 l5 | i5 G4 | x x x o o | x o | x | |
|
|
293
|
+
H6 l6 | i6 G5 | x x x x o o | x o | x | |
|
|
294
|
+
H7 l7 | i7 G6 | x x x x x o o | x o | x | |
|
|
295
|
+
-- -- | -- G7 | | | | |
|
|
296
|
+
=======================================================================================================================
|
|
297
|
+
-- -- | i1 -- | | | | |
|
|
298
|
+
-- -- | i2 -- | | | | |
|
|
299
|
+
-- -- | i3 -- | | | | |
|
|
300
|
+
K4 l4 | i4 H3 | x | x | x | x |
|
|
301
|
+
K5 l5 | i5 H4 | x x | x | x | x |
|
|
302
|
+
K6 l6 | i6 H5 | x x x | x | x | x |
|
|
303
|
+
K7 l7 | i7 H6 | x x x x | x | x | x |
|
|
304
|
+
-- -- | -- H7 | | | | |
|
|
305
|
+
=======================================================================================================================
|
|
306
|
+
""" # noqa: E501
|
|
307
|
+
assert step > 1, "step should be larger than 1 in multi-step attention mask."
|
|
308
|
+
assert step <= 4, "Currently only a step of 4 or smaller is supported!"
|
|
309
|
+
|
|
310
|
+
s = attn_mask.shape[-1]
|
|
311
|
+
zero_mask = torch.ones_like(attn_mask).bool()
|
|
312
|
+
mask_2_1 = attn_mask.clone().detach()
|
|
313
|
+
mask_2_1[:, :, :, :-1] = mask_2_1[:, :, :, 1:]
|
|
314
|
+
mask_2_2 = torch.ones_like(attn_mask).bool()
|
|
315
|
+
for i in range(1, s - 1):
|
|
316
|
+
mask_2_2[:, :, i, i] = False
|
|
317
|
+
|
|
318
|
+
if step == 2:
|
|
319
|
+
attn_mask = torch.cat(
|
|
320
|
+
(
|
|
321
|
+
torch.cat((attn_mask, zero_mask), dim=-1),
|
|
322
|
+
torch.cat((mask_2_1, mask_2_2), dim=-1),
|
|
323
|
+
),
|
|
324
|
+
dim=-2,
|
|
325
|
+
)
|
|
326
|
+
return attn_mask
|
|
327
|
+
|
|
328
|
+
mask_3_1 = mask_2_1.clone().detach()
|
|
329
|
+
mask_3_1[:, :, :, :-1] = mask_3_1[:, :, :, 1:]
|
|
330
|
+
mask_3_2 = mask_2_2.clone().detach()
|
|
331
|
+
mask_3_2[:, :, :, :-1] = mask_3_2[:, :, :, 1:]
|
|
332
|
+
mask_3_2[:, :, 1, 0] = True
|
|
333
|
+
mask_3_3 = mask_2_2.clone().detach()
|
|
334
|
+
mask_3_3[:, :, 1, 1] = True
|
|
335
|
+
|
|
336
|
+
if step == 3:
|
|
337
|
+
attn_mask = torch.cat(
|
|
338
|
+
(
|
|
339
|
+
torch.cat((attn_mask, zero_mask, zero_mask), dim=-1),
|
|
340
|
+
torch.cat((mask_2_1, mask_2_2, zero_mask), dim=-1),
|
|
341
|
+
torch.cat((mask_3_1, mask_3_2, mask_3_3), dim=-1),
|
|
342
|
+
),
|
|
343
|
+
dim=-2,
|
|
344
|
+
)
|
|
345
|
+
return attn_mask
|
|
346
|
+
|
|
347
|
+
mask_4_1 = mask_3_1.clone().detach()
|
|
348
|
+
mask_4_1[:, :, :, :-1] = mask_4_1[:, :, :, 1:]
|
|
349
|
+
mask_4_2 = mask_3_2.clone().detach()
|
|
350
|
+
mask_4_2[:, :, :, :-1] = mask_4_2[:, :, :, 1:]
|
|
351
|
+
mask_4_2[:, :, 2, 0] = True
|
|
352
|
+
mask_4_3 = mask_3_3.clone().detach()
|
|
353
|
+
mask_4_3[:, :, :, :-1] = mask_4_3[:, :, :, 1:]
|
|
354
|
+
mask_4_3[:, :, 2, 1] = True
|
|
355
|
+
mask_4_4 = mask_3_3.clone().detach()
|
|
356
|
+
mask_4_4[:, :, 2, 2] = True
|
|
357
|
+
|
|
358
|
+
attn_mask = torch.cat(
|
|
359
|
+
(
|
|
360
|
+
torch.cat((attn_mask, zero_mask, zero_mask, zero_mask), dim=-1),
|
|
361
|
+
torch.cat((mask_2_1, mask_2_2, zero_mask, zero_mask), dim=-1),
|
|
362
|
+
torch.cat((mask_3_1, mask_3_2, mask_3_3, zero_mask), dim=-1),
|
|
363
|
+
torch.cat((mask_4_1, mask_4_2, mask_4_3, mask_4_4), dim=-1),
|
|
364
|
+
),
|
|
365
|
+
dim=-2,
|
|
366
|
+
)
|
|
367
|
+
return attn_mask
|
|
368
|
+
|
|
369
|
+
|
|
370
|
+
class EagleLanguageModelEmbedding(LanguageModelEmbedding):
|
|
371
|
+
"""Allow last pp stage to also load the embedding."""
|
|
372
|
+
|
|
373
|
+
def sharded_state_dict(
|
|
374
|
+
self,
|
|
375
|
+
prefix: str = "",
|
|
376
|
+
sharded_offsets: tuple[tuple[int, int, int]] = (),
|
|
377
|
+
metadata: dict | None = None,
|
|
378
|
+
) -> ShardedStateDict:
|
|
379
|
+
"""Different from the default, we change the state_dict to have 1 replica at pp."""
|
|
380
|
+
state_dict = self.state_dict(prefix="", keep_vars=True)
|
|
381
|
+
|
|
382
|
+
weight_prefix = f"{prefix}word_embeddings.weight"
|
|
383
|
+
return {
|
|
384
|
+
weight_prefix: make_tp_sharded_tensor_for_checkpoint(
|
|
385
|
+
tensor=state_dict["word_embeddings.weight"],
|
|
386
|
+
key=weight_prefix,
|
|
387
|
+
allow_shape_mismatch=True,
|
|
388
|
+
prepend_offsets=sharded_offsets,
|
|
389
|
+
# (PP, TP, DP)
|
|
390
|
+
replica_id=(1, 0, get_data_parallel_rank(with_context_parallel=True)),
|
|
391
|
+
)
|
|
392
|
+
}
|
|
393
|
+
|
|
394
|
+
|
|
395
|
+
class EagleTransformerBlock(TransformerBlock):
|
|
396
|
+
"""Only store the EAGLE decoder in the last pp stage."""
|
|
397
|
+
|
|
398
|
+
def sharded_state_dict(
|
|
399
|
+
self, prefix: str = "", sharded_offsets: tuple = (), metadata: dict | None = None
|
|
400
|
+
) -> ShardedStateDict:
|
|
401
|
+
"""Generate a sharded state dictionary for the transformer block.
|
|
402
|
+
|
|
403
|
+
Args:
|
|
404
|
+
prefix (str, optional): Prefix to be added to all keys in the state dict.
|
|
405
|
+
Defaults to an empty string.
|
|
406
|
+
sharded_offsets (tuple, optional): Tuple of sharding offsets.
|
|
407
|
+
metadata (dict, optional): Additional metadata for sharding.
|
|
408
|
+
Can specify if layers are non-homogeneous. Defaults to None.
|
|
409
|
+
|
|
410
|
+
Returns:
|
|
411
|
+
ShardedStateDict: A dictionary containing the sharded state of the model.
|
|
412
|
+
"""
|
|
413
|
+
assert not sharded_offsets, "Unexpected sharded offsets"
|
|
414
|
+
|
|
415
|
+
sharded_state_dict = {}
|
|
416
|
+
|
|
417
|
+
layer_prefix = f"{prefix}layers."
|
|
418
|
+
num_layers = self.config.num_layers
|
|
419
|
+
for global_layer_offset, layer in enumerate(self.layers):
|
|
420
|
+
# global_layer_offset = layer.layer_number - 1 # self.layer_number starts at 1
|
|
421
|
+
state_dict_prefix = (
|
|
422
|
+
f"{layer_prefix}{global_layer_offset}." # module list index in TransformerBlock
|
|
423
|
+
)
|
|
424
|
+
sharded_prefix = layer_prefix
|
|
425
|
+
sharded_pp_offset = [
|
|
426
|
+
(0, global_layer_offset, num_layers)
|
|
427
|
+
] # PP sharding offset for ShardedTensors
|
|
428
|
+
|
|
429
|
+
layer_sharded_state_dict = layer.sharded_state_dict(
|
|
430
|
+
state_dict_prefix, sharded_pp_offset, metadata
|
|
431
|
+
)
|
|
432
|
+
replace_prefix_for_sharding(layer_sharded_state_dict, state_dict_prefix, sharded_prefix)
|
|
433
|
+
sharded_state_dict.update(layer_sharded_state_dict)
|
|
434
|
+
|
|
435
|
+
# Add modules other than self.layers
|
|
436
|
+
for name, module in self.named_children():
|
|
437
|
+
if module is not self.layers:
|
|
438
|
+
sharded_state_dict.update(
|
|
439
|
+
sharded_state_dict_default(
|
|
440
|
+
module, f"{prefix}{name}.", sharded_offsets, metadata
|
|
441
|
+
)
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
return sharded_state_dict
|
|
445
|
+
|
|
446
|
+
|
|
447
|
+
class EagleModule(MegatronModule):
|
|
448
|
+
"""EagleModule definition.
|
|
449
|
+
|
|
450
|
+
EagleModule consists of an FC projection and additional decoder layers.
|
|
451
|
+
"""
|
|
452
|
+
|
|
453
|
+
def __init__(
|
|
454
|
+
self,
|
|
455
|
+
config,
|
|
456
|
+
rotary_pos_emb: torch.nn.Module,
|
|
457
|
+
bias: bool = False,
|
|
458
|
+
):
|
|
459
|
+
"""Constructor.
|
|
460
|
+
|
|
461
|
+
EagleModule is essentially a GPTModel except that it only exists in
|
|
462
|
+
the last pp stage. As a result, pre_process must be True (otherwise
|
|
463
|
+
the decoder expects the input is from the receive buffer).
|
|
464
|
+
post_process must be True to perform the final_layernorm.
|
|
465
|
+
|
|
466
|
+
Args:
|
|
467
|
+
config: MCore transformer config
|
|
468
|
+
rotary_pos_emb: nn.Module.
|
|
469
|
+
"""
|
|
470
|
+
# Override transformer_config before superclass initialization
|
|
471
|
+
config.pipeline_model_parallel_size = 1
|
|
472
|
+
config.virtual_pipeline_model_parallel_size = None
|
|
473
|
+
config.num_layers_in_first_pipeline_stage = None
|
|
474
|
+
config.num_layers_in_last_pipeline_stage = None
|
|
475
|
+
super().__init__(config=config)
|
|
476
|
+
|
|
477
|
+
eagle_transformer_layer_spec = self._get_eagle_transformer_layer_spec(config)
|
|
478
|
+
|
|
479
|
+
self._num_aux_hidden_states = len(self.config.eagle_aux_hidden_state_layer_ids)
|
|
480
|
+
if self._num_aux_hidden_states > 0:
|
|
481
|
+
self.enorm = TENorm(config, config.hidden_size, config.layernorm_epsilon)
|
|
482
|
+
self._embeddings = None
|
|
483
|
+
elif self.config.use_mtp_layernorm:
|
|
484
|
+
self.enorm = TENorm(config, config.hidden_size, config.layernorm_epsilon)
|
|
485
|
+
self.hnorm = TENorm(config, config.hidden_size, config.layernorm_epsilon)
|
|
486
|
+
|
|
487
|
+
device = "cpu" if config.use_cpu_initialization else torch.cuda.current_device()
|
|
488
|
+
|
|
489
|
+
# EAGLE-3 uses aux_hidden_states (usually >= 3); otherwise EAGLE-1
|
|
490
|
+
fc_input_size_multiplier = (
|
|
491
|
+
self._num_aux_hidden_states if self._num_aux_hidden_states > 0 else 2
|
|
492
|
+
)
|
|
493
|
+
|
|
494
|
+
# This linear was previously a ColumnParallelLinear. We changed it to a normal linear
|
|
495
|
+
# since ColumnParallelLinear will have try to gather the input sequence when sequence
|
|
496
|
+
# parallel is used and does not allow gathering the outputs.
|
|
497
|
+
with torch.device(device):
|
|
498
|
+
self.fc = Linear(
|
|
499
|
+
config.hidden_size * fc_input_size_multiplier,
|
|
500
|
+
config.hidden_size,
|
|
501
|
+
config=config,
|
|
502
|
+
init_method=(lambda w: None), # not used
|
|
503
|
+
bias=bias,
|
|
504
|
+
)
|
|
505
|
+
|
|
506
|
+
self.rotary_pos_emb = rotary_pos_emb
|
|
507
|
+
|
|
508
|
+
# Eagle does not use the final_layernorm in decoder.
|
|
509
|
+
with torch.device(device):
|
|
510
|
+
self.decoder = EagleTransformerBlock(
|
|
511
|
+
config=config,
|
|
512
|
+
spec=eagle_transformer_layer_spec,
|
|
513
|
+
post_layer_norm=config.use_last_layernorm,
|
|
514
|
+
pre_process=True,
|
|
515
|
+
post_process=True,
|
|
516
|
+
)
|
|
517
|
+
|
|
518
|
+
if self._num_aux_hidden_states > 0:
|
|
519
|
+
layer = self.decoder.layers[0]
|
|
520
|
+
layer.register_forward_hook(self._eagle3_layer_forward_hook)
|
|
521
|
+
|
|
522
|
+
self_attention = layer.self_attention
|
|
523
|
+
if not isinstance(self_attention, SelfAttention):
|
|
524
|
+
raise ValueError("EAGLE-3 only support SelfAttention (MHA, GQA).")
|
|
525
|
+
|
|
526
|
+
# EAGLE-3's first attention require [input_layernorm_output, aux_hidden_states]
|
|
527
|
+
self_attention.register_forward_pre_hook(self._eagle3_attention_forward_pre_hook)
|
|
528
|
+
|
|
529
|
+
# EAGLE-3's first layer reduces hidden_states from 2h to h.
|
|
530
|
+
self_attention.linear_qkv = tensor_parallel.ColumnParallelLinear(
|
|
531
|
+
self_attention.config.hidden_size * 2,
|
|
532
|
+
self_attention.query_projection_size + 2 * self_attention.kv_projection_size,
|
|
533
|
+
config=self_attention.config,
|
|
534
|
+
init_method=self_attention.config.init_method,
|
|
535
|
+
gather_output=False,
|
|
536
|
+
bias=self_attention.config.add_bias_linear or self_attention.config.add_qkv_bias,
|
|
537
|
+
skip_bias_add=False,
|
|
538
|
+
is_expert=False,
|
|
539
|
+
tp_comm_buffer_name="qkv",
|
|
540
|
+
)
|
|
541
|
+
|
|
542
|
+
if self.config.draft_vocab_size != self.config.vocab_size:
|
|
543
|
+
# Need an extra lm_head for eagle module since vocab size is reduced.
|
|
544
|
+
assert self.config.draft_vocab_size <= self.config.vocab_size, (
|
|
545
|
+
"EAGLE module's vocab size should be <= base model vocab size!"
|
|
546
|
+
)
|
|
547
|
+
|
|
548
|
+
self.register_buffer(
|
|
549
|
+
"d2t", torch.zeros(self.config.draft_vocab_size, dtype=torch.int64)
|
|
550
|
+
)
|
|
551
|
+
if self.config.draft_vocab_size != self.config.vocab_size or self.config.has_lm_head:
|
|
552
|
+
self.eagle_output_layer = tensor_parallel.ColumnParallelLinear(
|
|
553
|
+
self.config.hidden_size,
|
|
554
|
+
self.config.draft_vocab_size,
|
|
555
|
+
config=self.config,
|
|
556
|
+
init_method=self.config.init_method,
|
|
557
|
+
bias=False,
|
|
558
|
+
skip_bias_add=False,
|
|
559
|
+
gather_output=False,
|
|
560
|
+
skip_weight_param_allocation=False,
|
|
561
|
+
)
|
|
562
|
+
|
|
563
|
+
def _get_eagle_transformer_layer_spec(self, config):
|
|
564
|
+
"""Get the TransformerLayer implementation spec.
|
|
565
|
+
|
|
566
|
+
IMPORTANT: EagleModule must use arbitrary_attention_mask since we need to
|
|
567
|
+
manipulate the mask to compute the correct loss. The default
|
|
568
|
+
causal mask will result in leaking.
|
|
569
|
+
"""
|
|
570
|
+
transformer_layer_spec = get_gpt_modelopt_spec(
|
|
571
|
+
config,
|
|
572
|
+
remap_te_layernorm=True,
|
|
573
|
+
use_arbitrary_attention_mask=True,
|
|
574
|
+
)
|
|
575
|
+
# If heterogenous layers (e.g. DeepSeek), transformer_layer_spec is a
|
|
576
|
+
# TransformerBlockSubmodules instead. We use the last layer_specs.
|
|
577
|
+
if "TransformerBlockSubmodules" in str(type(transformer_layer_spec)):
|
|
578
|
+
eagle_transformer_layer_spec = copy.deepcopy(transformer_layer_spec.layer_specs[-1])
|
|
579
|
+
else:
|
|
580
|
+
eagle_transformer_layer_spec = copy.deepcopy(transformer_layer_spec)
|
|
581
|
+
|
|
582
|
+
# Force TransformerLayer in case RealQuantTransformerLayer was used.
|
|
583
|
+
eagle_transformer_layer_spec.module = TransformerLayer
|
|
584
|
+
|
|
585
|
+
if not self.config.use_input_layernorm_in_first_layer:
|
|
586
|
+
eagle_transformer_layer_spec.submodules.input_layernorm = IdentityOp
|
|
587
|
+
return eagle_transformer_layer_spec
|
|
588
|
+
|
|
589
|
+
def _eagle3_layer_forward_hook(self, module, input, output) -> None:
|
|
590
|
+
if not isinstance(module, TransformerLayer):
|
|
591
|
+
raise ValueError(
|
|
592
|
+
"_eagle3_layer_forward_hook can only be registered to TransformerLayer"
|
|
593
|
+
)
|
|
594
|
+
hidden_states = (
|
|
595
|
+
output.clone().detach()
|
|
596
|
+
if isinstance(output, torch.Tensor)
|
|
597
|
+
else output[0].clone().detach()
|
|
598
|
+
)
|
|
599
|
+
self._next_hidden_states_input = hidden_states
|
|
600
|
+
|
|
601
|
+
def _eagle3_attention_forward_pre_hook(self, module, input_layernorm_output):
|
|
602
|
+
assert isinstance(input_layernorm_output[0], torch.Tensor)
|
|
603
|
+
assert self._embeddings is not None
|
|
604
|
+
embeddings = self._embeddings
|
|
605
|
+
self._embeddings = None
|
|
606
|
+
return (torch.cat((embeddings, input_layernorm_output[0]), dim=-1),)
|
|
607
|
+
|
|
608
|
+
def forward(
|
|
609
|
+
self,
|
|
610
|
+
embeddings: torch.Tensor,
|
|
611
|
+
hidden_states: torch.Tensor,
|
|
612
|
+
attention_mask: torch.Tensor,
|
|
613
|
+
rotary_pos_emb: torch.Tensor = None,
|
|
614
|
+
inference_params: InferenceParams = None,
|
|
615
|
+
packed_seq_params: PackedSeqParams = None,
|
|
616
|
+
extra_block_kwargs: dict | None = None,
|
|
617
|
+
) -> torch.Tensor:
|
|
618
|
+
"""Forward function."""
|
|
619
|
+
# NOTE: Even if sequence_parallel is used, the rotary_seq_len must be in the original
|
|
620
|
+
# length. Since we get the seq_len from hidden_states.shape[0], we need to
|
|
621
|
+
# multiply the the tp back.
|
|
622
|
+
rotary_seq_len = hidden_states.shape[0]
|
|
623
|
+
if self.config.sequence_parallel:
|
|
624
|
+
rotary_seq_len *= self.config.tensor_model_parallel_size
|
|
625
|
+
|
|
626
|
+
if self.config.use_mtp_layernorm:
|
|
627
|
+
embeddings = self.enorm(embeddings)
|
|
628
|
+
hidden_states = self.hnorm(hidden_states)
|
|
629
|
+
|
|
630
|
+
# EAGLE-1 uses [s, b, h] input but EAGLE-3 uses [s, b, 2h] input
|
|
631
|
+
if self._num_aux_hidden_states == 0:
|
|
632
|
+
# [s, b, 2h]
|
|
633
|
+
decoder_input = torch.cat((embeddings, hidden_states), dim=-1)
|
|
634
|
+
decoder_input = self.fc(decoder_input)[0]
|
|
635
|
+
else:
|
|
636
|
+
# EAGLE-3 forward
|
|
637
|
+
# EAGLE-3 uses self.fc outside eagle_module forward to convert hidden_states from [s, b, 3h]
|
|
638
|
+
self._embeddings = self.enorm(embeddings)
|
|
639
|
+
decoder_input = hidden_states
|
|
640
|
+
|
|
641
|
+
if rotary_pos_emb is None:
|
|
642
|
+
rotary_pos_emb = (
|
|
643
|
+
None if self.config.multi_latent_attention else self.rotary_pos_emb(rotary_seq_len)
|
|
644
|
+
)
|
|
645
|
+
|
|
646
|
+
self._next_hidden_states_input = None
|
|
647
|
+
|
|
648
|
+
decoder_input_list = [decoder_input]
|
|
649
|
+
self.decoder.set_input_tensor(decoder_input_list[0])
|
|
650
|
+
hidden_states = self.decoder(
|
|
651
|
+
hidden_states=decoder_input,
|
|
652
|
+
attention_mask=attention_mask,
|
|
653
|
+
inference_params=inference_params,
|
|
654
|
+
rotary_pos_emb=rotary_pos_emb,
|
|
655
|
+
packed_seq_params=packed_seq_params,
|
|
656
|
+
**(extra_block_kwargs or {}),
|
|
657
|
+
)
|
|
658
|
+
|
|
659
|
+
if self._next_hidden_states_input is None:
|
|
660
|
+
next_hidden_states_input = hidden_states
|
|
661
|
+
else:
|
|
662
|
+
next_hidden_states_input = self._next_hidden_states_input
|
|
663
|
+
self._next_hidden_states_input = None
|
|
664
|
+
|
|
665
|
+
return hidden_states, next_hidden_states_input
|
|
666
|
+
|
|
667
|
+
|
|
668
|
+
@EagleDMRegistry.register({GPTModel: "megatron.core.models.gpt.GPTModel"})
|
|
669
|
+
class _DynamicEagleGPTModel(EagleModel):
|
|
670
|
+
"""A ``megatron.core.models.gpt.GPTModel`` model with dynamic hyperparams."""
|
|
671
|
+
|
|
672
|
+
def _set_default_aux_hidden_state_layers(self):
|
|
673
|
+
if hasattr(self.config, "original_num_layers"):
|
|
674
|
+
num_layers = self.config.original_num_layers
|
|
675
|
+
else:
|
|
676
|
+
num_layers = self.config.num_layers
|
|
677
|
+
self.eagle_config.eagle_aux_hidden_state_layer_ids = [
|
|
678
|
+
1,
|
|
679
|
+
max(0, num_layers // 2 - 1),
|
|
680
|
+
max(0, num_layers - 4),
|
|
681
|
+
]
|
|
682
|
+
self.eagle_config.eagle_aux_hidden_state_layer_ids = list(
|
|
683
|
+
set(self.eagle_config.eagle_aux_hidden_state_layer_ids)
|
|
684
|
+
)
|
|
685
|
+
|
|
686
|
+
def _transformer_layer_forward_hook(self, module, input, output) -> None:
|
|
687
|
+
if not isinstance(module, TransformerLayer):
|
|
688
|
+
raise ValueError(
|
|
689
|
+
"_transformer_layer_forward_hook can only be registered to TransformerLayer"
|
|
690
|
+
)
|
|
691
|
+
if module.layer_number - 1 not in self.eagle_config.eagle_aux_hidden_state_layer_ids:
|
|
692
|
+
return
|
|
693
|
+
hidden_states = (
|
|
694
|
+
output.clone().detach()
|
|
695
|
+
if isinstance(output, torch.Tensor)
|
|
696
|
+
else output[0].clone().detach()
|
|
697
|
+
)
|
|
698
|
+
self._aux_hidden_states.append(hidden_states)
|
|
699
|
+
|
|
700
|
+
def _setup(self):
|
|
701
|
+
super()._setup()
|
|
702
|
+
self._register_temp_attribute("eagle_freeze_base_model", True)
|
|
703
|
+
self._register_temp_attribute("calibration_mode", False)
|
|
704
|
+
|
|
705
|
+
def modify(
|
|
706
|
+
self,
|
|
707
|
+
eagle_offline,
|
|
708
|
+
eagle_hidden_state_distillation,
|
|
709
|
+
eagle_self_logit_distillation,
|
|
710
|
+
eagle_freeze_base_model,
|
|
711
|
+
eagle_report_acc,
|
|
712
|
+
eagle_reuse_base_decoder,
|
|
713
|
+
eagle_loss_decay_factor,
|
|
714
|
+
eagle_architecture_config,
|
|
715
|
+
):
|
|
716
|
+
if self.config.pipeline_model_parallel_size > 1:
|
|
717
|
+
warnings.warn(
|
|
718
|
+
"Pipeline parallelism detected! _DynamicEagleGPTModel only supports "
|
|
719
|
+
"pipeline parallelism during TensorRT-LLM checkpoint export."
|
|
720
|
+
)
|
|
721
|
+
|
|
722
|
+
# Since there is a chance that EAGLE3 can have heterogenous layers (1st layer
|
|
723
|
+
# qkv is 2x large than the rest), we enable MCore hetereogeneous checkpoint.
|
|
724
|
+
if hasattr(self.config, "hetereogenous_dist_checkpoint"):
|
|
725
|
+
self.config.hetereogenous_dist_checkpoint = True
|
|
726
|
+
|
|
727
|
+
super().modify(
|
|
728
|
+
eagle_offline=eagle_offline,
|
|
729
|
+
eagle_hidden_state_distillation=eagle_hidden_state_distillation,
|
|
730
|
+
eagle_self_logit_distillation=eagle_self_logit_distillation,
|
|
731
|
+
eagle_freeze_base_model=eagle_freeze_base_model,
|
|
732
|
+
eagle_report_acc=eagle_report_acc,
|
|
733
|
+
eagle_reuse_base_decoder=eagle_reuse_base_decoder,
|
|
734
|
+
eagle_loss_decay_factor=eagle_loss_decay_factor,
|
|
735
|
+
eagle_architecture_config=eagle_architecture_config,
|
|
736
|
+
)
|
|
737
|
+
|
|
738
|
+
self.eagle_config = dict_to_config(
|
|
739
|
+
eagle_architecture_config,
|
|
740
|
+
self.config.use_cpu_initialization,
|
|
741
|
+
self.config.fp16,
|
|
742
|
+
self.config.bf16,
|
|
743
|
+
self.config.sequence_parallel,
|
|
744
|
+
)
|
|
745
|
+
|
|
746
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
747
|
+
assert eagle_self_logit_distillation, (
|
|
748
|
+
"Only logit distillation is supported when draft_vocab_size != vocab_size!"
|
|
749
|
+
)
|
|
750
|
+
|
|
751
|
+
# Use default aux_hidden_state layers if use_aux_hidden_state is True
|
|
752
|
+
# but no layer id is given
|
|
753
|
+
if (
|
|
754
|
+
self.eagle_config.use_aux_hidden_state
|
|
755
|
+
and len(self.eagle_config.eagle_aux_hidden_state_layer_ids) == 0
|
|
756
|
+
):
|
|
757
|
+
self._set_default_aux_hidden_state_layers()
|
|
758
|
+
|
|
759
|
+
if len(self.eagle_config.eagle_aux_hidden_state_layer_ids) > 0:
|
|
760
|
+
assert not self.eagle_hidden_state_distillation, (
|
|
761
|
+
"EAGLE-3 does not support hidden state distillation!"
|
|
762
|
+
)
|
|
763
|
+
|
|
764
|
+
# EAGLE-3 auxiliary hidden_states (only work for TP+EP, does not work for PP)
|
|
765
|
+
self._aux_hidden_states = []
|
|
766
|
+
|
|
767
|
+
if self.eagle_config.position_embedding_type not in ["rope", "yarn"]:
|
|
768
|
+
raise ValueError("For EAGLE, only RoPE or YaRN embedding are supported")
|
|
769
|
+
|
|
770
|
+
if not self.pre_process and self.post_process:
|
|
771
|
+
self.embedding = EagleLanguageModelEmbedding(
|
|
772
|
+
config=self.config,
|
|
773
|
+
vocab_size=self.vocab_size,
|
|
774
|
+
max_sequence_length=self.max_sequence_length,
|
|
775
|
+
position_embedding_type=self.position_embedding_type,
|
|
776
|
+
)
|
|
777
|
+
|
|
778
|
+
# Register TransformerLayer forward hook to extract aux hidden_states.
|
|
779
|
+
if len(self.eagle_config.eagle_aux_hidden_state_layer_ids) > 0:
|
|
780
|
+
for layer in self.decoder.layers:
|
|
781
|
+
layer.register_forward_hook(self._transformer_layer_forward_hook)
|
|
782
|
+
|
|
783
|
+
# Freeze all parameters
|
|
784
|
+
if self.eagle_freeze_base_model:
|
|
785
|
+
for name, param in self.named_parameters():
|
|
786
|
+
param.requires_grad = False
|
|
787
|
+
|
|
788
|
+
# Only the last PP stage has the additional projection and decoder layer.
|
|
789
|
+
# This is to simplify the export.
|
|
790
|
+
if self.post_process:
|
|
791
|
+
if self.eagle_reuse_base_decoder:
|
|
792
|
+
eagle_config = copy.deepcopy(self.config)
|
|
793
|
+
# Overwrite values from the eagle config
|
|
794
|
+
eagle_config.num_layers = self.eagle_config.num_layers
|
|
795
|
+
eagle_config.use_last_layernorm = self.eagle_config.use_last_layernorm
|
|
796
|
+
eagle_config.use_input_layernorm_in_first_layer = (
|
|
797
|
+
self.eagle_config.use_input_layernorm_in_first_layer
|
|
798
|
+
)
|
|
799
|
+
eagle_config.eagle_aux_hidden_state_layer_ids = (
|
|
800
|
+
self.eagle_config.eagle_aux_hidden_state_layer_ids
|
|
801
|
+
)
|
|
802
|
+
eagle_config.use_mtp_layernorm = self.eagle_config.use_mtp_layernorm
|
|
803
|
+
self.eagle_module = EagleModule(
|
|
804
|
+
eagle_config,
|
|
805
|
+
self.rotary_pos_emb,
|
|
806
|
+
bias=False,
|
|
807
|
+
)
|
|
808
|
+
else:
|
|
809
|
+
rotary_pos_emb = RotaryEmbedding(
|
|
810
|
+
kv_channels=self.eagle_config.kv_channels,
|
|
811
|
+
rotary_percent=self.eagle_config.rotary_percent,
|
|
812
|
+
rotary_interleaved=False,
|
|
813
|
+
seq_len_interpolation_factor=None,
|
|
814
|
+
rotary_base=self.eagle_config.rotary_base,
|
|
815
|
+
rope_scaling=self.eagle_config.rope_scaling,
|
|
816
|
+
rope_scaling_factor=self.eagle_config.rope_scaling_factor,
|
|
817
|
+
use_cpu_initialization=self.eagle_config.use_cpu_initialization,
|
|
818
|
+
)
|
|
819
|
+
|
|
820
|
+
self.eagle_module = EagleModule(
|
|
821
|
+
self.eagle_config,
|
|
822
|
+
rotary_pos_emb,
|
|
823
|
+
bias=False,
|
|
824
|
+
)
|
|
825
|
+
|
|
826
|
+
# Eagle loss functions
|
|
827
|
+
self.kld = logits_kld_loss
|
|
828
|
+
|
|
829
|
+
def _get_eagle_input_hidden_states(self, hidden_states: torch.Tensor, apply_fc: bool = True):
|
|
830
|
+
"""When _aux_hidden_states is not empty, then this is EAGLE-3.
|
|
831
|
+
|
|
832
|
+
Args:
|
|
833
|
+
hidden_states: last hidden_states
|
|
834
|
+
apply_fc: whether to apply EAGLE3 fc
|
|
835
|
+
"""
|
|
836
|
+
if len(self._aux_hidden_states) == 0:
|
|
837
|
+
return hidden_states
|
|
838
|
+
|
|
839
|
+
# [s / TP, b, len(self._aux_hidden_states) * h]
|
|
840
|
+
aux_hidden_states = torch.cat(self._aux_hidden_states, dim=-1)
|
|
841
|
+
self._aux_hidden_states.clear()
|
|
842
|
+
|
|
843
|
+
if apply_fc:
|
|
844
|
+
# [s / TP, b, 3h] -> [s / TP, b, h]
|
|
845
|
+
return self.eagle_module.fc(aux_hidden_states)[0]
|
|
846
|
+
else:
|
|
847
|
+
return aux_hidden_states
|
|
848
|
+
|
|
849
|
+
def _get_eagle_module_inputs(
|
|
850
|
+
self,
|
|
851
|
+
input_ids: torch.Tensor,
|
|
852
|
+
hidden_states: torch.Tensor,
|
|
853
|
+
attention_mask: torch.Tensor,
|
|
854
|
+
position_ids: torch.Tensor,
|
|
855
|
+
features: torch.Tensor | None = None,
|
|
856
|
+
):
|
|
857
|
+
"""Getting EAGLE module inputs."""
|
|
858
|
+
b = hidden_states.shape[1]
|
|
859
|
+
h = hidden_states.shape[2]
|
|
860
|
+
|
|
861
|
+
# [b, 1]
|
|
862
|
+
id_padding = torch.zeros((b, 1), dtype=input_ids.dtype, device=input_ids.device)
|
|
863
|
+
padded_input_ids = torch.cat((input_ids[:, 1:], id_padding), dim=-1)
|
|
864
|
+
|
|
865
|
+
rotary_pos_emb = self.eagle_module.rotary_pos_emb(padded_input_ids.shape[-1])
|
|
866
|
+
|
|
867
|
+
attn_mask = attention_mask.clone().detach()
|
|
868
|
+
attn_mask[:, :, :-1, :-1] = attention_mask[:, :, 1:, 1:]
|
|
869
|
+
attn_mask[:, :, -1, :] = True
|
|
870
|
+
attn_mask[:, :, :, -1] = True
|
|
871
|
+
|
|
872
|
+
eagle_inputs = {}
|
|
873
|
+
|
|
874
|
+
if self.eagle_config.parallel_draft_step > 1:
|
|
875
|
+
eagle_inputs["input_ids"] = padded_input_ids
|
|
876
|
+
eagle_inputs["position_ids"] = position_ids
|
|
877
|
+
if rotary_pos_emb is not None:
|
|
878
|
+
eagle_inputs["rotary_pos_emb"] = rotary_pos_emb
|
|
879
|
+
else:
|
|
880
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
881
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
882
|
+
|
|
883
|
+
if self.config.sequence_parallel:
|
|
884
|
+
gathered_hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
885
|
+
else:
|
|
886
|
+
gathered_hidden_states = hidden_states
|
|
887
|
+
eagle_inputs["hidden_states"] = gathered_hidden_states
|
|
888
|
+
|
|
889
|
+
for i in range(self.eagle_config.parallel_draft_step - 1):
|
|
890
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
891
|
+
(
|
|
892
|
+
eagle_inputs["input_ids"],
|
|
893
|
+
torch.full(
|
|
894
|
+
padded_input_ids.shape,
|
|
895
|
+
getattr(self, f"mask_token_{i}"),
|
|
896
|
+
device=padded_input_ids.device,
|
|
897
|
+
dtype=padded_input_ids.dtype,
|
|
898
|
+
),
|
|
899
|
+
),
|
|
900
|
+
dim=-1,
|
|
901
|
+
)
|
|
902
|
+
|
|
903
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
904
|
+
(
|
|
905
|
+
eagle_inputs["hidden_states"],
|
|
906
|
+
torch.zeros(
|
|
907
|
+
(1 + i, b, h), dtype=hidden_states.dtype, device=hidden_states.device
|
|
908
|
+
),
|
|
909
|
+
gathered_hidden_states[: -(1 + i)],
|
|
910
|
+
),
|
|
911
|
+
dim=0,
|
|
912
|
+
)
|
|
913
|
+
|
|
914
|
+
eagle_inputs["position_ids"] = torch.cat(
|
|
915
|
+
(eagle_inputs["position_ids"], position_ids), dim=-1
|
|
916
|
+
)
|
|
917
|
+
|
|
918
|
+
if rotary_pos_emb is not None:
|
|
919
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
|
920
|
+
(eagle_inputs["rotary_pos_emb"], rotary_pos_emb), dim=0
|
|
921
|
+
)
|
|
922
|
+
|
|
923
|
+
if self.config.sequence_parallel:
|
|
924
|
+
eagle_inputs["hidden_states"] = scatter_to_sequence_parallel_region(
|
|
925
|
+
eagle_inputs["hidden_states"]
|
|
926
|
+
)
|
|
927
|
+
|
|
928
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(
|
|
929
|
+
attn_mask, self.eagle_config.parallel_draft_step
|
|
930
|
+
)
|
|
931
|
+
elif features is None:
|
|
932
|
+
eagle_inputs["input_ids"] = padded_input_ids
|
|
933
|
+
eagle_inputs["hidden_states"] = hidden_states
|
|
934
|
+
eagle_inputs["attention_mask"] = attn_mask
|
|
935
|
+
eagle_inputs["position_ids"] = position_ids
|
|
936
|
+
eagle_inputs["rotary_pos_emb"] = rotary_pos_emb
|
|
937
|
+
elif features.shape[0] == hidden_states.shape[0]:
|
|
938
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
939
|
+
(padded_input_ids, padded_input_ids),
|
|
940
|
+
dim=-1,
|
|
941
|
+
)
|
|
942
|
+
|
|
943
|
+
if self.config.sequence_parallel:
|
|
944
|
+
gathered_hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
945
|
+
gathered_features = gather_from_sequence_parallel_region(features)
|
|
946
|
+
else:
|
|
947
|
+
gathered_hidden_states = hidden_states
|
|
948
|
+
gathered_features = features
|
|
949
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
950
|
+
(
|
|
951
|
+
gathered_hidden_states,
|
|
952
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
953
|
+
gathered_features[:-1, :, :],
|
|
954
|
+
),
|
|
955
|
+
dim=0,
|
|
956
|
+
)
|
|
957
|
+
if self.config.sequence_parallel:
|
|
958
|
+
eagle_inputs["hidden_states"] = scatter_to_sequence_parallel_region(
|
|
959
|
+
eagle_inputs["hidden_states"]
|
|
960
|
+
)
|
|
961
|
+
|
|
962
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 2)
|
|
963
|
+
eagle_inputs["position_ids"] = torch.cat((position_ids, position_ids), dim=-1)
|
|
964
|
+
|
|
965
|
+
if rotary_pos_emb is not None:
|
|
966
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=0)
|
|
967
|
+
else:
|
|
968
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
969
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
970
|
+
elif features.shape[0] == hidden_states.shape[0] * 2:
|
|
971
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
972
|
+
(padded_input_ids, padded_input_ids, padded_input_ids),
|
|
973
|
+
dim=-1,
|
|
974
|
+
)
|
|
975
|
+
|
|
976
|
+
if self.config.sequence_parallel:
|
|
977
|
+
gathered_hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
978
|
+
gathered_features = gather_from_sequence_parallel_region(features)
|
|
979
|
+
else:
|
|
980
|
+
gathered_hidden_states = hidden_states
|
|
981
|
+
gathered_features = features
|
|
982
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
983
|
+
(
|
|
984
|
+
gathered_hidden_states,
|
|
985
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
986
|
+
gathered_features[:-1, :, :],
|
|
987
|
+
),
|
|
988
|
+
dim=0,
|
|
989
|
+
)
|
|
990
|
+
if self.config.sequence_parallel:
|
|
991
|
+
eagle_inputs["hidden_states"] = scatter_to_sequence_parallel_region(
|
|
992
|
+
eagle_inputs["hidden_states"]
|
|
993
|
+
)
|
|
994
|
+
|
|
995
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 3)
|
|
996
|
+
eagle_inputs["position_ids"] = torch.cat(
|
|
997
|
+
(position_ids, position_ids, position_ids), dim=-1
|
|
998
|
+
)
|
|
999
|
+
|
|
1000
|
+
if rotary_pos_emb is not None:
|
|
1001
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
|
1002
|
+
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
|
1003
|
+
dim=0,
|
|
1004
|
+
)
|
|
1005
|
+
else:
|
|
1006
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
1007
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1008
|
+
else:
|
|
1009
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
1010
|
+
(padded_input_ids, padded_input_ids, padded_input_ids, padded_input_ids),
|
|
1011
|
+
dim=-1,
|
|
1012
|
+
)
|
|
1013
|
+
|
|
1014
|
+
if self.config.sequence_parallel:
|
|
1015
|
+
gathered_hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
1016
|
+
gathered_features = gather_from_sequence_parallel_region(features)
|
|
1017
|
+
else:
|
|
1018
|
+
gathered_hidden_states = hidden_states
|
|
1019
|
+
gathered_features = features
|
|
1020
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
1021
|
+
(
|
|
1022
|
+
gathered_hidden_states,
|
|
1023
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
1024
|
+
gathered_features[:-1, :, :],
|
|
1025
|
+
),
|
|
1026
|
+
dim=0,
|
|
1027
|
+
)
|
|
1028
|
+
if self.config.sequence_parallel:
|
|
1029
|
+
eagle_inputs["hidden_states"] = scatter_to_sequence_parallel_region(
|
|
1030
|
+
eagle_inputs["hidden_states"]
|
|
1031
|
+
)
|
|
1032
|
+
|
|
1033
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 4)
|
|
1034
|
+
eagle_inputs["position_ids"] = torch.cat(
|
|
1035
|
+
(position_ids, position_ids, position_ids, position_ids), dim=-1
|
|
1036
|
+
)
|
|
1037
|
+
|
|
1038
|
+
if rotary_pos_emb is not None:
|
|
1039
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
|
1040
|
+
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
|
1041
|
+
dim=0,
|
|
1042
|
+
)
|
|
1043
|
+
else:
|
|
1044
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
1045
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1046
|
+
|
|
1047
|
+
eagle_inputs["embedding"] = self.embedding(
|
|
1048
|
+
input_ids=eagle_inputs["input_ids"],
|
|
1049
|
+
position_ids=eagle_inputs["position_ids"],
|
|
1050
|
+
)
|
|
1051
|
+
|
|
1052
|
+
return eagle_inputs
|
|
1053
|
+
|
|
1054
|
+
def _compute_eagle_loss(self, logits, labels, eagle_logits):
|
|
1055
|
+
"""Compute the total loss for EAGLE.
|
|
1056
|
+
|
|
1057
|
+
logits: [s, b, vocab // TP]
|
|
1058
|
+
labels: [b, s]
|
|
1059
|
+
eagle_logits: [s, b, vocab // TP]
|
|
1060
|
+
"""
|
|
1061
|
+
# Compute lm loss (classification loss) or KLDivergence
|
|
1062
|
+
if self.eagle_self_logit_distillation:
|
|
1063
|
+
mapping = self.eagle_module.d2t if hasattr(self.eagle_module, "d2t") else None
|
|
1064
|
+
token_loss = self.kld(eagle_logits[:-1, :, :], logits[1:, :, :], mapping)
|
|
1065
|
+
else:
|
|
1066
|
+
token_loss = self.compute_language_model_loss(labels[:, 1:], eagle_logits[:-1, :, :])
|
|
1067
|
+
|
|
1068
|
+
# [b, s - 1]
|
|
1069
|
+
return token_loss
|
|
1070
|
+
|
|
1071
|
+
def _base_model_forward(
|
|
1072
|
+
self,
|
|
1073
|
+
input_ids: torch.Tensor,
|
|
1074
|
+
position_ids: torch.Tensor,
|
|
1075
|
+
attention_mask: torch.Tensor,
|
|
1076
|
+
decoder_input: torch.Tensor = None,
|
|
1077
|
+
inference_params: InferenceParams = None,
|
|
1078
|
+
packed_seq_params: PackedSeqParams = None,
|
|
1079
|
+
extra_block_kwargs: dict | None = None,
|
|
1080
|
+
return_eagle_inputs: bool = False,
|
|
1081
|
+
):
|
|
1082
|
+
# Word and rotary positional embeddings
|
|
1083
|
+
if decoder_input is not None:
|
|
1084
|
+
pass
|
|
1085
|
+
elif self.pre_process:
|
|
1086
|
+
decoder_input = self.embedding(input_ids=input_ids, position_ids=position_ids)
|
|
1087
|
+
else:
|
|
1088
|
+
# intermediate stage of pipeline
|
|
1089
|
+
# decoder will get hidden_states from decoder.input_tensor
|
|
1090
|
+
decoder_input = None
|
|
1091
|
+
|
|
1092
|
+
extra_kwargs = {"packed_seq_params": None} if mcore_version_higher_than("0.9.0") else {}
|
|
1093
|
+
|
|
1094
|
+
rotary_pos_emb = None
|
|
1095
|
+
yarn_mscale = 1.0
|
|
1096
|
+
if self.config.multi_latent_attention:
|
|
1097
|
+
# For MLA, rotary_pos_emb is computed per attention.
|
|
1098
|
+
rotary_pos_emb = None
|
|
1099
|
+
elif self.position_embedding_type == "rope":
|
|
1100
|
+
rotary_seq_len = self.rotary_pos_emb.get_rotary_seq_len(
|
|
1101
|
+
inference_params,
|
|
1102
|
+
self.decoder,
|
|
1103
|
+
decoder_input,
|
|
1104
|
+
self.config,
|
|
1105
|
+
**extra_kwargs,
|
|
1106
|
+
)
|
|
1107
|
+
rotary_pos_emb = self.rotary_pos_emb(rotary_seq_len)
|
|
1108
|
+
elif self.position_embedding_type == "yarn":
|
|
1109
|
+
rotary_seq_len = self.rotary_pos_emb.get_rotary_seq_len(
|
|
1110
|
+
inference_params,
|
|
1111
|
+
None,
|
|
1112
|
+
decoder_input,
|
|
1113
|
+
self.config,
|
|
1114
|
+
**extra_kwargs,
|
|
1115
|
+
)
|
|
1116
|
+
rotary_pos_emb, yarn_mscale = self.rotary_pos_emb(rotary_seq_len)
|
|
1117
|
+
else:
|
|
1118
|
+
raise ValueError(
|
|
1119
|
+
f"Only RoPE or YaRN are supported but got {self.position_embedding_type}"
|
|
1120
|
+
)
|
|
1121
|
+
|
|
1122
|
+
# [TODO]: yarn_mscale needs to be passed into TransformerBlock forward when supported.
|
|
1123
|
+
# Now the default value for yarn_mscale = 1.0
|
|
1124
|
+
hidden_states = self.decoder(
|
|
1125
|
+
hidden_states=decoder_input,
|
|
1126
|
+
attention_mask=attention_mask,
|
|
1127
|
+
inference_params=inference_params,
|
|
1128
|
+
rotary_pos_emb=rotary_pos_emb,
|
|
1129
|
+
packed_seq_params=packed_seq_params,
|
|
1130
|
+
**(extra_block_kwargs or {}),
|
|
1131
|
+
)
|
|
1132
|
+
|
|
1133
|
+
if return_eagle_inputs:
|
|
1134
|
+
return hidden_states, decoder_input
|
|
1135
|
+
else:
|
|
1136
|
+
return hidden_states, None
|
|
1137
|
+
|
|
1138
|
+
def _eagle_forward(
|
|
1139
|
+
self,
|
|
1140
|
+
eagle_inputs,
|
|
1141
|
+
output_weight,
|
|
1142
|
+
inference_params: InferenceParams = None,
|
|
1143
|
+
packed_seq_params: PackedSeqParams = None,
|
|
1144
|
+
extra_block_kwargs: dict | None = None,
|
|
1145
|
+
):
|
|
1146
|
+
eagle_hidden_states, eagle_hidden_states_pre_final_layernorm = self.eagle_module(
|
|
1147
|
+
eagle_inputs["embedding"],
|
|
1148
|
+
eagle_inputs["hidden_states"],
|
|
1149
|
+
eagle_inputs["attention_mask"],
|
|
1150
|
+
eagle_inputs["rotary_pos_emb"],
|
|
1151
|
+
inference_params=inference_params,
|
|
1152
|
+
packed_seq_params=packed_seq_params,
|
|
1153
|
+
**(extra_block_kwargs or {}),
|
|
1154
|
+
)
|
|
1155
|
+
|
|
1156
|
+
if hasattr(self.eagle_module, "eagle_output_layer"):
|
|
1157
|
+
eagle_logits, _ = self.eagle_module.eagle_output_layer(eagle_hidden_states)
|
|
1158
|
+
else:
|
|
1159
|
+
eagle_logits, _ = self.output_layer(eagle_hidden_states, weight=output_weight)
|
|
1160
|
+
|
|
1161
|
+
return eagle_hidden_states, eagle_logits, eagle_hidden_states_pre_final_layernorm
|
|
1162
|
+
|
|
1163
|
+
def forward(
|
|
1164
|
+
self,
|
|
1165
|
+
input_ids: torch.Tensor,
|
|
1166
|
+
position_ids: torch.Tensor = None,
|
|
1167
|
+
attention_mask: torch.Tensor = None,
|
|
1168
|
+
decoder_input: torch.Tensor = None,
|
|
1169
|
+
labels: torch.Tensor = None,
|
|
1170
|
+
inference_params: InferenceParams = None,
|
|
1171
|
+
packed_seq_params: PackedSeqParams = None,
|
|
1172
|
+
extra_block_kwargs: dict | None = None,
|
|
1173
|
+
return_eagle_inputs: bool = False,
|
|
1174
|
+
**kwargs,
|
|
1175
|
+
) -> torch.Tensor:
|
|
1176
|
+
if input_ids is not None and (position_ids is None or attention_mask is None):
|
|
1177
|
+
attention_mask, position_ids = get_default_attention_mask_and_position_ids(input_ids)
|
|
1178
|
+
|
|
1179
|
+
# When return_eagle_inputs is True, return decoder_input_for_eagle.
|
|
1180
|
+
# When LLM, decoder_input_for_eagle is just the text embeddings. However, when VLM
|
|
1181
|
+
# decoder_input_for_eagle will also contain projected image/video embeddings.
|
|
1182
|
+
hidden_states, decoder_input_for_eagle = self._base_model_forward(
|
|
1183
|
+
input_ids,
|
|
1184
|
+
position_ids,
|
|
1185
|
+
attention_mask,
|
|
1186
|
+
decoder_input,
|
|
1187
|
+
inference_params,
|
|
1188
|
+
packed_seq_params,
|
|
1189
|
+
extra_block_kwargs,
|
|
1190
|
+
return_eagle_inputs=return_eagle_inputs,
|
|
1191
|
+
)
|
|
1192
|
+
|
|
1193
|
+
# Typically, this is only the case when PP > 1.
|
|
1194
|
+
if not self.post_process:
|
|
1195
|
+
return hidden_states
|
|
1196
|
+
|
|
1197
|
+
output_weight = None
|
|
1198
|
+
if self.share_embeddings_and_output_weights:
|
|
1199
|
+
output_weight = self.shared_embedding_or_output_weight()
|
|
1200
|
+
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
|
1201
|
+
|
|
1202
|
+
# If EAGLE-3, aux_hidden_states are gathered by the forward_hook
|
|
1203
|
+
if return_eagle_inputs:
|
|
1204
|
+
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(
|
|
1205
|
+
hidden_states, apply_fc=False
|
|
1206
|
+
)
|
|
1207
|
+
|
|
1208
|
+
if self.config.sequence_parallel:
|
|
1209
|
+
eagle_module_input_hidden_states = gather_from_sequence_parallel_region(
|
|
1210
|
+
eagle_module_input_hidden_states
|
|
1211
|
+
)
|
|
1212
|
+
hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
1213
|
+
logits_sbh = gather_from_tensor_model_parallel_region(logits_sbh)
|
|
1214
|
+
# In case of VLM, there will be other fields for pixels.
|
|
1215
|
+
return {
|
|
1216
|
+
"input_ids": input_ids.squeeze(0).cpu(),
|
|
1217
|
+
"aux_hidden_states": eagle_module_input_hidden_states.squeeze(1).cpu(),
|
|
1218
|
+
"hidden_states": hidden_states.squeeze(1).cpu(),
|
|
1219
|
+
}
|
|
1220
|
+
else:
|
|
1221
|
+
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(
|
|
1222
|
+
hidden_states, apply_fc=True
|
|
1223
|
+
)
|
|
1224
|
+
|
|
1225
|
+
# Either inference or calibration mode, we want to make sure all weights have been exercised.
|
|
1226
|
+
# This makes sure all quantized weights have amax calibrated
|
|
1227
|
+
if inference_params is None or self.calibration_mode:
|
|
1228
|
+
eagle_inputs_0 = self._get_eagle_module_inputs(
|
|
1229
|
+
input_ids=input_ids,
|
|
1230
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1231
|
+
attention_mask=attention_mask,
|
|
1232
|
+
position_ids=position_ids,
|
|
1233
|
+
)
|
|
1234
|
+
|
|
1235
|
+
_, eagle_logits_0, eagle_hidden_states_0_pre_norm = self._eagle_forward(
|
|
1236
|
+
eagle_inputs_0,
|
|
1237
|
+
output_weight,
|
|
1238
|
+
inference_params=inference_params,
|
|
1239
|
+
packed_seq_params=packed_seq_params,
|
|
1240
|
+
**(extra_block_kwargs or {}),
|
|
1241
|
+
)
|
|
1242
|
+
|
|
1243
|
+
# If labels are not provided, return the original logits. We only return after
|
|
1244
|
+
# all eagle weights have been exercised for quantization calibration purpose.
|
|
1245
|
+
if labels is None:
|
|
1246
|
+
return logits_sbh.transpose(0, 1).contiguous()
|
|
1247
|
+
|
|
1248
|
+
# If eagle_freeze_base_model is set to True,
|
|
1249
|
+
# the base model is frozen .
|
|
1250
|
+
loss = self.compute_language_model_loss(labels, logits_sbh)
|
|
1251
|
+
loss = 0.0 * loss
|
|
1252
|
+
|
|
1253
|
+
if self.eagle_config.parallel_draft_step > 1:
|
|
1254
|
+
for i in range(self.eagle_config.parallel_draft_step):
|
|
1255
|
+
eagle_logits = eagle_logits_0[i * labels.shape[1] : (i + 1) * labels.shape[1]]
|
|
1256
|
+
loss_ = self._compute_eagle_loss(logits_sbh, labels, eagle_logits)
|
|
1257
|
+
loss_ = loss_[:, i:]
|
|
1258
|
+
loss[:, i + 1 :] += 1.0 * loss_
|
|
1259
|
+
return loss
|
|
1260
|
+
|
|
1261
|
+
loss_0 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_0)
|
|
1262
|
+
loss[:, 1:] += self.eagle_loss_decay_factor * loss_0
|
|
1263
|
+
|
|
1264
|
+
if self.eagle_report_acc and not self.training:
|
|
1265
|
+
acc = []
|
|
1266
|
+
with torch.no_grad():
|
|
1267
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
1268
|
+
eagle_logits_0[:-1, :, :]
|
|
1269
|
+
)
|
|
1270
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
1271
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1272
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
1273
|
+
top1_p = torch.eq(labels[:, 1:], eagle_top1).sum() / eagle_top1.numel()
|
|
1274
|
+
acc.append(top1_p)
|
|
1275
|
+
|
|
1276
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
1277
|
+
print(
|
|
1278
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 1st Top-1: {acc}",
|
|
1279
|
+
flush=True,
|
|
1280
|
+
)
|
|
1281
|
+
|
|
1282
|
+
# Second round of EAGLE loss
|
|
1283
|
+
eagle_inputs_1 = self._get_eagle_module_inputs(
|
|
1284
|
+
input_ids=input_ids,
|
|
1285
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1286
|
+
attention_mask=attention_mask,
|
|
1287
|
+
position_ids=position_ids,
|
|
1288
|
+
features=eagle_hidden_states_0_pre_norm,
|
|
1289
|
+
)
|
|
1290
|
+
|
|
1291
|
+
_, eagle_logits_2x, eagle_hidden_states_2x_pre_norm = self._eagle_forward(
|
|
1292
|
+
eagle_inputs_1,
|
|
1293
|
+
output_weight,
|
|
1294
|
+
inference_params=inference_params,
|
|
1295
|
+
packed_seq_params=packed_seq_params,
|
|
1296
|
+
**(extra_block_kwargs or {}),
|
|
1297
|
+
)
|
|
1298
|
+
eagle_logits_1 = eagle_logits_2x[labels.shape[1] :, :, :]
|
|
1299
|
+
|
|
1300
|
+
loss_1 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_1)
|
|
1301
|
+
# [b, s - 2]
|
|
1302
|
+
loss_1 = loss_1[:, 1:]
|
|
1303
|
+
loss[:, 2:] += self.eagle_loss_decay_factor**2 * loss_1
|
|
1304
|
+
|
|
1305
|
+
if self.eagle_report_acc and not self.training:
|
|
1306
|
+
acc = []
|
|
1307
|
+
with torch.no_grad():
|
|
1308
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
1309
|
+
eagle_logits_1[1:-1, :, :]
|
|
1310
|
+
)
|
|
1311
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
1312
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1313
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
1314
|
+
top1_p = torch.eq(labels[:, 2:], eagle_top1).sum() / eagle_top1.numel()
|
|
1315
|
+
acc.append(top1_p)
|
|
1316
|
+
|
|
1317
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
1318
|
+
print(
|
|
1319
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 2nd Top-1: {acc}",
|
|
1320
|
+
flush=True,
|
|
1321
|
+
)
|
|
1322
|
+
|
|
1323
|
+
# Third EAGLE loss
|
|
1324
|
+
eagle_inputs_2 = self._get_eagle_module_inputs(
|
|
1325
|
+
input_ids=input_ids,
|
|
1326
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1327
|
+
attention_mask=attention_mask,
|
|
1328
|
+
position_ids=position_ids,
|
|
1329
|
+
features=eagle_hidden_states_2x_pre_norm,
|
|
1330
|
+
)
|
|
1331
|
+
|
|
1332
|
+
_, eagle_logits_3x, eagle_hidden_states_3x_pre_norm = self._eagle_forward(
|
|
1333
|
+
eagle_inputs_2,
|
|
1334
|
+
output_weight,
|
|
1335
|
+
inference_params=inference_params,
|
|
1336
|
+
packed_seq_params=packed_seq_params,
|
|
1337
|
+
**(extra_block_kwargs or {}),
|
|
1338
|
+
)
|
|
1339
|
+
|
|
1340
|
+
eagle_logits_2 = eagle_logits_3x[-labels.shape[1] :, :, :]
|
|
1341
|
+
|
|
1342
|
+
loss_2 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_2)
|
|
1343
|
+
# [b, s - 3]
|
|
1344
|
+
loss_2 = loss_2[:, 2:]
|
|
1345
|
+
loss[:, 3:] += self.eagle_loss_decay_factor**3 * loss_2
|
|
1346
|
+
|
|
1347
|
+
if self.eagle_report_acc and not self.training:
|
|
1348
|
+
acc = []
|
|
1349
|
+
with torch.no_grad():
|
|
1350
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
1351
|
+
eagle_logits_2[2:-1, :, :]
|
|
1352
|
+
)
|
|
1353
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
1354
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1355
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
1356
|
+
top1_p = torch.eq(labels[:, 3:], eagle_top1).sum() / eagle_top1.numel()
|
|
1357
|
+
acc.append(top1_p)
|
|
1358
|
+
|
|
1359
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
1360
|
+
print(
|
|
1361
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 3rd Top-1: {acc}",
|
|
1362
|
+
flush=True,
|
|
1363
|
+
)
|
|
1364
|
+
|
|
1365
|
+
# Forth EAGLE loss
|
|
1366
|
+
eagle_inputs_3 = self._get_eagle_module_inputs(
|
|
1367
|
+
input_ids=input_ids,
|
|
1368
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1369
|
+
attention_mask=attention_mask,
|
|
1370
|
+
position_ids=position_ids,
|
|
1371
|
+
features=eagle_hidden_states_3x_pre_norm,
|
|
1372
|
+
)
|
|
1373
|
+
|
|
1374
|
+
_, eagle_logits_4x, eagle_hidden_states_4x_pre_norm = self._eagle_forward(
|
|
1375
|
+
eagle_inputs_3,
|
|
1376
|
+
output_weight,
|
|
1377
|
+
inference_params=inference_params,
|
|
1378
|
+
packed_seq_params=packed_seq_params,
|
|
1379
|
+
**(extra_block_kwargs or {}),
|
|
1380
|
+
)
|
|
1381
|
+
|
|
1382
|
+
eagle_logits_3 = eagle_logits_4x[-labels.shape[1] :, :, :]
|
|
1383
|
+
|
|
1384
|
+
loss_3 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_3)
|
|
1385
|
+
# [b, s - 4]
|
|
1386
|
+
loss_3 = loss_3[:, 3:]
|
|
1387
|
+
loss[:, 4:] += self.eagle_loss_decay_factor**4 * loss_3
|
|
1388
|
+
|
|
1389
|
+
if self.eagle_report_acc and not self.training:
|
|
1390
|
+
acc = []
|
|
1391
|
+
with torch.no_grad():
|
|
1392
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
1393
|
+
eagle_logits_3[3:-1, :, :]
|
|
1394
|
+
)
|
|
1395
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
1396
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1397
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
1398
|
+
top1_p = torch.eq(labels[:, 4:], eagle_top1).sum() / eagle_top1.numel()
|
|
1399
|
+
acc.append(top1_p)
|
|
1400
|
+
|
|
1401
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
1402
|
+
print(
|
|
1403
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 4th Top-1: {acc}",
|
|
1404
|
+
flush=True,
|
|
1405
|
+
)
|
|
1406
|
+
|
|
1407
|
+
return loss
|
|
1408
|
+
|
|
1409
|
+
def tree_decode(self, input_ids: torch.Tensor, tree: Tree):
|
|
1410
|
+
"""Tree-based decoding for EAGLE model using a mask-based approach.
|
|
1411
|
+
|
|
1412
|
+
This function implements a tree-based decoding strategy where each path of the tree
|
|
1413
|
+
represents potential token sequences. The function uses attention masks to control
|
|
1414
|
+
token dependencies and generate multiple candidate sequences in parallel.
|
|
1415
|
+
|
|
1416
|
+
Args:
|
|
1417
|
+
input_ids (torch.Tensor): Input token IDs of shape [batch_size, seq_len]
|
|
1418
|
+
treepaths (list[list[int]]): List of treepaths to decode
|
|
1419
|
+
|
|
1420
|
+
Returns:
|
|
1421
|
+
tuple: (base_token, base_draft_node, draft_tokens)
|
|
1422
|
+
- base_token: The next token predicted by the base model
|
|
1423
|
+
- base_draft_node: A TreeNode containing the base token prediction with a
|
|
1424
|
+
hierarchical structure of child nodes, where each child node
|
|
1425
|
+
represents a draft token generated by EAGLE
|
|
1426
|
+
- draft_tokens: all the draft tokens generated by EAGLE
|
|
1427
|
+
"""
|
|
1428
|
+
# Initial setup and base model forward pass
|
|
1429
|
+
padded_input_ids, seq_len = right_padding(input_ids)
|
|
1430
|
+
attention_mask, position_ids = get_default_attention_mask_and_position_ids(padded_input_ids)
|
|
1431
|
+
|
|
1432
|
+
# Get base model hidden states
|
|
1433
|
+
hidden_states, _ = self._base_model_forward(
|
|
1434
|
+
padded_input_ids,
|
|
1435
|
+
position_ids,
|
|
1436
|
+
attention_mask,
|
|
1437
|
+
)
|
|
1438
|
+
|
|
1439
|
+
if not self.post_process:
|
|
1440
|
+
return hidden_states
|
|
1441
|
+
|
|
1442
|
+
# Generate base token prediction
|
|
1443
|
+
output_weight = (
|
|
1444
|
+
self.shared_embedding_or_output_weight()
|
|
1445
|
+
if self.share_embeddings_and_output_weights
|
|
1446
|
+
else None
|
|
1447
|
+
)
|
|
1448
|
+
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
|
1449
|
+
logits_sbh = logits_sbh[:seq_len, :, :]
|
|
1450
|
+
|
|
1451
|
+
base_token = (
|
|
1452
|
+
gather_from_tensor_model_parallel_region(logits_sbh)[-1:, :, :]
|
|
1453
|
+
.argmax(dim=-1)
|
|
1454
|
+
.transpose(0, 1)
|
|
1455
|
+
)
|
|
1456
|
+
|
|
1457
|
+
# Early return if no steps needed
|
|
1458
|
+
if not tree.root.children:
|
|
1459
|
+
self._aux_hidden_states.clear()
|
|
1460
|
+
return base_token, None, None
|
|
1461
|
+
|
|
1462
|
+
# Prepare for tree decoding
|
|
1463
|
+
eagle_ids = torch.cat((input_ids[:, 1:], base_token), dim=-1)
|
|
1464
|
+
# EAGLE-3
|
|
1465
|
+
# Only the first iteration input_hidden_states are from aux_hidden_state layers
|
|
1466
|
+
hidden_states = self._get_eagle_input_hidden_states(hidden_states)
|
|
1467
|
+
|
|
1468
|
+
if self.config.sequence_parallel:
|
|
1469
|
+
hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
1470
|
+
hidden_states = hidden_states[:seq_len, :, :]
|
|
1471
|
+
|
|
1472
|
+
# relative id from [seq_len-1, seq_len] contains draft token position
|
|
1473
|
+
# [seq_len, seq_len + num_child_level_1] contains the number of children for level 1 and so on
|
|
1474
|
+
relative_ids = torch.tensor(
|
|
1475
|
+
[seq_len - 1, *list(tree.num_children.values())],
|
|
1476
|
+
device=input_ids.device,
|
|
1477
|
+
).cumsum(dim=0)
|
|
1478
|
+
|
|
1479
|
+
draft_position_ids = torch.arange(relative_ids[-1], device=input_ids.device)
|
|
1480
|
+
cur_pos = seq_len - 1
|
|
1481
|
+
for idx in range(len(relative_ids) - 1):
|
|
1482
|
+
draft_position_ids[relative_ids[idx] : relative_ids[idx + 1]] = cur_pos
|
|
1483
|
+
cur_pos += 1
|
|
1484
|
+
|
|
1485
|
+
draft_attention_mask = torch.full(
|
|
1486
|
+
(1, 1, relative_ids[-1], relative_ids[-1]), True, device=input_ids.device
|
|
1487
|
+
).triu_(1)
|
|
1488
|
+
draft_attention_mask[:, :, :, seq_len:] = True
|
|
1489
|
+
draft_attention_mask[:, :, seq_len - 1 :, seq_len - 1 :] = tree.attention_mask
|
|
1490
|
+
|
|
1491
|
+
draft_rotary_pos_emb = self.eagle_module.rotary_pos_emb(seq_len + tree.max_depth)
|
|
1492
|
+
draft_rotary_pos_emb = torch.cat(
|
|
1493
|
+
[draft_rotary_pos_emb[index : index + 1] for index in draft_position_ids], dim=0
|
|
1494
|
+
)
|
|
1495
|
+
|
|
1496
|
+
base_draft_node = TreeNode(base_token)
|
|
1497
|
+
queue = deque([(base_draft_node, tree.root)])
|
|
1498
|
+
draft_tokens = []
|
|
1499
|
+
# Tree decoding loop
|
|
1500
|
+
for step in range(tree.max_depth):
|
|
1501
|
+
# Prepare inputs for EAGLE forward pass
|
|
1502
|
+
padded_eagle_ids, seq_len, padded_hidden_states = right_padding(
|
|
1503
|
+
eagle_ids, hidden_states
|
|
1504
|
+
)
|
|
1505
|
+
|
|
1506
|
+
if self.config.sequence_parallel:
|
|
1507
|
+
padded_hidden_states = scatter_to_sequence_parallel_region(padded_hidden_states)
|
|
1508
|
+
|
|
1509
|
+
eagle_attention_mask, eagle_position_ids = get_default_attention_mask_and_position_ids(
|
|
1510
|
+
padded_eagle_ids
|
|
1511
|
+
)
|
|
1512
|
+
length = eagle_ids.shape[-1]
|
|
1513
|
+
eagle_attention_mask[:, :, :length, :length] = draft_attention_mask[
|
|
1514
|
+
:, :, :length, :length
|
|
1515
|
+
]
|
|
1516
|
+
eagle_attention_mask[:, :, length:, length:] = True
|
|
1517
|
+
eagle_position_ids[:length] = draft_position_ids[:length]
|
|
1518
|
+
padded_rotary_pos_emb = self.eagle_module.rotary_pos_emb(padded_eagle_ids.shape[-1])
|
|
1519
|
+
padded_rotary_pos_emb[:length] = draft_rotary_pos_emb[:length]
|
|
1520
|
+
|
|
1521
|
+
eagle_inputs = {
|
|
1522
|
+
"input_ids": padded_eagle_ids,
|
|
1523
|
+
"embedding": self.embedding(
|
|
1524
|
+
input_ids=padded_eagle_ids,
|
|
1525
|
+
position_ids=eagle_position_ids,
|
|
1526
|
+
),
|
|
1527
|
+
"hidden_states": padded_hidden_states,
|
|
1528
|
+
"attention_mask": eagle_attention_mask,
|
|
1529
|
+
"rotary_pos_emb": padded_rotary_pos_emb,
|
|
1530
|
+
}
|
|
1531
|
+
|
|
1532
|
+
# Forward pass through EAGLE
|
|
1533
|
+
_, eagle_logits, eagle_next_hidden_states_input = self._eagle_forward(
|
|
1534
|
+
eagle_inputs,
|
|
1535
|
+
output_weight,
|
|
1536
|
+
)
|
|
1537
|
+
# Process EAGLE outputs
|
|
1538
|
+
eagle_logits = eagle_logits[:seq_len, :, :]
|
|
1539
|
+
if self.config.sequence_parallel:
|
|
1540
|
+
eagle_next_hidden_states_input = gather_from_sequence_parallel_region(
|
|
1541
|
+
eagle_next_hidden_states_input
|
|
1542
|
+
)
|
|
1543
|
+
eagle_next_hidden_states_input = eagle_next_hidden_states_input[:seq_len, :, :]
|
|
1544
|
+
# Generate and store top-k tokens for each tree node
|
|
1545
|
+
for rel_idx in range(relative_ids[step], relative_ids[step + 1]):
|
|
1546
|
+
draft_node, tree_node = queue.popleft()
|
|
1547
|
+
n_topk = max(tree_node.children.keys()) + 1 if tree_node.children else 0
|
|
1548
|
+
# Get top-k tokens for current position
|
|
1549
|
+
new_ids = (
|
|
1550
|
+
gather_from_tensor_model_parallel_region(eagle_logits)[
|
|
1551
|
+
rel_idx : rel_idx + 1, :, :
|
|
1552
|
+
]
|
|
1553
|
+
.topk(n_topk, dim=-1)[1]
|
|
1554
|
+
.squeeze(0)
|
|
1555
|
+
)
|
|
1556
|
+
|
|
1557
|
+
for child_idx, child_node in tree_node.children.items():
|
|
1558
|
+
eagle_ids = torch.cat(
|
|
1559
|
+
(eagle_ids, new_ids[:, child_idx : child_idx + 1]), dim=-1
|
|
1560
|
+
)
|
|
1561
|
+
# value of the node is token id
|
|
1562
|
+
new_draft_node = TreeNode(new_ids[:, child_idx])
|
|
1563
|
+
draft_tokens.append(new_ids[:, child_idx])
|
|
1564
|
+
draft_node.children[child_idx] = new_draft_node
|
|
1565
|
+
queue.append((new_draft_node, child_node))
|
|
1566
|
+
|
|
1567
|
+
# Update hidden states for each branch
|
|
1568
|
+
hidden_states = torch.cat(
|
|
1569
|
+
(
|
|
1570
|
+
hidden_states,
|
|
1571
|
+
eagle_next_hidden_states_input[rel_idx : rel_idx + 1].repeat(
|
|
1572
|
+
len(tree_node.children), 1, 1
|
|
1573
|
+
),
|
|
1574
|
+
),
|
|
1575
|
+
dim=0,
|
|
1576
|
+
)
|
|
1577
|
+
draft_tokens = torch.cat(draft_tokens, dim=-1)
|
|
1578
|
+
return base_token, base_draft_node, draft_tokens
|
|
1579
|
+
|
|
1580
|
+
def pseudo_speculative_generate(
|
|
1581
|
+
self,
|
|
1582
|
+
input_ids: torch.Tensor,
|
|
1583
|
+
steps: int = 1,
|
|
1584
|
+
):
|
|
1585
|
+
"""Pseudo generate of the EAGLE GPTModel.
|
|
1586
|
+
|
|
1587
|
+
Returns:
|
|
1588
|
+
base_token (torch.Tensor): token from base model
|
|
1589
|
+
draft_tokens (torch.Tensor): draft tokens from eagle module
|
|
1590
|
+
"""
|
|
1591
|
+
padded_input_ids, seq_len = right_padding(input_ids)
|
|
1592
|
+
|
|
1593
|
+
attention_mask, position_ids = get_default_attention_mask_and_position_ids(padded_input_ids)
|
|
1594
|
+
|
|
1595
|
+
hidden_states, _ = self._base_model_forward(
|
|
1596
|
+
padded_input_ids,
|
|
1597
|
+
position_ids,
|
|
1598
|
+
attention_mask,
|
|
1599
|
+
)
|
|
1600
|
+
|
|
1601
|
+
if not self.post_process:
|
|
1602
|
+
return hidden_states
|
|
1603
|
+
|
|
1604
|
+
output_weight = None
|
|
1605
|
+
if self.share_embeddings_and_output_weights:
|
|
1606
|
+
output_weight = self.shared_embedding_or_output_weight()
|
|
1607
|
+
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
|
1608
|
+
|
|
1609
|
+
# Remove the padding
|
|
1610
|
+
logits_sbh = logits_sbh[:seq_len, :, :]
|
|
1611
|
+
|
|
1612
|
+
base_token = (
|
|
1613
|
+
gather_from_tensor_model_parallel_region(logits_sbh)[-1:, :, :]
|
|
1614
|
+
.argmax(dim=-1)
|
|
1615
|
+
.transpose(0, 1)
|
|
1616
|
+
)
|
|
1617
|
+
|
|
1618
|
+
# Early return
|
|
1619
|
+
if steps < 1:
|
|
1620
|
+
self._aux_hidden_states.clear()
|
|
1621
|
+
return base_token, None
|
|
1622
|
+
|
|
1623
|
+
eagle_ids = torch.cat((input_ids[:, 1:], base_token), dim=-1)
|
|
1624
|
+
|
|
1625
|
+
# EAGLE-3
|
|
1626
|
+
# Only the first iteration input_hidden_states are from aux_hidden_state layers
|
|
1627
|
+
hidden_states = self._get_eagle_input_hidden_states(hidden_states, apply_fc=True)
|
|
1628
|
+
# Remove the padding
|
|
1629
|
+
if self.config.sequence_parallel:
|
|
1630
|
+
hidden_states = gather_from_sequence_parallel_region(hidden_states)
|
|
1631
|
+
hidden_states = hidden_states[:seq_len, :, :]
|
|
1632
|
+
|
|
1633
|
+
draft_tokens = []
|
|
1634
|
+
for _ in range(steps):
|
|
1635
|
+
if self.eagle_config.parallel_draft_step > 1:
|
|
1636
|
+
for i in range(self.eagle_config.parallel_draft_step - 1):
|
|
1637
|
+
eagle_ids = torch.cat(
|
|
1638
|
+
(eagle_ids, getattr(self, f"mask_token_{i}").view((1, 1))), dim=-1
|
|
1639
|
+
)
|
|
1640
|
+
hidden_states = torch.cat((hidden_states, hidden_states[-1:]), dim=0)
|
|
1641
|
+
padded_eagle_ids, seq_len, padded_hidden_states = right_padding(
|
|
1642
|
+
eagle_ids, hidden_states
|
|
1643
|
+
)
|
|
1644
|
+
if self.config.sequence_parallel:
|
|
1645
|
+
padded_hidden_states = scatter_to_sequence_parallel_region(padded_hidden_states)
|
|
1646
|
+
eagle_attention_mask, eagle_position_ids = get_default_attention_mask_and_position_ids(
|
|
1647
|
+
padded_eagle_ids
|
|
1648
|
+
)
|
|
1649
|
+
|
|
1650
|
+
eagle_inputs = {}
|
|
1651
|
+
eagle_inputs["input_ids"] = padded_eagle_ids
|
|
1652
|
+
eagle_inputs["embedding"] = self.embedding(
|
|
1653
|
+
input_ids=padded_eagle_ids,
|
|
1654
|
+
position_ids=eagle_position_ids,
|
|
1655
|
+
)
|
|
1656
|
+
eagle_inputs["hidden_states"] = padded_hidden_states
|
|
1657
|
+
eagle_inputs["attention_mask"] = eagle_attention_mask
|
|
1658
|
+
|
|
1659
|
+
# [TODO] (chenhany): let the module compute itself
|
|
1660
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1661
|
+
|
|
1662
|
+
_, eagle_logits, eagle_next_hidden_states_input = self._eagle_forward(
|
|
1663
|
+
eagle_inputs,
|
|
1664
|
+
output_weight,
|
|
1665
|
+
)
|
|
1666
|
+
|
|
1667
|
+
eagle_logits = eagle_logits[:seq_len, :, :]
|
|
1668
|
+
if self.config.sequence_parallel:
|
|
1669
|
+
eagle_next_hidden_states_input = gather_from_sequence_parallel_region(
|
|
1670
|
+
eagle_next_hidden_states_input
|
|
1671
|
+
)
|
|
1672
|
+
eagle_next_hidden_states_input = eagle_next_hidden_states_input[:seq_len, :, :]
|
|
1673
|
+
|
|
1674
|
+
if self.eagle_config.parallel_draft_step > 1:
|
|
1675
|
+
draft_token = (
|
|
1676
|
+
gather_from_tensor_model_parallel_region(eagle_logits)[
|
|
1677
|
+
-self.eagle_config.parallel_draft_step :, :, :
|
|
1678
|
+
]
|
|
1679
|
+
.argmax(dim=-1)
|
|
1680
|
+
.transpose(0, 1)
|
|
1681
|
+
)
|
|
1682
|
+
else:
|
|
1683
|
+
draft_token = (
|
|
1684
|
+
gather_from_tensor_model_parallel_region(eagle_logits)[-1:, :, :]
|
|
1685
|
+
.argmax(dim=-1)
|
|
1686
|
+
.transpose(0, 1)
|
|
1687
|
+
)
|
|
1688
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1689
|
+
draft_token += self.eagle_module.d2t[draft_token]
|
|
1690
|
+
|
|
1691
|
+
if self.eagle_config.parallel_draft_step > 1:
|
|
1692
|
+
return base_token, draft_token
|
|
1693
|
+
|
|
1694
|
+
draft_tokens.append(draft_token)
|
|
1695
|
+
|
|
1696
|
+
eagle_ids = torch.cat((eagle_ids, draft_token), dim=-1)
|
|
1697
|
+
hidden_states = torch.cat(
|
|
1698
|
+
(hidden_states, eagle_next_hidden_states_input[-1:, :, :]), dim=0
|
|
1699
|
+
)
|
|
1700
|
+
|
|
1701
|
+
draft_tokens = torch.cat(draft_tokens, dim=-1)
|
|
1702
|
+
|
|
1703
|
+
return base_token, draft_tokens
|
|
1704
|
+
|
|
1705
|
+
|
|
1706
|
+
@OfflineEagleDMRegistry.register({GPTModel: "megatron.core.models.gpt.GPTModel"})
|
|
1707
|
+
class _DetachedEagleGPTModel(_DynamicEagleGPTModel):
|
|
1708
|
+
"""A wrapper for detached Eagle module."""
|
|
1709
|
+
|
|
1710
|
+
def modify(
|
|
1711
|
+
self,
|
|
1712
|
+
eagle_offline,
|
|
1713
|
+
eagle_hidden_state_distillation,
|
|
1714
|
+
eagle_self_logit_distillation,
|
|
1715
|
+
eagle_freeze_base_model,
|
|
1716
|
+
eagle_report_acc,
|
|
1717
|
+
eagle_reuse_base_decoder,
|
|
1718
|
+
eagle_loss_decay_factor,
|
|
1719
|
+
eagle_architecture_config,
|
|
1720
|
+
):
|
|
1721
|
+
super(_DynamicEagleGPTModel, self).modify(
|
|
1722
|
+
eagle_offline=eagle_offline,
|
|
1723
|
+
eagle_hidden_state_distillation=eagle_hidden_state_distillation,
|
|
1724
|
+
eagle_self_logit_distillation=eagle_self_logit_distillation,
|
|
1725
|
+
eagle_freeze_base_model=eagle_freeze_base_model,
|
|
1726
|
+
eagle_report_acc=eagle_report_acc,
|
|
1727
|
+
eagle_reuse_base_decoder=eagle_reuse_base_decoder,
|
|
1728
|
+
eagle_loss_decay_factor=eagle_loss_decay_factor,
|
|
1729
|
+
eagle_architecture_config=eagle_architecture_config,
|
|
1730
|
+
)
|
|
1731
|
+
|
|
1732
|
+
# Freeze all parameters
|
|
1733
|
+
if self.eagle_freeze_base_model:
|
|
1734
|
+
for name, param in self.named_parameters():
|
|
1735
|
+
param.requires_grad = False
|
|
1736
|
+
|
|
1737
|
+
self.eagle_config = dict_to_config(
|
|
1738
|
+
eagle_architecture_config,
|
|
1739
|
+
self.config.use_cpu_initialization,
|
|
1740
|
+
self.config.fp16,
|
|
1741
|
+
self.config.bf16,
|
|
1742
|
+
)
|
|
1743
|
+
|
|
1744
|
+
assert not eagle_reuse_base_decoder, (
|
|
1745
|
+
"_DetachedEagleGPTModel does not have a base model so eagle_reuse_base_decoder must be False!"
|
|
1746
|
+
)
|
|
1747
|
+
|
|
1748
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1749
|
+
assert eagle_self_logit_distillation, (
|
|
1750
|
+
"Only logit distillation is supported when draft_vocab_size != vocab_size!"
|
|
1751
|
+
)
|
|
1752
|
+
|
|
1753
|
+
# Use default aux_hidden_state layers if use_aux_hidden_state is True
|
|
1754
|
+
# but no layer id is given
|
|
1755
|
+
# layer ids are not used in detached eagle, but we need to set this to have correct fc_input_size_multiplier
|
|
1756
|
+
if (
|
|
1757
|
+
self.eagle_config.use_aux_hidden_state
|
|
1758
|
+
and len(self.eagle_config.eagle_aux_hidden_state_layer_ids) == 0
|
|
1759
|
+
):
|
|
1760
|
+
self._set_default_aux_hidden_state_layers()
|
|
1761
|
+
|
|
1762
|
+
# Only the last PP stage has the additional projection and decoder layer.
|
|
1763
|
+
# This is to simplify the export.
|
|
1764
|
+
if self.post_process:
|
|
1765
|
+
rotary_pos_emb = RotaryEmbedding(
|
|
1766
|
+
kv_channels=self.eagle_config.kv_channels,
|
|
1767
|
+
rotary_percent=self.eagle_config.rotary_percent,
|
|
1768
|
+
rotary_interleaved=False,
|
|
1769
|
+
seq_len_interpolation_factor=None,
|
|
1770
|
+
rotary_base=self.eagle_config.rotary_base,
|
|
1771
|
+
rope_scaling=self.eagle_config.rope_scaling,
|
|
1772
|
+
rope_scaling_factor=self.eagle_config.rope_scaling_factor,
|
|
1773
|
+
use_cpu_initialization=self.eagle_config.use_cpu_initialization,
|
|
1774
|
+
)
|
|
1775
|
+
|
|
1776
|
+
self.eagle_module = EagleModule(
|
|
1777
|
+
self.eagle_config,
|
|
1778
|
+
rotary_pos_emb,
|
|
1779
|
+
bias=False,
|
|
1780
|
+
)
|
|
1781
|
+
|
|
1782
|
+
# Eagle loss functions
|
|
1783
|
+
self.kld = logits_kld_loss
|
|
1784
|
+
|
|
1785
|
+
def _get_eagle_input_hidden_states(self, hidden_states: torch.Tensor, apply_fc: bool = True):
|
|
1786
|
+
if apply_fc:
|
|
1787
|
+
# [s / TP, b, 3h] -> [s / TP, b, h]
|
|
1788
|
+
return self.eagle_module.fc(hidden_states)[0]
|
|
1789
|
+
else:
|
|
1790
|
+
return hidden_states
|
|
1791
|
+
|
|
1792
|
+
def _get_detached_eagle_module_inputs(
|
|
1793
|
+
self,
|
|
1794
|
+
input_ids: torch.Tensor,
|
|
1795
|
+
hidden_states: torch.Tensor,
|
|
1796
|
+
attention_mask: torch.Tensor,
|
|
1797
|
+
position_ids: torch.Tensor,
|
|
1798
|
+
features: torch.Tensor | None = None,
|
|
1799
|
+
):
|
|
1800
|
+
"""Getting EAGLE module inputs."""
|
|
1801
|
+
b = hidden_states.shape[1]
|
|
1802
|
+
h = hidden_states.shape[2]
|
|
1803
|
+
|
|
1804
|
+
# [b, 1]
|
|
1805
|
+
id_padding = torch.zeros((b, 1), dtype=input_ids.dtype, device=input_ids.device)
|
|
1806
|
+
padded_input_ids = torch.cat((input_ids[:, 1:], id_padding), dim=-1)
|
|
1807
|
+
|
|
1808
|
+
rotary_pos_emb = self.eagle_module.rotary_pos_emb(padded_input_ids.shape[-1])
|
|
1809
|
+
|
|
1810
|
+
attn_mask = attention_mask.clone().detach()
|
|
1811
|
+
attn_mask[:, :, :-1, :-1] = attention_mask[:, :, 1:, 1:]
|
|
1812
|
+
attn_mask[:, :, -1, :] = True
|
|
1813
|
+
attn_mask[:, :, :, -1] = True
|
|
1814
|
+
|
|
1815
|
+
eagle_inputs = {}
|
|
1816
|
+
|
|
1817
|
+
assert self.eagle_config.parallel_draft_step == 1, (
|
|
1818
|
+
"Detached Eagle module does not support parallel draft yet!"
|
|
1819
|
+
)
|
|
1820
|
+
if features is None:
|
|
1821
|
+
eagle_inputs["input_ids"] = padded_input_ids
|
|
1822
|
+
eagle_inputs["hidden_states"] = hidden_states
|
|
1823
|
+
eagle_inputs["attention_mask"] = attn_mask
|
|
1824
|
+
eagle_inputs["position_ids"] = position_ids
|
|
1825
|
+
eagle_inputs["rotary_pos_emb"] = rotary_pos_emb
|
|
1826
|
+
elif features.shape[0] == hidden_states.shape[0]:
|
|
1827
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
1828
|
+
(padded_input_ids, padded_input_ids),
|
|
1829
|
+
dim=-1,
|
|
1830
|
+
)
|
|
1831
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
1832
|
+
(
|
|
1833
|
+
hidden_states,
|
|
1834
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
1835
|
+
features[:-1, :, :],
|
|
1836
|
+
),
|
|
1837
|
+
dim=0,
|
|
1838
|
+
)
|
|
1839
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 2)
|
|
1840
|
+
eagle_inputs["position_ids"] = torch.cat((position_ids, position_ids), dim=-1)
|
|
1841
|
+
|
|
1842
|
+
if rotary_pos_emb is not None:
|
|
1843
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat((rotary_pos_emb, rotary_pos_emb), dim=0)
|
|
1844
|
+
else:
|
|
1845
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
1846
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1847
|
+
elif features.shape[0] == hidden_states.shape[0] * 2:
|
|
1848
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
1849
|
+
(padded_input_ids, padded_input_ids, padded_input_ids),
|
|
1850
|
+
dim=-1,
|
|
1851
|
+
)
|
|
1852
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
1853
|
+
(
|
|
1854
|
+
hidden_states,
|
|
1855
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
1856
|
+
features[:-1, :, :],
|
|
1857
|
+
),
|
|
1858
|
+
dim=0,
|
|
1859
|
+
)
|
|
1860
|
+
|
|
1861
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 3)
|
|
1862
|
+
eagle_inputs["position_ids"] = torch.cat(
|
|
1863
|
+
(position_ids, position_ids, position_ids), dim=-1
|
|
1864
|
+
)
|
|
1865
|
+
|
|
1866
|
+
if rotary_pos_emb is not None:
|
|
1867
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
|
1868
|
+
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
|
1869
|
+
dim=0,
|
|
1870
|
+
)
|
|
1871
|
+
else:
|
|
1872
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
1873
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1874
|
+
else:
|
|
1875
|
+
eagle_inputs["input_ids"] = torch.cat(
|
|
1876
|
+
(padded_input_ids, padded_input_ids, padded_input_ids, padded_input_ids),
|
|
1877
|
+
dim=-1,
|
|
1878
|
+
)
|
|
1879
|
+
eagle_inputs["hidden_states"] = torch.cat(
|
|
1880
|
+
(
|
|
1881
|
+
hidden_states,
|
|
1882
|
+
torch.zeros((1, b, h), dtype=hidden_states.dtype, device=hidden_states.device),
|
|
1883
|
+
features[:-1, :, :],
|
|
1884
|
+
),
|
|
1885
|
+
dim=0,
|
|
1886
|
+
)
|
|
1887
|
+
|
|
1888
|
+
eagle_inputs["attention_mask"] = set_multi_step_attention_mask(attn_mask, 4)
|
|
1889
|
+
eagle_inputs["position_ids"] = torch.cat(
|
|
1890
|
+
(position_ids, position_ids, position_ids, position_ids), dim=-1
|
|
1891
|
+
)
|
|
1892
|
+
|
|
1893
|
+
if rotary_pos_emb is not None:
|
|
1894
|
+
eagle_inputs["rotary_pos_emb"] = torch.cat(
|
|
1895
|
+
(rotary_pos_emb, rotary_pos_emb, rotary_pos_emb, rotary_pos_emb),
|
|
1896
|
+
dim=0,
|
|
1897
|
+
)
|
|
1898
|
+
else:
|
|
1899
|
+
# [TODO] (yeyu): there will be problem here with MLA
|
|
1900
|
+
eagle_inputs["rotary_pos_emb"] = None
|
|
1901
|
+
|
|
1902
|
+
eagle_inputs["embedding"] = self.embedding(
|
|
1903
|
+
input_ids=eagle_inputs["input_ids"],
|
|
1904
|
+
position_ids=eagle_inputs["position_ids"],
|
|
1905
|
+
)
|
|
1906
|
+
|
|
1907
|
+
return eagle_inputs
|
|
1908
|
+
|
|
1909
|
+
def forward(
|
|
1910
|
+
self,
|
|
1911
|
+
input_ids: torch.Tensor = None,
|
|
1912
|
+
position_ids: torch.Tensor = None,
|
|
1913
|
+
attention_mask: torch.Tensor = None,
|
|
1914
|
+
decoder_input: torch.Tensor = None,
|
|
1915
|
+
labels: torch.Tensor = None,
|
|
1916
|
+
inference_params: InferenceParams = None,
|
|
1917
|
+
packed_seq_params: PackedSeqParams = None,
|
|
1918
|
+
extra_block_kwargs: dict | None = None,
|
|
1919
|
+
return_eagle_inputs: bool = False, # Not used in Detached Eagle
|
|
1920
|
+
**kwargs,
|
|
1921
|
+
) -> torch.Tensor:
|
|
1922
|
+
assert "aux_hidden_states" in kwargs, (
|
|
1923
|
+
"aux_hidden_states is required as input to _DetachedEagleGPTModel"
|
|
1924
|
+
)
|
|
1925
|
+
assert "hidden_states" in kwargs, (
|
|
1926
|
+
"hidden_states is required as input to _DetachedEagleGPTModel"
|
|
1927
|
+
)
|
|
1928
|
+
aux_hidden_states = kwargs.get("aux_hidden_states")
|
|
1929
|
+
hidden_states = kwargs.get("hidden_states")
|
|
1930
|
+
|
|
1931
|
+
# Note: labels is 1 token shorter than logits in detached mode
|
|
1932
|
+
|
|
1933
|
+
if position_ids is None or attention_mask is None:
|
|
1934
|
+
attention_mask, position_ids = get_default_attention_mask_and_position_ids(input_ids)
|
|
1935
|
+
|
|
1936
|
+
eagle_module_input_hidden_states = self._get_eagle_input_hidden_states(aux_hidden_states)
|
|
1937
|
+
output_weight = None
|
|
1938
|
+
if self.share_embeddings_and_output_weights:
|
|
1939
|
+
output_weight = self.shared_embedding_or_output_weight()
|
|
1940
|
+
logits_sbh, _ = self.output_layer(hidden_states, weight=output_weight)
|
|
1941
|
+
|
|
1942
|
+
eagle_inputs_0 = self._get_detached_eagle_module_inputs(
|
|
1943
|
+
input_ids=input_ids,
|
|
1944
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1945
|
+
attention_mask=attention_mask,
|
|
1946
|
+
position_ids=position_ids,
|
|
1947
|
+
)
|
|
1948
|
+
|
|
1949
|
+
_, eagle_logits_0, eagle_hidden_states_0_pre_norm = self._eagle_forward(
|
|
1950
|
+
eagle_inputs_0,
|
|
1951
|
+
None,
|
|
1952
|
+
inference_params=inference_params,
|
|
1953
|
+
packed_seq_params=packed_seq_params,
|
|
1954
|
+
**(extra_block_kwargs or {}),
|
|
1955
|
+
)
|
|
1956
|
+
|
|
1957
|
+
loss = torch.zeros(input_ids.shape).to(input_ids.device)
|
|
1958
|
+
|
|
1959
|
+
loss_0 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_0)
|
|
1960
|
+
loss[:, 1:] += self.eagle_loss_decay_factor * loss_0
|
|
1961
|
+
|
|
1962
|
+
if self.eagle_report_acc and not self.training:
|
|
1963
|
+
acc = []
|
|
1964
|
+
with torch.no_grad():
|
|
1965
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
1966
|
+
eagle_logits_0[:-2, :, :]
|
|
1967
|
+
)
|
|
1968
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
1969
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
1970
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
1971
|
+
top1_p = torch.eq(labels[:, 1:], eagle_top1).sum() / eagle_top1.numel()
|
|
1972
|
+
acc.append(top1_p)
|
|
1973
|
+
|
|
1974
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
1975
|
+
print(
|
|
1976
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 1st Top-1: {acc}",
|
|
1977
|
+
flush=True,
|
|
1978
|
+
)
|
|
1979
|
+
|
|
1980
|
+
# Second round of EAGLE loss
|
|
1981
|
+
eagle_inputs_1 = self._get_detached_eagle_module_inputs(
|
|
1982
|
+
input_ids=input_ids,
|
|
1983
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
1984
|
+
attention_mask=attention_mask,
|
|
1985
|
+
position_ids=position_ids,
|
|
1986
|
+
features=eagle_hidden_states_0_pre_norm,
|
|
1987
|
+
)
|
|
1988
|
+
|
|
1989
|
+
_, eagle_logits_2x, eagle_hidden_states_2x_pre_norm = self._eagle_forward(
|
|
1990
|
+
eagle_inputs_1,
|
|
1991
|
+
None,
|
|
1992
|
+
inference_params=inference_params,
|
|
1993
|
+
packed_seq_params=packed_seq_params,
|
|
1994
|
+
**(extra_block_kwargs or {}),
|
|
1995
|
+
)
|
|
1996
|
+
eagle_logits_1 = eagle_logits_2x[logits_sbh.shape[0] :, :, :]
|
|
1997
|
+
|
|
1998
|
+
loss_1 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_1)
|
|
1999
|
+
# [b, s - 2]
|
|
2000
|
+
loss_1 = loss_1[:, 1:]
|
|
2001
|
+
loss[:, 2:] += self.eagle_loss_decay_factor**2 * loss_1
|
|
2002
|
+
|
|
2003
|
+
if self.eagle_report_acc and not self.training:
|
|
2004
|
+
acc = []
|
|
2005
|
+
with torch.no_grad():
|
|
2006
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
2007
|
+
eagle_logits_1[1:-2, :, :]
|
|
2008
|
+
)
|
|
2009
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
2010
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
2011
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
2012
|
+
top1_p = torch.eq(labels[:, 2:], eagle_top1).sum() / eagle_top1.numel()
|
|
2013
|
+
acc.append(top1_p)
|
|
2014
|
+
|
|
2015
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
2016
|
+
print(
|
|
2017
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 2nd Top-1: {acc}",
|
|
2018
|
+
flush=True,
|
|
2019
|
+
)
|
|
2020
|
+
|
|
2021
|
+
# Third EAGLE loss
|
|
2022
|
+
eagle_inputs_2 = self._get_detached_eagle_module_inputs(
|
|
2023
|
+
input_ids=input_ids,
|
|
2024
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
2025
|
+
attention_mask=attention_mask,
|
|
2026
|
+
position_ids=position_ids,
|
|
2027
|
+
features=eagle_hidden_states_2x_pre_norm,
|
|
2028
|
+
)
|
|
2029
|
+
|
|
2030
|
+
_, eagle_logits_3x, eagle_hidden_states_3x_pre_norm = self._eagle_forward(
|
|
2031
|
+
eagle_inputs_2,
|
|
2032
|
+
None,
|
|
2033
|
+
inference_params=inference_params,
|
|
2034
|
+
packed_seq_params=packed_seq_params,
|
|
2035
|
+
**(extra_block_kwargs or {}),
|
|
2036
|
+
)
|
|
2037
|
+
|
|
2038
|
+
eagle_logits_2 = eagle_logits_3x[-logits_sbh.shape[0] :, :, :]
|
|
2039
|
+
|
|
2040
|
+
loss_2 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_2)
|
|
2041
|
+
# [b, s - 3]
|
|
2042
|
+
loss_2 = loss_2[:, 2:]
|
|
2043
|
+
loss[:, 3:] += self.eagle_loss_decay_factor**3 * loss_2
|
|
2044
|
+
|
|
2045
|
+
if self.eagle_report_acc and not self.training:
|
|
2046
|
+
acc = []
|
|
2047
|
+
with torch.no_grad():
|
|
2048
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
2049
|
+
eagle_logits_2[2:-2, :, :]
|
|
2050
|
+
)
|
|
2051
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
2052
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
2053
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
2054
|
+
top1_p = torch.eq(labels[:, 3:], eagle_top1).sum() / eagle_top1.numel()
|
|
2055
|
+
acc.append(top1_p)
|
|
2056
|
+
|
|
2057
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
2058
|
+
print(
|
|
2059
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 3rd Top-1: {acc}",
|
|
2060
|
+
flush=True,
|
|
2061
|
+
)
|
|
2062
|
+
|
|
2063
|
+
# Forth EAGLE loss
|
|
2064
|
+
eagle_inputs_3 = self._get_detached_eagle_module_inputs(
|
|
2065
|
+
input_ids=input_ids,
|
|
2066
|
+
hidden_states=eagle_module_input_hidden_states,
|
|
2067
|
+
attention_mask=attention_mask,
|
|
2068
|
+
position_ids=position_ids,
|
|
2069
|
+
features=eagle_hidden_states_3x_pre_norm,
|
|
2070
|
+
)
|
|
2071
|
+
|
|
2072
|
+
_, eagle_logits_4x, eagle_hidden_states_4x_pre_norm = self._eagle_forward(
|
|
2073
|
+
eagle_inputs_3,
|
|
2074
|
+
None,
|
|
2075
|
+
inference_params=inference_params,
|
|
2076
|
+
packed_seq_params=packed_seq_params,
|
|
2077
|
+
**(extra_block_kwargs or {}),
|
|
2078
|
+
)
|
|
2079
|
+
|
|
2080
|
+
eagle_logits_3 = eagle_logits_4x[-logits_sbh.shape[0] :, :, :]
|
|
2081
|
+
|
|
2082
|
+
loss_3 = self._compute_eagle_loss(logits_sbh, labels, eagle_logits_3)
|
|
2083
|
+
# [b, s - 4]
|
|
2084
|
+
loss_3 = loss_3[:, 3:]
|
|
2085
|
+
loss[:, 4:] += self.eagle_loss_decay_factor**4 * loss_3
|
|
2086
|
+
|
|
2087
|
+
if self.eagle_report_acc and not self.training:
|
|
2088
|
+
acc = []
|
|
2089
|
+
with torch.no_grad():
|
|
2090
|
+
gathered_logits = gather_from_tensor_model_parallel_region(
|
|
2091
|
+
eagle_logits_3[3:-2, :, :]
|
|
2092
|
+
)
|
|
2093
|
+
eagle_top1 = gathered_logits.transpose(0, 1).argmax(dim=-1)
|
|
2094
|
+
if self.eagle_config.draft_vocab_size != self.eagle_config.vocab_size:
|
|
2095
|
+
eagle_top1 += self.eagle_module.d2t[eagle_top1]
|
|
2096
|
+
top1_p = torch.eq(labels[:, 4:], eagle_top1).sum() / eagle_top1.numel()
|
|
2097
|
+
acc.append(top1_p)
|
|
2098
|
+
|
|
2099
|
+
if get_tensor_model_parallel_rank() == 0:
|
|
2100
|
+
print(
|
|
2101
|
+
f"{torch.distributed.get_rank():3}/{torch.distributed.get_world_size():3} EAGLE 4th Top-1: {acc}",
|
|
2102
|
+
flush=True,
|
|
2103
|
+
)
|
|
2104
|
+
|
|
2105
|
+
return loss
|
|
2106
|
+
|
|
2107
|
+
|
|
2108
|
+
class MegatronARValidation(AcceptanceRateValidation):
|
|
2109
|
+
"""This is the subclass for megatron model AR validation."""
|
|
2110
|
+
|
|
2111
|
+
def get_ground_truth(self, input_ids, osl):
|
|
2112
|
+
"""This function returns ground truth output tokens from the base model."""
|
|
2113
|
+
input_ids = copy.deepcopy(input_ids)
|
|
2114
|
+
for _ in range(osl):
|
|
2115
|
+
input_id, _ = self.model.pseudo_speculative_generate(input_ids, steps=0)
|
|
2116
|
+
input_ids = torch.cat((input_ids, input_id), dim=-1)
|
|
2117
|
+
if input_id[0, 0] == self.end_token:
|
|
2118
|
+
break
|
|
2119
|
+
return input_ids
|