| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389 |
- #!/usr/bin/env python
- """
- 方向 9 实验运行脚本 - 整合所有实验流程
- 实验列表:
- - E1: 基础谱收敛验证
- - E2: 跨域谱分层验证
- - E3: 能力涌现谱突变检测
- - E4: 对齐即谱工程
- - LCP: 逐层谱收敛轮廓
- 用法:
- # 运行所有实验
- python experiments/run_direction9_experiments.py --all
- # 运行单个实验
- python experiments/run_direction9_experiments.py --experiment E1
- # 生成可视化
- python experiments/run_direction9_experiments.py --visualize
- """
- import os
- import sys
- import json
- import argparse
- from pathlib import Path
- from datetime import datetime
- # 设置 HF 镜像
- os.environ["HF_ENDPOINT"] = "https://hf-mirror.com"
- # 项目根目录
- PROJECT_ROOT = Path(__file__).parent.parent
- sys.path.insert(0, str(PROJECT_ROOT))
- def check_prerequisites():
- """检查实验前置条件"""
- print("=" * 60)
- print("检查实验前置条件")
- print("=" * 60)
- issues = []
- # 检查模型
- print("\n[模型检查]")
- required_models = {
- "llama3.2-3b-instruct": "model/weights/llama3.2-3b-instruct",
- "Mistral-7B-v0.3": "model/weights/Mistral-7B-v0.3",
- "llama3-8b": "model/weights/llama3-8b",
- "Qwen2.5-7B-Instruct": "model/weights/Qwen2.5-7B-Instruct",
- "gemma-2-9b-it": "model/weights/gemma-2-9b-it"
- }
- for name, path in required_models.items():
- model_path = PROJECT_ROOT / path
- config_file = model_path / "config.json"
- if config_file.exists():
- print(f" ✓ {name}")
- else:
- print(f" ✗ {name} - 缺失")
- issues.append(f"模型缺失:{name}")
- # 检查数据集
- print("\n[数据集检查]")
- from database.corpus import CorpusLoader
- loader = CorpusLoader(PROJECT_ROOT / "database/corpus")
- required_datasets = ["gsm8k", "math", "humaneval", "alpaca", "bigbench", "flores200"]
- available = loader.list_available_domains()
- for ds in required_datasets:
- if ds in available:
- stats = loader.get_corpus_stats(ds)
- print(f" ✓ {ds}: {stats['num_texts']} 条")
- else:
- print(f" ✗ {ds} - 缺失")
- issues.append(f"数据集缺失:{ds}")
- # 检查依赖
- print("\n[依赖检查]")
- try:
- import ruptures
- print(" ✓ ruptures")
- except ImportError:
- print(" ✗ ruptures - 未安装")
- issues.append("依赖缺失:ruptures")
- try:
- import seaborn
- print(" ✓ seaborn")
- except ImportError:
- print(" ✗ seaborn - 未安装")
- issues.append("依赖缺失:seaborn")
- # GPU 检查
- print("\n[GPU 检查]")
- import torch
- if torch.cuda.is_available():
- print(f" ✓ CUDA {torch.version.cuda}")
- print(f" ✓ GPU: {torch.cuda.get_device_name(0)}")
- print(f" ✓ 显存:{torch.cuda.get_device_properties(0).total_memory / 1e9:.1f} GB")
- else:
- print(" ✗ CUDA 不可用 - 将使用 CPU (慢)")
- print("\n" + "=" * 60)
- if issues:
- print(f"发现 {len(issues)} 个问题:")
- for issue in issues:
- print(f" - {issue}")
- print("\n建议先解决上述问题再运行实验")
- return False
- else:
- print("✓ 所有前置条件满足")
- return True
- def run_experiment_e1(output_dir: str):
- """运行 E1 实验"""
- from experiments.cross_model_convergence import CrossModelConvergence, ExperimentConfig
- config = ExperimentConfig(
- models=[
- "llama3.2-3b-instruct",
- "Mistral-7B-v0.3",
- "llama3-8b",
- "Qwen2.5-7B-Instruct",
- "gemma-2-9b-it"
- ],
- model_paths={
- "llama3.2-3b-instruct": "model/weights/llama3.2-3b-instruct",
- "Mistral-7B-v0.3": "model/weights/Mistral-7B-v0.3",
- "llama3-8b": "model/weights/llama3-8b",
- "Qwen2.5-7B-Instruct": "model/weights/Qwen2.5-7B-Instruct",
- "gemma-2-9b-it": "model/weights/gemma-2-9b-it"
- },
- datasets=["gsm8k", "math", "humaneval", "alpaca", "flores200"],
- output_dir=output_dir,
- batch_size=4, # 降低 batch size 以防止 OOM
- max_length=512,
- pooling="mean"
- )
- analyzer = CrossModelConvergence(config)
- return analyzer.run_experiment_e1()
- def run_experiment_e2(output_dir: str):
- """运行 E2 实验 - 跨域谱分层验证"""
- from experiments.cross_model_convergence import CrossModelConvergence, ExperimentConfig
- # E2 复用 E1 的配置和数据
- config = ExperimentConfig(
- models=[
- "llama3.2-3b-instruct",
- "Mistral-7B-v0.3",
- "llama3-8b",
- "Qwen2.5-7B-Instruct",
- "gemma-2-9b-it"
- ],
- model_paths={
- "llama3.2-3b-instruct": "model/weights/llama3.2-3b-instruct",
- "Mistral-7B-v0.3": "model/weights/Mistral-7B-v0.3",
- "llama3-8b": "model/weights/llama3-8b",
- "Qwen2.5-7B-Instruct": "model/weights/Qwen2.5-7B-Instruct",
- "gemma-2-9b-it": "model/weights/gemma-2-9b-it"
- },
- datasets=["gsm8k", "math", "humaneval", "alpaca", "flores200"],
- output_dir=output_dir,
- batch_size=4,
- max_length=512,
- pooling="mean"
- )
- analyzer = CrossModelConvergence(config)
- return analyzer.run_experiment_e2()
- def run_experiment_e3(output_dir: str):
- """运行 E3 实验"""
- from experiments.emergence_detection import EmergenceDetector
- MODEL_SEQUENCE = [
- "llama3.2-3b-instruct",
- "Mistral-7B-v0.3",
- "llama3-8b",
- "Qwen2.5-7B-Instruct",
- "gemma-2-9b-it"
- ]
- MODEL_PATHS = {
- "llama3.2-3b-instruct": "model/weights/llama3.2-3b-instruct",
- "Mistral-7B-v0.3": "model/weights/Mistral-7B-v0.3",
- "llama3-8b": "model/weights/llama3-8b",
- "Qwen2.5-7B-Instruct": "model/weights/Qwen2.5-7B-Instruct",
- "gemma-2-9b-it": "model/weights/gemma-2-9b-it"
- }
- MODEL_MMLU = {
- "llama3.2-3b-instruct": 58.0,
- "Mistral-7B-v0.3": 62.5,
- "llama3-8b": 68.4,
- "Qwen2.5-7B-Instruct": 86.3,
- "gemma-2-9b-it": 82.0
- }
- detector = EmergenceDetector(
- model_sequence=MODEL_SEQUENCE,
- model_paths=MODEL_PATHS,
- model_mmlu=MODEL_MMLU,
- output_dir=output_dir
- )
- return detector.run_full_analysis()
- def run_experiment_e5(output_dir: str, dataset: str = "bigbench", sample_size: int = 100):
- """运行 E5 实验 - RS_cross 作为文本难度代理"""
- from experiments.text_difficulty_proxy import TextDifficultyProxy, E5Config
- config = E5Config(
- models=[
- "llama3.2-3b-instruct",
- "Mistral-7B-v0.3",
- "llama3-8b",
- "Qwen2.5-7B-Instruct",
- "gemma-2-9b-it"
- ],
- model_paths={
- "llama3.2-3b-instruct": "model/weights/llama3.2-3b-instruct",
- "Mistral-7B-v0.3": "model/weights/Mistral-7B-v0.3",
- "llama3-8b": "model/weights/llama3-8b",
- "Qwen2.5-7B-Instruct": "model/weights/Qwen2.5-7B-Instruct",
- "gemma-2-9b-it": "model/weights/gemma-2-9b-it"
- },
- model_mmlu={
- "llama3.2-3b-instruct": 58.0,
- "Mistral-7B-v0.3": 62.5,
- "llama3-8b": 68.4,
- "Qwen2.5-7B-Instruct": 86.3,
- "gemma-2-9b-it": 82.0
- },
- dataset=dataset,
- output_dir=output_dir,
- sample_size=sample_size,
- batch_size=4,
- max_length=512
- )
- analyzer = TextDifficultyProxy(config)
- return analyzer
- def run_visualization(input_dir: str, output_dir: str):
- """运行可视化"""
- from experiments.visualization_direction9 import Direction9Visualizer
- visualizer = Direction9Visualizer(output_dir)
- # 加载 E1 结果
- e1_result_file = Path(input_dir) / "cross_model/e1_result.json"
- if e1_result_file.exists():
- with open(e1_result_file) as f:
- e1_result = json.load(f)
- print("加载 E1 结果成功")
- else:
- e1_result = {}
- print("未找到 E1 结果文件")
- # 加载 E3 结果
- e3_result_file = Path(input_dir) / "emergence/emergence_results.json"
- if e3_result_file.exists():
- with open(e3_result_file) as f:
- e3_result = json.load(f)
- print("加载 E3 结果成功")
- else:
- e3_result = {}
- print("未找到 E3 结果文件")
- # 生成可视化
- model_mmlu = {
- "llama3.2-3b-instruct": 58.0,
- "Mistral-7B-v0.3": 62.5,
- "llama3-8b": 68.4,
- "Qwen2.5-7B-Instruct": 86.3,
- "gemma-2-9b-it": 82.0
- }
- if e1_result.get('r_effs'):
- visualizer.plot_rs_cross_comparison(e1_result.get('rs_cross', {}))
- # 尝试绘制 MMLU vs r_eff (需要重新组织数据结构)
- if e1_result.get('spd_matrices'):
- for dataset, spd in e1_result['spd_matrices'].items():
- model_names = list(e1_result.get('r_effs', {}).get(dataset, {}).keys())
- if model_names:
- visualizer.plot_spd_heatmap(spd, model_names, dataset)
- if e3_result:
- visualizer.plot_emergence_curve(e3_result)
- # 生成摘要仪表盘
- visualizer.create_summary_dashboard(e1_result, e3_result)
- def main():
- parser = argparse.ArgumentParser(description="方向 9 实验运行脚本")
- parser.add_argument("--all", action="store_true", help="运行所有实验")
- parser.add_argument("--experiment", type=str,
- choices=["E1", "E2", "E3", "E5", "LCP"],
- help="运行指定实验")
- parser.add_argument("--dataset", type=str, default="bigbench",
- help="数据集名称 (E5 实验用)")
- parser.add_argument("--sample", type=int, default=100,
- help="采样文本数量 (E5 实验用)")
- parser.add_argument("--visualize", action="store_true",
- help="生成可视化")
- parser.add_argument("--output-dir", type=str,
- default="experiments/output",
- help="输出目录")
- parser.add_argument("--skip-checks", action="store_true",
- help="跳过前置检查")
- args = parser.parse_args()
- print("=" * 60)
- print("方向 9 实验运行脚本")
- print(f"时间:{datetime.now().strftime('%Y-%m-%d %H:%M:%S')}")
- print("=" * 60)
- # 前置检查
- if not args.skip_checks:
- if not check_prerequisites():
- print("\n前置检查未通过,请解决上述问题")
- sys.exit(1)
- # 创建输出目录
- output_dir = Path(args.output_dir)
- output_dir.mkdir(parents=True, exist_ok=True)
- # 运行实验
- if args.all:
- print("\n" + "=" * 60)
- print("运行 E1: 基础谱收敛验证")
- print("=" * 60)
- run_experiment_e1(str(output_dir / "cross_model"))
- print("\n" + "=" * 60)
- print("运行 E3: 能力涌现谱突变检测")
- print("=" * 60)
- run_experiment_e3(str(output_dir / "emergence"))
- print("\n" + "=" * 60)
- print("生成可视化")
- print("=" * 60)
- run_visualization(str(output_dir), str(output_dir / "figures"))
- elif args.experiment:
- if args.experiment == "E1":
- run_experiment_e1(str(output_dir / "cross_model"))
- elif args.experiment == "E2":
- run_experiment_e2(str(output_dir / "cross_model"))
- elif args.experiment == "E3":
- run_experiment_e3(str(output_dir / "emergence"))
- elif args.experiment == "E5":
- analyzer = run_experiment_e5(
- str(output_dir / "e5"),
- dataset=args.dataset,
- sample_size=args.sample
- )
- # 加载文本并运行
- from database.corpus import CorpusLoader
- loader = CorpusLoader(PROJECT_ROOT / "database/corpus")
- texts = loader.load_texts(args.dataset, limit=args.sample)
- analyzer.run_analysis(texts)
- analyzer.save_results()
- analyzer.generate_report()
- elif args.visualize:
- run_visualization(str(output_dir), str(output_dir / "figures"))
- else:
- parser.print_help()
- if __name__ == "__main__":
- main()
|