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
| #!/usr/bin/env python3 | |
| """ | |
| 示例:手动重现 lm-evaluation-harness 的模型加载流程 | |
| 这个脚本展示了 lm-evaluation-harness 如何从 model_args 中读取配置并构建模型。 | |
| 你可以运行这个脚本来理解整个流程。 | |
| """ | |
| import sys | |
| import os | |
| # 添加 lm-evaluation-harness 到路径 | |
| sys.path.insert(0, os.path.join(os.path.dirname(__file__), '../../lm-evaluation-harness')) | |
| import torch | |
| import transformers | |
| from lm_eval import utils | |
| from lm_eval.api.registry import get_model | |
| def step1_parse_args_string(): | |
| """步骤1: 解析 model_args 字符串""" | |
| print("=" * 80) | |
| print("步骤1: 解析 model_args 字符串") | |
| print("=" * 80) | |
| # 模拟命令行参数: --model_args "pretrained=EleutherAI/gpt-j-6B,dtype=float,revision=main" | |
| model_args_string = "pretrained=EleutherAI/gpt-j-6B,dtype=float,revision=main" | |
| print(f"输入字符串: {model_args_string}") | |
| # 使用 lm-eval 的解析函数 | |
| parsed_args = utils.simple_parse_args_string(model_args_string) | |
| print(f"解析后的字典: {parsed_args}") | |
| print() | |
| return parsed_args | |
| def step2_get_model_class(): | |
| """步骤2: 获取模型类""" | |
| print("=" * 80) | |
| print("步骤2: 获取模型类") | |
| print("=" * 80) | |
| # 模拟命令行参数: --model hf | |
| model_name = "hf" | |
| print(f"模型名称: {model_name}") | |
| # 从注册表获取模型类 | |
| model_class = get_model(model_name) | |
| print(f"获取到的模型类: {model_class}") | |
| print(f"类名: {model_class.__name__}") | |
| print() | |
| return model_class | |
| def step3_load_config(pretrained, revision="main", trust_remote_code=False): | |
| """步骤3: 加载模型配置""" | |
| print("=" * 80) | |
| print("步骤3: 加载模型配置") | |
| print("=" * 80) | |
| print(f"模型路径/名称: {pretrained}") | |
| print(f"Revision: {revision}") | |
| print(f"Trust remote code: {trust_remote_code}") | |
| # 使用 transformers.AutoConfig.from_pretrained 加载配置 | |
| # 这是 lm-eval 在 _get_config() 中做的事情 | |
| config = transformers.AutoConfig.from_pretrained( | |
| pretrained, | |
| revision=revision, | |
| trust_remote_code=trust_remote_code, | |
| ) | |
| print(f"\n配置类型: {type(config)}") | |
| print(f"模型类型: {config.model_type}") | |
| print(f"词汇表大小: {config.vocab_size}") | |
| print(f"隐藏层大小: {getattr(config, 'n_embd', getattr(config, 'hidden_size', 'N/A'))}") | |
| print(f"层数: {getattr(config, 'n_layer', getattr(config, 'num_hidden_layers', 'N/A'))}") | |
| print(f"注意力头数: {getattr(config, 'n_head', getattr(config, 'num_attention_heads', 'N/A'))}") | |
| # 显示配置文件的路径 | |
| if hasattr(config, '_name_or_path'): | |
| print(f"\n配置来源: {config._name_or_path}") | |
| print() | |
| return config | |
| def step4_load_tokenizer(pretrained, revision="main", trust_remote_code=False): | |
| """步骤4: 加载 tokenizer""" | |
| print("=" * 80) | |
| print("步骤4: 加载 Tokenizer") | |
| print("=" * 80) | |
| print(f"模型路径/名称: {pretrained}") | |
| # 使用 transformers.AutoTokenizer.from_pretrained 加载 tokenizer | |
| # 这是 lm-eval 在 _create_tokenizer() 中做的事情 | |
| tokenizer = transformers.AutoTokenizer.from_pretrained( | |
| pretrained, | |
| revision=revision, | |
| trust_remote_code=trust_remote_code, | |
| use_fast=True, | |
| ) | |
| print(f"Tokenizer 类型: {type(tokenizer)}") | |
| print(f"词汇表大小: {tokenizer.vocab_size}") | |
| print(f"特殊 token:") | |
| print(f" - BOS: {tokenizer.bos_token} (ID: {tokenizer.bos_token_id})") | |
| print(f" - EOS: {tokenizer.eos_token} (ID: {tokenizer.eos_token_id})") | |
| print(f" - PAD: {tokenizer.pad_token} (ID: {tokenizer.pad_token_id})") | |
| print() | |
| return tokenizer | |
| def step5_load_model(pretrained, config, dtype="float", revision="main", trust_remote_code=False): | |
| """步骤5: 加载模型""" | |
| print("=" * 80) | |
| print("步骤5: 加载模型") | |
| print("=" * 80) | |
| print(f"模型路径/名称: {pretrained}") | |
| print(f"数据类型: {dtype}") | |
| # 转换 dtype 字符串为 torch.dtype | |
| if dtype == "float": | |
| torch_dtype = torch.float32 | |
| elif dtype == "float16": | |
| torch_dtype = torch.float16 | |
| elif dtype == "bfloat16": | |
| torch_dtype = torch.bfloat16 | |
| else: | |
| torch_dtype = torch.float32 | |
| print(f"Torch dtype: {torch_dtype}") | |
| # 根据配置确定模型类 | |
| # 这是 lm-eval 在 _get_backend() 和 _create_model() 中做的事情 | |
| model_type = config.model_type | |
| # 选择对应的模型类 | |
| if model_type in ["gpt2", "gptj", "gpt_neox", "llama", "mistral", "mixtral"]: | |
| model_class = transformers.AutoModelForCausalLM | |
| print(f"使用模型类: AutoModelForCausalLM (因果语言模型)") | |
| elif model_type in ["t5", "bart"]: | |
| model_class = transformers.AutoModelForSeq2SeqLM | |
| print(f"使用模型类: AutoModelForSeq2SeqLM (序列到序列模型)") | |
| else: | |
| model_class = transformers.AutoModelForCausalLM | |
| print(f"使用默认模型类: AutoModelForCausalLM") | |
| print(f"\n开始加载模型(这可能需要一些时间)...") | |
| # 使用 from_pretrained 加载模型 | |
| # 这是 lm-eval 在 _create_model() 中做的事情 | |
| try: | |
| model = model_class.from_pretrained( | |
| pretrained, | |
| revision=revision, | |
| torch_dtype=torch_dtype, | |
| trust_remote_code=trust_remote_code, | |
| device_map="auto", # 自动分配设备 | |
| ) | |
| print(f"模型类型: {type(model)}") | |
| print(f"模型参数数量: {sum(p.numel() for p in model.parameters()):,}") | |
| print(f"可训练参数数量: {sum(p.numel() for p in model.parameters() if p.requires_grad):,}") | |
| # 显示模型设备 | |
| if hasattr(model, 'device'): | |
| print(f"模型设备: {model.device}") | |
| elif hasattr(model, 'hf_device_map'): | |
| print(f"模型设备映射: {model.hf_device_map}") | |
| except Exception as e: | |
| print(f"加载模型时出错: {e}") | |
| print("注意: 这可能是由于内存不足或模型文件不存在") | |
| model = None | |
| print() | |
| return model | |
| def step6_create_hflm_instance(): | |
| """步骤6: 使用 lm-eval 创建完整的 HFLM 实例""" | |
| print("=" * 80) | |
| print("步骤6: 使用 lm-eval 创建完整的 HFLM 实例") | |
| print("=" * 80) | |
| # 模拟完整的命令行参数 | |
| model_name = "hf" | |
| model_args_string = "pretrained=EleutherAI/gpt-j-6B,dtype=float" | |
| print(f"模型名称: {model_name}") | |
| print(f"模型参数: {model_args_string}") | |
| # 获取模型类 | |
| model_class = get_model(model_name) | |
| # 使用 create_from_arg_string 创建实例(这是 lm-eval 实际使用的方法) | |
| print("\n使用 lm-eval 的 create_from_arg_string 创建模型实例...") | |
| try: | |
| # 注意: 实际创建模型需要时间和资源 | |
| # 这里只是展示流程,不实际加载大模型 | |
| print("(跳过实际模型加载,因为这需要大量内存和时间)") | |
| print("实际代码:") | |
| print(f" lm = {model_class.__name__}.create_from_arg_string(") | |
| print(f" '{model_args_string}',") | |
| print(f" {{'batch_size': 8, 'device': 'cuda'}}") | |
| print(f" )") | |
| except Exception as e: | |
| print(f"创建实例时出错: {e}") | |
| print() | |
| def main(): | |
| """主函数:演示完整的模型加载流程""" | |
| print("\n" + "=" * 80) | |
| print("lm-evaluation-harness 模型加载流程演示") | |
| print("=" * 80 + "\n") | |
| # 步骤1: 解析参数 | |
| parsed_args = step1_parse_args_string() | |
| # 步骤2: 获取模型类 | |
| model_class = step2_get_model_class() | |
| # 步骤3: 加载配置 | |
| pretrained = parsed_args.get("pretrained", "EleutherAI/gpt-j-6B") | |
| revision = parsed_args.get("revision", "main") | |
| trust_remote_code = parsed_args.get("trust_remote_code", False) | |
| print("\n注意: 以下步骤需要网络连接来下载模型文件") | |
| print("如果模型已缓存,将使用缓存版本\n") | |
| try: | |
| config = step3_load_config(pretrained, revision, trust_remote_code) | |
| # 步骤4: 加载 tokenizer | |
| tokenizer = step4_load_tokenizer(pretrained, revision, trust_remote_code) | |
| # 步骤5: 加载模型(可选,需要大量内存) | |
| dtype = parsed_args.get("dtype", "float") | |
| print("\n是否加载完整模型?这需要大量内存和时间。") | |
| print("(在实际使用中,lm-eval 会自动执行这一步)") | |
| load_full_model = False # 设置为 True 来实际加载模型 | |
| if load_full_model: | |
| model = step5_load_model(pretrained, config, dtype, revision, trust_remote_code) | |
| else: | |
| print("跳过完整模型加载(设置 load_full_model=True 来实际加载)") | |
| print() | |
| # 步骤6: 展示如何使用 lm-eval 创建实例 | |
| step6_create_hflm_instance() | |
| except Exception as e: | |
| print(f"\n错误: {e}") | |
| print("这可能是因为:") | |
| print("1. 网络连接问题(无法下载模型)") | |
| print("2. 模型名称不存在") | |
| print("3. 缺少必要的依赖") | |
| import traceback | |
| traceback.print_exc() | |
| print("\n" + "=" * 80) | |
| print("演示完成!") | |
| print("=" * 80) | |
| print("\n关键要点:") | |
| print("1. model_args 字符串被解析为字典") | |
| print("2. 根据 --model 参数获取对应的模型类(如 HFLM)") | |
| print("3. 使用 AutoConfig.from_pretrained() 加载 config.json") | |
| print("4. 使用 AutoTokenizer.from_pretrained() 加载 tokenizer") | |
| print("5. 使用 AutoModelForCausalLM.from_pretrained() 加载模型权重") | |
| print("\n详细说明请参考: LM_EVAL_MODEL_LOADING.md") | |
| if __name__ == "__main__": | |
| main() | |