Commit f73e2a81 f73e2a8106c4f54f3f03632606fcf3d8c9cea24f by 沈秋雨

修正prechunk链接出错

1 parent 89f85cbe
......@@ -21,6 +21,8 @@ RAGAS_GENERATOR_MODEL=gpt-4o-mini
RAGAS_JUDGE_MODEL=gpt-4o-mini
RAGAS_EMBEDDING_MODEL=text-embedding-3-small
RAGAS_ENABLE_THINKING=false
RAGAS_HTTP_KEEPALIVE=false
RAGAS_TESTSET_TRANSFORMS=single_hop_entities
TESTSET_SIZE=50
TESTSET_RAGAS_MODE=direct
......
......@@ -40,6 +40,8 @@ cp .env.example .env
- `RAGAS_EMBEDDING_BASE_URL` 指向 Infinity embedding 的 OpenAI-compatible `/v1`
- `RAGAS_*_MODEL` 是评估侧模型名称
- `RAGAS_ENABLE_THINKING=false` 只会在本评估项目的 RAGAS LLM 请求中发送 `chat_template_kwargs.enable_thinking=false`,不会改变 WeKnora 检索/问答服务的模型配置
- `RAGAS_HTTP_KEEPALIVE=false` 会让 RAGAS LLM 请求使用短连接,规避长流程中 async HTTP 连接清理问题
- `RAGAS_TESTSET_TRANSFORMS=single_hop_entities` 会让 `prechunked` 只运行单跳 QA 所需的实体抽取 transform;设为 `default` 可回到 Ragas 默认 prechunked transforms
## 首轮 Pilot
......
......@@ -297,12 +297,16 @@ TESTSET_RAGAS_MODE=direct
TESTSET_GENERATOR_MAX_TOKENS=4096
TESTSET_MAX_DOCUMENT_CHARS=2000
RAGAS_ENABLE_THINKING=false
RAGAS_HTTP_KEEPALIVE=false
RAGAS_TESTSET_TRANSFORMS=default
```
`direct` 模式会跳过 Ragas 默认的 `HeadlinesExtractor``SummaryExtractor``NERExtractor` 文档预处理链路,直接把 WeKnora chunks 组装成 Ragas KnowledgeGraph 并生成单跳 QA。`prechunked``langchain_docs` 仅用于对比实验,遇到本地 vLLM 结构化输出不稳定时不建议使用。
如果使用 Qwen thinking 模型,`RAGAS_ENABLE_THINKING=false` 会只在 RAGAS 请求里附加 `chat_template_kwargs.enable_thinking=false`,避免 RAGAS 的 JSON/Pydantic 结构化输出被 `Thinking Process` 前缀破坏;WeKnora 本身的检索问答链路不经过这些脚本,不会受影响。
如果 `prechunked` 模式在本地 vLLM 上出现 `Event loop is closed``APIConnectionError`,保持 `RAGAS_HTTP_KEEPALIVE=false`。如果想验证 Ragas 默认 prechunked transforms,可临时设置 `RAGAS_TESTSET_TRANSFORMS=default`,但它会重新启用 summary/filter/theme/relationship 等更重的中间步骤。
如果 vLLM 仍然报生成未完成,先把 `TESTSET_SIZE` 降到 3,再把 `TESTSET_MAX_DOCUMENT_CHARS` 调到 1000-1500 验证链路;`ragas.max_tokens` 主要用于后续评测阶段,不应该拿来无限放大测试集生成阶段的输出长度。
### WeKnora 问答没有 retrieved_contexts
......
......@@ -73,6 +73,8 @@ ragas:
judge_model: "${RAGAS_JUDGE_MODEL}"
embedding_model: "${RAGAS_EMBEDDING_MODEL}"
enable_thinking: "${RAGAS_ENABLE_THINKING:-false}"
http_keepalive: "${RAGAS_HTTP_KEEPALIVE:-false}"
testset_transforms: "${RAGAS_TESTSET_TRANSFORMS:-single_hop_entities}"
temperature: 0
max_tokens: 4096
timeout_seconds: 600
......
......@@ -10,8 +10,21 @@ def chat_extra_body(config: dict[str, Any]) -> dict[str, Any]:
def chat_openai_kwargs(config: dict[str, Any]) -> dict[str, Any]:
kwargs: dict[str, Any] = {}
extra_body = chat_extra_body(config)
return {"extra_body": extra_body} if extra_body else {}
if extra_body:
kwargs["extra_body"] = extra_body
if not _as_bool(config.get("http_keepalive", False)):
try:
import httpx
except ImportError:
return kwargs
timeout_seconds = float(config.get("timeout_seconds", 600))
limits = httpx.Limits(max_connections=1, max_keepalive_connections=0)
timeout = httpx.Timeout(timeout_seconds)
kwargs["http_client"] = httpx.Client(limits=limits, timeout=timeout)
kwargs["http_async_client"] = httpx.AsyncClient(limits=limits, timeout=timeout)
return kwargs
def _as_bool(value: Any) -> bool:
......
......@@ -20,6 +20,7 @@ from ragas.testset.synthesizers.single_hop.base import (
from ragas.testset.synthesizers.single_hop.specific import (
SingleHopSpecificQuerySynthesizer,
)
from ragas.testset.transforms.extractors.llm_based import NERExtractor
from weknora_eval.config import require_config
from weknora_eval.loaders import read_jsonl, write_jsonl
......@@ -238,6 +239,7 @@ def _generate_ragas_prechunked(
return generator.generate_with_chunks(
documents,
testset_size=size,
transforms=_prechunked_transforms(ragas_config, ragas_llm),
query_distribution=[(SingleHopSpecificQuerySynthesizer(llm=ragas_llm), 1.0)],
run_config=run_config,
raise_exceptions=True,
......@@ -264,6 +266,19 @@ def _generate_ragas_langchain_docs(
return generator.generate_with_langchain_docs(documents, **generate_kwargs)
def _prechunked_transforms(ragas_config: dict[str, Any], ragas_llm: Any) -> Any:
mode = str(ragas_config.get("testset_transforms", "single_hop_entities"))
if mode == "default":
return None
if mode == "single_hop_entities":
return [NERExtractor(llm=ragas_llm, filter_nodes=_is_chunk_node)]
raise ValueError(f"Unsupported ragas.testset_transforms: {mode}")
def _is_chunk_node(node: Any) -> bool:
return getattr(getattr(node, "type", None), "name", "") == "CHUNK"
def _build_embeddings(
config: dict[str, Any], ragas_config: dict[str, Any]
) -> OpenAIEmbeddings:
......