Skip to content

Commit 16f145d

Browse files
authored
Merge pull request #62 from e06084/main
feat: update llm_config in Evaluator
2 parents 4b5c575 + 5f212a1 commit 16f145d

10 files changed

Lines changed: 123 additions & 81 deletions

File tree

.gitignore

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,4 +45,12 @@ results/
4545
.coverage*
4646
coverage.xml
4747

48-
webmainbench.egg-info/*
48+
webmainbench.egg-info/*
49+
50+
# PyPI packaging
51+
build/
52+
dist/
53+
*.egg-info/
54+
.eggs/
55+
*.egg
56+
.pypirc

README.md

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,6 @@ WebMainBench is a specialized benchmark tool for end-to-end evaluation of web ma
4141
```bash
4242
# Basic installation
4343
pip install webmainbench
44-
45-
# Install with all optional dependencies
46-
pip install webmainbench[all]
47-
48-
# Development environment installation
49-
pip install webmainbench[dev]
5044
```
5145

5246
### Basic Usage
@@ -55,13 +49,18 @@ pip install webmainbench[dev]
5549
from webmainbench import DataLoader, Evaluator, ExtractorFactory
5650

5751
# 1. Load evaluation dataset
58-
dataset = DataLoader.load_jsonl("your_dataset.jsonl")
52+
dataset = DataLoader.load_jsonl("data/WebMainBench_dataset_sample2.jsonl")
5953

6054
# 2. Create extractor
6155
extractor = ExtractorFactory.create("trafilatura")
6256

6357
# 3. Run evaluation
64-
evaluator = Evaluator()
58+
evaluator = Evaluator(llm_config={
59+
"use_llm": True,
60+
"llm_base_url": "",
61+
"llm_api_key": "",
62+
"llm_model": "gpt-5-chat-latest",
63+
})
6564
result = evaluator.evaluate(dataset, extractor)
6665

6766
# 4. View results

data/WebMainBench_dataset_sample2.jsonl

Lines changed: 2 additions & 2 deletions
Large diffs are not rendered by default.

setup.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,11 @@
99
name="webmainbench",
1010
version="0.1.0",
1111
author="WebMainBench Team",
12-
author_email="webmainbench@example.com",
12+
author_email="chupei@pjlab.org.cn",
1313
description="A comprehensive benchmark for web main content extraction",
1414
long_description=long_description,
1515
long_description_content_type="text/markdown",
16-
url="https://github.com/example/webmainbench",
16+
url="https://github.com/opendatalab/WebMainBench",
1717
packages=find_packages(),
1818
classifiers=[
1919
"Development Status :: 3 - Alpha",
@@ -32,11 +32,15 @@
3232
],
3333
python_requires=">=3.8",
3434
install_requires=[
35-
"lxml==5.3.0",
35+
"lxml>=5.3.0",
3636
"jsonlines>=3.1.0",
3737
"requests>=2.28.0",
38-
"beautifulsoup4==4.12.0",
38+
"beautifulsoup4>=4.12.0",
3939
"numpy>=1.21.0,<2.0.0", # 避免NumPy 2.x兼容性问题
40+
"rapidfuzz>=3.0.0", # 用于文本编辑距离计算
41+
"apted>=1.0.3", # 用于树编辑距离计算(TEDS)
42+
"jieba>=0.42.0", # 用于中文分词
43+
"rouge>=1.0.0", # 用于 ROUGE 指标
4044
],
4145
extras_require={
4246
"all": [

webmainbench/config.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
"""
2-
全局配置文件
3-
"""
1+
"""Package-wide configuration."""
42

5-
# LLM配置,用于修正抽取工具的抽取结果
3+
# LLM settings for refinement of extractor outputs
64
LLM_CONFIG = {
75
'llm_base_url': '',
86
'llm_api_key': '',
97
'llm_model': 'deepseek-chat',
10-
'use_llm': True
8+
'use_llm': True,
119
}
10+
11+
# When True, print LLM enhancement / cache diagnostics (very noisy).
12+
METRICS_DEBUG = False

webmainbench/evaluator/evaluator.py

Lines changed: 66 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -78,81 +78,101 @@ def from_dict(cls, data: Dict[str, Any]) -> "EvaluationResult":
7878
class Evaluator:
7979
"""Main evaluator for web content extraction benchmarks."""
8080

81-
def __init__(self, metric_config: Dict[str, Any] = None):
81+
def __init__(self, metric_config: Dict[str, Any] = None,
82+
llm_config: Dict[str, Any] = None):
8283
"""
8384
Initialize the evaluator.
8485
8586
Args:
8687
metric_config: Configuration for metrics
88+
llm_config: Optional LLM configuration dict to override webmainbench/config.py.
89+
Supported keys:
90+
- use_llm (bool): whether to enable LLM enhancement
91+
- llm_base_url (str): API base URL
92+
- llm_api_key (str): API key
93+
- llm_model (str): model name (default: 'deepseek-chat')
94+
Example:
95+
Evaluator(llm_config={
96+
'use_llm': True,
97+
'llm_base_url': 'https://api.deepseek.com',
98+
'llm_api_key': 'sk-xxxxxxxxxxxx',
99+
'llm_model': 'deepseek-chat',
100+
})
87101
"""
88-
89-
self._validate_llm_config()
102+
self._validate_llm_config(llm_config)
90103

91104
self.metric_calculator = MetricCalculator(metric_config)
92105
self.metric_config = metric_config or {}
93106

94-
def _validate_llm_config(self):
95-
"""验证LLM配置的完整性和有效性"""
107+
def _validate_llm_config(self, llm_config: Dict[str, Any] = None):
108+
"""Validate LLM configuration completeness and API connectivity."""
96109
import time
97110
from ..config import LLM_CONFIG
98111

99-
if LLM_CONFIG.get('use_llm', False):
100-
# 检查配置完整性
101-
if not LLM_CONFIG.get('llm_base_url') or not LLM_CONFIG.get('llm_api_key'):
112+
# External llm_config takes priority over config.py
113+
config = {**LLM_CONFIG, **(llm_config or {})}
114+
115+
if config.get('use_llm', False):
116+
if not config.get('llm_base_url') or not config.get('llm_api_key'):
102117
print("\n" + "=" * 60)
103-
print("❌ 错误:LLM配置不完整!")
118+
print("❌ Error: Incomplete LLM configuration!")
104119
print("-" * 60)
105-
print("当前 use_llm = True,但缺少必要的API配置。")
106-
print("\n请在 webmainbench/config.py 中完成以下配置:")
107-
print(" 1. llm_base_url (例如: 'https://api.deepseek.com')")
108-
print(" 2. llm_api_key (例如: 'sk-xxxxxxxxxxxx')")
109-
print("\n或者设置 use_llm = False 来禁用LLM功能。")
120+
print("'use_llm' is set to True, but required API settings are missing.")
121+
print("\nOption 1 - Pass config directly to Evaluator:")
122+
print(" Evaluator(llm_config={")
123+
print(" 'use_llm': True,")
124+
print(" 'llm_base_url': 'https://api.deepseek.com',")
125+
print(" 'llm_api_key': 'sk-xxxxxxxxxxxx',")
126+
print(" })")
127+
print("\nOption 2 - Edit webmainbench/config.py:")
128+
print(" 1. llm_base_url (e.g. 'https://api.deepseek.com')")
129+
print(" 2. llm_api_key (e.g. 'sk-xxxxxxxxxxxx')")
130+
print("\nOption 3 - Disable LLM: set use_llm = False")
110131
print("=" * 60 + "\n")
111132
sys.exit(1)
112133

113-
# 验证API有效性
114134
try:
115135
from openai import OpenAI
116136

117-
print("正在验证LLM API配置...")
137+
print("Validating LLM API configuration...")
118138
client = OpenAI(
119-
base_url=LLM_CONFIG.get('llm_base_url'),
120-
api_key=LLM_CONFIG.get('llm_api_key')
139+
base_url=config.get('llm_base_url'),
140+
api_key=config.get('llm_api_key')
121141
)
122142

123-
# 发送测试请求
124-
response = client.chat.completions.create(
125-
model=LLM_CONFIG.get('llm_model', 'deepseek-chat'),
143+
client.chat.completions.create(
144+
model=config.get('llm_model', 'deepseek-chat'),
126145
messages=[{"role": "user", "content": "test"}],
127146
max_tokens=5,
128147
temperature=0
129148
)
130149

131-
print("✅ LLM API配置验证成功!\n使用 基础方案➕LLM增强提取效果 进行评测。")
150+
print("✅ LLM API validated. Running evaluation with LLM enhancement.\n")
132151

133152
except Exception as e:
134153
print("\n" + "=" * 60)
135-
print("❌ 错误:LLM API配置无效!")
154+
print("❌ Error: LLM API validation failed!")
136155
print("-" * 60)
137-
print(f"验证失败原因: {str(e)}")
138-
print("\n请检查 webmainbench/config.py 中的配置:")
139-
print(" 1. llm_base_url 是否正确")
140-
print(" 2. llm_api_key 是否有效")
141-
print(" 3. llm_model 是否支持")
142-
print(" 4. 网络连接是否正常")
143-
print("\n或者设置 use_llm = False 来禁用LLM功能。")
156+
print(f"Reason: {str(e)}")
157+
print("\nPlease check:")
158+
print(" 1. llm_base_url is correct")
159+
print(" 2. llm_api_key is valid")
160+
print(" 3. llm_model is supported")
161+
print(" 4. Network connectivity")
162+
print("\nAlternatively, set use_llm = False to disable LLM functionality.")
144163
print("=" * 60 + "\n")
145164
sys.exit(1)
146165
else:
147-
# 未启用LLM的提示
148166
print("\n" + "=" * 60)
149-
print("⚠️ 注意:当前未启用LLM增强提取效果功能")
150-
print(" 如需启用LLM增强提取效果,请在 webmainbench/config.py 中配置:")
151-
print(" - 设置 use_llm = True")
152-
print(" - 填写 llm_base_url")
153-
print(" - 填写 llm_api_key")
167+
print("ℹ️ LLM enhancement is disabled. Running in baseline mode.")
168+
print(" To enable LLM enhancement, pass llm_config to Evaluator:")
169+
print(" Evaluator(llm_config={")
170+
print(" 'use_llm': True,")
171+
print(" 'llm_base_url': '...',")
172+
print(" 'llm_api_key': '...',")
173+
print(" })")
154174
print("=" * 60)
155-
print(" (5秒后使用基础方案进行对比...)")
175+
print(" Continuing in 5 seconds...")
156176
time.sleep(5)
157177
print()
158178

@@ -289,10 +309,10 @@ def evaluate_batched(self,
289309
all_sample_results = []
290310
all_extraction_errors = []
291311

292-
print(f"🔄 开始批处理评测")
293-
print(f" 数据集: {jsonl_file_path}")
294-
print(f" 批大小: {batch_size}")
295-
print(f" 最大样本数: {max_samples or '无限制'}")
312+
print(f"🔄 Starting batched evaluation")
313+
print(f" Dataset: {jsonl_file_path}")
314+
print(f" Batch size: {batch_size}")
315+
print(f" Max samples: {max_samples if max_samples is not None else 'unlimited'}")
296316

297317
start_time = time.time()
298318

@@ -311,17 +331,17 @@ def evaluate_batched(self,
311331
processed_samples += len(batch_samples)
312332
total_samples += len(batch_samples)
313333

314-
print(f" 已处理: {processed_samples} 样本")
334+
print(f" Processed: {processed_samples} samples")
315335

316336
# 如果有输出文件,可以立即写入避免内存累积
317337
if output_file and len(all_sample_results) > 1000:
318338
DataSaver.append_intermediate_results(all_sample_results, output_file)
319339
all_sample_results = [] # 清空已保存的结果
320340

321341
end_time = time.time()
322-
print(f"✅ 批处理评测完成")
323-
print(f" 总耗时: {end_time - start_time:.2f}")
324-
print(f" 处理样本: {processed_samples}")
342+
print(f"✅ Batched evaluation finished")
343+
print(f" Elapsed: {end_time - start_time:.2f}s")
344+
print(f" Samples processed: {processed_samples}")
325345

326346
# 聚合结果
327347
overall_metrics = self._aggregate_metrics(all_sample_results)
@@ -363,7 +383,7 @@ def _process_batch(self, batch_samples: List[DataSample], extractor: BaseExtract
363383
})
364384

365385
except Exception as e:
366-
print(f"⚠️ 样本 {sample.id} 评测失败: {e}")
386+
print(f"⚠️ Sample {sample.id} evaluation failed: {e}")
367387
batch_errors.append({
368388
'sample_id': sample.id,
369389
'error': str(e),

webmainbench/metrics/base_content_splitter.py

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,16 @@
66
from openai import OpenAI
77

88

9+
def _metrics_debug(message: str) -> None:
10+
"""Print diagnostics only when METRICS_DEBUG is True (see webmainbench/config.py)."""
11+
try:
12+
from ..config import METRICS_DEBUG
13+
except ImportError:
14+
METRICS_DEBUG = False
15+
if METRICS_DEBUG:
16+
print(f"[DEBUG] {message}")
17+
18+
919
class BaseContentSplitter(ABC):
1020
"""抽象基类,用于从文本中提取特定类型的内容"""
1121

@@ -58,7 +68,7 @@ def should_use_llm(self, field_name: str) -> bool:
5868
def enhance_with_llm(self, basic_results: List[str], cache_key: str = None) -> List[str]:
5969
"""使用LLM增强基本提取结果"""
6070
if not basic_results:
61-
print(f"[DEBUG] 输入内容为空,跳过LLM增强")
71+
_metrics_debug("Empty input; skipping LLM enhancement")
6272
return []
6373

6474
# 生成缓存键
@@ -73,10 +83,10 @@ def enhance_with_llm(self, basic_results: List[str], cache_key: str = None) -> L
7383
try:
7484
with open(cache_file, 'r', encoding='utf-8') as f:
7585
cached_result = json.load(f)
76-
print(f"[DEBUG] 从缓存加载LLM增强结果: {len(cached_result)} ")
86+
_metrics_debug(f"Loaded LLM-enhanced result from cache: {len(cached_result)} items")
7787
return cached_result
7888
except Exception as e:
79-
print(f"[DEBUG] 缓存读取失败: {e}")
89+
_metrics_debug(f"Cache read failed: {e}")
8090

8191
# 实际的LLM增强逻辑
8292
try:
@@ -86,13 +96,13 @@ def enhance_with_llm(self, basic_results: List[str], cache_key: str = None) -> L
8696
try:
8797
with open(cache_file, 'w', encoding='utf-8') as f:
8898
json.dump(enhanced_results, f, ensure_ascii=False, indent=2)
89-
print(f"[DEBUG] LLM增强结果已缓存到: {cache_file}")
99+
_metrics_debug(f"LLM-enhanced result cached at: {cache_file}")
90100
except Exception as e:
91-
print(f"[DEBUG] 缓存保存失败: {e}")
101+
_metrics_debug(f"Cache write failed: {e}")
92102

93103
return enhanced_results
94104
except Exception as e:
95-
print(f"[DEBUG] LLM增强失败: {type(e).__name__}: {e}")
105+
_metrics_debug(f"LLM enhancement failed: {type(e).__name__}: {e}")
96106
return basic_results
97107

98108
@abstractmethod

webmainbench/metrics/code_extractor.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
import re
33
from typing import List, Dict, Any
44

5-
from .base_content_splitter import BaseContentSplitter
5+
from .base_content_splitter import BaseContentSplitter, _metrics_debug
66

77

88
class CodeSplitter(BaseContentSplitter):
@@ -87,5 +87,5 @@ def extract_basic(self, text: str) -> List[str]:
8787

8888
def _llm_enhance(self, basic_results: List[str]) -> List[str]:
8989
"""使用LLM增强代码提取结果(未实现)"""
90-
print(f"[DEBUG] 代码LLM增强功能尚未实现,返回原始结果")
90+
_metrics_debug("Code LLM enhancement not implemented; returning raw results")
9191
return basic_results

webmainbench/metrics/formula_extractor.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import re
22
from typing import List
3-
from .base_content_splitter import BaseContentSplitter
3+
from .base_content_splitter import BaseContentSplitter, _metrics_debug
44

55

66
class FormulaSplitter(BaseContentSplitter):
@@ -50,13 +50,13 @@ def extract(self, text: str, field_name: str = None) -> str:
5050
"""提取数学公式"""
5151
regex_formulas = self.extract_basic(text)
5252
if self.should_use_llm(field_name):
53-
print(f"[DEBUG] 使用LLM增强公式提取")
53+
_metrics_debug("Using LLM-enhanced formula extraction")
5454
formula_parts = self.enhance_with_llm(regex_formulas)
5555
if not formula_parts:
56-
print("[DEBUG] LLM增强后无有效公式")
56+
_metrics_debug("No valid formulas after LLM enhancement")
5757
else:
5858
formula_parts = regex_formulas
59-
print("[DEBUG] 跳过LLM增强,使用基础正则结果")
59+
_metrics_debug("Skipping LLM enhancement; using regex-only results")
6060
return '\n'.join(formula_parts)
6161

6262
def extract_basic(self, text: str) -> List[str]:
@@ -89,7 +89,7 @@ def extract_basic(self, text: str) -> List[str]:
8989
def _llm_enhance(self, basic_results: List[str]) -> List[str]:
9090
"""使用LLM增强公式提取结果"""
9191
if not self.client:
92-
print("[DEBUG] OpenAI客户端未初始化,返回基础提取结果")
92+
_metrics_debug("OpenAI client not initialized; returning basic extraction results")
9393
return basic_results
9494

9595
formulas_text = '\n'.join(basic_results)

0 commit comments

Comments
 (0)