Instructions to use KexuanShi/Megatron-LM with libraries, inference providers, notebooks, and local apps. Follow these links to get started.
- Libraries
- NeMo
How to use KexuanShi/Megatron-LM with NeMo:
# tag did not correspond to a valid NeMo domain.
- Notebooks
- Google Colab
- Kaggle
| # Copyright (c) 2025, NVIDIA CORPORATION. All rights reserved. | |
| """Convert a GPTModel.""" | |
| import functools | |
| import json | |
| import os | |
| import sys | |
| import warnings | |
| sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), "../../../"))) | |
| import modelopt.torch.speculative as mtsp | |
| import torch | |
| from modelopt.torch.export import import_mcore_gpt_from_hf | |
| from megatron.core import mpu | |
| from megatron.core.enums import ModelType | |
| from megatron.core.parallel_state import destroy_model_parallel | |
| from megatron.post_training.arguments import add_modelopt_args | |
| from megatron.post_training.checkpointing import load_modelopt_checkpoint | |
| from megatron.post_training.model_builder import modelopt_gpt_mamba_builder | |
| from megatron.post_training.utils import ( | |
| modelopt_version_at_least, | |
| report_current_memory_info, | |
| to_empty_if_meta, | |
| ) | |
| from megatron.training import get_args, get_tokenizer | |
| from megatron.training.checkpointing import save_checkpoint | |
| from megatron.training.initialize import initialize_megatron | |
| from megatron.training.utils import print_rank_0, unwrap_model | |
| from model_provider import model_provider | |
| ALGO_TO_CONFIG = { | |
| "eagle1": mtsp.config.EAGLE1_DEFAULT_CFG, | |
| "eagle3": mtsp.config.EAGLE3_DEFAULT_CFG, | |
| "eagle-mtp": mtsp.config.EAGLE_MTP_DEFAULT_CFG, | |
| } | |
| def add_convert_args(parser): | |
| """Add additional arguments for ModelOpt checkpoint convertion.""" | |
| group = parser.add_argument_group(title='ModelOpt MCore checkpoint convertion') | |
| group.add_argument( | |
| "--pretrained-model-path", type=str, default=None, help="HuggingFace pretrained model" | |
| ) | |
| group.add_argument( | |
| "--extra-model-path", type=str, default=None, help="Extra module weights to load" | |
| ) | |
| group.add_argument( | |
| '--algorithm', | |
| type=str, | |
| choices=["medusa", "eagle1", "eagle3", "None"], | |
| default="None", | |
| help='Chosing between different speculative decoding algorithms. Default is None.', | |
| ) | |
| group.add_argument( | |
| "--eagle-config", | |
| type=str, | |
| default=None, | |
| help="EAGLE architecture config. If not given, " | |
| "a default config will be use. If provided, it will overwrite the default config.", | |
| ) | |
| add_modelopt_args(parser) | |
| return parser | |
| def get_model(model_provider_func, model_type=ModelType.encoder_or_decoder, wrap_with_ddp=True): | |
| """Build the model.""" | |
| args = get_args() | |
| args.model_type = model_type | |
| pre_process = mpu.is_pipeline_first_stage() | |
| post_process = mpu.is_pipeline_last_stage() | |
| if args.init_model_with_meta_device: | |
| with torch.device("meta"): | |
| model = model_provider_func(pre_process=pre_process, post_process=post_process) | |
| to_empty_if_meta(model, device="cuda") | |
| else: | |
| model = model_provider_func(pre_process=pre_process, post_process=post_process) | |
| model.model_type = model_type | |
| return [model] | |
| def check_arguments(): | |
| """Checking user arguments.""" | |
| args = get_args() | |
| if args.num_layers_per_virtual_pipeline_stage is not None: | |
| print_rank_0("Interleaved pipeline schedule is not yet supported for text generation.") | |
| exit() | |
| if hasattr(args, 'moe_grouped_gemm') and args.moe_grouped_gemm == True: | |
| print_rank_0("WARNING: Forcing moe_grouped_gemm to False for PTQ and export.") | |
| args.moe_grouped_gemm = False | |
| if __name__ == "__main__": | |
| initialize_megatron( | |
| extra_args_provider=add_convert_args, | |
| args_defaults={ | |
| 'tokenizer_type': 'HuggingFaceTokenizer', | |
| 'no_load_rng': True, | |
| 'no_load_optim': True, | |
| }, | |
| ) | |
| check_arguments() | |
| args = get_args() | |
| # Meta device initialization for ParallelLinear only works if using cpu initialization. | |
| # Meta device initialization is used such that models can be materialized in low-precision | |
| # directly when ModelOpt real quant is used. Otherwise, the model is first initialized | |
| # as BF16 in memory which may result in OOM and defeat the purpose of real quant. | |
| if args.init_model_with_meta_device: | |
| args.use_cpu_initialization = True | |
| else: | |
| warnings.warn( | |
| "--init-model-with-meta-device is not set. If you would like to resume the " | |
| "model in low-bit directly (low-memory initialization and skipping 16-bit), " | |
| "--init-model-with-meta-device must be set.", | |
| UserWarning, | |
| ) | |
| model = get_model( | |
| functools.partial(model_provider, modelopt_gpt_mamba_builder), wrap_with_ddp=False | |
| ) | |
| report_current_memory_info() | |
| unwrapped_model = unwrap_model(model)[0] | |
| if args.pretrained_model_path is not None: | |
| import_dtype = torch.float16 if args.fp16 else torch.bfloat16 | |
| unwrapped_model = unwrap_model(model)[0] | |
| workspace_dir = os.environ.get("MLM_WORK_DIR", "/tmp") | |
| print_rank_0( | |
| "Import model from Hugging Face checkpoint in dtype {}.".format(str(import_dtype)) | |
| ) | |
| import_kwargs = {"dtype": import_dtype} | |
| if modelopt_version_at_least("0.41.0"): | |
| import_kwargs.update({"trust_remote_code": args.trust_remote_code}) | |
| import_mcore_gpt_from_hf( | |
| unwrapped_model, args.pretrained_model_path, workspace_dir, **import_kwargs | |
| ) | |
| elif args.load is not None: | |
| _ = load_modelopt_checkpoint(model) | |
| if args.algorithm in ("eagle1", "eagle3"): | |
| mtsp_config = ALGO_TO_CONFIG[args.algorithm] | |
| if args.eagle_config: | |
| with open(args.eagle_config) as f: | |
| eagle_config = json.load(f) | |
| mtsp_config["config"]["eagle_architecture_config"].update(eagle_config) | |
| if args.export_offline_model: | |
| mtsp_config["config"]["eagle_offline"] = True | |
| unwrapped_model = mtsp.convert(unwrapped_model, mtsp_config) | |
| if args.extra_model_path is not None: | |
| eagle_module = getattr(unwrapped_model, "eagle_module", None) | |
| if eagle_module is not None: | |
| mcore_eagle_state_dict = torch.load(args.extra_model_path) | |
| eagle_module.load_state_dict(mcore_eagle_state_dict, strict=False) | |
| elif args.algorithm == "medusa": | |
| config = {"medusa_num_heads": args.export_num_medusa_heads, "medusa_num_layers": 1} | |
| unwrapped_model = mtsp.convert(unwrapped_model, [("medusa", config)]) | |
| print_rank_0(f"Converted Model:\n {model}") | |
| torch.distributed.barrier() | |
| save_checkpoint(1, model, None, None, 0, release=True) | |
| destroy_model_parallel() | |