| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272 |
- #!/usr/bin/env python
- """
- 从魔搭(ModelScope)下载 LLM 模型
- 支持模型列表(示例):
- - Qwen2.5-7B-Instruct(已有,可重新下载)
- - Qwen2.5-14B-Instruct
- - Qwen2.5-32B-Instruct
- - Qwen3.5-7B-Instruct(如果可用)
- - Llama-3-8B-Instruct
- - Llama-3.1-8B-Instruct
- 用法:
- # 下载 Qwen2.5-7B-Instruct
- python model/download_from_modelscope.py --model qwen2.5-7b
- # 下载 Llama-3-8B-Instruct
- python model/download_from_modelscope.py --model llama3-8b
- # 下载指定模型(自定义)
- python model/download_from_modelscope.py --model-id Qwen/Qwen2.5-7B-Instruct
- """
- import os
- import sys
- import argparse
- from pathlib import Path
- from typing import Optional
- # 模型映射表
- MODEL_MAPPING = {
- # Qwen 系列
- "qwen2.5-7b": "Qwen/Qwen2.5-7B-Instruct",
- "qwen2.5-14b": "Qwen/Qwen2.5-14B-Instruct",
- "qwen2.5-32b": "Qwen/Qwen2.5-32B-Instruct",
- "qwen2.5-72b": "Qwen/Qwen2.5-72B-Instruct",
- "qwen3.5-7b": "Qwen/Qwen3.5-7B-Instruct",
- "qwen3.5-14b": "Qwen/Qwen3.5-14B-Instruct",
- "qwen3.5-32b": "Qwen/Qwen3.5-32B-Instruct",
- # Llama 系列
- "llama3-8b": "LLM-Research/Meta-Llama-3-8B-Instruct",
- "llama3-70b": "LLM-Research/Meta-Llama-3-70B-Instruct",
- "llama3.1-8b": "LLM-Research/Meta-Llama-3.1-8B-Instruct",
- "llama3.1-70b": "LLM-Research/Meta-Llama-3.1-70B-Instruct",
- "llama3.2-3b": "LLM-Research/Llama-3.2-3B-Instruct", # 魔搭特供版本
- # Mistral 系列(已有)
- "mistral-7b": "LLM-Research/Mistral-7B-v0.3",
- # Gemma 系列
- "gemma-2b": "LLM-Research/gemma-2b-it",
- "gemma-7b": "LLM-Research/gemma-7b-it",
- "gemma-9b": "LLM-Research/gemma-2-9b-it",
- }
- def check_modelscope_installed():
- """检查 modelscope 是否安装"""
- try:
- from modelscope import snapshot_download
- return True
- except ImportError:
- print("错误:未安装 modelscope 库")
- print("请先运行以下命令安装:")
- print(" pip install modelscope")
- print(" 或")
- print(" pip install modelscope -c https://modelscope.oss-cn-beijing.aliyuncs.com/releases/repo.txt")
- return False
- def download_model(model_id: str, output_dir: str, revision: str = "master") -> bool:
- """
- 从魔搭下载模型
- Args:
- model_id: 模型 ID,如 "Qwen/Qwen2.5-7B-Instruct"
- output_dir: 输出目录
- revision: 模型版本
- Returns:
- 下载是否成功
- """
- from modelscope import snapshot_download
- import inspect
- print(f"开始下载模型:{model_id}")
- print(f"输出目录:{output_dir}")
- print(f"版本:{revision}")
- print("-" * 50)
- try:
- # 检查 snapshot_download 支持的参数
- sig = inspect.signature(snapshot_download)
- params = {
- 'model_id': model_id,
- 'revision': revision,
- 'local_dir': output_dir,
- }
- # 根据版本决定是否使用 symlinks 参数
- if 'local_dir_use_symlinks' in sig.parameters:
- params['local_dir_use_symlinks'] = False
- elif 'use_symlinks' in sig.parameters:
- params['use_symlinks'] = False
- # 使用 snapshot_download 下载模型
- model_dir = snapshot_download(**params)
- print(f"\n下载完成!")
- print(f"模型路径:{model_dir}")
- # 列出下载的文件
- print("\n下载的文件:")
- for root, dirs, files in os.walk(output_dir):
- level = root.replace(output_dir, '').count(os.sep)
- indent = ' ' * 2 * level
- print(f'{indent}{os.path.basename(root)}/')
- subindent = ' ' * 2 * (level + 1)
- for file in files[:10]: # 只显示前 10 个文件
- print(f'{subindent}{file}')
- return True
- except Exception as e:
- print(f"\n下载失败:{e}")
- return False
- def get_model_info(model_name: str) -> Optional[dict]:
- """获取模型信息"""
- if model_name in MODEL_MAPPING:
- return {
- "name": model_name,
- "model_id": MODEL_MAPPING[model_name],
- "status": "已支持"
- }
- return None
- def list_available_models():
- """列出所有可用模型"""
- print("\n可用模型列表:")
- print("-" * 60)
- print(f"{'简写':<20} {'模型 ID':<35} {'状态'}")
- print("-" * 60)
- for name, model_id in MODEL_MAPPING.items():
- print(f"{name:<20} {model_id:<35} 已支持")
- print("-" * 60)
- print("\n使用方法:")
- print(" python model/download_from_modelscope.py --model <简写>")
- print(" python model/download_from_modelscope.py --model-id <完整模型 ID>")
- print()
- def main():
- parser = argparse.ArgumentParser(
- description="从魔搭(ModelScope)下载 LLM 模型",
- formatter_class=argparse.RawDescriptionHelpFormatter,
- epilog="""
- 示例:
- # 列出所有可用模型
- python model/download_from_modelscope.py --list
- # 下载 Qwen2.5-7B-Instruct
- python model/download_from_modelscope.py --model qwen2.5-7b
- # 下载 Llama-3-8B-Instruct
- python model/download_from_modelscope.py --model llama3-8b
- # 使用完整模型 ID 下载
- python model/download_from_modelscope.py --model-id Qwen/Qwen2.5-7B-Instruct
- """
- )
- parser.add_argument(
- "--model",
- type=str,
- choices=list(MODEL_MAPPING.keys()),
- help="使用简写下载模型(如 qwen2.5-7b, llama3-8b)"
- )
- parser.add_argument(
- "--model-id",
- type=str,
- help="使用完整模型 ID 下载(如 Qwen/Qwen2.5-7B-Instruct)"
- )
- parser.add_argument(
- "--output-dir",
- type=str,
- default=None,
- help="模型输出目录(默认:model/weights/{model_name})"
- )
- parser.add_argument(
- "--revision",
- type=str,
- default="master",
- help="模型版本(默认:master)"
- )
- parser.add_argument(
- "--list",
- action="store_true",
- help="列出所有可用模型"
- )
- args = parser.parse_args()
- # 列出模型
- if args.list:
- list_available_models()
- return 0
- # 检查参数
- if not args.model and not args.model_id:
- print("错误:请指定 --model 或 --model-id")
- print("使用 --list 查看可用模型")
- return 1
- # 检查安装
- if not check_modelscope_installed():
- return 1
- # 确定模型 ID
- if args.model:
- model_id = MODEL_MAPPING[args.model]
- model_name = args.model
- else:
- model_id = args.model_id
- model_name = model_id.split("/")[-1]
- # 确定输出目录
- if args.output_dir:
- output_dir = args.output_dir
- else:
- output_dir = os.path.join("model/weights", model_name)
- # 创建目录
- Path(output_dir).mkdir(parents=True, exist_ok=True)
- # 检查是否已存在
- config_file = os.path.join(output_dir, "config.json")
- if os.path.exists(config_file):
- print(f"警告:模型目录已存在:{output_dir}")
- response = input("是否覆盖下载?(y/N): ")
- if response.lower() != 'y':
- print("已取消")
- return 0
- # 下载模型
- success = download_model(model_id, output_dir, args.revision)
- if success:
- print("\n" + "=" * 50)
- print("下载成功!")
- print(f"\n下一步:更新 extract_representations.py 中的模型配置")
- print(f"添加新模型:{model_name}")
- print(f"模型路径:{output_dir}")
- print("=" * 50)
- return 0
- else:
- print("\n下载失败,请检查网络连接或模型 ID 是否正确")
- return 1
- if __name__ == "__main__":
- sys.exit(main())
|