Skip to content

Commit f7ba79a

Browse files
committed
feat(doc and api): Revamp README and add CLI API module
Updated the README with improved setup instructions, usage examples, and a new project logo. Added a new CLI API module (spectrumlab/cli/api.py), updated CLI and benchmark modules, and included a backup for benchmark/__init__.py. Also updated project metadata in pyproject.toml.
1 parent 6d9fa26 commit f7ba79a

9 files changed

Lines changed: 286 additions & 57 deletions

File tree

README.md

Lines changed: 62 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,20 @@
1-
# SpectrumLab
1+
<!-- # SpectrumLab -->
22

33
<div align="center">
4-
A pioneering unified platform designed to systematize and accelerate deep learning research in spectroscopy.
4+
<img src="assets/spectrumlab.svg" alt="SpectrumLab" width="600"/>
5+
6+
<p><strong>A pioneering unified platform designed to systematize and accelerate deep learning research in spectroscopy.</strong></p>
57
</div>
68

7-
## Quick Start
9+
## 🚀 Quick Start
810

911
### Environment Setup
1012

1113
We recommend using conda and uv for environment management:
1214

1315
```bash
1416
# Clone the repository
15-
git clone https://github.com/your-org/SpectrumLab.git
17+
git clone https://github.com/little1d/SpectrumLab.git
1618
cd SpectrumLab
1719

1820
# Create conda environment
@@ -23,38 +25,71 @@ pip install uv
2325
uv pip install -e .
2426
```
2527

26-
### One-Click Evaluation
28+
### Data Setup
2729

28-
1. **Switch to evaluation branch**
30+
Download benchmark data from Hugging Face:
2931

