Commit 5a879284 5a8792846d6cf6e590f6148fee68cd7cd89b69a1 by 沈秋雨

改为均衡抽样生成测试集

1 parent 67dc9bec
......@@ -71,7 +71,7 @@ python scripts/10_report.py
首轮建议只使用 2 个 PDF、1 个 XLSX 和 10 条审核通过 QA,确认 `retrieved_contexts``response`、Ragas 输入字段都正常后再扩展样本量。
默认 `04_parse_docs.py` 从 WeKnora 导出的 `data/exported/chunks.jsonl` 构造测试集来源,不再重复调用外部 PDF 解析器。`05_generate_testset.py` 默认使用 Ragas 结合评估侧 LLM 自动生成 QA;生成阶段使用 `TESTSET_RAGAS_MODE=direct`,直接把 WeKnora chunks 组装成 Ragas KnowledgeGraph 并生成单跳 QA,避免 Ragas 默认文档预处理链路重新抽标题、摘要和实体。生成阶段还会用 `TESTSET_MAX_DOCUMENT_CHARS` 限制单条来源上下文长度,并用 `TESTSET_GENERATOR_MAX_TOKENS` 控制生成输出预算,避免和后续评测用的 `ragas.max_tokens` 混在一起`local``mineru``rule_based` 只作为可选实验/兜底配置保留。
默认 `04_parse_docs.py` 从 WeKnora 导出的 `data/exported/chunks.jsonl` 构造测试集来源,不再重复调用外部 PDF 解析器。`05_generate_testset.py` 默认使用 Ragas 结合评估侧 LLM 自动生成 QA;生成阶段使用 `TESTSET_RAGAS_MODE=direct`,直接把 WeKnora chunks 组装成 Ragas KnowledgeGraph 并生成单跳 QA,避免 Ragas 默认文档预处理链路重新抽标题、摘要和实体。生成阶段还会用 `TESTSET_MAX_DOCUMENT_CHARS` 限制单条来源上下文长度,`TESTSET_GENERATOR_MAX_TOKENS` 控制生成输出预算,并按来源文件轮询抽样,避免测试集集中在单个文件`local``mineru``rule_based` 只作为可选实验/兜底配置保留。
## 主要产物
......
......@@ -298,7 +298,7 @@ TESTSET_GENERATOR_MAX_TOKENS=4096
TESTSET_MAX_DOCUMENT_CHARS=2000
RAGAS_ENABLE_THINKING=false
RAGAS_HTTP_KEEPALIVE=false
RAGAS_TESTSET_TRANSFORMS=default
RAGAS_TESTSET_TRANSFORMS=single_hop_entities
```
`direct` 模式会跳过 Ragas 默认的 `HeadlinesExtractor``SummaryExtractor``NERExtractor` 文档预处理链路,直接把 WeKnora chunks 组装成 Ragas KnowledgeGraph 并生成单跳 QA。`prechunked``langchain_docs` 仅用于对比实验,遇到本地 vLLM 结构化输出不稳定时不建议使用。
......
from __future__ import annotations
import asyncio
from collections import defaultdict
import inspect
import json
import logging
......@@ -71,7 +72,7 @@ def generate_ragas_testset(
return []
source_limit = min(len(source_rows), max(size * source_multiplier, size, 1))
selected_source_rows = source_rows[:source_limit]
selected_source_rows = _select_source_rows(source_rows, source_limit)
documents = [
Document(
page_content=_truncate_for_generation(row["content"], max_document_chars),
......@@ -85,9 +86,10 @@ def generate_ragas_testset(
for row in selected_source_rows
]
logger.info(
"Generating Ragas testset: target_size=%s source_documents=%s max_document_chars=%s generator_max_tokens=%s ragas_mode=%s",
"Generating Ragas testset: target_size=%s source_documents=%s source_files=%s max_document_chars=%s generator_max_tokens=%s ragas_mode=%s",
size,
len(documents),
len({row.get("source_file") or "unknown" for row in selected_source_rows}),
max_document_chars,
generator_max_tokens,
ragas_mode,
......@@ -129,6 +131,35 @@ def generate_ragas_testset(
return rows
def _select_source_rows(
source_rows: list[dict[str, Any]],
limit: int,
) -> list[dict[str, Any]]:
grouped: dict[str, list[dict[str, Any]]] = defaultdict(list)
source_order: list[str] = []
for row in source_rows:
source = str(row.get("source_file") or "unknown")
if source not in grouped:
source_order.append(source)
grouped[source].append(row)
selected: list[dict[str, Any]] = []
cursor = 0
while len(selected) < limit and source_order:
progressed = False
for source in source_order:
rows = grouped[source]
if cursor < len(rows):
selected.append(rows[cursor])
progressed = True
if len(selected) >= limit:
break
if not progressed:
break
cursor += 1
return selected
def _generate_ragas_direct_rows(
llm: ChatOpenAI,
documents: list[Document],
......