30-
```bash
31-
git checkout evaluation
32-
```
32+
- [SpectrumBench v1.0](https://huggingface.co/datasets/SpectrumWorld/spectrumbench_v_1.0)
3333

34-
2. **Download benchmark data**
34+
Extract the data to the `data` directory in the project root.
3535

36-
Benchmark data is hosted on Hugging Face. Please download it from the following link:
36+
### API Keys Configuration
3737

38-
[https://huggingface.co/datasets/SpectrumWorld/spectrumbench_v_1.0](https://huggingface.co/SpectrumWorld/spectrumbench_v_1.0/tree/main)
38+
```bash
39+
# Copy and edit environment configuration
40+
cp .env.example .env
41+
# Configure your API keys in the .env file
42+
```
43+
44+
## 💻 Usage
45+
46+
### Python API
3947

40-
After downloading, extract the data to the `data` directory in the project root.
48+
```python
49+
from spectrumlab.benchmark import get_benchmark_group
50+
from spectrumlab.models import GPT4o
51+
from spectrumlab.evaluator import get_evaluator
4152

42-
3. **Configure model parameters**
53+
# Load benchmark data
54+
benchmark = get_benchmark_group("perception")
55+
data = benchmark.get_data_by_subcategories("all")
4356

44-
```bash
45-
# Copy and edit environment configuration
46-
cp .env.example .env
47-
# Configure your API keys in the .env file
48-
```
57+
# Initialize model
58+
model = GPT4o()
59+
60+
# Get evaluator
61+
evaluator = get_evaluator("perception")
62+
63+
# Run evaluation
64+
results = evaluator.evaluate(
65+
data_items=data,
66+
model=model,
67+
save_path="./results"
68+
)
69+
70+
print(f"Overall accuracy: {results['metrics']['overall']['accuracy']:.2f}%")
71+
```
4972

50-
4. **Run evaluation**
73+
### Command Line Interface
5174

52-
```bash
53-
python run_evaluation.py
54-
55-
# Run in background
56-
nohup python run_evaluation.py > run_eval.log 2>&1 &
57-
```
75+
The CLI provides a simple way to run evaluations:
76+
77+
```bash
78+
# Basic evaluation
79+
spectrumlab eval --model gpt4o --level perception
80+
81+
# Specify data path and output directory
82+
spectrumlab eval --model claude --level signal --data-path ./data --output ./my_results
83+
84+
# Evaluate specific subcategories
85+
spectrumlab eval --model deepseek --level semantic --subcategories "IR_spectroscopy" "Raman_spectroscopy"
86+
87+
# Customize output length
88+
spectrumlab eval --model internvl --level generation --max-length 1024
89+
90+
# Get help
91+
spectrumlab eval --help
92+
```
5893

5994
## 🤝 Contributing
6095

@@ -63,4 +98,4 @@ We welcome community contributions! Please see [CONTRIBUTING.md](CONTRIBUTING.md
6398
## Acknowledgments
6499

65100
- **Experiment Tracking**: [SwanLab](https://github.com/SwanHubX/SwanLab/) for experiment management and visualization
66-
- **Evaluation Framework**: Inspired by [MMAR](https://github.com/ddlBoJack/MMAR)
101+
- **Choice Evaluator Framework**: Inspired by [MMAR](https://github.com/ddlBoJack/MMAR)

assets/spectrumlab.svg

Lines changed: 11 additions & 0 deletions
Loading

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "hatchling.build"
55
[project]
66
name = "spectrumlab"
77
version = "0.0.1"
8-
description = "Comprehensive toolkit for spectroscopy deep learning: dataset loading, training, evaluation, inference, and more"
8+
description = "A pioneering unified platform designed to systematize and accelerate deep learning research in spectroscopy."
99
readme = "README.md"
1010
requires-python = ">=3.10"
1111
authors = [

spectrumlab/benchmark/__init__.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,25 @@
33
from .generation_group import GenerationGroup
44
from .semantic_group import SemanticGroup
55

6-
__all__ = ["SignalGroup", "PerceptionGroup", "GenerationGroup", "SemanticGroup"]
6+
__all__ = [
7+
"SignalGroup",
8+
"PerceptionGroup",
9+
"GenerationGroup",
10+
"SemanticGroup",
11+
"get_benchmark_group",
12+
]
13+
14+
15+
def get_benchmark_group(level: str, path: str = "./data"):
16+
level_map = {
17+
"signal": SignalGroup,
18+
"perception": PerceptionGroup,
19+
"semantic": SemanticGroup,
20+
"generation": GenerationGroup,
21+
}
22+
23+
level_lower = level.lower()
24+
if level_lower not in level_map:
25+
raise ValueError(f"不支持的评估级别: {level}. 可选值: {list(level_map.keys())}")
26+
27+
return level_map[level_lower](path=path)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from .signal_group import SignalGroup
2+
from .perception_group import PerceptionGroup
3+
from .generation_group import GenerationGroup
4+
from .semantic_group import SemanticGroup
5+
6+
__all__ = ["SignalGroup", "PerceptionGroup", "GenerationGroup", "SemanticGroup"]

spectrumlab/cli/__init__.py

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,3 @@
1-
"""
2-
SpectrumLab - 化学谱学大模型 Benchmark 引擎
3-
"""
4-
51
__version__ = "0.0.1"
62

73

spectrumlab/cli/api.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
from typing import List, Dict, Optional, Any
2+
from ..benchmark import get_benchmark_group
3+
from ..evaluator import get_evaluator
4+
5+
6+
def run_evaluation(
7+
model,
8+
level: str,
9+
subcategories: Optional[List[str]] = None,
10+
data_path: str = "./data",
11+
save_path: str = "./results",
12+
max_out_len: int = 512,
13+
) -> Dict[str, Any]:
14+
print("🚀 Starting evaluation")
15+
print(f"📊 Model: {model.__class__.__name__}")
16+
print(f"📁 Level: {level}")
17+
print(f"📂 Data path: {data_path}")
18+
print(f"💾 Save path: {save_path}")
19+
20+
print("\n📥 Loading benchmark data...")
21+
benchmark = get_benchmark_group(level, data_path)
22+
23+
if subcategories:
24+
data = benchmark.get_data_by_subcategories(subcategories)
25+
print(f"📋 Subcategories: {subcategories}")
26+
else:
27+
data = benchmark.get_data_by_subcategories("all")
28+
print("📋 Subcategories: all")
29+
30+
print(f"📊 Total data items: {len(data)}")
31+
32+
print("\n⚙️ Getting evaluator...")
33+
evaluator = get_evaluator(level)
34+
35+
print("\n🔄 Running evaluation...")
36+
results = evaluator.evaluate(
37+
data_items=data,
38+
model=model,
39+
max_out_len=max_out_len,
40+
save_path=save_path,
41+
)
42+
43+
return results

spectrumlab/cli/main.py

Lines changed: 115 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,40 +1,135 @@
1-
"""
2-
SpectrumLab 命令行界面
3-
"""
4-
51
import argparse
2+
import sys
63
from typing import Optional, List
74

5+
from .api import run_evaluation
6+
from spectrumlab.models import (
7+
GPT4o,
8+
Claude_Sonnet_3_5,
9+
DeepSeek_VL2,
10+
InternVL,
11+
Qwen_2_5_VL_32B,
12+
)
13+
14+
AVAILABLE_MODELS = {
15+
"gpt4o": GPT4o,
16+
"claude": Claude_Sonnet_3_5,
17+
"deepseek": DeepSeek_VL2,
18+
"internvl": InternVL,
19+
"qwen-vl": Qwen_2_5_VL_32B,
20+
}
21+
822

923
def main(argv: Optional[List[str]] = None) -> int:
10-
"""
11-
SpectrumLab 主命令行入口点
12-
"""
1324
parser = argparse.ArgumentParser(
14-
prog="spectrumlab", description="化学谱学大模型 Benchmark 引擎"
25+
prog="spectrumlab",
26+
description="A pioneering unified platform designed to systematize and accelerate deep learning research in spectroscopy",
27+
)
28+
29+
parser.add_argument("--version", action="version", version="%(prog)s 0.1.0")
30+
31+
subparsers = parser.add_subparsers(dest="command", help="Available commands")
32+
33+
eval_parser = subparsers.add_parser("eval", help="Run model evaluation")
34+
35+
eval_parser.add_argument(
36+
"--model",
37+
"-m",
38+
required=True,
39+
choices=list(AVAILABLE_MODELS.keys()),
40+
help=f"Model name, options: {', '.join(AVAILABLE_MODELS.keys())}",
41+
)
42+
43+
eval_parser.add_argument(
44+
"--level",
45+
"-l",
46+
required=True,
47+
choices=["signal", "perception", "semantic", "generation"],
48+
help="Evaluation level",
1549
)
1650

17-
parser.add_argument("--version", action="version", version="%(prog)s 0.0.1")
51+
eval_parser.add_argument(
52+
"--subcategories",
53+
"-s",
54+
nargs="*",
55+
help="Specify subcategories (optional, default: all)",
56+
)
1857

19-
subparsers = parser.add_subparsers(dest="command", help="可用命令")
58+
eval_parser.add_argument(
59+
"--data-path", "-d", default="./data", help="Data path (default: ./data)"
60+
)
61+
62+
eval_parser.add_argument(
63+
"--output", "-o", default="./results", help="Output path (default: ./results)"
64+
)
2065

21-
# 示例子命令
22-
eval_parser = subparsers.add_parser("eval", help="运行评估")
23-
eval_parser.add_argument("--model", help="模型名称", required=True)
24-
eval_parser.add_argument("--dataset", help="数据集名称", required=True)
66+
eval_parser.add_argument(
67+
"--max-length", type=int, default=512, help="Max output length (default: 512)"
68+
)
2569

2670
args = parser.parse_args(argv)
2771

2872
if args.command == "eval":
29-
print(f"正在评估模型: {args.model}")
30-
print(f"使用数据集: {args.dataset}")
31-
return 0
73+
try:
74+
# Initialize the model
75+
if args.model not in AVAILABLE_MODELS:
76+
available = ", ".join(AVAILABLE_MODELS.keys())
77+
raise ValueError(
78+
f"Unsupported model: {args.model}. Available: {available}"
79+
)
80+
81+
model_class = AVAILABLE_MODELS[args.model]
82+
model_instance = model_class()
83+
84+
results = run_evaluation(
85+
model=model_instance,
86+
level=args.level,
87+
subcategories=args.subcategories,
88+
data_path=args.data_path,
89+
save_path=args.output,
90+
max_out_len=args.max_length,
91+
)
92+
93+
print("\n" + "=" * 50)
94+
print("📊 Evaluation Results")
95+
print("=" * 50)
96+
97+
if "error" in results:
98+
print(f"❌ Evaluation failed: {results['error']}")
99+
return 1
100+
101+
metrics = results.get("metrics", {})
102+
overall = metrics.get("overall", {})
103+
104+
print("✅ Evaluation completed!")
105+
print(f"📈 Overall accuracy: {overall.get('accuracy', 0):.2f}%")
106+
print(f"✅ Correct answers: {overall.get('correct', 0)}")
107+
print(f"📝 Total questions: {overall.get('total', 0)}")
108+
109+
subcategory_metrics = metrics.get("subcategory_metrics", {})
110+
if subcategory_metrics:
111+
print("\n📋 Subcategory details:")
112+
for subcategory, sub_metrics in subcategory_metrics.items():
113+
acc = sub_metrics.get("accuracy", 0)
114+
correct = sub_metrics.get("correct", 0)
115+
total = sub_metrics.get("total", 0)
116+
print(f" {subcategory}: {acc:.2f}% ({correct}/{total})")
117+
118+
print(f"\n💾 Results saved to: {args.output}")
119+
return 0
120+
121+
except Exception as e:
122+
print(f"❌ Evaluation failed: {e}")
123+
return 1
124+
32125
elif args.command is None:
33126
parser.print_help()
34127
return 0
35-
36-
return 0
128+
else:
129+
print(f"❌ Unknown command: {args.command}")
130+
parser.print_help()
131+
return 1
37132

38133

39134
if __name__ == "__main__":
40-
exit(main())
135+
sys.exit(main())

0 commit comments

Comments
 (0)